Scripts to use in Headless Mode

Discussions related to using VirtualBox on Linux hosts.
no1youknowz
Posts: 18
Joined: 12. Aug 2007, 16:08

Scripts to use in Headless Mode

Post by no1youknowz »

Since I have 5 servers with only 1 monitor and doing alot of work with the CLI. I decided to create some scripts. I thought I would share these in the community, as to be honest. Im very new to bash. Perphaps others working with CLI and headless mode could take my work and further it.

I've put these scripts in /root/.VirtualBox/Scripts and created symlinks to /usr/bin

vboxiso.sh - a script to control the dvd/cd image, even whilst the guest is on.

Code: Select all

#!/bin/sh

#ensure that the server name is entered
if [ -z "$1" ] ; then
        echo "Please enter the server you wish to start"
        echo "usage cmd <server>"
        exit 1
fi

if [ "$2" == "none" ] ; then
        echo Unmounting DVD/CD-ROM
elif [ -z "$2" ] ; then
        echo "Please enter the iso image you wish to mount"
        exit 1
elif [ -e $2 ] ; then
        donothing=0
else
        echo "$2 doesnt seem to exist, please check the path or filename"
        exit 1
fi

VBoxManage controlvm $1 dvdattach $2
vboxdelete.sh - a script to completely remove a guest from the system!

Code: Select all

#!/bin/sh

#integer for number of drives
num=1

# ensure that the server name is entered
if [ -z "$1" ] ; then
        echo "Please enter the server you wish to start"
        echo "usage cmd <server>"
        exit 1
fi

# loop through available hard drives
for vint in `grep hardDisk /root/.VirtualBox/Machines/"$1"/"$1".xml | cut -d\" -f6`; do

        len=${#vint}
        len=$(($len-2))
        uuid=`expr substr $vint 2 $len`
        path=`VBoxManage showvdiinfo $uuid`
        files=`echo $path | cut -d" " -f44`

        #remove hd's from vm guest
        case $num in
                1 )
                echo --- Unmounting hda ---
                VBoxManage modifyvm $1 -hda none
                echo --- Unregistering drive ---
                VBoxManage unregisterimage disk $uuid
                ;;
                2 )
                echo --- Unmounting hdd ---
                VBoxManage modifyvm $1 -hdd none
                echo --- Unregistering drive ---
                VBoxManage unregisterimage disk $uuid
                ;;
        esac

        rm -rf $files
        echo --- Deleted $files ---

        num=$(($num+1))
done

rm -rf "/root/.VirtualBox/Machines/"$1
VBoxManage unregistervm $1
echo --- Deleted VM Guest: $1 ---
These set of scripts, are to allow me to dynamically create TAP devices and assign them to the relevant bridge. It works on an 1:1 basis for interface to brige! Also, since I want to RDP into the guest immediately, it takes the VRDP IP and assigns it to the first TAP interface.

Unlike in the manual, I dont assign any network interfaces to the host interfaces created. vboxup.sh does this for me. However, I still use cleanuptap.sh as directed for the interfaces that I have. As when the VM shutsdown, its able to delete the TAP devices.

Unfortunately, the script doesnt take into account that a guest could crash and then you need to use the existing TAP devices. Or if you run the startup script again, it will create new TAP devices. I will fix this later.

vboxup.sh - Create the TAP devices per network interface

Code: Select all

#!/bin/sh

# Create variable for Tap interfaces
tap=0

# create array to store vbox interfaces
declare -a vbr

# create variables for checking bridges
array=0
flag=0

# check for how many bridged interfaces are present
for i in `service network status`; do
        #check using regular expression:
        if [[ "$i" =~ "br[0..9]*" ]] ; then
                # array is empty, add in card
                if [[ "$array" == 0 ]] ; then
                        vbr=( ${vbr[@]} $i )
                        array=$(($array+1))
                else
                        # check array for duplications
                        for a in ${vbr[@]}; do
                                if [ $i != $a ] ; then
                                        # set flag when dup found
                                        flag=$(($flag+1))
                                fi
                        done
                        # flag is up, add it to the array
                        if [ "$flag" == 1 ] ; then
                                vbr=( ${vbr[@]} $i )
                        fi
                fi
        fi
done

#No bridges configured, terminate script
if [ "$array" == 0 ] ; then
echo You have no bridges configured!
exit 1
fi

# Create Tap interfaces per network interfaces
for vint in `grep HostInterface /root/.VirtualBox/Machines/"$1"/"$1".xml | cut -d\" -f2`; do
        #Create the Tap Interface
        interface=`VBoxTunctl -b -u root`

        if [ -z "$interface" ]; then
                echo couldnt setup a TAP Device
                exit 1
        fi

        if [ "$tap" == 0 ]; then
                # get the netmask from br0
                ifcfg=`ifconfig br0`
                netmask=`echo $ifcfg | cut -d":" -f10`
                mask=`echo $netmask | cut -d" " -f1`

                # set an IP to the vbox interface
                # get the server.xml to get the RDP address
                rdpip=`grep RemoteDisplay /root/.VirtualBox/Machines/"$1"/"$1".xml | cut -d\" -f6`

                /sbin/ifconfig $interface $rdpip netmask $mask up
                tap=$(($tap+1))
        fi

        /sbin/ifconfig $interface up
        /usr/sbin/brctl addif ${vbr[$vint]} $interface

        # modify the guest vm to assign the host interface to that
        # virtual interface
        VBoxManage modifyvm $1 "-hostifdev"${#vint[@]} $interface
done

exit 0
vboxstart.sh - script to start a guest

Code: Select all

#!/bin/sh

#ensure that the server name is entered
if [ -z $1 ] ; then
        echo "Please enter the server you wish to start"
        echo "usage cmd <server>"
        exit 1
fi

showvminfo=`VBoxManage showvminfo $1`
showvminfoline=`echo $showvminfo | cut -d":" -f13`
status=`echo $showvminfoline | cut -d" " -f1`

if [[ "$status" = "running" ]] ; then
        echo VM Guest $1 is already powered on!
        exit 1
else
        VBoxUp $1
        VBoxVRDP -startvm "$1" &
fi
vboxstop.sh - script to stop a guest

Code: Select all

#!/bin/sh

#ensure that the server name is entered
if [ -z $1 ] ; then
        echo "Please enter the server you wish to stop"
        echo "usage cmd <server>"
        exit 1
fi

showvminfo=`VBoxManage showvminfo $1`
showvminfoline=`echo $showvminfo | cut -d":" -f13`
power=`echo $showvminfoline | cut -d" " -f1`
status=`echo $showvminfoline | cut -d" " -f2`

vm="$power $status"

if [[ "$vm" = "powered off" ]] ; then
        echo VM Guest $1 is already powered off!
        exit 1
else
        VBoxManage controlvm "$1" poweroff
        #VBoxDown "$1"
fi
cleanuptap.sh - remove TAP interfaces assigned to each network interface (taken from the manual)

Code: Select all

#!/bin/bash

VBoxTunctl -d $2
suds_sr
Posts: 4
Joined: 11. Oct 2007, 08:47

script for multiple virtual machine instances

Post by suds_sr »

Hi, I'm trying to run multiple virtual machine instances from a host machine. That is, to run about 4 virtual machines on a host machine one-by-one. Have anyone tried a script to automate this? (i.e., create vm, start vm, stop vm).

I need to do it for a few host machines. Any help is greatly appreciated.
Cheers,
Suds
erstazi
Posts: 17
Joined: 27. Dec 2007, 04:16
Primary OS: Debian Lenny
VBox Version: OSE self-compiled
Guest OSses: You name it, I test in it.
Location: USA
Contact:

Re: script for multiple virtual machine instances

Post by erstazi »

suds_sr wrote: I need to do it for a few host machines. Any help is greatly appreciated.
It is possible, with these scripts, just a bit of modification. Mainly, the startvm one, each VBoxVRDP vm needs its own RDP port, so the parameter -vrdpport XXXX needs set, just add an extra bit to that bash script and it will run smoother. Also, you can set it up so the virtual machines will start when you boot.
markba
Posts: 99
Joined: 1. Oct 2007, 23:50
Location: The Netherlands

Post by markba »

I created a script for showing the status of running vm's. With an extra parameter ('shutdown'), running vm's are saved.

It iterates over all registered vm's, so it is not necessery to enter the name or uuid of the session.

Code: Select all

#
#  See the actual version in a post below
#
I will further extend this script:
- show if VRDP is enabled and if so, on what port
- show only running vm's, new parameter 'listrunningvms'
- show memory usage and cpu-load for running vm's
- mass-start vms, new parameter 'startvms'
- if no session-name is given, all registered sessions will be started
Last edited by markba on 3. Sep 2008, 09:02, edited 1 time in total.
markba
Posts: 99
Joined: 1. Oct 2007, 23:50
Location: The Netherlands

Post by markba »

A new version of the vbox-script

Enhancements:
- Renamed from vbox-tool to vbox
- Only show saved session on shutdown
- Option 'shutdown' changed to 'save' (cause that's what happening)
- For running sessions, show runtime info: cpu-load and memory
- Added option 'showrun': retrieve status of running sessions
- Added option 'start': start all saved sessions
- powered off & aborted sessions are left alone
- Added option 'showall': retrieve status of all sessions
- No-parameter or incorrect parameter invocation gives usage-page
- Added option '--help': shows usage
- Show configured vrdp-port while showing and starting sessions

Usage: vboxtool [save | start | showall | showrun ]
showall - Show status of all sessions
showrun - Show status of running sessions
start - Start all saved sessions, powered off & aborted sessions are left alone
save - Save all running sessions

Code: Select all

#
#  See the actual version in a post below
#
Feedback is welcome.
Last edited by markba on 3. Sep 2008, 09:01, edited 2 times in total.
rawe
Posts: 7
Joined: 5. Aug 2008, 23:21

Perhaps a new feature to your script

Post by rawe »

Hi Mark

It seems like a nice script you've put together. Just the sort of thing I was looking for. Great!

My scenario: in my company we have an application server (host) running Linux and on this machine we have put a - growing - number of headless VirtualBox VMs. The users connect through RDP.
This works great (expect for Mac users using MS Remote Desktop for Mac, as VirtualBox have a reported - and according to the VirtualBox developers fixed in the coming VirtualBox 1.6.6, see http://forums.virtualbox.org/viewtopic. ... highlight= - bug. Mac users can still use Cord, though).

What I'm implementing right now is nightly backups of all the different VMs.
I plan to run a Cron job at a given time at night saving all the VMs using your script, do a copy of the home folder of the (virtual) user running all the VMs to get a backup of all the .vdi files and then restart the VMs by calling your script. This will probably be very easy to implement by using your script - so thank you very much for your effort!

Best

Rasmus Wehner
ROSA, Denmark
markba
Posts: 99
Joined: 1. Oct 2007, 23:50
Location: The Netherlands

Re: Perhaps a new feature to your script

Post by markba »

rawe wrote:What I'm implementing right now is nightly backups of all the different VMs.
No coincedence, but I'm currently implementing a backup option in the vbox script right now!

The things you mention (save sessions, copy files and starting sessions) are already implemented. The future version will be based on snaphots so incremental backups (therefore: fast!) will be possible. When finished, one script will do all the work, fully integrated. This script can be run as a cron job, just like you mentioned.

As soon as I have a crude version, I'll post it here. The next version, based on snapshots will follow later. If you are interested in discussing the backup mechanism, just ask and I'll post the design details also.
rawe
Posts: 7
Joined: 5. Aug 2008, 23:21

Backup feature in your script

Post by rawe »

This sounds great, Mark!
What we have planned was doing the actual backup (once your script has saved the VMs) via rsync as this would also make things incremental.

But doing things by snapshots is of course also a possibility. We're just using rsync in other places in our IT infrastructure to get things copied.

Of course using rsync as part of your scripts introduces dependencies to other programs than VboxManage etc. so perhaps the 'cleanest' version would be your solution (using snapshots and just copying those as backups).
But as I see it you need to make sure, that the user has the original version of the .vdi file somewhere safe - otherwise the snapshots aren't worth much (if I understand the snapshot files correctly, haven't used them myself I should stress).

Looking forward to see the new version of the script.

Currently I'm discussing a web (PHP) frontend that could be run on the application server (via Apache running locally on the server). It shouldn't be much of a problem making a small website that makes a GUI to your scripts, so that some of my co-workers not used to shell commands and SSH and stuff like that should be able to start and stop and save different VMs. No need to have all of the VMs running constantly (taking up CPU time) if some of the VMs are only used once or twice a month. Right now I have to start and stop those VMs, but of course I would prefer if people could just do that themselves.

If we decide to make such a web frontend then we will of course publish it as open source here on this forum - pointing to your scripts.

Best

Rasmus Wehner
Denmark
markba
Posts: 99
Joined: 1. Oct 2007, 23:50
Location: The Netherlands

Post by markba »

I'm already using rsync for file copying. Yes, rsync implements incremental backup (rolling checksum), but this strongly depends on the structure of the file to be copied; I'm not certain a VDI file provides the optimal format. So instead of relying on the builtin capabilities of rsync, implementing a system based om snapshots is more reliable, performance wise.If rsync can help, that's bonus.

You are right in the fact that besides snapshots, the VDI file it self should be backup up; of course, this is the main file! I was a little short in explanation on this.

Currently I'm researching a method to provide an online backup, i.e. without saving or pausing a session. That is essential for mission critical systems and if you don't have one, it's nice to develop something like this anyway. ;-)

But first a crude backup, i.e. copy all VDI's simply over by rsync. You can expect the update very soon and I'm looking forward to any feedback.
markba
Posts: 99
Joined: 1. Oct 2007, 23:50
Location: The Netherlands

Post by markba »

As promised, the renewed script with the backup option (first, crude approach). The next version will be incremental, based on snaphots.

Revision:
- Backup a specific session: vbox backup <session name>; running sessions are saved and started after backup has completed. This is only a first approach: copy complete vdi file. This is taking a long time because the complete VDI file has to be copied each and every time. Thus this can not be considered as a solution in real production systems
- Save a specific session: vbox save <session name>
- Start a specific session: vbox save <session name>
- Stop all running sessions or a specific session: vbox stop [session name]
- Renamed option 'showall' to 'show'
- Code refactoring

Usage: type 'vbox' without parameters.

Code: Select all

# 
#  See the actual version in a post below 
#
Last edited by markba on 8. Sep 2008, 20:18, edited 1 time in total.
rawe
Posts: 7
Joined: 5. Aug 2008, 23:21

Problems running your script

Post by rawe »

Hi Mark

Great work, as far as I can see.
But: I've copied your recent script to a vbox file on our application server, placed it in /usr/local/bin, made executable etc. and tried to run it.

This is the error I get:
vbox@app:~> /usr/local/bin/vbox show
/usr/local/bin/vbox: line 281: [: /usr/bin/VBoxManage: binary operator expected
/usr/local/bin/vbox: line 81: vboxmanage: command not found

Just to make sure, I ran the following commands (and got the following results):

vbox@app:/usr/local/bin> whereis VBoxManage
VBoxManage: /usr/bin/VBoxManage /usr/bin/X11/VBoxManage

vbox@app:/usr/local/bin> whereis vboxmanage
vboxmanage:

As you can see, I'm able to 'whereis' the VBoxManage file. And VirtualBox is running fine with two different VMs working and responding by RDP.

I'm running SUSE Linux 10.3 (AMD 64). Have you got any idea what's going wrong?

Best

Rasmus Wehner
ROSA, Denmark
markba
Posts: 99
Joined: 1. Oct 2007, 23:50
Location: The Netherlands

Re: Problems running your script

Post by markba »

rawe wrote:This is the error I get:
vbox@app:~> /usr/local/bin/vbox show
/usr/local/bin/vbox: line 281: [: /usr/bin/VBoxManage: binary operator expected
/usr/local/bin/vbox: line 81: vboxmanage: command not found

Just to make sure, I ran the following commands (and got the following results):

vbox@app:/usr/local/bin> whereis VBoxManage
VBoxManage: /usr/bin/VBoxManage /usr/bin/X11/VBoxManage

vbox@app:/usr/local/bin> whereis vboxmanage
vboxmanage:
I've seen this message before, but only when I'm making a syntax error; after correcting such an error, the message will disappear. I cannot imagine the syntax of for example awk is different on a Suse system then it is on Ubuntu (but we're never sure).

To find out, can you also try:

Code: Select all

whereis VBoxManage | awk 'BEGIN{FS="VBoxManage: "}{print $2}'
rawe wrote:I'm running SUSE Linux 10.3 (AMD 64).
The script is written and tested on Ubuntu Hardy (8.10), but I don't specifically expect a problem with Suse. We will track down this problem in due course.
Last edited by markba on 8. Sep 2008, 16:11, edited 1 time in total.
greenpossum
Volunteer
Posts: 98
Joined: 11. Jul 2008, 08:10

Re: Problems running your script

Post by greenpossum »

rawe wrote:Hi Mark

Great work, as far as I can see.
But: I've copied your recent script to a vbox file on our application server, placed it in /usr/local/bin, made executable etc. and tried to run it.

This is the error I get:
vbox@app:~> /usr/local/bin/vbox show
/usr/local/bin/vbox: line 281: [: /usr/bin/VBoxManage: binary operator expected
/usr/local/bin/vbox: line 81: vboxmanage: command not found

Just to make sure, I ran the following commands (and got the following results):

vbox@app:/usr/local/bin> whereis VBoxManage
VBoxManage: /usr/bin/VBoxManage /usr/bin/X11/VBoxManage

vbox@app:/usr/local/bin> whereis vboxmanage
vboxmanage:

As you can see, I'm able to 'whereis' the VBoxManage file. And VirtualBox is running fine with two different VMs working and responding by RDP.

I'm running SUSE Linux 10.3 (AMD 64). Have you got any idea what's going wrong?

Best

Rasmus Wehner
ROSA, Denmark
The problem is the script assumes that VBoxManage will be found in exactly one place, but as you saw, it is found in two places. I'll leave it to the author to fix.
markba
Posts: 99
Joined: 1. Oct 2007, 23:50
Location: The Netherlands

Re: Problems running your script

Post by markba »

greenpossum wrote:The problem is the script assumes that VBoxManage will be found in exactly one place, but as you saw, it is found in two places. I'll leave it to the author to fix.
Yes, that's quite odd. Lets see if and how to fix.

@rawe. How can you have two instances of vboxmange? Especially good to know because apparently, the first instance does not work.

When I'm back from work, I'll test the whereis-command, see what my system look like.
Last edited by markba on 8. Sep 2008, 16:22, edited 1 time in total.
rawe
Posts: 7
Joined: 5. Aug 2008, 23:21

Continued: problems with your script

Post by rawe »

Edit: this thread sure works fast. As I was typing my reply you guys already had a conversation going...

Well, the double instance-thing might be the explanation. So far so good.

Best

Rasmus Wehner
Denmark

Original message:

Hi Mark

Thank you very much for your quick reply.
I tried what you suggested, and this is the result:

app:~ # whereis VBoxManage | awk 'BEGIN{FS="VBoxManage: "}{print $2}'
/usr/bin/VBoxManage /usr/bin/X11/VBoxManage

Not sure exactly what we were to expect, but this somehow doesn't seem right to me. It seems that awk isn't doing anything at all to the result.

And just to make sure I checked that awk is installed on our system. And it is...

Could you tell me what the result of the command(s) should have been? Like: what result do you get when you execute the commands?

Best

Rasmus Wehner
Denmark
Post Reply