howto/cumin: Document my trick for automatically setting up an ssh tunnel authored by lelutin's avatar lelutin
I was tired of having to remember how to manually set this up after
having been yelled at by cumin.
......@@ -19,21 +19,24 @@ documented.
## Installation
### Virtualenv / pip
### Debian package
If Cumin is not available from your normal packages (see [bug 924685][]
for Debian), you must install it in a [Python virtualenv][].
cumin has been available through debian archives since boorkworm, so you can
simply:
[bug 924685]: https://bugs.debian.org/924685
sudo apt install cumin
First, install dependencies, Cumin and some patches:
If your distro does not have packages available, you can also install with a
python virtualenv. See the section below for how to achieve this.
sudo apt install python3-clustershell python3-pyparsing python3-requests python3-tqdm python3-yaml
python3 -m venv --system-site-packages ~/.virtualenvs/cumin
~/.virtualenvs/cumin/bin/pip3 install cumin
~/.virtualenvs/cumin/bin/pip3 uninstall tqdm pyparsing clustershell # force using trusted system packages
### Initial configuration
`cumin` is relatively useless for us if it doesn't poke puppetdb to resolve
which hosts to run commands on. So we want to get it to talk to puppetdb. Also,
it gets pretty annoying to have to manually setup the ssh tunnel after getting
an error printed out by cumin, so we can get the tunnel setup automatically.
Then drop the following configuration in
Once cumin is installed drop the following configuration in
`~/.config/cumin/config.yaml`:
transport: clustershell
......@@ -45,15 +48,112 @@ Then drop the following configuration in
log_file: cumin.log
default_backend: puppetdb
From here on we'll assume you use the following alias:
Now you can simply use an alias like the following:
alias cumin="~/.virtualenvs/cumin/bin/cumin --config ~/.config/cumin/config.yaml"
alias cumin="cumin --config ~/.config/cumin/config.yaml"
You should also make sure your machine has access to the PuppetDB
server configured above, with:
while making sure that you setup an ssh tunnel manually before calling cumin
like the following:
ssh -L8080:localhost:8080 puppetdb-01.torproject.org
Or instead of the alias and the ssh command, you can try setting up an
automatic tunnel upon calling `cumin`. See the following section to set that
up.
### Automatic tunneling to puppetdb with bash + systemd unit
This trick makes sure that you never forget to setup the ssh tunnel to puppedb
before running `cumin`. This section will replace `cumin` by a bash function,
so if you created a simple alias like mentioned in the previous section, you
should start by getting rid of that alias. Lastly, this trick requires `nc` in
order to verify if the tunnel port is open so, install it with:
sudo apt install nc
To get the automatic tunnel, we'll create a systemd unit that can bring the
tunnel up for us. Create the file
`~/.config/systemd/user/puppetdb-tunnel.service`, making sure to create the
missing directories in the path:
```systemd
[Unit]
Description=Setup port forward to puppetdb
After=network.target
[Service]
ExecStart=/usr/bin/ssh -nNT -o ExitOnForwardFailure=yes puppetdb-01.torproject.org
KillMode=mixed
```
With this in place, make sure that systemd has loaded this unit file:
systemd --user daemon-reload
The last missing piece is to create something that'll intercept `cumin` commands
and check whether your tunnel to puppetdb is currently listening and if not,
start the tunnel before handing your arguments to the actual `cumin` command.
Somewhere in your `~/.bashrc`, add the following:
# All output for starting the tunnel is on stderr so it can be filtered out if
# needed.
function cumin () {
if ! nc -z localhost 8080 2>/dev/null; then
echo -e "NOTE: starting tunnel with puppetdb, watch out for your token being sollicited" >&2
systemctl --user start puppetdb-tunnel.service
for i in {0..60}; do
if nc -z localhost 8080 2>/dev/null; then
# Clear line from the pesky wait dots
echo "" >&2
break
else
if [[ $i -eq 60 ]]; then
echo "error: tunnel not started correctly, bailing out" >&2
return 1
fi
echo -n "." >&2
sleep 1
fi
done
fi
# Now hand off the arguments to actually run cumin
/usr/bin/cumin --config=~/.config/cumin/config.yaml "$@"
}
With this set, now when you call `cumin [...]`, an ssh tunnel will be brought
up if needed, which could require you to confirm the ssh connection on your
token so keep an eye out for that.
The tunnel will keep running in the background so subsequent calls to cumin
will just go through immediately. If you ever want to tear down the ssh tunnel,
you can do so with this:
systemctl --user stop puppetdb-tunnel.service
### Virtualenv / pip
If Cumin is not available from your normal packages (see [bug 924685][]
for Debian), you must install it in a [Python virtualenv][].
[bug 924685]: https://bugs.debian.org/924685
First, install dependencies, Cumin and some patches:
sudo apt install python3-clustershell python3-pyparsing python3-requests python3-tqdm python3-yaml
python3 -m venv --system-site-packages ~/.virtualenvs/cumin
~/.virtualenvs/cumin/bin/pip3 install cumin
~/.virtualenvs/cumin/bin/pip3 uninstall tqdm pyparsing clustershell # force using trusted system packages
Now if you follow the initial setup section above, then you can either create
an alias in the following way:
alias cumin="~/.virtualenvs/cumin/bin/cumin --config ~/.config/cumin/config.yaml"
Or you can instead use the automatic ssh tunnel trick above, making sure to
change the path to cumin in the bash function.
## Example commands
This will run the `uptime` command on all hosts:
......
......