List forwarding rules in VirtualBox running headless (even with older VBoxManage versions)

The VBoxManage command is very handy for managing virtual machines in servers running headless. Adding and removing forwarding rules is super simple, you just call for example

# adding "rule1" for "vm_1" mapping TCP host_port to guest_port
VBoxManage modifyvm vm_1 --natpf1 "rule1,tcp,,host_port,,guest_port"

# deleting that same rule
VBoxManage modifyvm vm_1 --natpf1 delete rule1

I created two simple scripts so that I don’t have to remember the exact syntax every time: vm_forward_add and vm_forward_delete. You run the commands with no arguments, and they tell you what you need to add.

Listing the existing rules is a bit more complex, as VBoxManage has no option for that (not the version that I use, at least).

This is where xmlstarlet comes to the rescue. Xmlstarlet is a command-line tool for parsing XML that comes pre-installed in most UNIX systems.

Since forwarding rules are stored in VirtualBox .vbox files, which are just big XML files storing all properties for a VM, we can grab the information we want from there.

This is the script that I use to list all forwarding rules. I can’t guarantee that it works with any version of VirtualBox, but it works with any version <=4.3 (the one I use).

Feel free to use the script, the worst that it can do is… not work 🙂

About things that weren't too obvious: you need to include the XML schema not only in the XPath of the XML node you're interested in, but in all definitions (!).

So, say you have a node with this path and these attributes (xmlstarlet el -a lists all XPaths available in the XML file):

me@server:~ xmlstarlet el -a my_vm.vbox | grep Forwarding
VirtualBox/Machine/Hardware/Network/Adapter/NAT/Forwarding
VirtualBox/Machine/Hardware/Network/Adapter/NAT/Forwarding/@name
VirtualBox/Machine/Hardware/Network/Adapter/NAT/Forwarding/@proto
VirtualBox/Machine/Hardware/Network/Adapter/NAT/Forwarding/@hostport
VirtualBox/Machine/Hardware/Network/Adapter/NAT/Forwarding/@guestport

To query those four attributes you need to specify the XML schema using the -N option (easy to find in xmlstarlet‘s docs), but you also need to set that schema for every single attribute name!

So, this will fail:

xmlstarlet sel -N x="http://www.innotek.de/VirtualBox-settings" -t \
-m "//x:Machine/Hardware/Network/Adapter/NAT/Forwarding" -v @name \
-o " " -v @hostport -o " " -v @guestport -n my_vm.vbox

but this will work (note the repeated x:):

xmlstarlet sel -N x="http://www.innotek.de/VirtualBox-settings" -t \
-m "//x:Machine/x:Hardware/x:Network/x:Adapter/x:NAT/x:Forwarding" \
-v "concat(@name, ' - host:', @hostport, ' guest:', @guestport)" \
-n my_vm.vbox

I wish this was more explicit in xmlstarlet documentation!

Mounting a CD/DVD image on a VirtualBox 4.0+ VM running headless

VBoxManage is a great tool, but it’s really too powerful to have such a weakly organized --help screen.

Plus, recent VirtualBox versions have a subtly different syntax for common operations, and you may find several ways to perform a basic task depending on the version the post you find is talking about.

So, in order to mount a CD or DVD image while your VM is running (headless or not it doesn’t really matter… obviously if it is headless you have no choice) you have to type the following:

VBoxManage storageattach "your VM name" --storagectl 'Controller IDE' --port 1 --device 0 --type dvddrive --medium /path/to/your/iso/image.iso

Remember to escape your VM name in case it has whitespaces! Of course you may use uuids instead of names and you may attach hdds, fdds and specify whatever option you want. Just type

VBoxManage storageattach

by itself to see the specific help with all the info you need.