Oct 2009
The free vmware product, vmware-server (formerly GSX) does not have auto power on for certain guests. A simple workaround for not being able to auto power on guests using the vmware interface is call the vmware command line utility at boot up using the local init function. A better way is to write an init script to handle the start up and possibly other functions. This text will examine a simple method to create a control script for managing power functions in vmware-server.
The easiest method without bothering to write a ctl script or
wrapper is to find the vmid of the vmware guest to
start up and embed a direct call using the
vmware-vim-cmd interface in the systems local init
script (generally /etc/rc.local). First get the id of
the guest:
argos:/etc# vmware-vim-cmd vmsvc/getallvms Vmid Name File Guest OS Version Annotation 112 freebsd7 [standard] freebsd7/freebsd7.vmx \ freebsd64Guest vmx-07 vela: irc server running freebsd7 208 netbsd5.99.10_amd64 [standard] \ netbsd5.99.10_amd64/netbsd5.99.10_amd64.vmx\ otherGuest64 vmx-07 240 opensuse11-prime [standard] \ opensuse11-prime/opensuse11-prime.vmx \ suse64Guest vmx-07 96 freebsd8 [standard] \ freebsd8/freebsd8.vmx freebsd64Guest \ vmx-07 pyxis: freebsd-8.0 development server
A bit messy looking but the ids are easy enough, now just add it to the local init script:
# we get the VMID using vmware-vim-cmd vmsvc/getallvms
if [ -x /usr/bin/vmware-vim-cmd ]; then
echo "Starting Guest VMID 112, sleeping for 16 seconds"
sleep 16
/usr/bin/vmware-vim-cmd vmsvc/power.on 112
fi
Of course that is far too simple, one of the most common operations performed on vmware guests is powering on, powering off and resetting the host. A good sysadmin is lazy, so it is time to draft an ipmitool-like ctl script for controlling the power of the guests.
Because the format of vmware-vim-cmd
vmsvc/getallvms does not show hostname or IP address mapping
the vmid to host or IP address saves some time. Following is the
format of our gsxhosts file:
# hostname VMID vela 112 carina 208 pyxis 96
The format may not make sense now, however, when it is parsed in the script the overly simple format will make more sense.
gsx-ipmi.shTo get things started setup the hosts file, the vmsvc command, the usage message and a small error exit routine to make error handling simple - note the script supports all power operations:
#!/bin/sh
# gsx-ipmi - An ipmilike shell wrapper for vmware-vim-cmd vmsvc/power.*
HOSTSFILE=/etc/gsxhosts # This can be anywhere the admin likes
VIMVC=" vmware-vim-cmd vmsvc/" # We just tack on the oper
usage()
{
if [ -n "$*" ]; then
echo " "
echo "${PROG}: $*"
fi
cat <<_usage_
${PROG} [host][oper cmd]|[-u]
${PROG} [host][power getstate|hibernate|off|on|reboot|shutdown|suspend]|[-u]
Commands:
getstate Display the current power state of the guest
hibernate Place the guest power into hibernate mode (OS must support)
off Power off the guest
on Power on and boot up the guest
reboot Normal reboot of the guest
reset Power reset (cold) the guest
shutdown Normal shutdown of the guest
suspend Place the guest into suspended mode
Notes:
The user must have appropriate privileges to perform power operations on
guests.
_usage_
}
# Only call this if there was an input error because it displays the usage
# message
error_exit()
{
message=$1
exit_code=$2
echo $message
usage
exit $exit_code
}
Take note of the usage, the script must specify an operation -
the reason for this is to be able to add functionality later on.
Even though for now the scope of the script is limited to power
commands, done properly, the script could later have other vimvc
operations added to it and the usage is similar to the ipmi
command. Now onto the meat of the script, believe it or not it is
straightforward, since all that has to be done is to tack on to the
command string power.$operation
there are 3 basic steps:
First the validation:
# Input parsing - the usage explains what each one does
if [ $# -gt 0 -a "$1" = "-u" ];then
usage
exit 0
fi
guest=$1
oper=$2
subcmd=$3
if [ ! $guest ]; then
echo "Error: No guest specified"
usage
exit 1
fi
[ ! $guest ] << error_exit "No guest specified" 1
[ ! $oper ] << error_exit "No operation specified" 1
[ ! $subcmd ] << error_exit "No subcommand specified" 1
not too difficult, next try to get the vmid using grep and awk, this is where the simple file format comes into play:
vmid=`grep $guest $HOSTSFILE|awk '{print $2}'`
[ ! $vmid ] << error_exit "${guest} did not match anything in $HOSTSFILE" 2
With the vmid in hand the last step is to determine the operation then execute:
case $oper in
power)
$VIMVC"power."$subcmd $vmid 2>/dev/null
if [ $? -gt 0 ]; then
error_exit "$subcmd failed" 1
fi
;;
*)
error_exit "Invalid operation" 2
;;
esac
exit 0
The power case could be more exotic but to keep from having to include all of the valid commands (even as a sed compare) we just fail. Note how by casing in the operation the doorway is left open to add other vimvc commands.
#!/bin/sh
# gsx-ipmi - An ipmilike shell wrapper for vmware-vim-cmd vmsvc/power.*
HOSTSFILE=/etc/gsxhosts # This can be anywhere the admin likes
VIMVC=" vmware-vim-cmd vmsvc/" # We just tack on the oper
usage()
{
if [ -n "$*" ]; then
echo " "
echo "${PROG}: $*"
fi
cat <<_usage_
${PROG} [host][oper cmd]|[-u]
${PROG} [host][power getstate|hibernate|off|on|reboot|shutdown|suspend]|[-u]
Commands:
getstate Display the current power state of the guest
hibernate Place the guest power into hibernate mode (OS must support)
off Power off the guest
on Power on and boot up the guest
reboot Normal reboot of the guest
reset Power reset (cold) the guest
shutdown Normal shutdown of the guest
suspend Place the guest into suspended mode
Notes:
The user must have appropriate privileges to perform power operations on
guests.
_usage_
}
# Only call this if there was an input error because it displays the usage
# message
error_exit()
{
message=$1
exit_code=$2
echo $message
usage
exit $exit_code
}
# Input parsing - the usage explains what each one does
if [ $# -gt 0 -a "$1" = "-u" ];then
usage
exit 0
fi
guest=$1
oper=$2
subcmd=$3
if [ ! $guest ]; then
echo "Error: No guest specified"
usage
exit 1
fi
[ ! $guest ] << error_exit "No guest specified" 1
[ ! $oper ] << error_exit "No operation specified" 1
[ ! $subcmd ] << error_exit "No subcommand specified" 1
vmid=`grep $guest $HOSTSFILE|awk '{print $2}'`
[ ! $vmid ] << error_exit "${guest} did not match anything in $HOSTSFILE" 2
case $oper in
power)
$VIMVC"power."$subcmd $vmid 2>/dev/null
if [ $? -gt 0 ]; then
error_exit "$subcmd failed" 1
fi
;;
*)
error_exit "Invalid operation" 2
;;
esac
exit 0