Some fun updates for vagrant hackers… I wanted to use the venerable clustered SSH (cssh
) and screen
with vagrant. I decided to expand on my vsftp
script. First read:
and
to get up to speed on the background information.
Vagrant screen:
First, a simple screen
hack… I often use my vssh
alias to quickly ssh into a machine, but I don’t want to have to waste time with sudo
-ing to root and then running screen
each time. Enter vscreen
:
# vagrant screen
function vscreen {
[ "$1" = '' ] || [ "$2" != '' ] && echo "Usage: vscreen <vm-name> - vagrant screen" 1>&2 && return 1
wd=`pwd` # save wd, then find the Vagrant project
while [ "`pwd`" != '/' ] && [ ! -e "`pwd`/Vagrantfile" ] && [ ! -d "`pwd`/.vagrant/" ]; do
#echo "pwd is `pwd`"
cd ..
done
pwd=`pwd`
cd $wd
if [ ! -e "$pwd/Vagrantfile" ] || [ ! -d "$pwd/.vagrant/" ]; then
echo 'Vagrant project not found!' 1>&2 && return 2
fi
d="$pwd/.ssh"
f="$d/$1.config"
h="$1"
# hostname extraction from user@host pattern
p=`expr index "$1" '@'`
if [ $p -gt 0 ]; then
let "l = ${#h} - $p"
h=${h:$p:$l}
fi
# if mtime of $f is > than 5 minutes (5 * 60 seconds), re-generate...
if [ `date -d "now - $(stat -c '%Y' "$f" 2> /dev/null) seconds" +%s` -gt 300 ]; then
mkdir -p "$d"
# we cache the lookup because this command is slow...
vagrant ssh-config "$h" > "$f" || rm "$f"
fi
[ -e "$f" ] && ssh -t -F "$f" "$1" 'screen -xRR'
}
$ vscreen root@machine
which logs in as root, to machine and gets me (back) into screen
. This is almost identical to the vsftp script which I explained in an earlier blog post.
Vagrant cssh:
First you’ll need to install cssh
. On my Fedora machine it’s as easy as:
# yum install -y clusterssh
I’ve been hacking a lot on Puppet-Gluster lately, and occasionally multi-machine hacking demands multi-machine key punching. Enter vcssh
:
# vagrant cssh
function vcssh {
[ "$1" = '' ] && echo "Usage: vcssh [options] [user@]<vm1>[ [user@]vm2[ [user@]vmN...]] - vagrant cssh" 1>&2 && return 1
wd=`pwd` # save wd, then find the Vagrant project
while [ "`pwd`" != '/' ] && [ ! -e "`pwd`/Vagrantfile" ] && [ ! -d "`pwd`/.vagrant/" ]; do
#echo "pwd is `pwd`"
cd ..
done
pwd=`pwd`
cd $wd
if [ ! -e "$pwd/Vagrantfile" ] || [ ! -d "$pwd/.vagrant/" ]; then
echo 'Vagrant project not found!' 1>&2 && return 2
fi
d="$pwd/.ssh"
cssh="$d/cssh"
cmd=''
cat='cat '
screen=''
options=''
multi='f'
special=''
for i in "$@"; do # loop through the list of hosts and arguments!
#echo $i
if [ "$special" = 'debug' ]; then # optional arg value...
special=''
if [ "$1" -ge 0 -o "$1" -le 4 ]; then
cmd="$cmd $i"
continue
fi
fi
if [ "$multi" = 'y' ]; then # get the value of the argument
multi='n'
cmd="$cmd '$i'"
continue
fi
if [ "${i:0:1}" = '-' ]; then # does argument start with: - ?
# build a --screen option
if [ "$i" = '--screen' ]; then
screen=' -o RequestTTY=yes'
cmd="$cmd --action 'screen -xRR'"
continue
fi
if [ "$i" = '--debug' ]; then
special='debug'
cmd="$cmd $i"
continue
fi
if [ "$i" = '--options' ]; then
options=" $i"
continue
fi
# NOTE: commented-out options are probably not useful...
# match for key => value argument pairs
if [ "$i" = '--action' -o "$i" = '-a' ] || \
[ "$i" = '--autoclose' -o "$i" = '-A' ] || \
#[ "$i" = '--cluster-file' -o "$i" = '-c' ] || \
#[ "$i" = '--config-file' -o "$i" = '-C' ] || \
#[ "$i" = '--evaluate' -o "$i" = '-e' ] || \
[ "$i" = '--font' -o "$i" = '-f' ] || \
#[ "$i" = '--master' -o "$i" = '-M' ] || \
#[ "$i" = '--port' -o "$i" = '-p' ] || \
#[ "$i" = '--tag-file' -o "$i" = '-c' ] || \
[ "$i" = '--term-args' -o "$i" = '-t' ] || \
[ "$i" = '--title' -o "$i" = '-T' ] || \
[ "$i" = '--username' -o "$i" = '-l' ] ; then
multi='y' # loop around to get second part
cmd="$cmd $i"
continue
else # match single argument flags...
cmd="$cmd $i"
continue
fi
fi
f="$d/$i.config"
h="$i"
# hostname extraction from user@host pattern
p=`expr index "$i" '@'`
if [ $p -gt 0 ]; then
let "l = ${#h} - $p"
h=${h:$p:$l}
fi
# if mtime of $f is > than 5 minutes (5 * 60 seconds), re-generate...
if [ `date -d "now - $(stat -c '%Y' "$f" 2> /dev/null) seconds" +%s` -gt 300 ]; then
mkdir -p "$d"
# we cache the lookup because this command is slow...
vagrant ssh-config "$h" > "$f" || rm "$f"
fi
if [ -e "$f" ]; then
cmd="$cmd $i"
cat="$cat $f" # append config file to list
fi
done
cat="$cat > $cssh"
#echo $cat
eval "$cat" # generate combined config file
#echo $cmd && return 1
#[ -e "$cssh" ] && cssh --options "-F ${cssh}$options" $cmd
# running: bash -c glues together --action 'foo --bar' type commands...
[ -e "$cssh" ] && bash -c "cssh --options '-F ${cssh}${screen}$options' $cmd"
}
$ vcssh annex{1..4} -l root
or like this:
$ vcssh root@hostname foo user@bar james@machine --action 'pwd'
which, as you can see, passes cssh
arguments through! Can you see any other special surprises in the code? Well, you can run vcssh
like this too:
$ vcssh root@foo james@bar --screen
which will perform exactly as vscreen
did above, but in cssh
!
You’ll see that the vagrant ssh-config
lookups are cached, so this will be speedy when it’s running hot, but expect a few seconds delay when you first run it. If you want a longer cache timeout, it’s easy to change yourself in the function.
I’ve uploaded the code here, so that you don’t have to copy+paste it from my blog!
Happy hacking,
James
You can follow James on Mastodon for more frequent updates and other random thoughts.
You can follow James on Twitter for more frequent updates and other random thoughts.
You can support James on GitHub if you'd like to help sustain this kind of content.
You can support James on Patreon if you'd like to help sustain this kind of content.
Your comment has been submitted and will be published if it gets approved.
Click here to see the patch you generated.
Comments
Nothing yet.
Post a comment