a remote SSH command-line runner based on YAML recipe files.
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
TODO - show the most basic command: `./blade “hostname” -h somehost.com
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.
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.