in managementnode/lib/VCL/new.pm [88:440]
sub process {
my $self = shift;
my $request_id = $self->data->get_request_id();
my $request_state_name = $self->data->get_request_state_name();
my $request_preload_only = $self->data->get_request_preload_only();
my $reservation_count = $self->data->get_reservation_count();
my $reservation_id = $self->data->get_reservation_id();
my $reservation_is_parent = $self->data->is_parent_reservation;
my $computer_id = $self->data->get_computer_id();
my $computer_short_name = $self->data->get_computer_short_name();
my $computer_state_name = $self->data->get_computer_state_name();
my $computer_next_image_name = $self->data->get_computer_nextimage_name(0);
my $computer_provisioning_name = $self->data->get_computer_provisioning_name();
my $image_id = $self->data->get_image_id();
my $image_name = $self->data->get_image_name();
my $imagerevision_id = $self->data->get_imagerevision_id();
# If reload state is reload and computer is part of block allocation confirm imagerevisionid is the production image.
if ($request_state_name eq 'reload' && is_inblockrequest($computer_id)) {
notify($ERRORS{'OK'}, 0, "request state is '$request_state_name', computer $computer_id is in blockrequest, making sure reservation is assigned production image revision");
my $imagerev_info = get_production_imagerevision_info($image_id);
unless ($imagerevision_id == $imagerev_info->{id}) {
notify($ERRORS{'OK'}, 0, "imagerevision_id does not match imagerevision_id= $imagerevision_id imagerev_info $imagerev_info->{id}");
$self->data->set_imagerevision_id($imagerev_info->{id});
$self->data->set_sublog_imagerevisionid($imagerev_info->{id});
$self->data->set_image_name($imagerev_info->{imagename});
$self->data->set_imagerevision_revision($imagerev_info->{revision});
# Reset variables in this scope
$imagerevision_id = $imagerev_info->{id};
$image_name = $imagerev_info->{imagename};
}
}
# Confirm requested computer is available
if ($self->computer_not_being_used()) {
notify($ERRORS{'OK'}, 0, "$computer_short_name is not being used");
}
elsif ($request_state_name eq 'tomaintenance') {
# Computer is being used
# Loop until computer is not being used
# Wait a maximum of 3 hours
my $total_wait_seconds = (60 * 60 * 3);
# Check every 5 minutes
my $attempt_delay_seconds = (60 * 5);
my $sub_ref = $self->can("computer_not_being_used");
my $message = "waiting for existing reservations on $computer_short_name to end";
if (!$self->code_loop_timeout($sub_ref, [$self], $message, $total_wait_seconds, $attempt_delay_seconds)) {
notify($ERRORS{'CRITICAL'}, 0, "$computer_short_name could not be put into maintenance because it is NOT available");
# Return request state back to the original
if (update_request_state($request_id, 'failed', $request_state_name)) {
notify($ERRORS{'OK'}, 0, "request state set to 'failed'/'$request_state_name'");
}
else {
notify($ERRORS{'WARNING'}, 0, "failed to set request state back to 'failed'/'$request_state_name'");
}
notify($ERRORS{'OK'}, 0, "exiting");
exit;
}
}
elsif ($request_state_name ne 'new') {
# Computer is not available, not a new request (most likely a simple reload)
notify($ERRORS{'WARNING'}, 0, "request state=$request_state_name, $computer_short_name is NOT available");
# Update request state to complete
if (update_request_state($request_id, "complete", $request_state_name)) {
notify($ERRORS{'OK'}, 0, "request state updated to 'complete'/'$request_state_name'");
}
else {
notify($ERRORS{'CRITICAL'}, 0, "failed to update the request state to 'complete'/'$request_state_name'");
}
notify($ERRORS{'OK'}, 0, "exiting");
exit;
} ## end elsif ($request_state_name ne 'new') [ if ($self->computer_not_being_used())
elsif ($request_preload_only) {
# Computer is not available, preload only = true
notify($ERRORS{'WARNING'}, 0, "preload reservation, $computer_short_name is NOT available");
# Set the computer next image so it gets loaded if/when other reservations are complete
if (!defined($computer_next_image_name) || $image_name ne $computer_next_image_name) {
notify($ERRORS{'OK'}, 0, "preload only request, $computer_short_name is not available, setting computer next image to $image_name");
if (setnextimage($computer_id, $image_id)) {
notify($ERRORS{'OK'}, 0, "$computer_short_name next image set to $image_name");
}
else {
notify($ERRORS{'WARNING'}, 0, "failed to set $computer_short_name next image to $image_name");
}
}
else {
notify($ERRORS{'OK'}, 0, "preload only request, $computer_short_name is not available, computer next image is already set to $image_name");
}
# Only the parent reservation is allowed to modify the request state in this module
if (!$reservation_is_parent) {
notify($ERRORS{'OK'}, 0, "child preload reservation, computer is not available, states will be changed by the parent, exiting");
exit;
}
# Return back to original states
notify($ERRORS{'OK'}, 0, "parent preload reservation, returning states back to original");
# Set the preload flag back to 1 so it will be processed again
if (update_preload_flag($request_id, 1)) {
notify($ERRORS{'OK'}, 0, "updated preload flag to 1");
}
else {
notify($ERRORS{'WARNING'}, 0, "failed to update preload flag to 1");
}
# Return request state back to the original
if (update_request_state($request_id, $request_state_name, $request_state_name)) {
notify($ERRORS{'OK'}, 0, "request state set back to '$request_state_name'/'$request_state_name'");
}
else {
notify($ERRORS{'WARNING'}, 0, "failed to set request state back to '$request_state_name'/'$request_state_name'");
}
# Return computer state back to the original
if (update_computer_state($computer_id, $computer_state_name)) {
notify($ERRORS{'OK'}, 0, "$computer_short_name state set back to '$computer_state_name'");
}
else {
notify($ERRORS{'WARNING'}, 0, "failed to set $computer_short_name state back to '$computer_state_name'");
}
notify($ERRORS{'OK'}, 0, "exiting");
exit;
} ## end elsif ($request_preload_only) [ if ($self->computer_not_being_used())
else {
# Computer not available, state=new, PRELOADONLY = false
notify($ERRORS{'WARNING'}, 0, "$computer_short_name is NOT available");
# Call reservation_failed
$self->reservation_failed("process failed because computer is not available");
}
# If state is tomaintenance, place machine into maintenance state and set request to complete
if ($request_state_name =~ /tomaintenance/) {
notify($ERRORS{'OK'}, 0, "setting computer $computer_short_name state to 'maintenance'");
# Set the computer state to 'maintenance' first
if (update_computer_state($computer_id, 'maintenance')) {
notify($ERRORS{'OK'}, 0, "$computer_short_name state set to 'maintenance'");
}
else {
notify($ERRORS{'CRITICAL'}, 0, "failed to set $computer_short_name state to 'maintenance', exiting");
exit;
}
if ($self->provisioner->can("post_maintenance_action")) {
notify($ERRORS{'DEBUG'}, 0, "attempting to perform post maintenance actions for provisioning engine: " . ref($self->provisioner));
if ($self->provisioner->post_maintenance_action()) {
notify($ERRORS{'OK'}, 0, "post maintenance actions completed $computer_short_name");
}
else {
notify($ERRORS{'CRITICAL'}, 0, "failed to complete post maintenance actions on $computer_short_name");
}
}
else {
notify($ERRORS{'DEBUG'}, 0, "post maintenance actions skipped, post_maintenance_action subroutine not implemented by " . ref($self->provisioner));
}
# Update the request state to complete
# Do not update log.ending for tomaintenance reservations
if (update_request_state($request_id, 'complete', $request_state_name)) {
notify($ERRORS{'OK'}, 0, "request state set to 'complete'/'$request_state_name'");
}
else {
notify($ERRORS{'WARNING'}, 0, "failed to set request state to 'complete'/'$request_state_name'");
}
notify($ERRORS{'OK'}, 0, "exiting");
exit;
}
# Confirm requested resouces are available
if ($request_state_name eq 'tovmhostinuse' && ($image_name =~ /noimage/i || $computer_provisioning_name =~ /none/i)) {
notify($ERRORS{'OK'}, 0, "$computer_short_name will not be reloaded, image: $image_name, provisioning name: $computer_provisioning_name");
}
elsif ($self->reload_image()) {
notify($ERRORS{'OK'}, 0, "$computer_short_name is loaded with $image_name");
}
elsif ($request_preload_only) {
# Load failed preload only = true
notify($ERRORS{'WARNING'}, 0, "preload reservation, failed to load $computer_short_name with $image_name");
# Check if parent, only the parent is allowed to modify the request state in this module
if (!$reservation_is_parent) {
notify($ERRORS{'OK'}, 0, "this is a child preload reservation, states will be changed by the parent");
notify($ERRORS{'OK'}, 0, "exiting");
exit;
}
# Return back to original states
notify($ERRORS{'OK'}, 0, "this is a parent preload reservation, returning states back to original");
# Set the preload flag back to 1 so it will be processed again
if (update_preload_flag($request_id, 1)) {
notify($ERRORS{'OK'}, 0, "updated preload flag to 1");
}
else {
notify($ERRORS{'WARNING'}, 0, "failed to update preload flag to 1");
}
# Return request state back to the original
if (update_request_state($request_id, $request_state_name, $request_state_name)) {
notify($ERRORS{'OK'}, 0, "request state set back to '$request_state_name'/'$request_state_name'");
}
else {
notify($ERRORS{'WARNING'}, 0, "failed to set request state back to '$request_state_name'/'$request_state_name'");
}
# Return computer state back to the original
if (update_computer_state($computer_id, $computer_state_name)) {
notify($ERRORS{'OK'}, 0, "$computer_short_name state set back to '$computer_state_name'");
}
else {
notify($ERRORS{'WARNING'}, 0, "failed to set $computer_short_name state back to '$computer_state_name'");
}
notify($ERRORS{'OK'}, 0, "exiting");
exit;
} ## end elsif ($request_preload_only) [ if ($self->reload_image())
else {
# Load failed, PRELOADONLY = false
notify($ERRORS{'WARNING'}, 0, "failed to load $computer_short_name with $image_name");
# Call reservation_failed, problem computer not opened for reservation
$self->reservation_failed("process failed after trying to load or make available");
}
# Parent only checks and waits for any other images to complete and checkin
if ($reservation_is_parent && $reservation_count > 1) {
# Needed for computerloadflow
insertloadlog($reservation_id, $computer_id, "nodeready", "$computer_short_name is loaded with $image_name (cluster parent)");
# Wait on child reservations
if ($self->wait_for_child_reservations()) {
notify($ERRORS{'OK'}, 0, "done waiting for child reservations, they are all ready");
}
else {
# Call reservation_failed, problem computer not opened for reservation
$self->reservation_failed("child reservations never all became ready");
}
} ## end if ($reservation_is_parent && $reservation_count...
# Check if 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 state of computer and exit
$self->state_exit(undef, 'available');
}
my $next_computer_state;
my $next_request_state;
# Attempt to reserve the computer if this is a 'new' reservation
# These steps are not done for simple reloads
notify($ERRORS{'OK'}, 0, "request_state_name= $request_state_name");
if ($request_state_name =~ /^(new|reinstall)/) {
if ($request_preload_only) {
# Return back to original states
notify($ERRORS{'OK'}, 0, "this is a preload reservation, returning states back to original");
# Set the preload flag back to 1 so it will be processed again
if (update_preload_flag($request_id, 1)) {
notify($ERRORS{'OK'}, 0, "updated preload flag to 1");
}
else {
notify($ERRORS{'WARNING'}, 0, "failed to update preload flag to 1");
}
# Set variables for the next states
$next_computer_state = $computer_state_name;
$next_request_state = $request_state_name;
} ## end if ($request_preload_only)
else {
# Perform the steps necessary to prepare the computer for a user
if ($self->reserve_computer()) {
notify($ERRORS{'OK'}, 0, "$computer_short_name with $image_name successfully reserved");
}
else {
# reserve_computer() returned false
notify($ERRORS{'OK'}, 0, "$computer_short_name with $image_name could NOT be reserved");
# Call reservation_failed, problem computer not opened for reservation
$self->reservation_failed("process failed after attempting to reserve the computer");
}
# Set variables for the next states
# Don't change state of computer to reserved yet, reserved.pm will do this after it initializes
# This is done to reduce the delay between when Connect is shown to the user and the firewall is prepared
$next_computer_state = "";
$next_request_state = "reserved";
} ## end else [ if ($request_preload_only)
} ## end if ($request_state_name eq 'new')
elsif ($request_state_name eq 'tovmhostinuse') {
# Set variables for the next states
$next_computer_state = "vmhostinuse";
$next_request_state = "complete";
}
else {
# Set variables for the next states
$next_computer_state = "available";
$next_request_state = "complete";
}
# Update the computer state
if ($next_computer_state) {
if (update_computer_state($computer_id, $next_computer_state)) {
notify($ERRORS{'OK'}, 0, "$computer_short_name state set to '$next_computer_state'");
}
else {
notify($ERRORS{'WARNING'}, 0, "failed to set $computer_short_name state to '$next_computer_state'");
}
}
# Update request state if this is the parent reservation
# Only parent reservations should modify the request state
if ($reservation_is_parent && update_request_state($request_id, $next_request_state, $request_state_name)) {
notify($ERRORS{'OK'}, 0, "request state set to '$next_request_state'/'$request_state_name'");
}
elsif ($reservation_is_parent) {
notify($ERRORS{'CRITICAL'}, 0, "failed to set request state to '$next_request_state'/'$request_state_name'");
notify($ERRORS{'OK'}, 0, "exiting");
exit;
}
else {
notify($ERRORS{'OK'}, 0, "this is a child image, request state NOT changed to '$next_request_state'");
}
# Add nodeready last before process exits, this is used by the cluster parent to determine when child reservations are ready
# Needed for computerloadflow
insertloadlog($reservation_id, $computer_id, "nodeready", "$computer_short_name is loaded with $image_name");
notify($ERRORS{'OK'}, 0, "exiting");
exit;
} ## end sub process