Autostart VM on boot MacOS Mojave

Discussions related to using VirtualBox on Mac OS X hosts.
Post Reply
DaveGB
Posts: 3
Joined: 27. Mar 2012, 13:33

Autostart VM on boot MacOS Mojave

Post by DaveGB »

I want to start a VM on boot. I followed the instructions in the manual but don't see where the machine to start is configured, and nothing starts on boot, so I have clearly misunderstood something.

I found https://gist.github.com/reidransom/6042016 but

Code: Select all

VBoxManage modifyvm Ubuntu --autostart-enabled on
returned an error:
VBoxManage: error: Could not find a registered machine named 'Ubuntu'
VBoxManage: error: Details: code VBOX_E_OBJECT_NOT_FOUND (0x80bb0001), component VirtualBoxWrap, interface IVirtualBox, callee nsISupports
VBoxManage: error: Context: "FindMachine(Bstr(a->argv[0]).raw(), machine.asOutParam())" at line 524 of file VBoxManageModifyVM.cpp
and

Code: Select all

VBoxManage list vms
gave no results so VBoxManage doesn't seem to know about the VMs that are configured in the GUI.

Code: Select all

VBoxManage registervm <path>
registered the VM so I could (and did) set it to auto-start. However, it still doesn't autostart.

I can start it using

Code: Select all

VBoxManage startvm Ubuntu --type headless
I would like my VM to autostart when the machine boots. That's not quite achievable because the disk is encrypted so I actually have to login first, but I can live with that. Please could someone point me in the right direction to automate the VM start?

Also, with MacOS Catalina, the actual OS is on a seporate partition. I could possible create an additional small, non-encrypted disk to hold the virtual drive so it may be possible to start it on boot. Any thoughts?

Context: VirtualBox 6.0 on MacOS Mojave (10.14.6)

Thanks in advance.
Last edited by socratis on 27. Jul 2019, 23:04, edited 1 time in total.
Reason: Fixed formatting.
socratis
Site Moderator
Posts: 27329
Joined: 22. Oct 2010, 11:03
Primary OS: Mac OS X other
VBox Version: PUEL
Guest OSses: Win(*>98), Linux*, OSX>10.5
Location: Greece

Re: Autostart VM on boot MacOS Mojave

Post by socratis »

DaveGB wrote:That's not quite achievable because the disk is encrypted so I actually have to login first
I'm glad that you figured out the obvious. ;)

So, you can forget all about the "autostart VM at boot", I don't think it will work in your case. Since you "can live with that", I would suggest a different approach, one that's using the "Open at login" option of OSX.
  1. Modify your VM so that it starts headless, since you won't be able to control the command line:
    • VBoxManage modifyvm "Ubuntu" --defaultfrontend headless
  2. Right-click on the VM in VirtualBox Manager, select "Create Alias on Desktop". I tried moving the alias to another folder, but that didn't work right-away, and I didn't deal with it any further.
  3. Go to your System Preferences » Users and Groups » select your account » Login Items » add the Alias from the previous step. You could also check the "Hide" option, which might make the headless step 1, a little bit superfluous. Haven't tried it though...
There's a side effect of launching the VirtualBox Manager, but you could close it as soon as you see it. ;)

There could be more convoluted scenarios, like doing something with "~/Library/LaunchAgents", not sure if it's going to be any more advantageous or not...

DaveGB wrote:I could possible create an additional small, non-encrypted disk to hold the virtual drive so it may be possible to start it on boot. Any thoughts?
As I said, if the simple solution above doesn't cover your needs, then we can start exploring more advanced options.

Since I don't use the autostart feature (and not that many do) I preferred to simply logout/login rather than reboot my computer to test the proposed scenario...
Do NOT send me Personal Messages (PMs) for troubleshooting, they are simply deleted.
Do NOT reply with the "QUOTE" button, please use the "POST REPLY", at the bottom of the form.
If you obfuscate any information requested, I will obfuscate my response. These are virtual UUIDs, not real ones.
socratis
Site Moderator
Posts: 27329
Joined: 22. Oct 2010, 11:03
Primary OS: Mac OS X other
VBox Version: PUEL
Guest OSses: Win(*>98), Linux*, OSX>10.5
Location: Greece

Re: Autostart VM on boot MacOS Mojave

Post by socratis »

socratis wrote:There could be more convoluted scenarios, like doing something with "~/Library/LaunchAgents", not sure if it's going to be any more advantageous or not...
Well, as luck would have it, I was chatting with user 'granada29' and we came up with the proper .plist that can launch a VM at startup. The advantage includes that you don't get VirtualBox launched, just the VM. Here's what the .plist should look like:
<?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>org.virtualbox.launch.My VM</string>
	<key>ProgramArguments</key>
	<array>
		<string>/Applications/VirtualBox.app/Contents/MacOS/VBoxManage</string>
		<string>startvm</string>
		<string>My VM</string>
		<string>--type</string>
		<string>headless</string>
	</array>
	<key>RunAtLoad</key>
	<true/>
</dict>
</plist>
Save that as "org.virtualbox.launch.My VM.plist" (just so that you don't get any conflicts) in "/Users/<you>/Library/LaunchAgents/", and in your next login, your VM is going to be running hidden.

And then, 'granada29' wrote a quick script to automate the whole thing! 8)

Code: Select all

#!/bin/sh

VMNAME=$1
AGENT=org.virtualbox.launch."$VMNAME"

cat<<EOF > /tmp/"$AGENT"
<?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>org.virtualbox.launch.$VMNAME</string>
	<key>ProgramArguments</key>
	<array>
		<string>/Applications/VirtualBox.app/Contents/MacOS/VBoxManage</string>
		<string>startvm</string>
		<string>$VMNAME</string>
		<string>--type</string>
		<string>headless</string>
	</array>
	<key>RunAtLoad</key>
	<true/>
</dict>
</plist>
EOF

mkdir -p ~/Library/LaunchAgents
mv /tmp/"$AGENT" ~/Library/LaunchAgents/"$AGENT".plist
Just save it as "VBoxLaunch.sh", and use it as:
  • sh VBoxLaunch.sh "My VM"
That's the bare minimum required to get a headless VM running at login. More improvements are likely to follow...
Do NOT send me Personal Messages (PMs) for troubleshooting, they are simply deleted.
Do NOT reply with the "QUOTE" button, please use the "POST REPLY", at the bottom of the form.
If you obfuscate any information requested, I will obfuscate my response. These are virtual UUIDs, not real ones.
DaveGB
Posts: 3
Joined: 27. Mar 2012, 13:33

Re: Autostart VM on boot MacOS Mojave

Post by DaveGB »

Much appreciated. I'll give it a go
socratis
Site Moderator
Posts: 27329
Joined: 22. Oct 2010, 11:03
Primary OS: Mac OS X other
VBox Version: PUEL
Guest OSses: Win(*>98), Linux*, OSX>10.5
Location: Greece

Re: Autostart VM on boot MacOS Mojave

Post by socratis »

We've expanded the script above to have some more bells and whistles. You can always find the latest in granada29's website, but I'll make sure to include a copy of it here in the forums:

Code: Select all

#!/bin/sh
set -u

AGENT=""
DEBUG=""
HEADLESS=""
LAUNCHAGENT=""
REMOVE=""
TEMPAGENT=""
VERBOSE=""
VMNAME=""

VERSION="1.0.0"
VBOXMANAGE="/Applications/VirtualBox.app/Contents/MacOS/VBoxManage"

my_usage()
{
	echo ""
	echo "VBoxLaunchAgent [options] \"<VM_name>\""
	echo ""
	echo "options         [-h|--headless]"
	echo "                [-d|--debug]"
	echo "                [-r|--remove]"
	echo "                [-v|--verbose]"
	exit $1
}

showMessage()
{
	if [ "x"$VERBOSE = "x""true" ]; then
		echo "$@"
	fi
}

get_options()
{
	if [ $# -eq "0" ]; then
		echo "*** ERROR: No arguments specified. You must specify a VM."
		my_usage 1
	fi

	while test $# -ge 2;
	do
		ARG="$1"

		case "$ARG" in
		-d|--debug)
			DEBUG="true"
			shift
			;;

		-h|--headless)
			HEADLESS="true"
			shift
			;;

		-r|--remove)
			REMOVE="true"
			shift
			;;

		-v|--verbose)
			VERBOSE="true"
			shift
			;;

		*)
			echo "*** ERROR: Invalid argument: $ARG"
			my_usage 1
			;;
		esac
	done

	VMNAME="$1"
	AGENT=org.virtualbox.launch."$VMNAME"
	TEMPAGENT=/tmp/"$AGENT"
	LAUNCHAGENT=~/Library/LaunchAgents/"$AGENT".plist
	if [ "x"$VERBOSE = "x""true" ]; then
		echo ""
		echo "VERBOSE OUTPUT"
		echo "--------------------------------------------------------------------------------"
		echo "DEBUG        = $DEBUG"
		echo "HEADLESS     = $HEADLESS"
		echo "REMOVE       = $REMOVE"
		echo "VERBOSE      = $VERBOSE"
		echo "VMNAME       = $VMNAME"
		echo "AGENT        = $AGENT"
		echo "LAUNCHAGENT  = $LAUNCHAGENT"
		echo "TEMPAGENT    = $TEMPAGENT"
		echo ""
	fi
}

checkVBoxInstalled()
{
	if [ ! -e "$VBOXMANAGE" ]; then
		echo "VirtualBox is not installed."
		my_usage 1
	fi
}

vmExists()
{
	"$VBOXMANAGE" showvminfo "$VMNAME" >/dev/null 2>&1
	rc=$?
	if [ $rc != 0 ]; then
		echo "VM not found: $VMNAME"
		my_usage 1
	fi
	showMessage "VirtualBox VM found. . . : $VMNAME"
}

agentExists()
{
	if [ -e "$LAUNCHAGENT" ]; then
		echo "The Launch Agent ($LAUNCHAGENT) already exists!"
		echo "Do you want to overwrite it? (Yes/No)"
		printf "\a"

		read MY_ANSWER
		if [ "$MY_ANSWER" != "Yes" -a "$MY_ANSWER" != "YES" -a "$MY_ANSWER" != "yes" -a "$MY_ANSWER" != "Y" -a "$MY_ANSWER" != "y" ] ; then
			echo "Aborting Launch Agent creation. Your answer was: '$MY_ANSWER'".
			exit 2;
		fi
	fi
}

removeAgent()
{
	if [ "x"$REMOVE = "x""true" ]; then
		if [ -e "$LAUNCHAGENT" ]; then
			launchctl unload -F "$LAUNCHAGENT" >/dev/null 2>&1
			rm -f "$LAUNCHAGENT"
			showMessage "Removed Launch Agent . . : $LAUNCHAGENT"
		else
			showMessage "Launch Agent not found . : $LAUNCHAGENT"	
		fi
		exit 0
	fi
}

makeAgent()
{
	(
		echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
		echo "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"
		echo "<plist version=\"1.0\">"
		echo "<dict>"
		echo "	<key>Label</key>"
		echo "	<string>org.virtualbox.launch.$VMNAME</string>"

		if [ "x"$DEBUG = "x""true" ]; then
		(
			echo "	<key>StandardOutPath</key>"
			echo "	<string>/tmp/$VMNAME.log</string>"
			echo "	<key>StandardErrorPath</key>"
			echo "	<string>/tmp/$VMNAME.error.log</string>"
		)
		fi

		echo "	<key>ProgramArguments</key>"
		echo "	<array>"
		echo "		<string>$VBOXMANAGE</string>"
		echo "		<string>startvm</string>"
		echo "		<string>$VMNAME</string>"

		if [ "x"$HEADLESS = "x""true" ]; then
			echo "		<string>--type</string>"
			echo "		<string>headless</string>"
		fi

		echo "	</array>"
		echo "	<key>RunAtLoad</key>"
		echo "	<true/>"
		echo "</dict>"
		echo "</plist>"
	) > "$TEMPAGENT"
	showMessage "Created temporary file . : $TEMPAGENT"
}

echo "================================================================================"
echo "$(basename $0) - Launch Agent creation tool for starting a VM at login"
echo "================================================================================"
echo "Version: $VERSION"
echo "Copyright (C) 2019, granada29 @ VirtualBox forums."
echo "All rights reserved."
echo ""

checkVBoxInstalled
get_options "$@"
removeAgent
vmExists
agentExists
makeAgent

mv "$TEMPAGENT" "$LAUNCHAGENT"
echo "Created Launch Agent . . : $LAUNCHAGENT"

exit 0
The options should be straight forward:
  • -h|--headless
    • By default the script creates a Launch Agent for a VM that's running normally. Given this option, that VM will start in the background, headless.
  • -d|--debug
    • This will create an additional two files in the "/tmp" folder, "/tmp/$VMNAME.log" and "/tmp/$VMNAME.error.log" in case something goes wrong and you want to look at the error output.
  • -r|--remove
    • Remove an already existing Launch Agent entry for "VM_name".
  • -v|--verbose
    • Print analytical messages about what the script is doing.
Do NOT send me Personal Messages (PMs) for troubleshooting, they are simply deleted.
Do NOT reply with the "QUOTE" button, please use the "POST REPLY", at the bottom of the form.
If you obfuscate any information requested, I will obfuscate my response. These are virtual UUIDs, not real ones.
Post Reply