Author: arkurth Date: Thu Sep 9 18:43:46 2010 New Revision: 995535 URL: http://svn.apache.org/viewvc?rev=995535&view=rev Log: VCL-164 Added commands to Version_6.pm::run_sysprep to set the interfaces to use DHCP immediately before Sysprep.exe is run since the call to enable DHCP in Windows.pm::pre_capture was removed. Also added commands to delete the default routes so that the persistent routes are not saved in the image. This now matches the way sysprep.exe is called for version 5.x.
Added Provisioning.pm::wait_for_power_off() subroutine. Updated run_sysprep subroutines to call wait_for_power_off after sysprep.exe is executed. Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_5.pm incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_6.pm incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_5.pm URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_5.pm?rev=995535&r1=995534&r2=995535&view=diff ============================================================================== --- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_5.pm (original) +++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_5.pm Thu Sep 9 18:43:46 2010 @@ -292,7 +292,7 @@ sub run_sysprep { # Run Sysprep.exe $sysprep_command .= "C:/Sysprep/sysprep.exe /quiet /reseal /mini /forceshutdown & "; - # Shutdown the computer - Sysprep does not always shut the computer down + # Shutdown the computer - Sysprep does not always shut the computer down automatically $sysprep_command .= "$system32_path/shutdown.exe -s -t 0 -f"; $sysprep_command .= "\""; @@ -315,19 +315,19 @@ sub run_sysprep { notify($ERRORS{'WARNING'}, 0, "$computer_node_name never became unresponsive to ping"); return 0; } - - # Wait for 3 minutes then call provisioning module's power_off() subroutine - # Sysprep does not always shut down the computer when it is done - notify($ERRORS{'OK'}, 0, "sleeping for 3 minutes to allow Sysprep.exe to finish"); - sleep 180; - - # Call power_off() to make sure computer is shut down - if (!$self->provisioner->power_off()) { - # Computer could not be shut off - notify($ERRORS{'WARNING'}, 0, "unable to power off $computer_node_name"); - return 0; + + # Wait maximum of 10 minutes for computer to power off + my $power_off = $self->provisioner->wait_for_power_off(600); + if (!defined($power_off)) { + # wait_for_power_off result will be undefined if the provisioning module doesn't implement a power_status subroutine + notify($ERRORS{'OK'}, 0, "unable to determine power status of $computer_node_name from provisioning module, sleeping 5 minutes to allow computer time to power off"); + sleep 300; } - + elsif (!$power_off) { + notify($ERRORS{'WARNING'}, 0, "$computer_node_name never powered off after running sysprep.exe"); + return; + } + return 1; } 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=995535&r1=995534&r2=995535&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 Thu Sep 9 18:43:46 2010 @@ -1583,7 +1583,32 @@ EOF $self->run_slmgr_dlv(); # Run Sysprep.exe, use cygstart to lauch the .exe and return immediately - my $sysprep_command = "/bin/cygstart.exe cmd.exe /c \"$system32_path_dos\\sysprep\\sysprep.exe /generalize /oobe /shutdown /quiet /unattend:$system32_path_dos\\sysprep\\Unattend.xml\""; + my $sysprep_command = "/bin/cygstart.exe cmd.exe /c \""; + + # First enable DHCP on the private and public interfaces and delete the default route + my $private_interface_name = $self->get_private_interface_name(); + my $public_interface_name = $self->get_public_interface_name(); + if (!$private_interface_name || !$public_interface_name) { + notify($ERRORS{'WARNING'}, 0, "unable to determine private and public interface names, failed to enable DHCP and shut down $computer_node_name"); + return; + } + + # Release any DHCP addresses and delete the default route + $sysprep_command .= "$system32_path/ipconfig.exe /release & "; + $sysprep_command .= "$system32_path/route.exe DELETE 0.0.0.0 MASK 0.0.0.0 & "; + + # Disable DHCP + $sysprep_command .= "$system32_path/netsh.exe interface ip set address name=\\\"$private_interface_name\\\" source=dhcp & "; + $sysprep_command .= "$system32_path/netsh.exe interface ip set dns name=\\\"$private_interface_name\\\" source=dhcp & "; + $sysprep_command .= "$system32_path/netsh.exe interface ip set address name=\\\"$public_interface_name\\\" source=dhcp & "; + $sysprep_command .= "$system32_path/netsh.exe interface ip set dns name=\\\"$public_interface_name\\\" source=dhcp & "; + + # Run Sysprep.exe + $sysprep_command .= "$system32_path_dos\\sysprep\\sysprep.exe /generalize /oobe /shutdown /quiet /unattend:$system32_path_dos\\sysprep\\Unattend.xml"; + + $sysprep_command .= "\""; + + # Run Sysprep.exe, use cygstart to lauch the .exe and return immediately my ($sysprep_status, $sysprep_output) = run_ssh_command($computer_node_name, $management_node_keys, $sysprep_command); if (defined($sysprep_status) && $sysprep_status == 0) { notify($ERRORS{'OK'}, 0, "initiated Sysprep.exe, waiting for $computer_node_name to become unresponsive"); @@ -1601,14 +1626,19 @@ EOF if (!$self->wait_for_no_ping(720)) { # Computer never stopped responding to ping notify($ERRORS{'WARNING'}, 0, "$computer_node_name never became unresponsive to ping"); - return 0; + return; } - # Call power_off() to make sure computer is shut down - if (!$self->provisioner->power_off()) { - # Computer could not be shut off - notify($ERRORS{'WARNING'}, 0, "unable to power off $computer_node_name"); - return 0; + # Wait maximum of 10 minutes for computer to power off + my $power_off = $self->provisioner->wait_for_power_off(600); + if (!defined($power_off)) { + # wait_for_power_off result will be undefined if the provisioning module doesn't implement a power_status subroutine + notify($ERRORS{'OK'}, 0, "unable to determine power status of $computer_node_name from provisioning module, sleeping 5 minutes to allow computer time to shutdown"); + sleep 300; + } + elsif (!$power_off) { + notify($ERRORS{'WARNING'}, 0, "$computer_node_name never powered off"); + return; } return 1; 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=995535&r1=995534&r2=995535&view=diff ============================================================================== --- incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm (original) +++ incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm Thu Sep 9 18:43:46 2010 @@ -316,6 +316,61 @@ sub retrieve_image { #///////////////////////////////////////////////////////////////////////////// +=head2 wait_for_power_off + + Parameters : Maximum number of seconds to wait (optional), seconds to delay between attempts (optional) + Returns : 1 - If computer is powered off + 0 - If computer is still powered on after waiting + undefined - Unable to determine power status + Description : Attempts to check the power status of the computer specified in + the DataStructure for the current reservation. It will wait up to + a maximum number of seconds for the computer to be powered off + (default: 300 seconds). The delay between attempts can be + specified as the 2nd argument in seconds (default: 15 seconds). + +=cut + +sub wait_for_power_off { + 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; + } + + # Attempt to get the total number of seconds to wait from the arguments + my $total_wait_seconds = shift; + if (!defined($total_wait_seconds) || $total_wait_seconds !~ /^\d+$/) { + $total_wait_seconds = 300; + } + + # Seconds to wait in between loop attempts + my $attempt_delay_seconds = shift; + if (!defined($attempt_delay_seconds) || $attempt_delay_seconds !~ /^\d+$/) { + $attempt_delay_seconds = 15; + } + + # Check if the provisioning module implements a power status subroutine + if (!$self->can('power_status')) { + notify($ERRORS{'WARNING'}, 0, "power_status subroutine has not been implemented by the provisioning module: " . ref($self)); + return; + } + + my $computer_name = $self->data->get_computer_short_name(); + + 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)) { + return 1; + } + else { + notify($ERRORS{'WARNING'}, 0, "$computer_name has not powered off after waiting $total_wait_seconds seconds, returning 0"); + return 0; + } +} + +#///////////////////////////////////////////////////////////////////////////// + 1; __END__