svn commit: samba r16604 - in branches/SOC/bnh: . perl

brad at samba.org brad at samba.org
Wed Jun 28 03:46:25 GMT 2006


Author: brad
Date: 2006-06-28 03:46:25 +0000 (Wed, 28 Jun 2006)
New Revision: 16604

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=16604

Log:
Create a root directory for the perl files and add what i've done so far.

initial_setup.conf is a config file which has parameters used by the initial_setup.sh script. This script calls vm_setup.pl which (for now) contains a perl object to interact with a vmware guest using the VmPerl and vix APIs in a unified manner. The purpose of this script is to interact with the vmware server itself to take a guest snapshot, and perform the initial windows setup by copying windows scripts to the vm and executing them there.

These scripts use the VMware VmPerl and vix APIs. These come with the VMware console package. The version I used was VMware-server-linux-client-1.0.0-27828.zip.

After unzipping this file, the libraries can be installed by extracting the VMware-vix-e.x.p-27828.tar.gz and VMware-VmPerlAPI-e.x.p-27828.tar.gz archives and running the vmware-install.pl scripts inside their respective directories.


Added:
   branches/SOC/bnh/perl/
   branches/SOC/bnh/perl/initial_setup.conf
   branches/SOC/bnh/perl/initial_setup.sh
   branches/SOC/bnh/perl/vm_setup.pl


Changeset:
Added: branches/SOC/bnh/perl/initial_setup.conf
===================================================================
--- branches/SOC/bnh/perl/initial_setup.conf	2006-06-28 02:22:28 UTC (rev 16603)
+++ branches/SOC/bnh/perl/initial_setup.conf	2006-06-28 03:46:25 UTC (rev 16604)
@@ -0,0 +1,36 @@
+
+# Point these at the files that STDOUT and STDERR should be redirected to
+# during the setup, test and removal phases of the test.
+# These files are deleted when the setup begins its run.
+# Special files (devices, named pipes, etc) are not deleted.
+STDOUT_REDIR="initial_setup.stdout"
+STDERR_REDIR="initial_setup.stderr"
+
+# The path to the vmware image config file local to the vmware server.
+export VM_CFG_PATH="/var/lib/vmware/Virtual Machines/Windows Server 2003 EE -2/Windows Server 2003 EE -2.vmx"
+
+# The username and password of the administrative account to create on
+# the windows guest.
+export GUEST_USERNAME="tortureuser"
+export GUEST_PASSWORD="torturepass"
+
+# Where our setup scripts should be copied to on the windows guest.
+export GUEST_SCRIPT_PATH="C:\"
+
+# Where these scripts will be copied from on the unix host.
+# I don't know how this will work if the unix host is a different
+# system than the vmware server host.
+export LOCAL_SCRIPT_PATH="./windows-scripts"
+
+# These parameters are optional, and change the windows guest
+# hostname and workgroup if set.
+#export GUEST_HOSTNAME="tortureguest"
+#export GUEST_WORKGROUP="SMBTEST"
+
+# These parameters are optional. If not specified, the script tries to access
+# a local vmware server as the executing user.
+# logged-in user running the script are used.
+#export HOST_SERVER_NAME="localhost"
+#export HOST_SERVER_PORT=902
+#export HOST_USERNAME="vmwareuser"
+#export HOST_PASSWORD="password"

Added: branches/SOC/bnh/perl/initial_setup.sh
===================================================================
--- branches/SOC/bnh/perl/initial_setup.sh	2006-06-28 02:22:28 UTC (rev 16603)
+++ branches/SOC/bnh/perl/initial_setup.sh	2006-06-28 03:46:25 UTC (rev 16604)
@@ -0,0 +1,76 @@
+#!/bin/sh
+
+# A shell script to connect to a VMware Server VM using their perl API,
+# take a snapshot,
+# copy visual basic scripts used for setup and testing,
+# and run the initial setup scripts.
+# Copyright Brad Henry <brad at samba.org> 2006
+# Released under the GNU GPL v2 or later.
+
+. initial_setup.conf
+
+vm_setup()
+{
+	echo -e "\nSetting up the windows environment." >> $STDOUT_REDIR
+	perl vm_setup.pl >> $STDOUT_REDIR 2>> $STDERR_REDIR
+	err_rtn=$?
+}
+
+display_output()
+{
+	cat $STDOUT_REDIR
+	cat $STDERR_REDIR
+}
+
+remove_files()
+{
+	# If these redirect to special files, we won't delete them.
+	for redir in $STDERR_REDIR \
+			$STDOUT_REDIR
+	do
+
+		if [ ! -b $redir \
+			-a ! -c $redir \
+			-a ! -p $redir ]
+			then
+				rm -f $redir
+		fi
+	done
+}
+
+create_files()
+{
+	touch $STDOUT_REDIR
+	touch $STDERR_REDIR
+}
+
+check_error()
+{
+	if [ $err_rtn -ne 0 ]
+		then
+			echo -e $err_str >> $err_redir
+			# Report output recieved so far.
+			display_output
+			# Exit in error
+			exit $err_rtn
+		else
+			echo -e $err_ok_str >> $err_redir
+	fi
+}
+
+# If we crashed on a previous run, we want to know that our log files are clean.
+remove_files
+
+# Create the local log files.
+create_files
+
+# Connect to the VM, get the ip, take a snapshot,
+# and run the initial windows configuration.
+err_str="\nVM setup failed."
+err_ok_str="\nVM setup completed successfully."
+err_redir=$STDERR_REDIR
+vm_setup
+check_error
+
+display_output
+exit $err_rtn


Property changes on: branches/SOC/bnh/perl/initial_setup.sh
___________________________________________________________________
Name: svn:executable
   + *

Added: branches/SOC/bnh/perl/vm_setup.pl
===================================================================
--- branches/SOC/bnh/perl/vm_setup.pl	2006-06-28 02:22:28 UTC (rev 16603)
+++ branches/SOC/bnh/perl/vm_setup.pl	2006-06-28 03:46:25 UTC (rev 16604)
@@ -0,0 +1,324 @@
+#!/usr/bin/perl -w
+
+# A perl script to handle
+# connecting to a VMware Server VM using their perl API,
+# take a snapshot,
+# copy visual basic scripts used for setup and testing,
+# and run the initial setup scripts.
+# Copyright Brad Henry <brad at samba.org> 2006
+# Released under the GNU GPL v2 or later.
+
+# VMware Perl API
+use VMware::VmPerl;
+use VMware::VmPerl::VM;
+use VMware::VmPerl::ConnectParams;
+
+# VMware C bindings
+use VMware::Vix::Simple;
+use VMware::Vix::API::Constants;
+
+# We can't use strict while we are using VIX constants.
+# use strict;
+
+# Create a class to abstract from the Vix and VMPerl APIs.
+{ package VMHost;
+	my $perl_vm = VMware::VmPerl::VM::new();
+	my $perl_vm_credentials;
+	my $vix_vm;
+	my $vix_vm_host;
+
+	my $err_code = 0;
+	my $err_str = "";
+
+	my $hostname;
+	my $port;
+	my $username;
+	my $password;
+	my $vm_cfg_path;
+
+	sub error {
+		my $old_err_code = $err_code;
+		my $old_err_str = $err_str;
+		$err_code = 0;
+		$err_str = "";
+		return ($old_err_code, $old_err_str);
+	}
+
+	# Power on the guest if it isn't already running.
+	# Returns 0 when the guest is already running, and 
+	# if not, it waits until it is started.
+	sub start_guest {
+		my $vm_power_state = $perl_vm->get_execution_state();
+		if (!defined($vm_power_state)) {
+			($err_code, $err_str) = $perl_vm->get_last_error();
+			return ($err_code);
+		}
+		if ($vm_power_state == VMware::VmPerl::VM_EXECUTION_STATE_OFF
+			|| $vm_power_state ==
+				VMware::VmPerl::VM_EXECUTION_STATE_SUSPENDED)
+		{
+			if (!$perl_vm->start()) {
+				($err_code, $err_str) = 
+					$perl_vm->get_last_error();
+				return ($err_code);
+			}
+			while ($perl_vm->get_tools_last_active() == 0) {
+				sleep(60);
+			}
+		}
+		return ($err_code);
+	}
+
+	sub host_connect {
+		# When called as a method, the first parameter passed is the
+		# name of the method. Called locally, this function will lose
+		# the first parameter.
+		shift @_;
+		($hostname, $port, $username, $password, $vm_cfg_path) = @_;
+
+		# Connect to host using vmperl api.
+		$perl_vm_credentials = 
+			VMware::VmPerl::ConnectParams::new($hostname, $port,
+				$username, $password);
+		if (!$perl_vm->connect($perl_vm_credentials, $vm_cfg_path)) {
+			($err_code, $err_str) = $perl_vm->get_last_error();
+			undef $perl_vm;
+			return ($err_code);
+		}
+
+		# Connect to host using vix api.
+		($err_code, $vix_vm_host) =
+			VMware::Vix::Simple::HostConnect(
+				VMware::Vix::Simple::VIX_API_VERSION,
+				VMware::Vix::Simple::VIX_SERVICEPROVIDER_VMWARE_SERVER,
+				$hostname, $port, $username, $password,
+				0, VMware::Vix::Simple::VIX_INVALID_HANDLE);
+		if ($err_code != VMware::Vix::Simple::VIX_OK) {
+			($err_code, $err_str) = $vix_vm_host->get_last_error();
+			undef $perl_vm;
+			undef $vix_vm;
+			undef $vix_vm_host;
+			return ($err_code);
+		}
+
+		# Power on our guest os if it isn't already running.
+		$err_code = start_guest();
+		if ($err_code != 0) {
+			my $old_err_str = $err_str;
+			$err_str = "Starting guest power after connect " .
+					"failed: " . $old_err_str;
+			undef $perl_vm;
+			undef $vix_vm;
+			undef $vix_vm_host;
+			return ($err_code);
+		}
+
+		# Open VM.
+		($err_code, $vix_vm) = 
+			VMware::Vix::Simple::VMOpen($vix_vm_host, $vm_cfg_path);
+		if ($err_code != VMware::Vix::Simple::VIX_OK) {
+			($err_code, $err_str) = $vix_vm->get_last_error();
+			undef $perl_vm;
+			undef $vix_vm;
+			undef $vix_vm_host;
+			return ($err_code);
+		}
+		return ($err_code);
+	}
+
+	sub host_disconnect {
+		undef $perl_vm;
+
+		$perl_vm = VMware::VmPerl::VM::new();
+		if (!$perl_vm) {
+			$err_code = 1;
+			$err_str = "Error creating new VmPerl object";
+		}
+	
+		undef $vix_vm;
+		VMware::Vix::Simple::HostDisconnect($vix_vm_host);
+		VMware::Vix::Simple::ReleaseHandle($vix_vm_host);
+		return ($err_code);
+	}
+
+	sub host_reconnect {
+		$err_code = host_disconnect();
+		if ($err_code != 0) {
+			my $old_err_str = $err_str;
+			$err_str = "Disconnecting from host failed: " .
+					$old_err_str;
+			return ($err_code);
+		}
+
+		$err_code = host_connect(NULL, $hostname, $port, $username,
+				$password, $vm_cfg_path);
+		if ($err_code != 0) {
+			my $old_err_str = $err_str;
+			$err_str = "Re-connecting to host failed: " .
+					$old_err_str;
+			return ($err_code);
+		}
+		return ($err_code);
+	}
+
+	sub create_snapshot {
+		my $snapshot;
+
+		($err_code, $snapshot) = 
+			VMware::Vix::Simple::VMCreateSnapshot($vix_vm,
+			"Snapshot", "Created by vm_setup.pl", 0,
+			VMware::Vix::Simple::VIX_INVALID_HANDLE);
+
+		VMware::Vix::Simple::ReleaseHandle($snapshot);
+
+		if ($err_code != VMware::Vix::Simple::VIX_OK) {
+			($err_code, $err_str) = $vix_vm->get_last_error();
+			return $err_code;
+		}
+
+		$err_code = host_reconnect();
+		if ($err_code != 0) {
+			my $old_err_str = $err_str;
+			$err_str = "Reconnecting to host after creating " .
+					"snapshot: " . $old_err_str;
+			return ($err_code);
+		}
+		return ($err_code);
+	}
+
+	sub revert_snapshot {
+		my $snapshot;
+
+		# We are passing 0 to VMGetRootSnapshot because we can only 
+		# have one snapshot in vmware server, and it has an id of 0.
+		($err_code, $snapshot) = 
+			VMware::Vix::Simple::VMGetRootSnapshot($vix_vm, 0);
+		if ($err_code != VMware::Vix::Simple::VIX_OK) {
+			($err_code, $err_str) = $vix_vm->get_last_error();
+			return ($err_code);
+		}
+
+		my $job = VMware::Vix::API::VM::RevertToSnapshot($vix_vm,
+				$snapshot, 0, 
+				VMware::Vix::Simple::VIX_INVALID_HANDLE,
+				undef,0);
+
+# We have something of a problem here. If we resume a snapshot using:
+#    $err_code = VMware::Vix::Simple::VMRevertToSnapshot($vix_vm,
+#                  $snapshot, 0, VMware::Vix::Simple::VIX_INVALID_HANDLE);
+# we hang because of an:
+#	VMware::Vix::API::Job::Wait($job, VMware::Vix::Simple::VIX_PROPERTY_NONE);
+# that never returns.
+# When we reconnect, the guest is in a suspended
+# mode. If we skip the implicit wait, and reconnect() after we revert, we're ok.
+		$err_code = host_reconnect();
+		if ($err_code != 0) {
+			my $old_err_str = $err_str;
+			$err_str = "Reconnecting to host after reverting " .
+					"snapshot: " . $old_err_str;
+			VMware::Vix::Simple::ReleaseHandle($snapshot);
+			VMware::Vix::API::API::ReleaseHandle($job);
+			return ($err_code);
+		}
+
+		VMware::Vix::Simple::ReleaseHandle($snapshot);
+		VMware::Vix::API::API::ReleaseHandle($job);
+		return ($err_code);
+	}
+
+	sub copy_to_guest {
+		$err_code = -1;
+		$err_str = "Function copy_to_guest() is not yet implemented";
+
+		return ($err_code);
+	}
+
+	sub run_on_guest {
+		$err_code = -1;
+		$err_str = "Function run_on_guest() is not yet implemented";
+
+		return ($err_code);
+	}
+
+	sub get_guest_ip {
+		my $guest_ip = $perl_vm->get_guest_info('ip');
+
+		if (!defined($guest_ip)) {
+			($err_code, $err_str) = $perl_vm->get_last_error();
+			return NULL;
+		}
+
+		if (!($guest_ip)) {
+			$err_code = 1;
+			$err_str = "Guest did not set the 'ip' variable";
+			return NULL;
+		}
+		return $guest_ip;
+	}
+
+	sub DESTROY {
+		disconnect();
+		undef $perl_vm;
+		undef $vix_vm_host;
+	}
+}
+
+sub check_error {
+	my $vm = VMHost;
+	my $custom_err_str = "";
+	($vm, $custom_err_str) = @_;
+
+	my ($err_code, $err_str) = $vm->error;
+	if ($err_code != 0) {
+		undef $vm;
+		die $custom_err_str . "Returned $err_code: $err_str.\n";
+	}
+}
+
+# Read in parameters from environment.
+my $vm_cfg_path = $ENV{'VM_CFG_PATH'};
+my $host_server_name = $ENV{'HOST_SERVER_NAME'};
+my $host_server_port = $ENV{'HOST_SERVER_PORT'};
+if (!defined($host_server_port)) {
+	$host_server_port = 902;
+}
+
+my $host_username = $ENV{'HOST_USERNAME'};
+my $host_password = $ENV{'HOST_PASSWORD'};
+
+my $guest_username = $ENV{'GUEST_USERNAME'};
+my $guest_password = $ENV{'GUEST_PASSWORD'};
+my $guest_hostname = $ENV{'GUEST_HOSTNAME'};
+my $guest_workgroup = $ENV{'GUEST_WORKGROUP'};
+my $guest_script_path = $ENV{'GUEST_SCRIPT_PATH'};
+my $local_script_path = $ENV{'LOCAL_SCRIPT_PATH'};
+
+my $vm = VMHost;
+$vm->host_connect($host_server_name, $host_server_port, $host_username,
+			$host_password, $vm_cfg_path);
+check_error($vm, "Error in \$vm->connect().\n");
+print "Connected successfully to VM.\n";
+
+my $guest_ip = $vm->get_guest_ip();
+check_error($vm, "Error in \$vm->get_guest_ip().\n");
+print "The IP address of $vm_cfg_path is: $guest_ip.\n";
+
+# Create a pristine snapshot to revert to if things go badly.
+$vm->create_snapshot();
+check_error($vm, "Error in \$vm->create_snapshot().\n");
+print "Snapshot creation has started.\n";
+
+# Copy the windows setup scripts to the VM.
+$vm->copy_to_guest($local_script_path,$guest_script_path);
+check_error($vm, "Error in \$vm->copy_to_guest().\n");
+print "Windows setup scripts have been copied to the VM.\n";
+
+# Run win_setup.wsh on the VM.
+$cmd = "cscript $guest_script_path win_setup.wsf /username:$guest_username" .
+		"/password: $guest_password";
+$vm->run_on_guest($cmd);
+check_error($vm, "Error in \$vm->run_on_guest() executing " . $cmd . ".\n");
+print "Windows setup scripts have been successfully executed on the VM.\n";
+
+# Destroy the vm object and disconnect from the vm.
+undef $vm;


Property changes on: branches/SOC/bnh/perl/vm_setup.pl
___________________________________________________________________
Name: svn:executable
   + *



More information about the samba-cvs mailing list