Created
April 4, 2012 03:35
-
-
Save jorgebraz/2297565 to your computer and use it in GitHub Desktop.
VirtualBox Headless VM helper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# SGR (Select Graphic Rendition) parameters | |
# Code Effect Note | |
# 0 Reset / Normal all attributes off | |
# 1 Bright (increased intensity) or Bold | |
# 2 Faint (decreased intensity) not widely supported | |
# 3 Italic: on not widely supported. Sometimes treated as inverse. | |
# 4 Underline: Single | |
# 5 Blink: Slow less than 150 per minute | |
# 6 Blink: Rapid MS-DOS ANSI.SYS; 150 per minute or more; not widely supported | |
# 7 Image: Negative inverse or reverse; swap foreground and background | |
# 8 Conceal not widely supported | |
# 9 Crossed-out Characters legible, but marked for deletion. Not widely supported. | |
# 10 Primary(default) font | |
# 11–19 n-th alternate font Select the n-th alternate font. 14 being the fourth alternate font, up to 19 being the 9th alternate font. | |
# 20 Fraktur hardly ever supported | |
# 21 Bright/Bold: off or Underline: Double bold off not widely supported, double underline hardly ever | |
# 22 Normal color or intensity neither bright, bold nor faint | |
# 23 Not italic, not Fraktur | |
# 24 Underline: None not singly or doubly underlined | |
# 25 Blink: off | |
# 26 Reserved | |
# 27 Image: Positive | |
# 28 Reveal conceal off | |
# 29 Not crossed out | |
# 30–37 Set text color 30 + x, where x is from the color table below | |
# 38 Set xterm-256 text color next arguments are 5;x where x is color index (0..255) | |
# 39 Default text color implementation defined (according to standard) | |
# 40–47 Set background color 40 + x, where x is from the color table below | |
# 48 Set xterm-256 background color next arguments are 5;x where x is color index (0..255) | |
# 49 Default background color implementation defined (according to standard) | |
# 50 Reserved | |
# 51 Framed | |
# 52 Encircled | |
# 53 Overlined | |
# 54 Not framed or encircled | |
# 55 Not overlined | |
# 56–59 Reserved | |
# 60 ideogram underline or right side line hardly ever supported | |
# 61 ideogram double underline or double hardly ever supported | |
# line on the right side | |
# 62 ideogram overline or left side line hardly ever supported | |
# 63 ideogram double overline or double hardly ever supported | |
# line on the left side | |
# 64 ideogram stress marking hardly ever supported | |
# 90–99 Set foreground color, high intensity aixterm (not in standard) | |
# 100–109 Set background color, high intensity aixterm (not in standard) | |
# Styled-echo. | |
# Argument $1 = message | |
# Argument $2 = color | |
# Argument $3 = style | |
# Argument $4 = background color | |
# Argument $5 = background color | |
function secho() | |
{ | |
if [ "$1" == "--help" ]; then | |
echo "help" | |
return | |
fi | |
local reset="\e[0m" | |
local style_bold='\e[1m' | |
local style_underline='\e[4m' | |
local style_blink='\e[5m' | |
local style_negative='\e[7m' | |
local style_default="$reset" | |
local color_black='\e[30m' | |
local color_red='\e[31m' | |
local color_green='\e[32m' | |
local color_yellow='\e[33m' | |
local color_blue='\e[34m' | |
local color_magenta='\e[35m' | |
local color_cyan='\e[36m' | |
local color_white='\e[37m' | |
local color_default='\e[39m' | |
local bg_black='\e[40m' | |
local bg_red='\e[41m' | |
local bg_green='\e[42m' | |
local bg_yellow='\e[43m' | |
local bg_blue='\e[44m' | |
local bg_magenta='\e[45m' | |
local bg_cyan='\e[46m' | |
local bg_white='\e[47m' | |
local bg_default='\e[49m' | |
local default_msg="This is the default message!" | |
color=$(eval "echo \$color_${2}") | |
style=$(eval "echo \$style_${3}") | |
background=$(eval "echo \$bg_${4}") | |
message=${1:-$default_msg} # Defaults to default message. | |
newline=${5:-1} # Defaults to default message. | |
if [ "$color" == "" ]; then | |
color=${color_default} # Defaults to black, if not specified. | |
fi | |
if [ "$style" == "" ]; then | |
style=${style_default} # Defaults to black, if not specified. | |
fi | |
if [ "$background" == "" ]; then | |
background=${bg_default} # Defaults to black, if not specified. | |
fi | |
if [ $newline -eq 1 ]; then | |
newline="\n" | |
else | |
newline="" | |
fi | |
printf "${style}${background}${color}${message}${reset}${newline}" | |
return | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
source "$(pwd)/secho.sh" | |
function start_spinner { | |
# $1 : msg to display | |
_spinner "start" "${1}" & | |
# set global spinner pid | |
_sp_pid=$! | |
disown | |
} | |
function stop_spinner { | |
# $1 : command exit status | |
_spinner "stop" $1 $_sp_pid | |
unset _sp_pid | |
} | |
function _spinner() { | |
# $1 start/stop | |
# | |
# on start: $2 display message | |
# on stop : $2 process exit status | |
# $3 spinner function pid (supplied from stop_spinner) | |
local on_success="DONE" | |
local on_fail="FAIL" | |
case $1 in | |
start) | |
# calculate the column where spinner and status msg will be displayed | |
let column=$(tput cols)-${#2}-8 | |
# display message and position the cursor in $column column | |
echo -ne ${2} | |
printf "%${column}s" | |
# start spinner | |
i=1 | |
sp='\|/-' | |
delay=0.15 | |
while : | |
do | |
if [ $i != 1 ]; then | |
printf "\b\b${sp:i++%${#sp}:1}]" | |
else | |
echo -n "[ " | |
printf "\b${sp:i++%${#sp}:1}]" | |
fi | |
#printf "\b${sp:i++%${#sp}:1}]" | |
sleep $delay | |
done | |
;; | |
stop) | |
if [[ -z ${3} ]]; then | |
echo "spinner is not running.." | |
exit 1 | |
fi | |
kill $3 > /dev/null 2>&1 | |
# inform the user uppon success or failure | |
printf "\b\b" | |
if [[ $2 -eq 0 ]]; then | |
#printf "${green}${on_success}${nc}" | |
secho "$on_success" green default default 0 | |
else | |
#printf "${red}${on_fail}${nc}" | |
secho "$on_fail" red negative default 0 | |
fi | |
echo -n "]" | |
echo "" | |
;; | |
*) | |
echo "invalid argument, try {start/stop}" | |
exit 1 | |
;; | |
esac | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
source "$(pwd)/secho.sh" | |
source "$(pwd)/spinner.sh" | |
SELECTED_VM="" | |
DOT_FOLDER=~/.vmh | |
CONF_FILE=~/.vmh/conf | |
SELECTED_VM_FILE=~/.vmh/selected_vm | |
function connect() # Connects to the selected Virtual Machine, starting it if needed | |
{ | |
local STATE=$(_state) | |
local SLEEP=15 | |
if [ "$STATE" == 'running' ]; then | |
echo "Starting a secure shell connection to $SELECTED_VM" | |
shell | |
fi | |
if [ "$STATE" != 'running' ]; then | |
read -n1 -s -p "The Virtual machine $VM is not started, do you want to start it? (Y/n)" ANSWER | |
case "$ANSWER" in | |
"" | [yY] | [yY][Ee][Ss] ) | |
start | |
echo "Starting a secure shell connection to $SELECTED_VM" | |
shell | |
;; | |
[nN] | [n|N][O|o] ) | |
echo "" | |
echo "Exiting"; | |
$(exit 1) | |
;; | |
* ) | |
echo "" | |
echo "y/n" | |
$(exit 1) | |
;; | |
esac | |
fi | |
} | |
function start() # Starts the selected Virtual Machine | |
{ | |
local STATE=$(_state) | |
local SLEEP=15 | |
if [ "$STATE" == 'running' ]; then | |
echo "The VM $VM is already powered on!" | |
fi | |
if [ "$STATE" != 'running' ]; then | |
echo "Powering $VM on will take a few seconds" | |
VBoxManage startvm $SELECTED_VM --type headless | |
start_spinner "Booting up..." | |
#trap "kill -9 $! > /dev/null 2>&1;trap 1 2 3 8 15" 1 2 3 8 15 | |
trap "kill -9 $! > /dev/null 2>&1;trap INT TERM KILL" INT TERM KILL | |
local READY="" | |
local IP="value" | |
while [[ "$READY" != "succeeded" ]] | |
do | |
sleep 1 | |
IP=$(_ip) | |
if [ "$IP" != "value" ]; then | |
READY=$(nc -zn $IP 22 | grep -o "succeeded") | |
fi | |
done | |
stop_spinner $? | |
fi | |
} | |
function stop() # Stops the selected Virtual Machine | |
{ | |
local STATE=$(_state) | |
local SLEEP=15 | |
if [ "$STATE" != 'running' ]; then | |
echo "The VM $SELECTED_VM is already powered off!" | |
fi | |
if [ "$STATE" == 'running' ]; then | |
echo "Powering $SELECTED_VM off will take a few seconds" | |
VBoxManage controlvm $SELECTED_VM acpipowerbutton | |
#start_spinner "Shutting down..." | |
#trap "kill -9 $! > /dev/null 2>&1;trap 1 2 3 8 15" 1 2 3 8 15 | |
trap "kill -9 $! > /dev/null 2>&1;trap INT TERM KILL" INT TERM KILL | |
local ELAPSED=0 | |
while [[ "$STATE" == 'running' ]] | |
do | |
sleep 2 | |
let ELAPSED+=2 | |
STATE=$(_state) | |
if [ "$ELAPSED" -gt 15 ]; then | |
VBoxManage controlvm $SELECTED_VM acpipowerbutton | |
ELAPSED=0 | |
fi | |
done | |
stop_spinner $? | |
fi | |
} | |
function restart() # Restarts the selected Virtual Machine | |
{ | |
VBoxManage controlvm $SELECTED_VM reset | |
} | |
function shell() # Establishes a secure shell connection to the selected Virtual Machine | |
{ | |
ssh $(_ip) | |
} | |
function properties() # Enumerates properties for the selected Virtual Machine | |
{ | |
VBoxManage guestproperty enumerate $SELECTED_VM | |
} | |
function status() # Shows the status for the selected Virtual Machine | |
{ | |
VBoxManage showvminfo $SELECTED_VM | grep State | |
} | |
function list() # Lists Virtual Machines available for selection | |
{ | |
VBoxManage list vms | awk '{ print $1 }' | |
} | |
function use() # Select a Virtual Machine from the available VMs | |
{ | |
VMS=($(list)) | |
if [ "$1" == "" ]; then | |
secho "${#VMS[*]} Virtual machines found:" green bold | |
for i in ${!VMS[*]}; do | |
string="${VMS[$i]:1:${#VMS[$i]}-2}" | |
echo "[$i] $string" | |
done | |
read -e -p "Which VM do you want to use? " ANSWER | |
else | |
ANSWER=$1 | |
fi | |
# No answer | |
if [ "$ANSWER" == "" ]; then | |
secho "You must select a VM, either by typing number or name..." red bold | |
use | |
else | |
# $ANSWER is a digit | |
if [[ $ANSWER = *[[:digit:]]* ]]; then | |
VM=${VMS[$ANSWER]} | |
VM="${VM:1:${#VM}-2}" | |
else | |
# Serach for $ANSWER in $VMS array | |
for item in ${VMS[*]}; do | |
item="${item:1:${#item}-2}" | |
if [ "$item" == "$ANSWER" ]; then | |
VM=$ANSWER | |
fi | |
done; | |
fi | |
if [ "$VM" == "" ]; then | |
secho "The Virtual Machine your selecting doesn't exist, please select another" red bold | |
use | |
else | |
SELECTED_VM="$VM" | |
fi | |
fi | |
_select_vm | |
} | |
function _help | |
{ | |
secho "Usage: " green bold | |
grep "^function" $0 \ | |
| grep -v "^function _" \ | |
| sed s/function/vmhelper/ \ | |
| sed s/\(\)/\ \<Virtual\ Machine\>\ / | |
} | |
function _interactive | |
{ | |
actions="list use status properties restart start stop help _help" | |
interactive=0; | |
for action in ${actions[*]}; do | |
if [ "$action" == "$1" ]; then | |
interactive=1; | |
fi | |
done; | |
if [ "$interactive" -eq 1 ]; then | |
echo "" | |
message=$(secho "What else? [help] # " blue negative) | |
read -e -p "$message " ANSWER | |
echo "" | |
_dispatch $ANSWER | |
fi | |
} | |
function _dispatch | |
{ | |
if [ "$(type -t $1)" == "function" ]; then | |
if [ "$1" == "help" ]; then | |
_help | |
else | |
$(echo "$1") | |
fi | |
_interactive $1 | |
exit | |
else | |
if [ -n "$1" ]; then | |
secho "Unrecognized command <$1> " red bold | |
fi | |
_help | |
_interactive "_help" | |
exit | |
fi | |
} | |
function _select_vm | |
{ | |
echo "SELECTED_VM=${SELECTED_VM}" > $SELECTED_VM_FILE | |
secho " ${SELECTED_VM} is selected " black bold cyan | |
} | |
function _state | |
{ | |
VBoxManage showvminfo $SELECTED_VM | grep State | awk '{ print $2 }' | egrep -v ^'\(' | |
} | |
function _ip | |
{ | |
VBoxManage guestproperty get $SELECTED_VM "/VirtualBox/GuestInfo/Net/0/V4/IP" | awk '{ print $2 }' | |
} | |
function _dot_files | |
{ | |
if [ ! -d $DOT_FOLDER ]; then | |
mkdir $DOT_FOLDER | |
fi | |
if [ -f $CONF_FILE ]; then | |
source $CONF_FILE | |
else | |
touch $CONF_FILE | |
fi | |
if [ -f $SELECTED_VM_FILE ]; then | |
source $SELECTED_VM_FILE | |
else | |
touch $SELECTED_VM_FILE | |
fi | |
} | |
_dot_files | |
# Check for selected Virtual Machine | |
if [ -n "$2" ]; then | |
use $2 | |
if [ "$1" == "use" ]; then | |
exit | |
fi | |
else | |
if [ "$SELECTED_VM" == "" ]; then | |
use | |
fi | |
fi | |
_select_vm | |
_dispatch $1 |
I should probably rename function launch to connect
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
USAGE
First give it execution permission
$ chmod +x vm-helper.sh
Now just
$ ./vm-helper.sh FUNCTION VMNAME
Examples