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