Author: fapeeler Date: Wed Apr 28 20:02:39 2010 New Revision: 939069 URL: http://svn.apache.org/viewvc?rev=939069&view=rev Log: VCL-180
added power_off,power_on,power_status,power_reset,wait_for_on,wait_for_off routines Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/xCAT2.pm Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/xCAT2.pm URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/xCAT2.pm?rev=939069&r1=939068&r2=939069&view=diff ============================================================================== --- incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/xCAT2.pm (original) +++ incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/xCAT2.pm Wed Apr 28 20:02:39 2010 @@ -2182,6 +2182,415 @@ sub _get_base_template_filename { #///////////////////////////////////////////////////////////////////////////// +=head2 power_off + + Parameters : $computer_node_name (optional) + Returns : + Description : + +=cut + +sub power_off { + my $argument_1 = shift; + my $argument_2 = shift; + + my $computer_node_name; + + # Check if subroutine was called as an object method + if (ref($argument_1) =~ /xcat/i) { + my $self = $argument_1; + + $computer_node_name = $argument_2; + + # Check if computer argument was specified + # If not, use computer node name in the data object + if (!$computer_node_name) { + $computer_node_name = $self->data->get_computer_node_name(); + } + } ## end if (ref($argument_1) =~ /xcat/i) + else { + # Subroutine was not called as an object method, 2 arguments must be specified + $computer_node_name = $argument_1; + } + + # Check if computer was determined + if (!$computer_node_name) { + notify($ERRORS{'WARNING'}, 0, "computer could not be determined from arguments"); + return; + } + + # Turn computer off + my $power_status = 'unknown'; + my $off_attempts = 0; + while ($power_status !~ /off/) { + $off_attempts++; + + if ($off_attempts == 3) { + notify($ERRORS{'WARNING'}, 0, "failed to turn $computer_node_name off, rpower status not is off aft er 3 attempts"); + return; + } + + # Attempt to run rpower <node> off + _rpower($computer_node_name, 'off'); + + # Wait up to 1 minute for the computer power status to be off + if (wait_for_off($computer_node_name, 1)) { + last; + } + + $power_status = power_status($computer_node_name); + } ## end while ($power_status !~ /off/) + notify($ERRORS{'OK'}, 0, "successfully powered off $computer_node_name"); + return 1; +} ## end sub power_off + +#///////////////////////////////////////////////////////////////////////////// + +=head2 power_status + + Parameters : $computer_node_name (optional) + Returns : + Description : + +=cut + +sub power_status { + my $argument_1 = shift; + my $argument_2 = shift; + + my $computer_node_name; + + # Check if subroutine was called as an object method + if (ref($argument_1) =~ /xcat/i) { + my $self = $argument_1; + + $computer_node_name = $argument_2; + + # Check if computer argument was specified + # If not, use computer node name in the data object + if (!$computer_node_name) { + $computer_node_name = $self->data->get_computer_node_name(); + } + } ## end if (ref($argument_1) =~ /xcat/i) + else { + # Subroutine was not called as an object method, 2 arguments must be specified + $computer_node_name = $argument_1; + } + + # Check if computer was determined + if (!$computer_node_name) { + notify($ERRORS{'WARNING'}, 0, "computer could not be determined from arguments"); + return; + } + + # Call rpower to determine power status + my $rpower_stat = _rpower($computer_node_name, 'stat'); + notify($ERRORS{'DEBUG'}, 0, "retrieved power status of $computer_node_name: $rpower_stat"); + + if (!$rpower_stat) { + notify($ERRORS{'WARNING'}, 0, "failed to determine power status, rpower subroutine returned $rpower_stat"); + return; + } + elsif ($rpower_stat =~ /^(on|off)$/i) { + return lc($1); + } + else { + notify($ERRORS{'WARNING'}, 0, "failed to determine power status, unexpected output returned from rpower: $rpower_stat"); + return; + } +} ## end sub power_status + + +#///////////////////////////////////////////////////////////////////////////// + +=head2 power_reset + + Parameters : $computer_node_name (optional) + Returns : + Description : + +=cut + +sub power_reset { + my $argument_1 = shift; + my $argument_2 = shift; + + my $computer_node_name; + + # Check if subroutine was called as an object method + if (ref($argument_1) =~ /xcat/i) { + my $self = $argument_1; + + $computer_node_name = $argument_2; + + # Check if computer argument was specified + # If not, use computer node name in the data object + if (!$computer_node_name) { + $computer_node_name = $self->data->get_computer_node_name(); + } + } ## end if (ref($argument_1) =~ /xcat/i) + else { + # Subroutine was not called as an object method, 2 arguments must be specified + $computer_node_name = $argument_1; + } + + # Check if computer was determined + if (!$computer_node_name) { + notify($ERRORS{'WARNING'}, 0, "computer could not be determined from arguments"); + return; + } + + # Turn computer off + my $off_attempts = 0; + while (!power_off($computer_node_name)) { + $off_attempts++; + + if ($off_attempts == 3) { + notify($ERRORS{'WARNING'}, 0, "failed to turn $computer_node_name off, rpower status not is off after 3 attempts"); + return; + } + sleep 2; + } ## end while (!power_off($computer_node_name)) + + # Turn computer on + my $on_attempts = 0; + while (!power_on($computer_node_name)) { + $on_attempts++; + if ($on_attempts == 3) { + notify($ERRORS{'WARNING'}, 0, "failed to turn $computer_node_name on, rpower status not is on after 3 attempts"); + return; + } + + sleep 2; + } ## end while (!power_on($computer_node_name)) + + notify($ERRORS{'OK'}, 0, "successfully reset power on $computer_node_name"); + return 1; +} ## end sub power_reset + +#///////////////////////////////////////////////////////////////////////////// + +=head2 power_on + + Parameters : $computer_node_name (optional) + Returns : + Description : + +=cut + +sub power_on { + my $argument_1 = shift; + my $argument_2 = shift; + + my $computer_node_name; + + # Check if subroutine was called as an object method + if (ref($argument_1) =~ /xcat/i) { + my $self = $argument_1; + + $computer_node_name = $argument_2; + + # Check if computer argument was specified + # If not, use computer node name in the data object + if (!$computer_node_name) { + $computer_node_name = $self->data->get_computer_node_name(); + } + } ## end if (ref($argument_1) =~ /xcat/i) + else { + # Subroutine was not called as an object method, 2 arguments must be specified + $computer_node_name = $argument_1; + } + + # Check if computer was determined + if (!$computer_node_name) { + notify($ERRORS{'WARNING'}, 0, "computer could not be determined from arguments"); + return; + } + + # Turn computer on + my $on_attempts = 0; + my $power_status = 'unknown'; + while ($power_status !~ /on/) { + $on_attempts++; + + if ($on_attempts == 3) { + notify($ERRORS{'WARNING'}, 0, "failed to turn $computer_node_name on, rpower status not is on after 3 attempts"); + return; + } + + _rpower($computer_node_name, 'on'); + + # Wait up to 1 minute for the computer power status to be on + if (wait_for_on($computer_node_name, 1)) { + last; + } + + $power_status = power_status($computer_node_name); + } ## end while ($power_status !~ /on/) + + notify($ERRORS{'OK'}, 0, "successfully powered on $computer_node_name"); + return 1; +} ## end sub power_on +#///////////////////////////////////////////////////////////////////////////// + +=head2 wait_for_on + + Parameters : Maximum number of minutes to wait (optional) + Returns : 1 if computer is on, 0 otherwise + Description : + +=cut + +sub wait_for_on { + my $argument_1 = shift; + my $argument_2 = shift; + my $argument_3 = shift; + + my $self; + my $computer_node_name; + my $total_wait_minutes; + + # Check if subroutine was called as an object method + if (ref($argument_1) =~ /xcat/i) { + $self = $argument_1; + + if (defined $argument_3) { + $computer_node_name = $argument_2; + $total_wait_minutes = $argument_3; + } + else { + $computer_node_name = $self->data->get_computer_node_name(); + $total_wait_minutes = $argument_2; + } + + } ## end if (ref($argument_1) =~ /xcat/i) + else { + # Subroutine was not called as an object method, 2 arguments must be specified + $computer_node_name = $argument_1; + $total_wait_minutes = $argument_2; + } + + # Check if computer was determined + if (!$computer_node_name) { + notify($ERRORS{'WARNING'}, 0, "computer could not be determined from arguments"); + return; + } + + # Make sure total wait minutes was determined + if (!defined($total_wait_minutes) || $total_wait_minutes !~ /^\d+$/) { + notify($ERRORS{'DEBUG'}, 0, "total wait minutes argument not specified, using default of 5 minutes"); + $total_wait_minutes = 5; + } + + # Looping configuration variables # Seconds to wait in between loop attempts + my $attempt_delay = 15; + # Total loop attempts made + # Add 1 to the number of attempts because if you're waiting for x intervals, you check x+1 times including at 0 + my $attempts = ($total_wait_minutes * 4) + 1; + + notify($ERRORS{'OK'}, 0, "waiting for $computer_node_name to turn on, maximum of $total_wait_minutes minutes"); + + # Loop until computer is on + for (my $attempt = 1; $attempt <= $attempts; $attempt++) { + if ($attempt > 1) { + notify($ERRORS{'OK'}, 0, "attempt " . ($attempt - 1) . "/" . ($attempts - 1) . ": $computer_node_name is not on, sleeping for $attempt_delay seconds"); + sleep $attempt_delay; + } + + if (power_status($computer_node_name) =~ /on/i) { + notify($ERRORS{'OK'}, 0, "$computer_node_name is on"); + return 1; + } + } ## end for (my $attempt = 1; $attempt <= $attempts... + + # Calculate how long this waited + my $total_wait = ($attempts * $attempt_delay); + notify($ERRORS{'WARNING'}, 0, "$computer_node_name is NOT on after waiting for $total_wait seconds"); + return 0; +} ## end sub wait_for_on + +#///////////////////////////////////////////////////////////////////////////// + +=head2 wait_for_off + + Parameters : Maximum number of minutes to wait (optional) + Returns : 1 if computer is off, 0 otherwise + Description : + +=cut + +sub wait_for_off { + my $argument_1 = shift; + my $argument_2 = shift; + my $argument_3 = shift; + + my $self; + my $computer_node_name; + my $total_wait_minutes; + + # Check if subroutine was called as an object method + if (ref($argument_1) =~ /xcat/i) { + $self = $argument_1; + + if (defined $argument_3) { + $computer_node_name = $argument_2; + $total_wait_minutes = $argument_3; + } + else { + $computer_node_name = $self->data->get_computer_node_name(); + $total_wait_minutes = $argument_2; + } + + } ## end if (ref($argument_1) =~ /xcat/i) + else { + # Subroutine was not called as an object method, 2 arguments must be specified + $computer_node_name = $argument_1; + $total_wait_minutes = $argument_2; + } + + # Check if computer was determined + if (!$computer_node_name) { + notify($ERRORS{'WARNING'}, 0, "computer could not be determined from arguments"); + return; + } + + # Make sure total wait minutes was determined + if (!defined($total_wait_minutes) || $total_wait_minutes !~ /^\d+$/) { + notify($ERRORS{'DEBUG'}, 0, "total wait minutes argument not specified, using default of 5 minutes"); + $total_wait_minutes = 5; + } + + # Looping configuration variables + # Seconds to wait in between loop attempts + my $attempt_delay = 15; + # Total loop attempts made + # Add 1 to the number of attempts because if you're waiting for x intervals, you check x+1 times including at 0 + my $attempts = ($total_wait_minutes * 4) + 1; + + notify($ERRORS{'OK'}, 0, "waiting for $computer_node_name to turn off, maximum of $total_wait_minutes minutes"); + + # Loop until computer is off + for (my $attempt = 1; $attempt <= $attempts; $attempt++) { + if ($attempt > 1) { + notify($ERRORS{'OK'}, 0, "attempt " . ($attempt - 1) . "/" . ($attempts - 1) . ": $computer_node_name is not off, sleeping for $attempt_delay seconds"); + sleep $attempt_delay; + } + + if (power_status($computer_node_name) =~ /off/i) { + notify($ERRORS{'OK'}, 0, "$computer_node_name is off"); + return 1; + } + } ## end for (my $attempt = 1; $attempt <= $attempts... + + # Calculate how long this waited + my $total_wait = ($attempts * $attempt_delay); + notify($ERRORS{'WARNING'}, 0, "$computer_node_name is NOT off after waiting for $total_wait seconds"); + return 0; +} ## end sub wait_for_off + + +#///////////////////////////////////////////////////////////////////////////// + initialize() if (!$XCAT_ROOT); #/////////////////////////////////////////////////////////////////////////////