Skip to content

Instantly share code, notes, and snippets.

@rogual
Forked from mheiges/vcssh
Last active August 20, 2018 13:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rogual/b1659e708750b5c3050276ad056eea1f to your computer and use it in GitHub Desktop.
Save rogual/b1659e708750b5c3050276ad056eea1f to your computer and use it in GitHub Desktop.
wrapper for Vagrant ssh that manages a ControlMaster for instant ssh connections
#!/bin/bash
# ssh to vagrant hosts can be slow due to Ruby overhead of running
# 'vagrant ssh' and ssh overhead to setup the network connection.
#
# This wrapper uses that slow setup routine once to create a reusable ssh
# ControlMaster socket. Subsequent connections invoke the ssh executable
# directly (bypassing Ruby) and connect over the ControlMaster socket
# (bypassing the connection setup) so are almost instantaneous.
#
# Example usage,
# vcssh el6
#
# A ControlMaster is created for each user so
# vcssh el6 -- -l joeuser
# should work as well.
#
# navigate up directory tree until .vagrant directory is found
# or we hit /.
while : ; do
[[ "$PWD" == '/' ]] && {
echo .vagrant directory not found
exit 1
}
control_dir=$PWD/.vagrant
[[ -d $control_dir ]] && break
cd ..
done
vagrant_args=()
ssh_args=()
sep='-- '
args="$@"
case $args in
(*"$sep"*)
vagrant_args=(${args%%"$sep"*})
ssh_args=(${args#*"$sep"})
;;
(*)
vagrant_args=($args)
ssh_args=()
;;
esac
# extract any login name in the ssh args so we can
# create a distinct controlmaster channel for the user.
for i in "${!ssh_args[@]}"; do
arg=${ssh_args[$i]}
case $arg in
('-l')
ssh_user="${ssh_args[$i+1]}"
;;
('-l'*)
ssh_user="${arg#-l}"
;;
('reset'*)
RM_CONTROLMASTER=1
;;
esac
done
[[ -n "$ssh_user" ]] && ssh_user_prefix="${ssh_user}_"
vm_name=${vagrant_args:-default}
control_path=."vagrant/machines/${vm_name}/${ssh_user_prefix}sshcontrolmaster"
if [[ "$RM_CONTROLMASTER" -eq "1" ]]; then
rm -rf $control_path
echo 'controlmaster removed'
exit
fi
#echo ssh_args ${ssh_args[@]}; echo vm_name "'$vm_name'";exit
if [[ -S "$control_path" ]]; then
if ! echo | nc -U "$control_path" > /dev/null; then
echo "removing stale controlmaster socket"
rm -f "$control_path"
fi
fi
if [[ ! -S $control_path ]]; then
vagrant ssh-config $vm_name | ssh -t -t -fN \
-F /dev/stdin \
-o 'ControlPersist=4h' \
-o 'ControlMaster auto' \
-o "ControlPath $control_path" "$vm_name" \
${ssh_args[@]}
fi
ssh -o ControlPath=${control_path} ${vm_name} ${ssh_args[@]}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment