rc.d script for running multiple VirtualBox VMs from /etc/rc.conf

Tobias Oberstein tobias.oberstein at tavendo.de
Tue Apr 12 19:15:41 UTC 2011


I wanted to configure multiple VirtualBox VMs to startup automatically at boot time and generally be a nice citizen to the FreeBSD way of starting up stuff.

Using that rc.d script (see attached) you can configure starting up multiple VirtualBox VMs from /etc/rc.conf:

## VirtualBox VMs
vboxvm_enable="YES"
vboxvm_machines="vm1 vm2"

## VM1
vboxvm_vm1_enable="YES"
vboxvm_vm1_name="vm1"
vboxvm_vm1_user="vbox_vm1"
vboxvm_vm1_log="vboxvm.log"
vboxvm_vm1_vncport="5901"
vboxvm_vm1_vncpassword="secret1"

## VM2
vboxvm_vm2_enable="YES"
vboxvm_vm2_name="vm2"
vboxvm_vm2_user="vbox_vm2"
vboxvm_vm2_log="vboxvm.log"
vboxvm_vm2_vncport="5902"
vboxvm_vm2_vncpassword="secret2"

==

The script must be put to

/usr/local/etc/rc.d/vboxvm

and understands three commands: start, stop and status.

You can use it on all VMs configured (and enabled)

$ /usr/local/etc/rc.d/vboxvm status
VBox machine 'vm1' is running.
VBox machine 'vm2' is running.

or on a specific VM

$ /usr/local/etc/rc.d/vboxvm stop vm1

==

The parameters:

vboxvm_<VM Name>_enable
=> mandatory : enable/disable the VM

vboxvm_<VM Name>_name
=> mandatory : VirtualBox name of the VM

vboxvm_<VM Name>_user
=> mandatory : the Unix user under which the VM will be run (using VBoxHeadless)

vboxvm_<VM Name>_log
=> optional : log file when VBoxHeadless runs the VM

vboxvm_<VM Name>_vncport
=> optional : when given, VBoxHeadless with active VNC server embedded

vboxvm_<VM Name>_vncpassword
=> optional : when VNC is active, a password

==

bugs/limits:

1) the restart/rcvar commands do now work
2) when the system shuts down, it doesnt wait for "stop" to finish graceful shutdown of VMs

I'm new to writing rc.d on FreeBSD, so if someone knows how to fix those, I'd be interested.

==

credits: the script skeleton was shamelessly stolen from /usr/local/etc/rc.d/apache22 ;)

cheers,
Tobias

-------------- next part --------------
#!/bin/sh

# PROVIDE: vboxvm
# REQUIRE: LOGIN
# KEYWORD: shutdown

. /etc/rc.subr

name="vboxvm"
rcvar=`set_rcvar`

load_rc_config $name

if [ -n "$2" ]; then
	machine="$2"
	if [ "x${vboxvm_machines}" != "x" ]; then
		eval vboxvm_name="\${vboxvm_${machine}_name:-}"
		if [ "x${vboxvm_name}" = "x" ]; then
			echo "You must define a VM name (vboxvm_${machine}_name)"
			exit 1
		fi
		eval vboxvm_user="\${vboxvm_${machine}_user:-}"
		if [ "x${vboxvm_user}" = "x" ]; then
			echo "You must define a VM execution user (vboxvm_${machine}_user)"
			exit 1
		fi
		eval vboxvm_log="\${vboxvm_${machine}_log:-${vboxvm_name}.log}"
		eval vboxvm_vncport="\${vboxvm_${machine}_vncport:-}"
		eval vboxvm_vncpassword="\${vboxvm_${machine}_vncpassword:-}"
		if [ "x${vboxvm_vncport}" = "x" -a "x${vboxvm_vncpassword}" != "x" ]; then
			echo "Warning: VNC password, but no VNC port specified for machine '${machine}' - VNC will be disabled."
		fi
	else
		echo "$0: extra argument ignored"
	fi
else
	if [ "x${vboxvm_machines}" != "x" -a "x$1" != "x" ]; then
		for machine in ${vboxvm_machines}; do
			eval _enable="\${vboxvm_${machine}_enable}"
			case "x${_enable:-${vboxvm_enable}}" in
			x|x[Nn][Oo]|x[Nn][Oo][Nn][Ee])
            echo "VBox machine '${machine}' skipped (disabled)."
				continue
				;;
			x[Yy][Ee][Ss])
				;;
			*)
				if test -z "$_enable"; then
					_var=vboxvm_enable
				else
					_var=vboxvm_"${machine}"_enable
				fi
				echo "Bad value" \
				    "'${_enable:-${vboxvm_enable}}'" \
				    "for ${_var}. " \
				    "VBox machine '${machine}' skipped."
				continue
				;;
			esac
			/usr/local/etc/rc.d/vboxvm $1 ${machine}
			retcode="$?"
			if [ "0${retcode}" -ne 0 ]; then
				failed="${machine} (${retcode}) ${failed:-}"
			else
				success="${machine} ${success:-}"
			fi
		done
		exit 0
	fi
fi

start_cmd="vboxvm_start"
stop_cmd="vboxvm_stop"
status_cmd="vboxvm_status"
extra_commands="status"

vboxvm_start()
{
    echo "VBox machine '${vboxvm_name}' powering up."
    if [ "x${vboxvm_vncport}" != "x" ]; then
       if [ "x${vboxvm_vncpassword}" = "x" ]; then
          vncopts="--vnc --vncport ${vboxvm_vncport}"
       else
          vncopts="--vnc --vncport ${vboxvm_vncport} --vncpass ${vboxvm_vncpassword}"
       fi
    fi
    if [ "x${vboxvm_log}" != "x" ]; then
       logopts="1>${vboxvm_log} 2>&1"
    fi
    cmd="exec /usr/local/bin/VBoxHeadless ${vncopts} -s ${vboxvm_name} ${logopts} &"
    su -l ${vboxvm_user} -c "${cmd}"
}

vboxvm_stop()
{
    echo "VBox machine '${vboxvm_name}' powering down."
    su -l ${vboxvm_user} -c "exec /usr/local/bin/VBoxManage controlvm ${vboxvm_name} acpipowerbutton"
}

vboxvm_status()
{
    runningvms="`su -l ${vboxvm_user} -c 'exec /usr/local/bin/VBoxManage list runningvms'`"
    myvm="`echo ${runningvms} | grep -c ${vboxvm_name}`"
    if [ "${myvm}" -ne "0" ]; then
       echo "VBox machine '${vboxvm_name}' is running."
    else
       echo "VBox machine '${vboxvm_name}' is powered down."
    fi
}

run_rc_command "$1"


More information about the freebsd-emulation mailing list