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'");


Reply via email to