This tutorial is designed to get you up and running with Rucksack. It assumes that you've already got Rucksack installed. If it's not installed yet, head over to the README and install it before proceeding (or just run pip install rucksack
).
By the end of this tutorial, you will understand how to write a Rucksack config file.
You will need access to a Linux host (either remote over SSH, or localhost).
Rucksack uses nested YAML dictionaries in its config file. These are then used to create auto-completions. The easiest way to understand the syntax is by example, so let's start simple.
Imagine that you always run uptime && echo && free -h && echo && df -h
as a quick one-liner when logging into a system to troubleshoot. Typing that out (or even remembering it) sounds tedious, so let's put that into a file in your local directory called rucksack.yml
:
system:
performance:
get-basic-info:
command: "uptime && echo && free -h && echo && df -h"
Once you've got a rucksack.yml
, fire up Rucksack: ruck --host ${host or IP address}
(if no --host
is specified, then Rucksack will use localhost
by default).
Rucksack will connect to the remote host over SSH (unless you specify localhost
or 127.0.0.1
) and you can start using it to execute your basic command:
That was a simple one-liner, so let's get more advanced. Imagine that you have another useful one-liner to find the 10 largest files in a directory, but you want the ability to specify the directory as an argument. Easy! Rucksack renders out commands using Jinja templates.
Add the following to your rucksack.yml
and give it a shot:
storage:
find-largest-files:
command: du -h -d 1 {{ directory }} | sort -hr | head -n 10
args:
- directory:
mandatory: True
That's cool, but what if you wanted to have your most common directories as suggested arguments, and just default to /var/log
if no argument is provided?
Let's update the storage find-largest-files
command to provide some options to the user:
storage:
find-largest-files:
command: du -h -d 1 {{ directory }} | sort -hr | head -n 10
args:
- directory:
mandatory: True
default: /var/log
values:
- /etc
- /home
- /var/log
This is starting to look more useful, but there's still that hardcoded value of 10
for head -n 10
. What if we wanted head
to only append -n
if we provided a value? And while we're at it, let's make the du
depth an argument:
storage:
find-largest-files:
command: du -h -d {{ depth }} {{ directory }} | sort -hr | head
args:
- directory:
mandatory: True
default: /var/log
values:
- /etc
- /home
- /var/log
- depth:
mandatory: True
default: 1
- num_files:
arg_string: -n {{ num_files }}
When an argument has an arg_string
, it is only rendered and appended to the command when the argument is specified. Because the arg_string
is appended to the command
, this only works if you are adding an argument to the final command in a long one-liner. For example: this wouldn't work for the sort
command in our example.
Static argument values, like the ones we've seen so far, are great. But what if the value of your argument is actually the output of another command?
For example: running the smartctl
command to check disk health is useful, but how do you know the names of the disks on your system? Every system is different, and you can't rely on a static list of potential argument values.
Imagine that you run lsblk -d -o NAME | tail -n +2 | grep -v loop
to find block devices on your system. You can have rucksack
present the output of a command, such as this one, as potential argument values. Let's add a new section and command to rucksack.yml
:
disk:
get-health:
command: sudo smartctl -a /dev/{{ disk }}
args:
- disk:
mandatory: True
from_command: lsblk -d -o NAME | tail -n +2 | grep -v loop
Be aware that command output is cached, so this approach might not be appropriate for values that change often.
If you've made it this far, you have a good idea of how to write a Rucksack config file. Congratulations! Next time you come across a useful one-liner, throw it into a Rucksack config and save your brain the trouble of memorizing it.
This is pretty much all there is to Rucksack. Feel free to review the README for additional info, such as where to put your config files, or how to enable logging. And of course, feel free to open an issue (or a PR) if you find any problems.