Skip to content

Instantly share code, notes, and snippets.

@jasoncodes
Created October 6, 2010 11:16
Show Gist options
  • Save jasoncodes/613198 to your computer and use it in GitHub Desktop.
Save jasoncodes/613198 to your computer and use it in GitHub Desktop.
Run VMware Fusion headless at Mac OS system startup

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)
<?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>
#/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
@xeniode
Copy link

xeniode commented Sep 8, 2011

I was able to get a vm machine to boot via fusion in headless mode at boot with the login prompt enabled. All you need to do is take out


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 ##

Add /Library/Application Support/Vmware Fusion/boot.sh —start above local WAIT=180

Also change

vmrun start "$VMX" nogui to vmrun –T ws start “$VMX” nogui

@uxp
Copy link

uxp commented Apr 10, 2012

plist files in /Library/LaunchDaemons will automatically load upon system boot (well, whenever launchd says to after system boot), but plists in /Library/LaunchAgents will load after user login. Obviously, /Library/LaunchAgents are loaded for all users system wide, and ~/Library/LaunchAgents are loaded per-user.

It would probably be best to put this plist in the /Library/LaunchAgents directory, and it might be a better idea to put them in the user's ~/Library/LaunchAgents directory, just to ensure you aren't loading unnecessary resources into memory and consuming CPU if there is more than one account, with the added benefit of making sure the system is fully operational before you start trying to boot another underneath it.

@jkister
Copy link

jkister commented May 6, 2013

@garretjames hoping you're still listening. do you know the equivalent "boot.sh" command on Fusion 5.0.3 ?

@quatauta
Copy link

For VMware Fusion 6, there is services.sh in /Applications/VMware Fusion.app/Contents/Library to start VMware Fusion services

@Gemeinagent
Copy link

Thanks. This, and the fact that vmrun is now located at "/Applications/VMware Fusion.app/Contents/Library/vmrun" helped me a lot.
I created a symlink to vmrun for easier access: 'ln -s "/Applications/VMware Fusion.app/Contents/Library/vmrun" /usr/local/bin/vmrun'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment