You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by ar...@apache.org on 2011/04/29 16:51:24 UTC

svn commit: r1097825 - in /incubator/vcl/trunk/managementnode/lib/VCL/Module: OS.pm OS/Windows.pm OS/Windows/Version_6.pm Provisioning.pm Provisioning/VMware/VMware.pm

Author: arkurth
Date: Fri Apr 29 14:51:24 2011
New Revision: 1097825

URL: http://svn.apache.org/viewvc?rev=1097825&view=rev
Log:
VCL-466
Added check_cygwin subroutine to Windows.pm. Added call to this subroutine from pre_capture. This subroutine checks/sets the CYGWIN environment variable configured for the sshd service. It should be set to 'ntsec nodosfilewarning'. The 'nodosfilewarning' parameter is necessary to overcome a problem with Cygwin 1.7 where a warning is displayed the first time a DOS-style file path is used to run a command. If the value isn't correct, it sets it and restarts the sshd service. Added get_environment_variable_value and restart_service subroutines to accomplish this.

Updated Version_6.pm::set_ignore_default_routes to handle computers with a single interface.

VCL-465
Updated Windows.pm::get_network_configuration to return the configuration if the computer has a single interface.

VCL-450
Updated Linux.pm::remove_existing_vms. Added a check after the matching VMs were deleted to make sure the computer assigned to the reservation isn't responding to SSH. If it is, then there is a VM running which the code couldn't find. This will cause problems and may cause the user to connect to a VM with an image other than the one requested.  If a running VM is detected, an attempt is made to determine the vmx path of the running VM by calling get_active_vmx_file_path. This VM isn't shutdown or deleted but the path is included in the error message.

Updated VMware.pm::get_active_vmx_file_path to check the type of OS loaded on the computer before calling the OS subroutines. Added OS.pm::get_os_type to accomplish this. The OS doesn't necessarily match the OS of the reservation image so the normal $self->os calls will fail if the OS doesn't match. A new OS object is created and used if they don't match.


Other
Copied execute subroutine from Linux.pm to OS.pm since it can be used by Windows too.

Updated Windows.pm::search_and_replace_in_files to improve error checking.

Updated Provisioning.pm::wait_for_power_off to make the code more readable and to prevent the possibility of a 'uninitialized concatenation' error from occurring if power_status returns undefined.

Modified:
    incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm
    incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
    incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_6.pm
    incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm
    incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=1097825&r1=1097824&r2=1097825&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm Fri Apr 29 14:51:24 2011
@@ -1013,6 +1013,99 @@ sub create_text_file {
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 execute
+
+ Parameters  : $command, $display_output (optional)
+ Returns     : array ($exit_status, $output)
+ Description : Executes a command on the computer via SSH.
+
+=cut
+
+sub execute {
+	my $self = shift;
+	unless (ref($self) && $self->isa('VCL::Module')) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine can only be called as an object method");
+		return;
+	}
+	
+	# Get the command argument
+	my $command = shift;
+	if (!$command) {
+		notify($ERRORS{'WARNING'}, 0, "command argument was not specified");
+		return;
+	}
+	
+	# Get 2nd display output argument if supplied, or set default value
+	my $display_output = shift || '0';
+	
+	# Get the computer node name
+	my $computer_name = $self->data->get_computer_node_name() || return;
+	
+	# Get the identity keys used by the management node
+	my $management_node_keys = $self->data->get_management_node_keys() || '';
+	
+	# Run the command via SSH
+	my ($exit_status, $output) = run_ssh_command($computer_name, $management_node_keys, $command, '', '', $display_output);
+	if (defined($exit_status) && defined($output)) {
+		if ($display_output) {
+			notify($ERRORS{'OK'}, 0, "executed command: '$command', exit status: $exit_status, output:\n" . join("\n", @$output));
+		}
+		return ($exit_status, $output);
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to run command on $computer_name: $command");
+		return;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_os_type
+
+ Parameters  : None
+ Returns     : If successful: string
+               If failed: false
+ Description : Determines the OS type currently installed on the computer. It
+               returns 'windows' or 'linux'.
+
+=cut
+
+sub get_os_type {
+	my $self = shift;
+	if (ref($self) !~ /VCL::Module/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+	
+	# Get the computer node name
+	my $computer_node_name = $self->data->get_computer_node_name() || return;
+	
+	my $command = 'uname -a';
+	my ($exit_status, $output) = $self->execute($command);
+	if (!defined($output)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to run command to determine OS type currently installed on $computer_node_name");
+		return;
+	}
+	elsif ($exit_status ne '0') {
+		notify($ERRORS{'WARNING'}, 0, "error occurred attempting to determine OS type currently installed on $computer_node_name\ncommand: '$command'\noutput:\n" . join("\n", @$output));
+		return;
+	}
+	elsif (grep(/linux/i, @$output)) {
+		notify($ERRORS{'DEBUG'}, 0, "Linux OS is currently installed on $computer_node_name, output:\n" . join("\n", @$output));
+		return 'linux';
+	}
+	elsif (grep(/win/i, @$output)) {
+		notify($ERRORS{'DEBUG'}, 0, "Windows OS is currently installed on $computer_node_name, output:\n" . join("\n", @$output));
+		return 'windows';
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "unable to determine OS type currently installed on $computer_node_name, the '$command' output does not contain 'win' or 'linux':\n" . join("\n", @$output));
+		return;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 1;
 __END__
 

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm?rev=1097825&r1=1097824&r2=1097825&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm Fri Apr 29 14:51:24 2011
@@ -265,6 +265,16 @@ sub pre_capture {
 
 =item *
 
+ Make sure Cygwin is configured correctly
+
+=cut
+
+	if (!$self->check_cygwin()) {
+		notify($ERRORS{'WARNING'}, 0, "failed to verify that Cygwin is configured correctly");
+	}
+
+=item *
+
  Set root as the owner of /home/root
 
 =cut
@@ -4942,10 +4952,6 @@ sub get_network_configuration {
 		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
 		return;
 	}
-
-	my $management_node_keys = $self->data->get_management_node_keys();
-	my $computer_node_name   = $self->data->get_computer_node_name();
-	my $system32_path        = $self->get_system32_path() || return;
 	
 	# Check if a 'public' or 'private' network type argument was specified
 	my $network_type = lc(shift());
@@ -4953,6 +4959,19 @@ sub get_network_configuration {
 		notify($ERRORS{'WARNING'}, 0, "network type argument can only be 'public' or 'private'");
 		return;
 	}
+
+	my $management_node_keys = $self->data->get_management_node_keys();
+	my $computer_node_name   = $self->data->get_computer_node_name();
+	my $system32_path        = $self->get_system32_path() || return;
+	
+	# Get the computer private IP address
+	my $computer_private_ip_address = $self->data->get_computer_private_ip_address();
+	if (!$computer_private_ip_address) {
+		notify($ERRORS{'DEBUG'}, 0, "unable to retrieve computer private IP address from reservation data");
+		return;
+	}
+	
+	
 	
 	my %network_configuration;
 	if (!$self->{network_configuration}) {
@@ -5047,7 +5066,7 @@ sub get_network_configuration {
 		$self->{network_configuration} = \%network_configuration;
 	}
 	else {
-		notify($ERRORS{'DEBUG'}, 0, "network configuration has already been retrieved");
+		#notify($ERRORS{'DEBUG'}, 0, "network configuration has already been retrieved");
 		%network_configuration = %{$self->{network_configuration}};
 	}
 	
@@ -5057,12 +5076,7 @@ sub get_network_configuration {
 		return \%network_configuration;
 	}
 	
-	# Get the computer private IP address
-	my $computer_private_ip_address = $self->data->get_computer_private_ip_address();
-	if (!$computer_private_ip_address) {
-		notify($ERRORS{'DEBUG'}, 0, "unable to retrieve computer private IP address from reservation data");
-		return;
-	}
+	my $private_is_public = is_public_ip_address($computer_private_ip_address);
 	
 	my $public_interface_name;
 	my $private_interface_name;
@@ -5126,7 +5140,11 @@ sub get_network_configuration {
 			else {
 				notify($ERRORS{'DEBUG'}, 0, "interface found with non-public address not matching private address for reservation: $interface_name, address(es): " . join (", ", @ip_addresses));
 				
-				if ($public_interface_name) {
+				if ($private_is_public) {
+					notify($ERRORS{'DEBUG'}, 0, "private interface IP address is public, this will be returned unless another interface with a public IP address is found");
+					next;
+				}
+				elsif ($public_interface_name) {
 					notify($ERRORS{'DEBUG'}, 0, "already found another interface with a non-public address not matching private address for reservation, the one previously found will be used if a public address isn't found");
 					next;
 				}
@@ -5138,7 +5156,7 @@ sub get_network_configuration {
 			
 		}
 	}
-
+	
 	if ($network_type =~ /private/i) {
 		if ($private_interface_name) {
 			return {$private_interface_name => $network_configuration{$private_interface_name}};
@@ -5152,6 +5170,10 @@ sub get_network_configuration {
 		if ($public_interface_name) {
 			return {$public_interface_name => $network_configuration{$public_interface_name}};
 		}
+		elsif ($private_interface_name) {
+			notify($ERRORS{'DEBUG'}, 0, "did not find a separate public interface, assuming a single interface is being used, returning private interface configuration: '$private_interface_name'");
+			return {$private_interface_name => $network_configuration{$private_interface_name}};
+		}
 		else {
 			notify($ERRORS{'WARNING'}, 0, "failed to find a public interface:\n" . format_data(\%network_configuration));
 			return;
@@ -6216,7 +6238,7 @@ sub run_unix2dos {
 =head2 search_and_replace_in_files
 
  Parameters  : 
- Returns     :
+ Returns     : 
  Description : 
 
 =cut
@@ -6265,7 +6287,7 @@ sub search_and_replace_in_files {
 		notify($ERRORS{'WARNING'}, 0, "unable to run ssh command to run grep on directory: $base_directory, pattern: $search_pattern");
 		return;
 	}
-	elsif ("@$grep_output" =~ /No such file/i) {
+	elsif (grep(/No such file/i, @$grep_output)) {
 		notify($ERRORS{'DEBUG'}, 0, "no files to process, base directory does not exist: $base_directory");
 		return 1;
 	}
@@ -6277,6 +6299,10 @@ sub search_and_replace_in_files {
 		notify($ERRORS{'OK'}, 0, "no files were found matching pattern '$search_pattern' in: $base_directory");
 		return 1;
 	}
+	elsif (grep(/(grep|bash|warning|error):/i, @$grep_output) || $grep_status != 0) {
+		notify($ERRORS{'WARNING'}, 0, "error occurred running command: '$grep_command'\noutput:\n" . join("\n", @$grep_output));
+		return;
+	}
 	else {
 		notify($ERRORS{'DEBUG'}, 0, "found files matching pattern '$search_pattern' in $base_directory:\n" . join("\n", @$grep_output));
 	}
@@ -6764,6 +6790,51 @@ sub stop_service {
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 restart_service
+
+ Parameters  : $service_name
+ Returns     : boolean
+ Description : Restarts the Windows service specified by the argument. The
+               service is started if it is not running.
+
+=cut
+
+sub restart_service {
+	my $self = shift;
+	if (ref($self) !~ /windows/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+
+	my $management_node_keys = $self->data->get_management_node_keys();
+	my $computer_node_name   = $self->data->get_computer_node_name();
+	my $system32_path        = $self->get_system32_path() || return;
+	
+	my $service_name = shift;
+	if (!$service_name) {
+		notify($ERRORS{'WARNING'}, 0, "service name was not passed as an argument");
+		return;
+	}
+
+	my $command = "$system32_path/net.exe stop \"$service_name\" ; $system32_path/net.exe start \"$service_name\"";
+	my ($status, $output) = run_ssh_command($computer_node_name, $management_node_keys, $command, '', '', 1);
+	if (!defined($output)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to run command to restart service: $service_name");
+		return;
+	}
+	elsif ($status == 0) {
+		notify($ERRORS{'OK'}, 0, "restarted service: $service_name, output:\n" . join("\n", @$output));
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to restart service: $service_name, exit status: $status, output:\n" . join("\n", @$output));
+		return 0;
+	}
+
+	return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 service_exists
 
  Parameters  : $service_name
@@ -10280,6 +10351,131 @@ EOF
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 check_cygwin
+
+ Parameters  : none
+ Returns     : boolean
+ Description : Checks the CYGWIN environment variable to make sure it is set
+               to 'ntsec nodosfilewarning'. If not, the registry is updated, the
+               sshd service is restarted, and the value is checked again.
+
+=cut
+
+sub check_cygwin {
+	my $self = shift;
+	if (ref($self) !~ /windows/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+	
+	my $computer_node_name   = $self->data->get_computer_node_name();
+	
+	my $environment_variable_name = 'CYGWIN';
+	my $correct_value = 'ntsec nodosfilewarning';
+	
+	my $environment_variable_value = $self->get_environment_variable_value($environment_variable_name);
+	if ($environment_variable_value && $environment_variable_value eq $correct_value) {
+		notify($ERRORS{'DEBUG'}, 0, "$environment_variable_name environment variable is set correctly on $computer_node_name: '$environment_variable_value'");
+		return 1;
+	}
+	else {
+		notify($ERRORS{'DEBUG'}, 0, "$environment_variable_name environment variable is not set correctly on $computer_node_name:\ncorrect value: $correct_value\ncurrent value: '$environment_variable_value'");
+	}
+	
+	# Set the correct value in the registry for the sshd service parameters
+	my $key = 'HKLM\\SYSTEM\\CurrentControlSet\\services\\sshd\\Parameters\\Environment'; 
+	if (!$self->reg_add($key, $environment_variable_name, 'REG_SZ', $correct_value)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to set sshd service $environment_variable_name environment variable in the registry to '$correct_value'");
+		return;
+	}
+	
+	if (!$self->restart_service('sshd')) {
+		notify($ERRORS{'WARNING'}, 0, "failed to restart the sshd service after the $environment_variable_name environment variable was set in the registry to '$correct_value'");
+		return;
+	}
+	
+	$environment_variable_value = $self->get_environment_variable_value($environment_variable_name);
+	if ($environment_variable_value && $environment_variable_value eq $correct_value) {
+		notify($ERRORS{'DEBUG'}, 0, "verified $environment_variable_name environment variable is set correctly after updating the registry: '$environment_variable_value'");
+		return 1;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "$environment_variable_name environment variable is still not set correctly after updating the registry:\ncorrect value: $correct_value\ncurrent value: '$environment_variable_value'");
+		return;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_environment_variable_value
+
+ Parameters  : $environment_variable_name
+ Returns     : string
+ Description : Retrieves the value of the environment variable specified by the
+					argument. An empty string is returned if the variable is not set.
+
+=cut
+
+sub get_environment_variable_value {
+	my $self = shift;
+	if (ref($self) !~ /windows/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+	
+	my $computer_node_name   = $self->data->get_computer_node_name();
+	
+	# Get the environment variable name argument
+	my $environment_variable_name = shift;
+	if (!defined($environment_variable_name)) {
+		notify($ERRORS{'WARNING'}, 0, "environment variable name argument was not supplied");
+		return;
+	}
+	
+	# Determine how the environment variable should be echo'd
+	my $command = 'bash --login -c "';
+	if ($environment_variable_name =~ /^\$/) {
+		# Unix-style environment variable name passed beginning with a '$', echo it from the Cygwin bash shell
+		$environment_variable_name = uc($environment_variable_name);
+		$command .= "echo \\$environment_variable_name";
+	}
+	elsif ($environment_variable_name =~ /^\%.*\%$/) {
+		# DOS-style environment variable name passed enclosed in '%...%', echo it from a command prompt
+		$command .= "cmd.exe /c echo $environment_variable_name";
+	}
+	else {
+		# Plain-word environment variable name passed, enclose it in '%...%' and echo it from a command prompt
+		$command .= "cmd.exe /c echo \%$environment_variable_name\%";
+	}
+	$command .= '"';
+	
+	my ($exit_status, $output) = $self->execute($command);
+	if (!defined($output)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to run command to retrieve value of '$environment_variable_name' environment variable on $computer_node_name");
+		return;
+	}
+	elsif ($exit_status ne '0' || grep(/bash:/, @$output)) {
+		notify($ERRORS{'WARNING'}, 0, "error occurred attempting to retrieve value of '$environment_variable_name' environment variable on $computer_node_name\ncommand: '$command'\noutput:\n" . join("\n", @$output));
+		return;
+	}
+	elsif (scalar @$output > 1) {
+		notify($ERRORS{'WARNING'}, 0, "unexpected output returned from command to retrieve value of '$environment_variable_name' environment variable on $computer_node_name\ncommand: '$command'\noutput:\n" . join("\n", @$output));
+		return;
+	}
+	
+	my $value = @$output[0];
+	if (scalar @$output == 0 || $value =~ /^\%.*\%$/) {
+		notify($ERRORS{'DEBUG'}, 0, "'$environment_variable_name' environment variable is not set on $computer_node_name");
+		return '';
+	}
+	else {
+		notify($ERRORS{'DEBUG'}, 0, "retrieved value of '$environment_variable_name' environment variable on $computer_node_name: '$value'");
+		return $value;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 1;
 __END__
 

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_6.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_6.pm?rev=1097825&r1=1097824&r2=1097825&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_6.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_6.pm Fri Apr 29 14:51:24 2011
@@ -1691,43 +1691,39 @@ sub set_ignore_default_routes {
 		return;	
 	}
 	
-	# Run netsh.exe to configure any default routes configured for the private interface to be ignored
-	my $private_netsh_command = "$system32_path/netsh.exe interface ip set interface \"$private_interface_name\" ignoredefaultroutes=enabled";
-	my ($private_netsh_exit_status, $private_netsh_output) = run_ssh_command($computer_node_name, $management_node_keys, $private_netsh_command);
-	if (defined($private_netsh_exit_status) && $private_netsh_exit_status == 0) {
-		notify($ERRORS{'OK'}, 0, "configured interface \"$private_interface_name\": ignore default routes = enabled");
-	}
-	elsif (defined($private_netsh_exit_status)) {
-		notify($ERRORS{'WARNING'}, 0, "failed to configure interface \"$private_interface_name\": ignore default routes = enabled, exit status: $private_netsh_exit_status, output:\n@{$private_netsh_output}");
-		return;
-	}
-	else {
-		notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to configure interface \"$private_interface_name\": ignore default routes = enabled");
-		return;
-	}
-	
 	# Get the public interface name
 	my $public_interface_name = $self->get_public_interface_name();
-	if (!$private_interface_name) {
+	if (!$public_interface_name) {
 		notify($ERRORS{'WARNING'}, 0, "unable to determine public interface name");
 		return;	
 	}
 	
 	# Run netsh.exe to configure any default routes configured for the public interface to be used
-	my $public_netsh_command = "$system32_path/netsh.exe interface ip set interface \"$public_interface_name\" ignoredefaultroutes=disabled";
-	my ($public_netsh_exit_status, $public_netsh_output) = run_ssh_command($computer_node_name, $management_node_keys, $public_netsh_command);
-	if (defined($public_netsh_exit_status) && $public_netsh_exit_status == 0) {
-		notify($ERRORS{'OK'}, 0, "configured interface \"$public_interface_name\": ignore default routes = disabled");
+	my $netsh_command = "$system32_path/netsh.exe interface ip set interface \"$public_interface_name\" ignoredefaultroutes=disabled";
+	
+	# If multiple interfaces are used, set the private interface to ignore default routes
+	if ($private_interface_name ne $public_interface_name) {
+		notify($ERRORS{'DEBUG'}, 0, "computer has multiple network interfaces, configuring ignore default routes:\nprivate interface '$private_interface_name': enabled\npublic interface '$public_interface_name': disabled");
+		$netsh_command .= " & $system32_path/netsh.exe interface ip set interface \"$private_interface_name\" ignoredefaultroutes=enabled";
 	}
-	elsif (defined($public_netsh_exit_status)) {
-		notify($ERRORS{'WARNING'}, 0, "failed to configure interface \"$public_interface_name\": ignore default routes = disabled, exit status: $public_netsh_exit_status, output:\n@{$public_netsh_output}");
+	else {
+		notify($ERRORS{'DEBUG'}, 0, "computer has a single network interface, configuring ignore default routes:\ninterface '$private_interface_name': enabled");
+	}
+	
+	my ($netsh_exit_status, $netsh_output) = run_ssh_command($computer_node_name, $management_node_keys, $netsh_command);
+	if (!defined($netsh_output)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to configure ignore default routes");
 		return;
 	}
-	else {
-		notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to configure interface \"$public_interface_name\": ignore default routes = disabled");
+	elsif ($netsh_exit_status == 0) {
+		notify($ERRORS{'OK'}, 0, "configured ignore default routes");
+	}
+	elsif (defined($netsh_exit_status)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to configure ignore default routes, exit status: $netsh_exit_status\ncommand: '$netsh_command'\noutput:\n" . join("\n", @$netsh_output));
 		return;
 	}
 	
+	
 	return 1;
 }
 
@@ -1801,8 +1797,10 @@ sub sanitize_files {
 		return;
 	}
 	
+	my $system32_path = $self->get_system32_path() || return;
+	
 	my @file_paths = (
-		'$SYSTEMROOT/System32/sysprep',
+		"$system32_path/sysprep",
 		'$SYSTEMROOT/Panther',
 	);
 	

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm?rev=1097825&r1=1097824&r2=1097825&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm Fri Apr 29 14:51:24 2011
@@ -321,7 +321,30 @@ sub wait_for_power_off {
 	my $message = "waiting a maximum of $total_wait_seconds for $computer_name to be powered off";
 	
 	# Call code_loop_timeout and invert the result
-	if ($self->code_loop_timeout(sub{return ($self->power_status() =~ /off/i)}, [$computer_name], "waiting for $computer_name to power off", $total_wait_seconds, $attempt_delay_seconds)) {
+	my $code_loop_result = $self->code_loop_timeout(
+		sub{
+			my $power_status = $self->power_status();
+			if (!defined($power_status)) {
+				return;
+			}
+			elsif ($power_status =~ /off/i) {
+				return 1;
+			}
+			else {
+				return 0;
+			}
+		},
+		[$computer_name],
+		"waiting for $computer_name to power off",
+		$total_wait_seconds,
+		$attempt_delay_seconds
+	);
+	
+	if (!defined($code_loop_result)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to determine power status of $computer_name, returning undefined");
+		return;
+	}
+	elsif ($code_loop_result) {
 		return 1;
 	}
 	else {

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm?rev=1097825&r1=1097824&r2=1097825&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm Fri Apr 29 14:51:24 2011
@@ -779,10 +779,47 @@ sub get_active_vmx_file_path {
 		return;
 	}
 	
+	my $os_type = $self->data->get_image_os_type();
 	my $computer_name = $self->data->get_computer_short_name();
 	
+	my $active_os;
+	my $active_os_type = $self->os->get_os_type();
+	if (!$active_os_type) {
+		notify($ERRORS{'WARNING'}, 0, "unable to determine active vmx file path, OS type currently installed on $computer_name could not be determined");
+		return;
+	}
+	elsif ($active_os_type ne $os_type) {
+		notify($ERRORS{'DEBUG'}, 0, "OS type currently installed on $computer_name does not match the OS type of the reservation image:\nOS type installed on $computer_name: $active_os_type\nreservation image OS type: $os_type");
+		
+		my $active_os_perl_package;
+		if ($active_os_type =~ /linux/i) {
+			$active_os_perl_package = 'VCL::Module::OS::Linux';
+		}
+		else {
+			$active_os_perl_package = 'VCL::Module::OS::Windows';
+		}
+		
+		if ($active_os = $self->create_os_object($active_os_perl_package)) {
+			notify($ERRORS{'DEBUG'}, 0, "created a '$active_os_perl_package' OS object for the '$active_os_type' OS type currently installed on $computer_name");
+		}
+		else {
+			notify($ERRORS{'WARNING'}, 0, "unable to determine active vmx file path, failed to create a '$active_os_perl_package' OS object for the '$active_os_type' OS type currently installed on $computer_name");
+			return;
+		}
+	}
+	else {
+		notify($ERRORS{'DEBUG'}, 0, "'$active_os_type' OS type currently installed on $computer_name matches the OS type of the image assigned to this reservation");
+		$active_os = $self->os;
+	}
+	
+	# Make sure the active OS object implements the required subroutines called below
+	if (!$active_os->can('get_private_mac_address') || !$active_os->can('get_public_mac_address')) {
+		notify($ERRORS{'WARNING'}, 0, "unable to determine active vmx file path, " . ref($active_os) . " OS object does not implement 'get_private_mac_address' and 'get_public_mac_address' subroutines");
+		return;
+	}
+	
 	# Get the MAC addresses being used by the running VM for this reservation
-	my @vm_mac_addresses = ($self->os->get_private_mac_address(), $self->os->get_public_mac_address());
+	my @vm_mac_addresses = ($active_os->get_private_mac_address(), $active_os->get_public_mac_address());
 	if (!@vm_mac_addresses) {
 		notify($ERRORS{'WARNING'}, 0, "unable to retrieve the private and public MAC address being used by VM $computer_name");
 		return;
@@ -1429,6 +1466,22 @@ sub remove_existing_vms {
 		}
 	}
 	
+	# Make sure the computer assigned to this reservation isn't still responding
+	# This could occur if a VM was configured to use the IP address but the directory where the VM resides doesn't match the name VCL would have given it
+	if ($self->os->is_ssh_responding()) {
+		my $private_ip_address = $self->data->get_computer_private_ip_address() || '';
+		notify($ERRORS{'WARNING'}, 0, "$computer_name ($private_ip_address) is still responding to SSH after deleting deleting matching VMs, attempting to determine vmx file path");
+		
+		my $active_vmx_file_path = $self->get_active_vmx_file_path();
+		if ($active_vmx_file_path) {
+			notify($ERRORS{'CRITICAL'}, 0, "VM is still running after attempting to delete all existing matching VMs: $computer_name ($private_ip_address)\nvmx file path: '$active_vmx_file_path'");
+		}
+		else {
+			notify($ERRORS{'CRITICAL'}, 0, "VM is still running after attempting to delete all existing matching VMs: $computer_name ($private_ip_address), unable to determine vmx file path");
+		}
+		return;
+	}
+	
 	# Set the computer current image in the database to 'noimage'
 	if (update_computer_imagename($computer_id, 'noimage')) {
 		notify($ERRORS{'DEBUG'}, 0, "set computer $computer_name current image to 'noimage'");