blade

a remote SSH command-line runner based on YAML recipe files.

View the Project on GitHub

Quickstart

Here we will create our first recipe that operates against a fictitious remote hostname called blade-dev. To follow along ensure you have an active internet connection and substitute blade-dev for some remote host that you can reach and execute commands on.

Create an empty directory under: ~/.blade/recipes to house recipe files.

> mkdir -p ~/.blade/recipes

Create a simple recipe file called hostname.blade.yaml.

> cat << EOF > ~/.blade/recipes/hostname.blade.yaml
hosts: ["blade-host"]
exec:
  - hostname
EOF

Invoke your new recipe by running Blade like so:

# Runs the recipe with default parameters.
> blade run hostname

You should the following output

2018/02/19 14:21:38 Starting recipe: hostname
blade-dev: blade-dev
2018/02/19 14:21:40 Completed recipe: hostname - 1 success | 0 failed | 1 total

Examples

TODO - show the most basic command: `./blade “hostname” -h somehost.com

.blade/recipes folder

The ~/.blade/recipes folder is special hidden folder that you should add in your user’s ~/ path. This folder is special because you can place all of your .blade.yaml files here organized in directory/command hierarchy to your liking. This affords you a place on your file-system to build a repository of recipe files that you may want to have also under source control such as github.

Tutorial

In this tutorial, we’re going to simulate creating a very basic command that we want to run on a infrastructure named: tutorial. Blade doesn’t care how you organize your folder hierarchy but you should model your folder hierachy based on the command hierarchy that you makes sense to you and your organization.

In the recipes/tutorial/ folder create this file and name it: hostname.blade.yaml. This file has a single command that will be run on a single host.

hosts: ["blade-dev"]
exec:
  - hostname

Place the file above in the following folder hierarchy.

recipes
└── tutorial
    └── hostname.blade.yaml

Run the following command:

./blade run
# Output below:
run [command]

Usage:
  blade run [command]

Available Commands:
  tutorial

Flags:
  -h, --help              help for run
  ...

Notice that Blade’s run command is aware of the tutorial folder. The run command is the primary entry point into executing .yaml files.

Now run the tutorial command and notice that you now have a hostname command available.

./blade run tutorial
Usage:
  blade run tutorial [command]

Available Commands:
  hostname

Flags:
  -h, --help   help for tutorial

The idea here is that a folder represents a command of which sub-commands can be executed. This implies that “folder” based command does nothing more than group sub-commands of which can be executed like so:

./blade run tutorial hostname
# Output below:
2018/02/15 22:15:44 Starting recipe: tutorial.hostname.blade.yaml
blade-dev: blade-dev
2018/02/15 22:15:46 Completed recipe: tutorial.hostname.blade.yaml - 1 success | 0 failed | 1 total

At this point, we’ve executed a single remote command called hostname on a single remote host called blade-dev. Let’s modify our single hostname.blade.yaml file to run on more hosts.

hosts: ["blade-dev", "blade-prod"]
exec:
  - hostname

Here we’ve defined another host we have access to and we can now rerun our command:

./blade run tutorial hostname
# Output below:
2018/02/15 22:19:14 Starting recipe: tutorial.hostname.blade.yaml
blade-dev: blade-dev
blade-prod: blade-prod
2018/02/15 22:19:17 Completed recipe: tutorial.hostname.blade.yaml - 2 success | 0 failed | 2 total

As you can see, Blade has now executed a single command on each remote host. This execution happened in a serial fashion where only a single host was executed at a time.

Let’s modify the hostname.blade.yaml to execute an additional command per host and save that change.

hosts: ["blade-dev", "blade-prod"]
exec:
  - hostname
  - sleep 5

Rerun the command: ./blade run tutorial hostname and observe that for each host running there is a 5 second delay due to the sleep command. This means, that because we execute these commands in serial on one host first, then the other Blade will take a total of 10 seconds to complete for both hosts.

But, with the power of concurrency, we can update our hostname.blade.yaml file to have our commands executed at a concurrency level of 2. Let’s also add a third echo command so we can observe how this changes the behavior of our run.

hosts: ["blade-dev", "blade-prod"]
exec:
  - echo "starting `hostname`"
  - sleep 5
overrides:
  concurrency: 2

Rerun the command: /.blade run tutorial hostname and now observe that because we added a concurrency override of 2 and even though we have a sleep delay of 5 seconds, both servers start and execute these remote commands and the entire Blade session finishes in about 5 seconds.

Instead of updating our hostname.blade.yaml file we additionally could have used Blade’s command-line flags to override the concurrency behavior like so:

./blade run tutorial hostname -c2 # or --concurrency 2

This effectively acheives the same thing but instead controls the concurrency amount via the usage of an ad-hoc command line flag.

Features

Possible Future Features