Open smklein opened 3 years ago
I'm trying to create a setup where I have "one VM for development", and "one VM under test" - it's kinda a pain to try to remember which IP address is associated with which one, so this is a little shortcut to make my workflow better.
I have a pattern I end up using a bit that might help here. I have a script, _nc_virsh
, (in my ~/bin
which is in my $PATH
):
#!/bin/bash
# vim: set ts=8 sts=8 sw=8 noet:
fatal() {
local rc=$1
local msg=$2
shift 2
printf "ERROR: $msg\n" "$@" >&2
exit $rc
}
DOMAIN="$1"
LOOKUPHOST="$2"
LOOKUPPORT="$3"
if [[ -z $DOMAIN || -z $LOOKUPHOST || -z $LOOKUPPORT ]]; then
fatal 2 'missing arguments'
fi
sans_domain=$(sed "s/\\.${DOMAIN}\$//" <<< "$LOOKUPHOST")
if ! res=$(virsh domifaddr "$sans_domain"); then
fatal 3 'could not look up libvirt domain "%s"\n' "$sans_domain"
fi
if ! ip=$(awk '$3 == "ipv4" { gsub("/.*", "", $4);
print($4); exit(0); }' <<< "$res") || [[ -z "$ip" ]]; then
fatal 4 'could not locate IP address for "%s"\n' "$sans_domain"
fi
printf 'translating "%s" --> %s\n' "$sans_domain" "$ip" >&2
exec nc "$ip" "$LOOKUPPORT"
I then configure an entry in ~/.ssh/config
:
Host *.vm
User jclulow
ProxyCommand _nc_virsh vm %h %p
ForwardAgent yes
ServerAliveInterval 15
When ssh
is figuring out how to connect, if it matches the *.vm
wildcard then this entry gets used. For example, if I ssh helios.vm
, it invokes the script: _nc_virsh vm helios.vm 22
. The script then uses virsh
(as you've done in your helper) the get the IP address and invokes nc
as a ProxyCommand
to start the connection:
$ ssh root@helios.vm
translating "helios" --> 192.168.122.15
The illumos Project master-0-g8af575c0af December 2020
root@helios:~# logout
Connection to helios.vm closed.
$ ssh helios.vm
translating "helios" --> 192.168.122.15
The illumos Project master-0-g8af575c0af December 2020
You have new mail.
jclulow@helios:~$ logout
Connection to helios.vm closed.
It has the advantage that it will work for other tools that leverage ssh
like rsync
and scp
and git
:
$ rsync root@helios.vm:./
translating "helios" --> 192.168.122.15
drwx------ 6 2020/12/04 02:08:32 .
-rw------- 37 2020/12/04 02:08:32 .bash_history
-rw-r--r-- 158 2020/12/02 11:28:33 .bashrc
-rw-r--r-- 377 2020/12/02 11:28:33 .profile
drwx------ 3 2020/12/04 00:19:35 .ssh
It will correctly fail to connect if the domain you specify is not running or doesn't exist:
$ ssh tribblix.vm
error: Failed to query for interfaces addresses
error: Requested operation is not valid: domain is not running
ERROR: could not look up libvirt domain "tribblix"
What do you think?
I have a pattern I end up using a bit that might help here. I have a script,
_nc_virsh
, (in my~/bin
which is in my$PATH
):#!/bin/bash # vim: set ts=8 sts=8 sw=8 noet: fatal() { local rc=$1 local msg=$2 shift 2 printf "ERROR: $msg\n" "$@" >&2 exit $rc } DOMAIN="$1" LOOKUPHOST="$2" LOOKUPPORT="$3" if [[ -z $DOMAIN || -z $LOOKUPHOST || -z $LOOKUPPORT ]]; then fatal 2 'missing arguments' fi sans_domain=$(sed "s/\\.${DOMAIN}\$//" <<< "$LOOKUPHOST") if ! res=$(virsh domifaddr "$sans_domain"); then fatal 3 'could not look up libvirt domain "%s"\n' "$sans_domain" fi if ! ip=$(awk '$3 == "ipv4" { gsub("/.*", "", $4); print($4); exit(0); }' <<< "$res") || [[ -z "$ip" ]]; then fatal 4 'could not locate IP address for "%s"\n' "$sans_domain" fi printf 'translating "%s" --> %s\n' "$sans_domain" "$ip" >&2 exec nc "$ip" "$LOOKUPPORT"
I then configure an entry in
~/.ssh/config
:Host *.vm User jclulow ProxyCommand _nc_virsh vm %h %p ForwardAgent yes ServerAliveInterval 15
When
ssh
is figuring out how to connect, if it matches the*.vm
wildcard then this entry gets used. For example, if Issh helios.vm
, it invokes the script:_nc_virsh vm helios.vm 22
. The script then usesvirsh
(as you've done in your helper) the get the IP address and invokesnc
as aProxyCommand
to start the connection:$ ssh root@helios.vm translating "helios" --> 192.168.122.15 The illumos Project master-0-g8af575c0af December 2020 root@helios:~# logout Connection to helios.vm closed. $ ssh helios.vm translating "helios" --> 192.168.122.15 The illumos Project master-0-g8af575c0af December 2020 You have new mail. jclulow@helios:~$ logout Connection to helios.vm closed.
It has the advantage that it will work for other tools that leverage
ssh
likersync
andscp
andgit
:$ rsync root@helios.vm:./ translating "helios" --> 192.168.122.15 drwx------ 6 2020/12/04 02:08:32 . -rw------- 37 2020/12/04 02:08:32 .bash_history -rw-r--r-- 158 2020/12/02 11:28:33 .bashrc -rw-r--r-- 377 2020/12/02 11:28:33 .profile drwx------ 3 2020/12/04 00:19:35 .ssh
It will correctly fail to connect if the domain you specify is not running or doesn't exist:
$ ssh tribblix.vm error: Failed to query for interfaces addresses error: Requested operation is not valid: domain is not running ERROR: could not look up libvirt domain "tribblix"
What do you think?
So, first impressions: That's extremely rad, and I plan on playing with my ssh config way more now that I know it applies to this suite of commands.
The only thing that bums me out about that current implementation is that it requires some... manual intervention to make things work (custom script, custom path, custom config). I updated this PR to incorporate basically everything you did, but hopefully make it easier for folks checking out this repo for the first time.
TL;DR:
ssh_setup.sh
adds the ssh config, pointing to the _nc_virsh.sh
script within the repo_nc_virsh.sh
acts more-or-less exactly like your version, but with minor usability tweaks (listing valid domains if the user misspells something).
Usage: