Author: arkurth Date: Tue Sep 8 14:48:01 2009 New Revision: 812535 URL: http://svn.apache.org/viewvc?rev=812535&view=rev Log: VCL-215 Updated State.pm::reservation_failed() to check if the computer state is maintenance before updating it in order to prevent the state of computers in maintenance to be changed.
Added DataStructure.pm::get_computer_state_name(). This sub queries the database for the current value of a computer's state rather than simply returning what's saved in the data structure. This sub should eventually replace utils.pm::get_current_computer_state_name(). Modified: incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm incubator/vcl/trunk/managementnode/lib/VCL/Module/State.pm Modified: incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm?rev=812535&r1=812534&r2=812535&view=diff ============================================================================== --- incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm (original) +++ incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm Tue Sep 8 14:48:01 2009 @@ -1842,6 +1842,97 @@ #///////////////////////////////////////////////////////////////////////////// +=head2 get_computer_state_name + + Parameters : computer name (optional + Returns : String containing state name for a particular computer + Description : Queries database for current computer state and returns the + state name. The database is queried rather than simply returning + the value in the data structure in case the computer state + changed by some other process after the reservation process + began. This is mainly done for safety in case the computer state + gets set to maintenance. + +=cut + + +sub get_computer_state_name { + my $self; + my $argument = shift; + my $computer_name; + + # Check if subroutine was called as an object method + if (ref($argument) && $argument->isa('VCL::DataStructure')) { + # Subroutine was called as an object method, check if an argument was specified + $self = $argument; + $argument = shift; + if ($argument) { + # Argument was specified, use this as the computer name + $computer_name = $argument; + } + else { + # Argument was not specified, get the computer short name for this reservation + $computer_name = $self->get_computer_short_name(); + } + } + elsif (ref($argument)) { + notify($ERRORS{'WARNING'}, 0, "subroutine was called with an illegal argument type: " . ref($argument)); + return; + } + else { + # Subroutine was not called as an object method + $computer_name = $argument; + } + + # Make sure the computer name was determined either from an argument or the request data + if (!$computer_name) { + notify($ERRORS{'WARNING'}, 0, "unable to determine computer name from argument or request data"); + return; + } + + notify($ERRORS{'DEBUG'}, 0, "attempting to retrieve current state of computer $computer_name from the database"); + + # Create the select statement + my $select_statement = " + SELECT DISTINCT + state.name AS name + FROM + state, + computer + WHERE + computer.stateid = state.id + AND computer.hostname LIKE '$computer_name%' + "; + + # Call the database select subroutine + # This will return an array of one or more rows based on the select statement + my @selected_rows = database_select($select_statement); + + # Check to make sure 1 row was returned + if (scalar @selected_rows == 0) { + notify($ERRORS{'WARNING'}, 0, "zero rows were returned from database select"); + return (); + } + elsif (scalar @selected_rows > 1) { + notify($ERRORS{'WARNING'}, 0, scalar @selected_rows . " rows were returned from database select"); + return (); + } + + # Make sure we return undef if the column wasn't found + if (defined $selected_rows[0]{name}) { + my $computer_state_name = $selected_rows[0]{name}; + notify($ERRORS{'DEBUG'}, 0, "retrieved current state of computer $computer_name from the database: $computer_state_name"); + $self->set_computer_state_name($computer_state_name); + return $computer_state_name; + } + else { + notify($ERRORS{'WARNING'}, 0, "unable to retrieve current state of computer $computer_name from the database"); + return undef; + } +} + +#///////////////////////////////////////////////////////////////////////////// + 1; __END__ Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/State.pm URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/State.pm?rev=812535&r1=812534&r2=812535&view=diff ============================================================================== --- incubator/vcl/trunk/managementnode/lib/VCL/Module/State.pm (original) +++ incubator/vcl/trunk/managementnode/lib/VCL/Module/State.pm Tue Sep 8 14:48:01 2009 @@ -256,24 +256,30 @@ } # Get the required data - my $request_id = $self->data->get_request_id(); - my $request_logid = $self->data->get_request_log_id(); - my $reservation_id = $self->data->get_reservation_id(); - my $computer_id = $self->data->get_computer_id(); - my $computer_short_name = $self->data->get_computer_short_name(); - my $request_state_name = $self->data->get_request_state_name(); - my $request_laststate_name = $self->data->get_request_laststate_name(); + my $request_id = $self->data->get_request_id(); + my $request_logid = $self->data->get_request_log_id(); + my $reservation_id = $self->data->get_reservation_id(); + my $computer_id = $self->data->get_computer_id(); + my $computer_short_name = $self->data->get_computer_short_name(); + my $request_state_name = $self->data->get_request_state_name(); + my $request_laststate_name = $self->data->get_request_laststate_name(); + my $computer_state_name = $self->data->get_computer_state_name(); # Check if the request has been deleted if (is_request_deleted($request_id)) { notify($ERRORS{'OK'}, 0, "request has been deleted, setting computer state to available and exiting"); # Update the computer state to available - if (update_computer_state($computer_id, "available")) { - notify($ERRORS{'OK'}, 0, "$computer_short_name ($computer_id) state set to 'available'"); + if ($computer_state_name !~ /^(maintenance)/){ + if (update_computer_state($computer_id, "available")) { + notify($ERRORS{'OK'}, 0, "$computer_short_name ($computer_id) state set to 'available'"); + } + else { + notify($ERRORS{'OK'}, 0, "failed to set $computer_short_name ($computer_id) state to 'available'"); + } } else { - notify($ERRORS{'OK'}, 0, "failed to set $computer_short_name ($computer_id) state to 'available'"); + notify($ERRORS{'WARNING'}, 0, "computer $computer_short_name ($computer_id) state NOT set to available because the current state is $computer_state_name"); } notify($ERRORS{'OK'}, 0, "exiting 0"); @@ -292,7 +298,7 @@ } - if($request_state_name =~ /^(new|reserved|inuse|image)/){ + if ($request_state_name =~ /^(new|reserved|inuse|image)/){ # Update log table ending column to failed for this request if (update_log_ending($request_logid, "failed")) { notify($ERRORS{'OK'}, 0, "updated log ending value to 'failed', logid=$request_logid"); @@ -302,12 +308,17 @@ } } - # Update the computer state to failed - if (update_computer_state($computer_id, "failed")) { - notify($ERRORS{'OK'}, 0, "computer $computer_short_name ($computer_id) state set to failed"); + # Update the computer state to failed as long as it's not currently maintenance + if ($computer_state_name !~ /^(maintenance)/){ + if (update_computer_state($computer_id, "failed")) { + notify($ERRORS{'OK'}, 0, "computer $computer_short_name ($computer_id) state set to failed"); + } + else { + notify($ERRORS{'WARNING'}, 0, "unable to set computer $computer_short_name ($computer_id) state to failed"); + } } else { - notify($ERRORS{'WARNING'}, 0, "unable to set computer $computer_short_name ($computer_id) state to failed"); + notify($ERRORS{'WARNING'}, 0, "computer $computer_short_name ($computer_id) state NOT set to failed because the current state is $computer_state_name"); } # Update the request state to failed