Virtualized virtual environment

In the case when you don’t have enough hardware to test ESXi environment there is a chance to run virtual ESX(i) environment on ESX or ESXi . Obviously in this case the performance  of the virtual ESX(i) environment won’t be ideal therefore the primary function for this environment is for testing functions.

Continue reading “Virtualized virtual environment”

Advertisements

How to set pagefile when booting a BitLocked vhd drive

When you use a vhd file for booting, you have no possibilities to reserve space for the pagefile inside the vhd (Windows does not support it). You need to place the file outside of the virtual drive.  But what if your vhd has already been encrypted? In this case you have no chance to set virtual memory for the OS due to security reasons. Your pagefile wouldn’t be encrypted, which is not allowed.

Continue reading “How to set pagefile when booting a BitLocked vhd drive”

Application Virtualization Error

Today when I tested a freshly made App-V package (Office 2003), I got an interesting error after I tried to run it on client side.

“The Application Virtualization Client could not launch <application name>.

There is not enough space in the Application Virtualization cache. Report the following error code to your System Administrator.

Error code: 4615186-16D1160A-0000E029”

First I didn’t understand why I got the message, because I’ve already tested many different virtualized applications without any error.

Continue reading “Application Virtualization Error”

Command line reference for Microsoft Virtual PC

When I started to use Windows 7 instead of XP, at the first time the switch wasn’t easy. I have a lot of different applications which are not able to run in the new environment. Therefore I create a virtual machine under MS Virtual PC. I installed an XP with the applications which had issues on Windows 7.

After a while I started to get bored the way how I needed to start the virtual XP machine. I always opened the Virtual PC Console, browse the machine and finally I turned on it. I was wondering whether an easier way exists?

Continue reading “Command line reference for Microsoft Virtual PC”

How to shrink vhd files

I guess not me the only one, who have already had problem due to the size of a vhd file. After you created a new machine under Microsoft Virtual PC, and you want to add a new virtual disk to the config, you can select four different options:

I always choose the “Dynamically expanding” one, because in my opinion this is the most convenient. In this case I won’t face with the size problem, and my vhd can dynamically grow. And what if I would like to reduce the size, because I successfully free up some space inside my VM?

Continue reading “How to shrink vhd files”

Create local Centos and Debian mirrors for KVM guest install

Introduction

One of the bigger problems kvm solutions require is the install process. I prefer fully automated installations, since all machines follow a set of standards, and are alike to all previous machines. Since starting a cdrom based installation doesnt give the possibility to use a console in kvm (all machine provisions from my point of view should be automatic, and if needed I should be able to jump in and check status), I have the choice to go with PXE boot or network based installation.  I have done some initial research with PXE, but didnt find it fit for my needs. So I decided to go with network based installations.

Some prefer virt-manager as provisioning tool, but X sessions are a little overkill in my opinion, and if not mandatory should be avoided.
Continue reading “Create local Centos and Debian mirrors for KVM guest install”

Query kvm xml information script

Introduction

One of the problems I was expieriencing after creating a machine is to gather information for further post scripts. I had thaught of creating a mysql table with all the information of the hosts, but I have’nt designed it yet, and decided to rather query information straight from the domain xml.

A further possibility for the scipt is to run it from cron, and check if the database is updated with the correct information.

Setup

According to my previous post ( http://wp.me/p1kux7-bi ), the machine setup has not changed.

Script

root@localhost # cat host_info.pl
#!/usr/bin/perl
###############
#
#  Query information about the host
#
use strict;
use warnings;
use Getopt::Long;
use Switch;

##############
#  XML location and variables
my $XMLDIR="/etc/libvirt/qemu";
my $debug = 0;
my $help = 0;
my $host = 0;
my $list = 0;
my $memory = 0;
my $vcpu = 0;
my $disk = 0;
my $mac = 0;
my $name = 0;
my $verbose =0;
my $all = 1;

################
# Arguments
GetOptions("help|?" => \$help,
           "verbose|v" => \$verbose,
           "h|host=s" => \$host,
           "l|list" => \$list,
           "xml=s"   => \$XMLDIR,
           "mem" => sub { $memory=1 , $all=0 } ,
           "disk" => sub { $disk=1 , $all=0 } ,
           "cpu" => sub { $vcpu=1 , $all=0 } ,
           "name" => sub { $name=1, $all=0 },
           "mac" => sub { $mac=1, $all=0},
           "all" => \$all,
           "d|debug" => \$debug
        );

if ( $help ) {
        print "How to use the query host tool\n";
        print "$0 \$options \n";
        print "-? or help               help\n";
        print "-l or list               list all host information\n";
        print "-h or host               show information for one host\n";
        print "-xml                     Change default XML directory (default: '$XMLDIR')\n";
        print "-v or verbose            be verbose by output\n";
        print "-mem                     show memory\n";
        print "-name                    show name in output\n";
        print "-disk                    show disk\n";
        print "-cpu                     return number of cpus\n";
        print "-mac                     return mac address\n";
        print "-all                     print all info\n";
        print "-debug                   print debug information\n";
}

sub openxml($) {
    my $file= $_[0];
    $debug and print $file."\n";
    my $omemory = 0 ;
    my $ovcpu = 0 ;
    my $odisk = 0 ;
    my $omac = 0 ;
    my $oname = 0 ;
    my ( $prefix,$postfix ) = 0;
    open ( my $FILE, $file );
    while ( my $line = <$FILE>) {
        chomp $line;
        $debug and print $line."\n";
        if ( $line =~ /^\s*<mac address='/ ) {
            ( $prefix, $omac, $postfix ) = $line =~ /(^\s*<mac address=')([^']*[^'])('\/>\s*$)/;
            $debug and print "The mac address is:'$omac'\n";
        }
        if ( $line =~ /^\s*<memory>/ ) {
            ( $prefix, $omemory, $postfix ) = $line =~ /(^\s*<memory>)([^>]*[^<])(<\/memory>\s*$)/;
            $debug and print "My memory is:'$omemory'\n";
        }
        if ( $line =~ /^\s*<vcpu>/ ) {
            ( $prefix, $ovcpu, $postfix ) = $line =~ /(^\s*<vcpu>)([^<>]*)(<\/vcpu>\s*$)/;
            $debug and print "My Vcpu is:'$ovcpu'\n";
        }
        if ( $line =~ /^\s*<source dev='/ ) {
            ( $prefix, $odisk, $postfix ) = $line =~ /(^\s*<source dev=')([^']*[^'])('\/>\s*$)/;
            $debug and print "My disk is:'$odisk'\n";
        }
        if ( $line =~ /^\s*<name>/ ) {
            ( $prefix, $oname, $postfix ) = $line =~ /(^\s*<name>)([^']*[^'])(<\/name>\s*$)/;
            $debug and print "My name is:'$oname'\n";
        }
    }
    return ( $oname, $omemory, $omac, $ovcpu, $odisk );
    close $FILE;
}

sub format(@) {
    my ( $fname, $fmemory, $fmac, $fcpu, $fdisk) = @_;
    my $outstring = "";
    $debug and print "My variables for format sub:name =>'$fname' memory =>'$fmemory' mac =>'$fmac' cpu =>'$fcpu' disk =>'$fdisk'\n";
    if ( $all ) {
        $debug and print "All argument found.\n";
        ($verbose and $outstring= "host=$fname memory=$fmemory mac=$fmac cpu=$fcpu disk=$fdisk" ) or $outstring="$fname $fmemory $fmac $fcpu $fdisk";
    } else {
        $debug and print "I am in the else tree\n";
        if ( $name ne 0 ) {
            $debug and print "Name specified\n";
            ($verbose and $outstring .= "host=$fname ") or $outstring.="$fname ";
            $debug and print "My outstring is:'$outstring'\n";
        }
        if ( $memory ne 0 ) {
            $debug and print "Memory specified.\n";
            ($verbose and $outstring .= "memory=$fmemory ") or $outstring.="$fmemory ";
            $debug and print "\n";
        }
        if ( $mac ne 0 ) {
            $debug and print "Mac specified.\n";
            ($verbose and $outstring .= "mac=$fmac ") or $outstring.="$fmac ";
            $debug and print "\n";
        }
        if ( $vcpu ne 0 ) {
            $debug and print "CPU specified.\n";
            ($verbose and $outstring .= "cpu=$fcpu " ) or $outstring.="$fcpu ";
            $debug and print "\n";
        }
        if ( $disk ne 0 ) {
            $debug and print "Disk specified.\n";
            ($verbose and $outstring .= "disk=$fdisk") or $outstring.="$fdisk ";
            $debug and print "\n";
        }
    }
    $debug and print "My outstring is:'$outstring'\n";
    return($outstring);
}

if ( $host ) {
    $debug and print "Host specified :'$host'\n";
    my $file="$XMLDIR/$host.xml";
    $debug and print "My file is '$file'\n";
    if ( -e $file ) {
        $debug and print "File exists\n";
        my @output = openxml($file);
        $debug and print "My output was:'@output'\n";
        ( $verbose and print &format(@output)."\n") or print &format(@output)."\n";
    } else {
        $debug and print "File doesnt exist:'$file'\n";
    }
}
elsif ( $list ) {
    $debug and print "List specified\n";
    my @files=<$XMLDIR/*.xml>;
    $debug and print "My list is:'@files'\n";
    foreach my $file ( @files ) {
        $debug and print "File found doing sub on it:'$file'\n";
        my @output = openxml($file);
        $debug and print "My output was:'@output'\n";
        ( $verbose and print &format(@output)."\n" ) or print &format(@output)."\n";
    }
} else {
        $debug and print "No host or list specified.\n";
}

Explanation

Let’s iterate through the lines of code.

The entry point of the script is at line 137. There are 3 possbilities. Either 1 machine information is requested then a host is specified. If every information is requested from all hosts then a list is  generated. An unexpected possibility that neither a specific host or list is requested then nothing is printed  (except if we specify the debug option).

Since kvm names its xml files according to the domainname, this can be used for querying. It is possible in some setups when the domainname.xml is renamed and the filename and the domainname entry in the xml are not the same. Some checks or monitoring solutions need to find such cases aswell.

In the case that a list has to be processed, all xml files within the requested folder  (default for kvm is /etc/libvirt/qemu on debian) are added to a array, and with a loop every file is treated like a single host, passed onto openxml sub, which will be discussed later.

If only a single host is required the above step can be skipped and the file can be opened with openxml sub.

Openxml sub

This is the heart of the program, which can be attuned to your requirments. Attributes which I found important were mac address, maximum memory, virtual cpu limit, name and disk(this is useful for example for resize.sh at http://wp.me/p1kux7-bi ). If other information is required this sub should be changed.

One interesting question is if all xml files are according to standard format, and what are those standards in your enviroment. For example I have vcpus defined as follows:


<vcpu>2</vcpu>

According to libvirt domain xml format guide at http://libvirt.org/formatdomain.html this should be the correct and accepted version,although I have seen setups using different format:


<vcpu=2/>

After openxml sub is run  it returns with all information.

For large scale deployments this is not optimised. There is alot of unneeded information queried which should never be touched if not requested. CPU time and IO is expensive and should be kept to minimum.

Format sub

Format sub prints the information. This has been prepared for user and script handling. The main idea is that if we specify the -v (verbose) argument, the output is verbose  showing which value represents what:

root@localhost# host_info.pl -v -h debian
host=debian memory=262144 mac=ac:de:48:4a:88:f0 cpu=1 disk=/dev/mapper/lvm-vg_debian

or without the verbose argument for script parsing:

root@localhost# host_info.pl -h debian
debian 262144 ac:de:48:4a:88:f0 1 /dev/mapper/lvm-vg_debian

There are also some extra arguments which can be supplied if specific information is required. If we only need the memory, or mac address we can simly query that:

root@localhost# host_info.pl -h debian -v -mac
mac=ac:de:48:4a:88:f0

Also the requested information can be chained together:


root@localhost# host_info.pl -h debian -v -mac -mem
memory=262144 mac=ac:de:48:4a:88:f0

In case a list is requested all information is printed in a new line.

Thaughts

My purpose with this script is to feed post scripts and have the possibility to update sql database with information or to check data cosistency after updates.

If we are in a large scale enviroment then disk IO for querying files can be costful and a backend database file would be cheaper and easier to query.