This post will show how to start stop Virtualbox with systemd. The documentation for both auto-starting virtualbox and that for systemd I found to be appalling. The virtual box documentation has an example but that is wrong. The example code is bash and it is sourced by another file. There is a variable assignment at the top but it has spaces around the equals so it fails with a schoolboy syntax error. For systemd what there is, and there is a lot of it, does not make sense. The man pages have lots of English words that go together to mean nothing but the usual marketing bullshit we are constantly get bombarded with.
How I Got Here
I sorted out this little project I used mainly trial and error. After I found the official documentation to be a let down I read a number of answers to questions and a few blog post. None gave a complete system set up to Start Stop VirtualBox with systemd. All in all I’m very glad I had a minimal server that boots very quickly 🙂 It gets tedious waiting for the VM to boot and close down. See this post on how to create a minimal server install.
Get rid of vboxautostart-service
So to begin. The Oracle vboxautostart-service installed with Virtualbox has never worked reliably for me even after extensive hacking of the source code in the scripts. With that said we can disable that service as we will not be using it.
sudo systemctl disable vboxautostart-service
If you want a deep clean also get rid of the source unit file for vboxautostart-service. That way it can never get turned back on again. Although it will probably get put back at the next update. 🙁
sudo rm -rf /lib/systemd/system/vboxautostart-service.service
If the config directory used by vboxautostart-service was created you can also delete that too. We will not be using anything in there either.
sudo rm -rf /etc/vbox
User permissions for Virtualbox
The user who will run our VMs will need to be in the group vboxusers. If you have already been using Virtualbox then your users probable is already. First, let’s see if it is already there then append it as necessary.
richard adm cdrom sudo audio dip video plugdev lpadmin sambashare
Richard is not a member of vboxusers it is not listed. Append the group to your list of existing groups, do not forget the -a for append 🙂
sudo usermod -a -G vboxusers richard
Now you will need to log out and back in again, to pick up the new group. The output of groups will show it added.
richard adm cdrom sudo audio dip video plugdev lpadmin sambashare vboxusers
New Unit File for systemd
To start stop VirtualBox with systemd we will create our own new unit file. This is a first try, we will make it better later on. This is the one and only file to create nothing else is needed. Open up the file with your favorite editor.
Create a new Unit file
sudo nano /etc/systemd/system/vm_autostart_name.service
Add this text as the contents. I picked bits from assorted posts and help documentation to get this layout. This is the bare bones that I got to work. I would love to explain what each line does, but the documentation is so bad I still do not know. 🙁
You will need to change the three occurrences of vm_name to the name of your own VM guest. Do not use a ‘-‘ hyphon or dash in the name of your VM, systemd will not allow that to work, more systemd BS. Also note the User=richard in the [Service] section I’m guessing you will need to change that too.
[Unit] Description=VM vm_name After=network.target vboxdrv.service Before=runlevel2.target shutdown.target [Service] User=richard Group=vboxusers Type=forking Restart=no TimeoutSec=5min IgnoreSIGPIPE=no KillMode=process GuessMainPID=no RemainAfterExit=yes ExecStart=/usr/bin/VBoxManage startvm vm_name --type headless ExecStop=/usr/bin/VBoxManage controlvm vm_name acpipowerbutton [Install] WantedBy=multi-user.target
Reload systemd daemon
As you have added or changed a file that systemd uses you have to reload the daemon. If you do not reload, you get a warning from systemd to do just that and nothing will work correctly until you do. Why is systemd better than what we had already? Systemd knows the files need to be reloaded so why not do it or have an option to allow that to happen. How very Microsoft.
sudo systemctl daemon-reload
Using the service
Now we can enable our service and start to test it out.
sudo systemctl enable vm_autostart_name
We can now stop, start and use status to see how things are going. The status gives you some idea what is going on. Running tail -f on the syslog gives a little bit more info when you start to debug your service for typos.
sudo systemctl start vm_autostart_name sudo systemctl stop vm_autostart_name sudo systemctl status vm_autostart_name
That should all be working now. From the command line try starting it up and the seeing the status. Stop the VM and make sure that workings. You should also be able to shut down the host and the VM will shutdown and then restart as the host is booted. Almost sorted. This service only works for that one hard coded VM. That could be pain if you have many VMs.
Wildcard Names For Services
We do not want to have to create a new unit file for every VM. Yay a good popint for systemd but i could do more with a SysV init script. :). We can use a feature of systemd. I found this little gem by looking at the source of other services already installed.
Disable the vm_autostart_name.service and then rename the unit file to vm_autostart@.service. Find all occurrences of vm_name or whatever you called your VM, replacing them with %I (percent, capital I, as in ‘I’ wrote this post).
sudo systemctl disable vm_autostart_name sudo mv /etc/systemd/system/vm_autostart_name.service /etc/systemd/system/vm_autostart@.service
Save the changes and do not forget to reload the systemd daemon it won’t do that for itself.
sudo systemctl daemon-reload
NOTE: VM names MUST be not include ‘-‘, hyphons, change them to ‘_’, underscores. Systemd
annoyingly converts ‘-‘ into a ‘/’. A VM name of test-server becomes test/server and therefore cannot be found. I saw a message in the syslog when looking to see why it had failed to work.
Enable the new service
We enable this multi-use service with the name of the VM after the ‘@’ as shown below. We cannot enable the actual service name, vm_autostart@.service,from the unit file. Again in the examples below change vm_name to the name of your VM.
sudo systemctl enable vm_autostart@vm_name
And then use it with the following,
sudo systemctl status vm_autostart@vm_name sudo systemctl start vm_autostart@vm_name sudo systemctl stop vm_autostart@vm_name
Now we only have to enable the service for each VM, you will not have to create a new unit file etc. for each. That is, it we can now start stop VirtualBox with systemd and it will automatically start them up at boot time and close them down when the host machine is shut down.
While testing out start stop VirtualBox with systemd I found that under some circumstances the service would not close down the VMs. If you start a VM with the service. You can then close it with the service. If you start the VM without using the service it will not close down with the service stop command. Also, if you start the VM with the service and then try to start the VM again, by mistake, you cannot use the service to close it down.
If you do find a solution please let me know.
Some not particularly helpful documents
loads of other man systemd* files.
You have noticed this was a bit of a rant. Before starting this project and this post I had no particular position on systemd. Now I know it is bad. Even the developers don’t have a clue how it works, so they resort to the verbose bullshit in their man pages, to cover it up.