-
-
Save vidrowan/4091028 to your computer and use it in GitHub Desktop.
Control parallels VM via command line and mount remote users home dir as network share with sshfs
This file contains 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/sh | |
# Parallels VM management | |
# start/pause/resume Parallels VM. When starting VM mounts VM users home dir (default) as | |
# network share on local machine using fuse4x and sshfs. When pausing VM, unmounts network | |
# share before pausing VM. | |
vmsb() { #Usage: vmsb <command:string [start|resume|pause|stop]> | |
#### Colors #### | |
txtrst='\\033[0m' # Text Reset | |
txtred='\\033[0\;31m' # Red | |
txtgrn='\\033[0\;32m' # Green | |
bldred='\\033[1\;31m' # BoldRed | |
bldcyn='\\033[1\;36m' # BoldCyan | |
bldwht='\\033[1\;37m' # BoldWhite | |
bldylw='\\033[1\;33m' # BoldYellow | |
bldred='\\033[1\;31m' # BoldRed | |
alias NORMAL="echo -en ${txtrst} > /dev/tty;" | |
alias SUCCESS="echo -en ${bldgrn} > /dev/tty;" | |
alias CMDINFO="echo -en ${bldcyn} > /dev/tty;" | |
alias INFO="echo -en ${bldwht} > /dev/tty;" | |
alias FEEDBACK="echo -en ${txtgrn} > /dev/tty;" | |
alias WARNING="echo -en ${bldylw} > /dev/tty;" | |
alias FAILURE="echo -en ${bldred} > /dev/tty;" | |
#### END Colors #### | |
#### Usage #### | |
usage() | |
{ | |
cat << EOF | |
vmsb info. | |
Description: | |
This function start/pause/resume/stops a single pre-set Parallels VM. | |
When starting the VM, the script mounts the VM users home dir (default) as network share on local machine using fuse4x and sshfs. | |
When pausing the VM, the script unmounts network share before pausing VM. | |
OPTIONS: | |
-d - Debug Mode | |
-h - Help | |
-m - Machine name of the parallels VM you want to control, find availble names with "prlctl list -a" | |
-u - User name. The connection string for user on VM. i.e.: user@virtualmachine/ipaddress. You can look up the IP of the remote VM from the terminal in the VM: $ /sbin/ifconfig | grep "inet addr:" | |
-p - Mount Point Path. Absolute path "pwd -P" of a folder your user owns (not the home dir) that can be used as the mountpoint for the network share. Note: This directory will be temporarily "replaced" by the mounted remote drive; It will appear to be renamed in Finder, possibly something like; "fuse4x volume 0 (sshfs)" | |
ARGUMENTS: | |
command - (required) action the script should take: start|resume|pause|stop | |
USAGE EXAMPLES: | |
$ vmsb [-dh -m <string:"MachineName"> -u <string:"UserName@MachineAddress"> -p <string:"Mount Point Path">] <command:string [start|resume|pause|stop]> | |
Simple usage if VM vars are hardcoded: | |
$ vmsb start; | |
Complex usage if passing VM vars: | |
$ vmsb -d -m "Red Hat Enterprise Linux 6" -u "myUser@localhost" -p "/Applications/MAMP/htdocs/parallels_hds/" stop | |
$ vmsb -d -m "Red Hat Enterprise Linux 6" -u "myuser@10.1.1.1" -p "~/parallels_hd_mount/" start | |
EOF | |
} | |
#### END Usage #### | |
#### Options #### #ref: http://wiki.bash-hackers.org/howto/getopts_tutorial | |
OPTIND=1 #set the OPTIND to 1 before each use. Ref: http://ss64.com/bash/getopts.html "OPTIND is initialized to 1 each time the shell or a shell script is invoked." In this case (in a bash function) it's initialized once for each shell session so we need to reset it inside each function. | |
# (p)reset vars | |
HELP=0 | |
DEBUG=0 | |
# Check for options. (currently in a while loop and case statement for potential expansion) | |
while getopts ":dhm:u:p:" OPTION; | |
do | |
case $OPTION in | |
d) # DEBUG | |
DEBUG=1 | |
INFO echo "Debuging mode" > /dev/tty; NORMAL | |
;; | |
h) | |
# Help | |
HELP=1 | |
if (($DEBUG)) ; then | |
INFO echo "Debug msg: Setting HELP: $HELP" > /dev/tty; NORMAL | |
fi | |
break | |
;; | |
m) # MACHINE NAME | |
# parallels VM you want to control, find availble names with "prlctl list -a" | |
VM="$OPTARG" | |
if (($DEBUG)) ; then | |
INFO echo "Debug msg: Machine VM Name set with -m: $VM" > /dev/tty; NORMAL | |
fi | |
;; | |
u) # USER NAME | |
# connection string for user on $VM ie user@virtualmachine | |
CONNECT="$OPTARG" | |
if (($DEBUG)) ; then | |
INFO echo "Debug msg: Connection string for user on $VM ie user@virtualmachine -u: $CONNECT" > /dev/tty; NORMAL | |
fi | |
;; | |
p) # MOUNT POINT PATH | |
# Absolute path "pwd -P" of a folder your user owns (not the home dir) that can be used as the mountpoint for the network share | |
MNTPOINT="$OPTARG" | |
if (($DEBUG)) ; then | |
INFO echo "Debug msg: Absolute path 'pwd -P' of a folder your user owns (not the home dir) that can be used as the mountpoint for the network share; -p: $MNTPOINT" > /dev/tty; NORMAL | |
fi | |
;; | |
?) #if no option is given continue on | |
INFO echo "Unknown option: -$OPTARG" > /dev/tty; NORMAL | |
;; | |
esac | |
done | |
shift $((OPTIND-1)) #prepare OPTIND for the next option | |
#### END Options #### | |
#Set arg1 from non-option arguments | |
ARG1=$1 | |
if (($DEBUG)) ; then | |
INFO echo "Debug msg: ARG1 = \$1: $ARG1" > /dev/tty; NORMAL | |
fi | |
#if there are no options then: arg1 = $1 if it doesn't start with '-' | |
if [ ! -n "$ARG1" ] && [[ -n "$1" ]] && [[ $1 != -* ]] && [[ $# -gt 0 ]] ; then | |
ARG1=$1 | |
if (($DEBUG)) ; then | |
WARNING echo "Debug msg: No arguments passed. ARG1 = \$1: $ARG1" > /dev/tty; NORMAL | |
fi | |
fi | |
#check for --help | |
if [[ $1 == "--help" ]] ; then | |
HELP=1 | |
fi | |
if (($HELP)) && (($DEBUG)) ; then | |
INFO echo "Debug msg: HELP: $HELP" > /dev/tty; NORMAL | |
fi | |
#Check for required vars: $VM, $CONNECT, $MNTPOINT & ARG1; if empty or ARG1 starts with a '-' then show usage, else execute script | |
if [ ! -n "$VM" ] || [ ! -n "$CONNECT" ] || [ ! -n "$MNTPOINT" ] || [ ! -n "$ARG1" ] || [[ "$ARG1" == -* ]] || (($HELP)) ; then | |
if (($DEBUG)) ; then | |
FAILURE echo "Debug msg: Failed to meet requirements or help was called: Check for required vars: VM ($VM), CONNECT ($CONNECT), MNTPOINT ($MNTPOINT) & ARG1 ($ARG1); if empty OR ARG1 starts with a '-' OR HELP = 1; then show usage, else execute script" > /dev/tty; NORMAL | |
fi | |
# Display Usage: | |
usage | |
else | |
#### Execute script #### | |
# Current running status of $VM | |
if (($DEBUG)) ; then | |
INFO echo "Debug msg: Setting VM Status: prlctl list \"$VM\" -o status --no-header" > /dev/tty; NORMAL | |
fi | |
VMSTATUS=`prlctl list "$VM" -o status --no-header`; | |
if (($DEBUG)) ; then | |
INFO echo "Debug msg: VM Status: $VMSTATUS" > /dev/tty; NORMAL | |
fi | |
# if starting vm, start vm then wait then mount network share | |
if [ "$ARG1" = "start" ] || [ "$ARG1" = "resume" ] | |
then | |
case "$VMSTATUS" in | |
"running" ) | |
INFO echo "$VM is already running." > /dev/tty; NORMAL | |
;; | |
"stopped" ) | |
INFO echo "prlctl start $VM" > /dev/tty; NORMAL | |
prlctl start "$VM"; | |
;; | |
"paused" | "suspended") | |
INFO echo "prlctl resume $VM" > /dev/tty; NORMAL | |
prlctl resume "$VM"; | |
;; | |
esac | |
# mount network share, only if it hasn't already been mounted | |
if [ ! -f "$MNTPOINT/.bash_logout" ] | |
then | |
# give time for vm to boot | |
COUNT=0 | |
while [ $VMSTATUS != "running" ] | |
do | |
(( COUNT++ )) | |
INFO echo "Waiting for \"$VM\" to finish booting: $COUNT" > /dev/tty; NORMAL | |
sleep 1; | |
VMSTATUS=`prlctl list "$VM" -o status --no-header`; | |
done | |
FEEDBACK echo -en "Mounting network share:\n sshfs $CONNECT: $MNTPOINT \n" > /dev/tty; NORMAL | |
sshfs "$CONNECT": "$MNTPOINT"; | |
fi | |
# if pausing or stopping vm, unmount mounted sshfs mounted network share then pause or stop VM | |
elif [ "$ARG1" = "pause" ] || [ "$ARG1" = "stop" ] | |
then | |
# no need to run pause if machine isn't running | |
if [ ! "$VMSTATUS" = "running" ] | |
then | |
FEEDBACK echo "$VM is not currently running, it is currently $VMSTATUS" > /dev/tty; NORMAL | |
else | |
# only unmount if network share is mounted | |
if [ -f "$MNTPOINT/.bash_logout" ] | |
then | |
FEEDBACK echo "Unmounting network share:" > /dev/tty; NORMAL | |
FEEDBACK echo "diskutil unmount $MNTPOINT" > /dev/tty; NORMAL | |
diskutil unmount "$MNTPOINT"; | |
fi | |
# while for network share to unmount before continuing. | |
COUNT=0 | |
while [ -f "$MNTPOINT/.bash_logout" ] | |
do | |
FEEDBACK echo "$COUNT" > /dev/tty; NORMAL | |
sleep 1; | |
(( COUNT++ )) | |
done | |
# Never stop as that is like unplugging the VM. | |
FEEDBACK echo "prlctl pause $VM" > /dev/tty; NORMAL | |
prlctl pause "$VM"; | |
# give time for vm to pause | |
COUNT=0 | |
while [ $VMSTATUS != "paused" ] | |
do | |
(( COUNT++ )) | |
INFO echo "Waiting for \"$VM\" to finish pausing: $COUNT" > /dev/tty; echo -en ${txtrst} > /dev/tty; | |
sleep 1; | |
VMSTATUS=`prlctl list "$VM" -o status --no-header`; | |
done | |
fi | |
else | |
FEEDBACK echo "prlctl $@ $VM" > /dev/tty; NORMAL | |
prlctl $@ "$VM"; | |
fi | |
#### Next Steps #### | |
# give time for vm to pause | |
COUNT=0 | |
while [ "$VMSTATUS" != "" ] | |
do | |
(( COUNT++ )) | |
INFO echo "Waiting for \"$VM\" to finish: $COUNT" > /dev/tty; echo -en ${txtrst} > /dev/tty; | |
sleep 1; | |
VMSTATUS=`prlctl list "$VM" -o status --no-header`; | |
done | |
INFO echo "Current Status: $VMSTATUS" > /dev/tty; NORMAL | |
INFO echo "Available Options: [start|resume|pause|stop]" > /dev/tty; NORMAL | |
case "$VMSTATUS" in | |
"running" ) | |
CMDINFO echo "vmsb -m \"$VM\" -u \"$CONNECT\" -p \"$MNTPOINT\" pause" > /dev/tty; NORMAL | |
CMDINFO echo "vmsb -m \"$VM\" -u \"$CONNECT\" -p \"$MNTPOINT\" stop" > /dev/tty; NORMAL | |
;; | |
"stopped" ) | |
CMDINFO echo "vmsb -m \"$VM\" -u \"$CONNECT\" -p \"$MNTPOINT\" start" > /dev/tty; NORMAL | |
;; | |
"paused" | "suspended" ) | |
CMDINFO echo "vmsb -m \"$VM\" -u \"$CONNECT\" -p \"$MNTPOINT\" resume" > /dev/tty; NORMAL | |
;; | |
esac | |
#### END Next Steps #### | |
#### END Execute script #### | |
fi # end else -#If not ARG1 or ARG1 starts with a '-' then show usage, else execute script | |
shift $((OPTIND-1)) #prepare OPTIND for the next option | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Added help documentation. Shown when no var is passed to function or when --help is passed.