Giving back as best I can..

This blog is an attempt to share some of the utilities, techniques and ideas that I employ on a day to day basis as an open source professional. It truly is a difficult thing to make money on a service rather than a product, but in the interest of furthering less expensive software, I feel a need to contribute back to the open source community in exchange for all that it has provided me. If there is something you find useful here, please feel free to let me know. If you see something that clearly could be made better, also please let me know, as we're all in this big digital world together. I am, by no means, the utmost authority on anything (that I'm aware of), so please, if you feel I have something to learn, teach me! Thanks for stopping by and good luck! -Aubrey

Tuesday, April 8, 2008

VMWare Server 1.x newvm script

At my main gig, we have begun a heavy transition towards virtualization. Since we are somewhat strapped for cash, my expertise comes in handy. I have been a VMWare user since 2000 and have focused quite a bit of energy towards making use of VMWare Server, the successor to VMWare's GSX Server, which they began to release for free in an effort to combat some of the other less expensive virtualization options, such as Sun's Zones, Xen Server or even Microsoft Virtual Server. I found that Microsoft went to great lengths at my last place of employment to try to embed their poor excuse for virtualization in our infrastructure. Ultimately, that failed, due to severe limitations in use and also poor functionality, when compared to VMWare ESX server, which I assisted in the justification of. So, having quite a bit of experience with this product, I was tasked with the responsibility of architecting a new virtual infrastructure for our customer facing equipment with an eerily familiar budget of $0.

Lucky for me, we had the luxury of a Netapp SAN in our main pop, which is like a dream for VMWare. A SAN, and especially a Netapp SAN, due to its inherent ability to act as an NFS NAS head, allows multiple VMWare host servers to connect up and share disk space for as many VMs as the disk space will allow. In addition, you get the inherent safety and speed from heavily RAIDed disks. One of the features that ESX gives you, which is not present in the free server is the ability to rapidly create a VM from a template and, knowing we needed that functionality, I set out to mimic it with the 'sysadmin swiss army knife,' PERL.


NEWVM.PL:

** This script assumes you have a VM template created for your environment **

#!/usr/bin/perl

use strict;
use Getopt::Std;
use File::Copy::Recursive qw(dircopy);

# Where are your VMs located?
my $vmpath = "/mnt/netapp_nfs/";
# Second vmpath for system calls - needed in case of space in dir name
my $sysvmpath = '/mnt/netapp_nfs/';
# The name of the template vm's directory.
my $template = "template";
# I use this to label my vmx and vmsd files by OS
my $os = "RHEL_4";
# Accepts an incoming command line argument to name the new vm.
my $vmname = $ARGV[0];
chomp $vmname;
my $orig = "$vmpath" . "$template";
my $new = "$vmpath" . "$vmname";
my $passed = scalar(@ARGV);
my $oldflat = "$new/$template-flat.vmdk";
my $newflat = "$new/$vmname-flat.vmdk";
my $oldvmdk = "$new/$template.vmdk";
my $newvmdk = "$new/$vmname.vmdk";
my $vmx = "$new/RHEL_4.vmx";
# Second vmx for system calls - modify it by OS again
my $sysvmx="$sysvmpath" . "$vmname" . "/RHEL_4.vmx";
my $vmdkcon;
my $vmxcon;

# Exit if no argument or the vm dir is already there.
die "\nError: Please provide the name of the new VM as an argument.\n\n" if $passed != 1;
die "\nError: The new VM directory already exists.\n\n" if -e $new;

# System call to copy the appropriate template over to the new vm - believe it or not,
# forking a system call for this is faster than doing it in perl.
print "\nCopying template directory. This can take some time...\n";
dircopy("$orig","$new") or die $!;
print "Done!\n";

# Change the file names to match the vm
print "Moving vmdk files...\n";
rename $oldflat, $newflat;
rename $oldvmdk, $newvmdk;
print "Done!\n";

# Change template references in the vmdk and vmx files

undef $/;

print "Modifying vmdk and vmx files...\n";
open(VMDKREAD,"$newvmdk") or die "\nError: Couldn't read vmdk.\n\n";
while(){
$vmdkcon = $_;
$vmdkcon =~ s/$template/$vmname/g;
}
close(VMDKREAD);

open(VMDKWRITE,">$newvmdk") or die "\nError: Couldn't write vmdk.\n\n";
print VMDKWRITE $vmdkcon;
close(VMDKWRITE);

open(VMXREAD,"$vmx") or die "\nError: Couldn't read vmx.\n\n";
while(){
$vmxcon = $_;
$vmxcon =~ s/$template/$vmname/g;
}
close(VMXREAD);

open(VMXWRITE,">$vmx") or die "\nError: Couldn't write vmx.\n\n";
print VMXWRITE $vmxcon;
close(VMXWRITE);
print "Done!\n";

# Remove old vmsd file - needed for pausing your new vm.
system("/bin/rm -f $new/*.vmsd");

# Register the vm for vmware inventory list on the host server
print "Registering your new VM with VMWare Server...\n";
system("/usr/bin/vmware-cmd -s register $sysvmx");
print "Done!\n";

# Power on the new vm
print "Powering on your new VM...\n";
system("/usr/bin/vmware-cmd $sysvmx start");
print "Done!\n";

# Notify user of success.
print "\nYour VM is made and ready to use. Please connect to the appropriate host\nwith VMWare Server Console and configure.\n";



So that should do it. Of course, the script will need to be modified to fit your own environment. Feel free to give it a whirl and see what happens. It works for us and ends up taking approximately 4 minutes to create a 10 GB VM from our template. If you have any questions, of course, feel free to send a message or leave a comment!