Automatically starting and stopping your VirtualBox VM
I’ve been having a lot of trouble recently with my wifi. As a technologist, there’s nothing more embarrassing than having your friends come over and laugh at you when your wifi is broken — or worse, unreliable. There’s a much longer story where I upgrade my wifi to something awesome (namely, the UniFi access points from Ubiquiti)… but this part of the story is particularly about how I fought and won a tiny battle with VirtualBox. I’m detailing it here so that others can find it and benefit.
So let’s fast forward past the part where I install the UniFi Controller (which is an excellent piece of technology), and find out that my 32-bit Debian home router doesn’t let me enable a critical feature. Let’s fast forward past the part where I decide that I should try installing a 64-bit Debian guest virtual machine in a virtual container inside my 32-bit Debian host system. Let’s even fast forward past the part where I get VirtualBox set up mostly properly (replete with all kinds of traps, pitfalls that I either narrowly avoid, or spend hours wallowing in). I get it installed and I get it running and life is good.
But there’s a hitch. Now I’m running a machine-within-a-machine and the inner machine is in charge of my home wifi network. So it’s got to be reliable, otherwise refer above to: friends laughing at me. But sometimes the host machine has to be rebooted and when that happens, I need the guest VM to shut down cleanly and start up again cleanly. That should be simple, right? You’d think that VirtualBox would have this nailed down — but it turns out that they don’t.
After much trawling around the internet, the best solution appears to be to set your guest machine to AutoStart mode and use a service called vboxautostart-service to automatically start and stop the service. But unfortunately, the script that comes with the Debian VirtualBox package is not really designed well. It’ll start the service — if you follow the direction — but it won’t cleanly stop it. So if my host machine reboots, then the guest vm shuts down uncleanly.. and then the guest machine might not restart cleanly when I reboot. It’s also grossly over-engineered for my needs and thoroughly offends my engineering sensibilities.
After much Googling of the deep web and learning of the many clever things, I found that there’s a very simple way to do this on a per VM basis. I’m sharing that here in the hopes that it helps others.
It boils down to this:
vboxautostart-service, get thee gone from my sight
If it’s already configured as a service on your system, you can either leave it alone, or you can tell the system to ignore it with:
systemctl disable vboxautostart-service
Then, create your shiny new service
Let’s say that your guest VM is called unifi and you want to create a new service that starts your VM in headless mode.
In /etc/systemd/system create a file called unify-vm.service and put this in it:
[Unit] Description=Unifi VM service After=network.target vboxdrv.service
[Service] ExecStart=/usr/bin/vboxheadless -s unifi ExecStop=/usr/bin/vboxmanage controlvm unifi acpipowerbutton User=runasthisuser Group=vboxusers
(I bold-faced the parts of the config that are specific to my UniFi setup, you’ll probably want to change those bits). This basically tells systemd how to start and stop a headless VM.
Enable your service
You have to tell systemd that there’s a new service with:
and that you want want your service to start at boot time with:
systemctl enable unifi-vm
Important! Change ownership of script to startup user from script:
chown runasthisuser:runasthisuser unify-vm.service
(optionaly chmod +x)
Your guest VM should shut down cleanly when your host shuts down. And when your host reboots, your guest should boot up with it. It’s a surprisingly easy process, and it should be fairly robust across upgrades. Share and enjoy.
Note: Stop running vm:
VBoxManage controlvm nameofvm poweroff ======================================
If you are looking to start your VirtualBox VMs automatically on boot using systemd look no further.
Create the Service File
This Arch Linux wiki page contains a sample service file that you can use to start VirtualBoxVMs in a headless mode. Add a file called ‘vboxvmservice@.service’ in /etc/systemd/system/.
Put this in the file:
[Unit] Description=VBox Virtual Machine %i Service Requires=systemd-modules-load.service After=systemd-modules-load.service [Service] User=user Group=vboxusers ExecStart=/usr/bin/VBoxHeadless -s %i ExecStop=/usr/bin/VBoxManage controlvm %i savestate [Install] WantedBy=multi-user.target
Replace the user after user= with the username you want to run the VMs. Make sure that the user is in the vboxusers group. If you need to delay the start of the VMs until after your network is started or a network share is mounted, locate the service you want to wait for using ‘systemctl’ and then substitute the service, mount, or network behind ‘After=’.
You can also replace ‘savestate’ in ‘ExecStop=’ with ‘poweroff’ or ‘acpipowerbutton’ to hard-stop the VM, or ask for a clean shut-down, respectively.
Enable the Service
To enable one or more VMs at boot, enter:
#systemctl enable vboxvmservice@vm_name.service
Use ‘systemctl start’ to immediately start the VM. After your computer starts up, you can use ‘systemctl –failed’ to make sure everything went smoothly. You may need to turn off 3D video features for your VM to run in headless mode.
You can continue to manage your VMs using the GUI interface if you choose. For more information on using systemd, see the general Arch Linux Wiki Page.