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' }
I usually run it this way:
$ 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" }
This can be called like this:
$ 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
No comments:
Post a Comment