Rock1965
3/5/2018 - 7:14 AM

Run VMware Fusion headless at Mac OS system startup

Run VMware Fusion headless at Mac OS system startup

#/bin/bash -e

export PATH="/usr/bin:/bin:/usr/sbin:/sbin:/Library/Application Support/VMware Fusion"

VMNAME="$1"
VMX="/Virtual Machines/${VMNAME}.vmwarevm/${VMNAME}.vmx"
if [ ! -f "$VMX" ]
then
	echo "$VMX" not found >&2
	exit 1
fi

function wait_for_host()
{

	local WAIT=180

	while ! [ -e /var/run/vmnet-bridge-vmnet.pid -o -e /var/run/vmnet-bridge-vmnet0.pid ]; do
		local WAIT=$((WAIT - 1))
		if [ $WAIT -le 0 ]
		then
			echo Timeout waiting for VMware drivers.
			exit 1
		fi
		sleep 1
	done

	while ! who | awk '{print $2}' | grep -q ^console$
	do
		local WAIT=$((WAIT - 1))
		if [ $WAIT -le 0 ]
		then
			echo Timeout waiting for console login.
			exit 1
		fi
		sleep 1
	done

}

function is_running()
{
	local VMX="$1"
	ps -eco pid=,command= | awk '{if ($2=="vmware-vmx") print $1}' | while read PID
	do
		if ps -o args= $PID | tr ' ' '\n' | grep -qFx "$VMX"
		then
			return 42 #found
		fi
	done
	[ "$?" == "42" ]
}

wait_for_host

if is_running "$VMX"
then
	echo "$1" already running. Attaching to existing.
else
	vmrun start "$VMX" nogui
fi

trap 'vmrun stop "$VMX" soft' SIGKILL SIGTERM SIGHUP SIGINT

while is_running "$VMX"
do
	sleep 5
done
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.jasoncodes.vms.template</string>
<key>ProgramArguments</key>
<array>
<string>/Virtual Machines/bin/vmdaemon</string>
<string>template</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>ExitTimeOut</key>
<integer>300</integer>
</dict>
</plist>

Run VMware Fusion headless at Mac OS system startup.

I heard you like headless VMs on your Mac so I wrote this script for your launchds.

Assumptions

  • Tested on Mac OS X 10.6.4 with VMware Fusion 2.0.5 and 3.1.1.
  • A interactive user automatically logs into the system at startup. I had some issues trying to get this running without an interactive user logged in. I automatically log in for Airfoil Speakers anyway.
  • Your virtual machines live in /Virtual Machines

Method

  1. Place the vmdaemon script into /Virtual Machines and make it executable (sudo chmod 755 vmdaemon) and owned by root (sudo chown root:wheel vmdaemon).
  2. Copy the template plist into /Virtual Machines. The plist should also be chmod 644 and chown root:wheel.
  3. For each VM you want to run headless, copy the template property list file and change the filename, label and 2nd program argument to match your VM name.
  4. Symlink the plist into /Library/LaunchDaemons
  5. Run launchctl load -w $PLIST to start the VM.
  6. Use launchctl unload -w $PLIST to initiate a graceful shutdown of the VM. By default it will wait up to 5 minutes for the VM to shutdown. This can be configured in ExitTimeOut in the plist

Forks and Feedback

If you try this out with your own setup, I'd like to hear how things go. Patches via gist forks are welcome.

  • Jason Weathered (@jasoncodes)