While trying to get a Dell 1320c (USB only) color laser printer to work on my PCLinuxOS workstation I learned a nifty trick... How to set up a VirtualBox VM (or multiple VM's) to run headless, start/restore automatically at boot, and save-state automatically at shutdown.
I'm posting it in the Advanced Users Section because it requires some messing with init scripts, but I hope the following tutorial will make it accessible to even new linux users.
Step 1:Get your VM set up to your liking... If haven't already, use pinoc's wonderful
GetVirtualBox app from our repo's to install the non-OSE edition of Virtual Box; this will allow for
VirtualBox Remote Desktop Protocol (VRDP) support and USB use. Depending on your planned use you may also want to create a bridged network adapter for easy sharing across the network (..in my case it was needed to share a windows-only USB printer across my LAN). I also used the virtual box GUI to set my VM to automatically make my USB printer available / connected at start up of the VM.
Step 2:Create the init script... this is a modification of a script borrowed from
here:
As root:
touch /etc/init.d/vboxcontrol
chmod 755 /etc/init.d/vboxcontrol
kwrite /etc/init.d/vboxcontrol &
Then copy/paste/save the following code into the empty script file created/opened above (..note that you will need to change
VM_USER in the script to the username that owns / created your VM's):
#! /bin/sh
# vboxcontrol Startup script for VirtualBox Virtual Machines
#
# chkconfig: 345 99 01
# description: Manages VirtualBox VMs
# processname: vboxcontrol
#
# pidfile: /var/run/vboxcontrol/vboxcontrol.pid
#
### BEGIN INIT INFO
#
### END INIT INFO
#
# Version 20120317 by travisn000 based on:
# Version 20090301 by Kevin Swanson <kswan.info> based on:
# Version 2008051100 by Jochem Kossen <jochem.kossen@gmail.com>
# [url]http://farfewertoes.com[/url]
#
# Released in the public domain
#
# Source function library.
if [ -f /etc/init.d/functions ] ; then
. /etc/init.d/functions
elif [ -f /etc/rc.d/init.d/functions ] ; then
. /etc/rc.d/init.d/functions
else
exit 1
fi
################################################################################
# INITIAL CONFIGURATION
VBOXDIR="/etc/virtualbox"
VM_USER="guest"
USE_NAT="no"
export PATH="${PATH:+$PATH:}/bin:/usr/bin:/usr/sbin:/sbin"
if [ -f $VBOXDIR/config ]; then
. $VBOXDIR/config
fi
SU="su $VM_USER -c"
VBOXMANAGE="VBoxManage -nologo"
################################################################################
# FUNCTIONS
# Determine if USE_NAT is set to "yes"
use_nat() {
if [ "$USE_NAT" = "yes" ]; then
return `true`
else
return `false`
fi
}
log_failure_msg() {
echo $1
}
log_action_msg() {
echo $1
}
# Check for running machines every few seconds; return when all machines are
# down
wait_for_closing_machines() {
RUNNING_MACHINES=`$SU "$VBOXMANAGE list runningvms" | wc -l`
if [ $RUNNING_MACHINES != 0 ]; then
sleep 5
echo " ..waiting for VM shut-down to complete.."
wait_for_closing_machines
fi
}
################################################################################
# RUN
case "$1" in
start)
if [ -f /etc/virtualbox/machines_enabled ]; then
cat /etc/virtualbox/machines_enabled | while read VM; do
log_action_msg "Starting VM: $VM ..."
$SU "$VBOXMANAGE startvm "$VM" -type vrdp"
RETVAL=$?
done
touch /var/lock/subsys/vboxcontrol
fi
;;
stop)
## NOTE: this stops all running VM's. Not just the ones listed in the config
## NOTE2: used controllvm 'savestate' instead of 'acpipowerbutton' to avoid hang
## with guest OS "..are you sure?" GUI prompts with acpipowerbutton
$SU "$VBOXMANAGE list runningvms" | cut -d\" -f2 | while read VM; do
log_action_msg "Saving state and powering off VM: $VM ..."
$SU "$VBOXMANAGE controlvm "$VM" savestate"
done
rm -f /var/lock/subsys/vboxcontrol
wait_for_closing_machines
;;
start-vm)
log_action_msg "Starting VM: $2 ..."
$SU "$VBOXMANAGE startvm "$2" -type vrdp"
;;
stop-vm)
log_action_msg "Stopping VM: $2 ..."
$SU "$VBOXMANAGE controlvm "$2" acpipowerbutton"
;;
savestate-vm)
log_action_msg "Saving state and powering off VM: $2 ..."
$SU "$VBOXMANAGE controlvm "$2" savestate"
;;
poweroff-vm)
log_action_msg "Powering off VM: $2 ..."
$SU "$VBOXMANAGE controlvm "$2" poweroff"
;;
status)
echo "The following virtual machines are currently running:"
$SU "$VBOXMANAGE list runningvms" | while read VM; do
echo -n "$VM ("
echo -n `$SU "VBoxManage showvminfo ${VM%% *}|grep -m 1 Name:|sed -e 's/^Name:s*//g'"`
echo ')'
done
;;
*)
echo "Usage: $0 {start|stop|status|start-vm <VM name>|stop-vm <VM name>|savestate-vm <VM name>|poweroff-vm <VM name>}"
exit 3
esac
exit 0
Step 3:Create/populate a "machines_enabled" config file... As the regular non-root user / vbox owner you can run the following command to get a list containing the name(s) of that users VirtualBox VM's (..or just get your VM names from the Oracle VirtualBox GUI):
vboxmanage list vms
As root, we will add the VM Name(s) to the config file that we want to auto-start at boot... the file should contain only one VM name per line and nothing else:
mkdir /etc/virtualbox
echo "My_FirstVM_Name" >> /etc/virtualbox/machines_enabled ###NOTE: replace My_FirstVM_Name, and repeat as needed..
cat /etc/virtualbox/machines_enabled ###..verify the file contains one VM name per line and nothing else
Step 4:Set init script to run automatically... As root: set vboxcontrol service to auto start with chkconfig & verify (second command should show "on" for init level 3,4,5):
chkconfig --add vboxcontrol
chkconfig --list vboxcontrol
Step 5:Verify and test... Your specified VM's should auto-start in a headless configuration upon boot, save state and shut off cleanly at reboot/shut-down, and you should now be able to use your new vboxcontrol service commands to manipulate your VM's at any time as either root or the VM owner/user:
Start ALL VirtalMachines listed in the machines_enable file:
service vboxcontrol startView Status of Running VirtualMachines
service vboxcontrol statusStop ALL VirtualMachines currently running and save their current state
service vboxcontrol stopStart a Specific VirtualMachine Only !!
service vboxcontrol start-vm <VM NAME>Stop a Specific VirtualMachine Only ( send acpi powerbutton signal -- NOTE: this can often appear to hang, as the guest OS may have a GUI prompt within the VM asking the user to confirm this action; if you don't have a RDP connection to the guest visible you will not see this confirmation prompt and cannot click "OK" to allow the shut-down to continue [in KDE4 this prompt will timeout automatically after ~15 seconds, but not in Windows XP, and I don't know about other linux DE's])
service vboxcontrol stop-vm <VM-NAME>Save and Stop a Specific VirtualMachine Only (..this is a more reliable way to stop a VM; it will save the VM state and shut it off without sending the guest OS acpi power signal, thus avoiding the above mentioned issues)
service vboxcontrol savestate-vm <VM-NAME>Send Power Kill signal to VirtualMachine (immediate power off -- has the same effect on a virtual machine as pulling the power cable on a real computer. the state of the VM is NOT saved beforehand, and data may be lost)
service vboxcontrol poweroff-vm <VM-NAME>