sub reload_image()

in managementnode/lib/VCL/new.pm [452:624]


sub reload_image {
	my $self = shift;

	my $request_state_name              = $self->data->get_request_state_name();
	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 $computer_state_name             = $self->data->get_computer_state_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();
	my $server_request_id               = $self->data->get_server_request_id();
	my $server_request_fixed_ip         = $self->data->get_server_request_fixed_ip();
	
	my $node_status_string;
	insertloadlog($reservation_id, $computer_id, "statuscheck", "checking status of node");
	
	# If request state is 'reinstall' or computer state is 'reload', force reload
	if ($request_state_name eq 'reinstall' || $computer_state_name eq 'reload') {
		$node_status_string = 'reload';
		$computer_state_name = 'reload';
	}
	else {
		$node_status_string = $self->provisioner->node_status() || 'RELOAD';
	}
	
	
	if ($computer_state_name eq 'reload') {
		# Always call load() if state is reload regardless of node_status()
		# Admin-initiated reloads will always cause node to be reloaded
		notify($ERRORS{'OK'}, 0, "request state is $request_state_name, node will be reloaded regardless of status");
		$node_status_string = 'reload';
	}
	
	# Check if the status string returned by node_status = 'ready'
	if ($node_status_string =~ /^ready/i) {
		# node_status returned 'ready'
		notify($ERRORS{'OK'}, 0, "node_status returned '$node_status_string', $computer_short_name will not be reloaded");
	}
	elsif ($node_status_string =~ /^post_load/i) {
		notify($ERRORS{'OK'}, 0, "node_status returned '$node_status_string', OS post_load tasks will be performed on $computer_short_name");
		
		# Check if the OS module implements a post_load subroutine
		if ($self->os->can('post_load')) {
			if ($self->os->post_load()) {
				$node_status_string = 'READY';
				
				# Add a line to currentimage.txt indicating post_load has run
				$self->os->set_post_load_status();
			}
			else {
				notify($ERRORS{'WARNING'}, 0, "failed to execute OS module's post_load() subroutine, $computer_short_name will be reloaded");
				$node_status_string = 'POST_LOAD_FAILED';
			}
		}
		else {
			$node_status_string = 'READY';
			notify($ERRORS{'WARNING'}, 0, "provisioning module's node_status subroutine returned '$node_status_string' but OS module " . ref($self->os) . " does not implement a post_load() subroutine, $computer_short_name will not be reloaded");
		}
	}
	
	# Provisioning module's node_status subroutine did not return 'ready'
	if ($node_status_string !~ /^ready/i) {
		notify($ERRORS{'OK'}, 0, "node status is $node_status_string, $computer_short_name will be reloaded");
		insertloadlog($reservation_id, $computer_id, "loadimageblade", "$computer_short_name must be reloaded with $image_name");
		
		# Make sure provisioning module's load() subroutine exists
		if (!$self->provisioner->can("load")) {
			notify($ERRORS{'CRITICAL'}, 0, ref($self->provisioner) . "->load() subroutine does not exist, returning");
			insertloadlog($reservation_id, $computer_id, "failed", ref($self->provisioner) . "->load() subroutine does not exist");
			return;
		}
		
		# Update the computer state to reloading
		if (update_computer_state($computer_id, "reloading")) {
			notify($ERRORS{'OK'}, 0, "computer $computer_short_name state set to reloading");
			insertloadlog($reservation_id, $computer_id, "info", "computer state updated to reloading");
		}
		else {
			notify($ERRORS{'CRITICAL'}, 0, "unable to set $computer_short_name into reloading state, returning");
			insertloadlog($reservation_id, $computer_id, "failed", "unable to set computer $computer_short_name state to reloading");
			return;
		}
		
		# Make sure the image exists on this management node's local disks
		# Attempt to retrieve it if necessary
		if ($self->provisioner->can("does_image_exist")) {
			notify($ERRORS{'DEBUG'}, 0, "calling " . ref($self->provisioner) . "->does_image_exist()");
			
			if ($self->provisioner->does_image_exist($image_name)) {
				notify($ERRORS{'OK'}, 0, "$image_name exists on this management node");
				# Needed for computerloadflow	
				insertloadlog($reservation_id, $computer_id, "doesimageexists", "confirmed image exists");
			}
			else {
				notify($ERRORS{'OK'}, 0, "$image_name does not exist on this management node");
				insertloadlog($reservation_id, $computer_id, "doesimageexists", "confirmed image exists");
				
				# Try to retrieve the image files from another management node
				if ($self->provisioner->can("retrieve_image")) {
					notify($ERRORS{'DEBUG'}, 0, "calling " . ref($self->provisioner) . "->retrieve_image()");
					
					if ($self->provisioner->retrieve_image($image_name)) {
						notify($ERRORS{'OK'}, 0, "$image_name was retrieved from another management node");
						# Needed for computerloadflow	
						insertloadlog($reservation_id, $computer_id, "copyfrompartnerMN", "Retrieving image");
					}
					else {
						notify($ERRORS{'CRITICAL'}, 0, "$image_name does not exist on management node and could not be retrieved");
						insertloadlog($reservation_id, $computer_id, "failed", "requested image does not exist on management node and could not be retrieved");
						$self->reservation_failed("$image_name does not exist unable to retrieve image from another management node", "available");
					}
				} ## end if ($self->provisioner->can("retrieve_image"...
				else {
					notify($ERRORS{'CRITICAL'}, 0, "unable to retrieve image from another management node, retrieve_image() is not implemented by " . ref($self->provisioner));
					insertloadlog($reservation_id, $computer_id, "failed", "failed requested image does not exist on management node, retrieve_image() is not implemented");
					$self->reservation_failed("$image_name does not exist", "available");
				}
			} ## end else [ if ($self->provisioner->does_image_exist($image_name...
		} ## end if ($self->provisioner->can("does_image_exist"...
		else {
			notify($ERRORS{'OK'}, 0, "unable to check if image exists, does_image_exist() not implemented by " . ref($self->provisioner));
		}
		
		# OS currently installed on computer may not be the same type as $self->os
		# Attempt to create a new OS object representing OS currently installed and check if that object implements a 'pre_reload' subroutine
		if ($self->os->is_ssh_responding()) {
			my $computer_current_os = $self->create_current_os_object($computer_id, 1);
			if ($computer_current_os) {
				$computer_current_os->pre_reload();
			}
		}
		
		# Call provisioning module's load() subroutine
		notify($ERRORS{'OK'}, 0, "calling " . ref($self->provisioner) . "->load() subroutine");
		insertloadlog($reservation_id, $computer_id, "info", "calling " . ref($self->provisioner) . "->load() subroutine");
		if ($self->provisioner->load()) {
			# Add a line to currentimage.txt indicating post_load has run
			$self->os->set_post_load_status();
			
			notify($ERRORS{'OK'}, 0, "$image_name was successfully reloaded on $computer_short_name");
			insertloadlog($reservation_id, $computer_id, "loadimagecomplete", "$image_name was successfully reloaded on $computer_short_name");
		}
		else {
			notify($ERRORS{'WARNING'}, 0, "$image_name failed to load on $computer_short_name, returning");
			insertloadlog($reservation_id, $computer_id, "loadimagefailed", "$image_name failed to load on $computer_short_name");
			return;
		}
	}
	
	# Update the current image ID in the computer table
	if (update_currentimage($computer_id, $image_id, $imagerevision_id)) {
		notify($ERRORS{'OK'}, 0, "updated computer table for $computer_short_name: currentimageid=$image_id");
	}
	else {
		notify($ERRORS{'WARNING'}, 0, "failed to update computer table for $computer_short_name: currentimageid=$image_id");
	}
	
	if ($server_request_id) {
		notify($ERRORS{'DEBUG'}, 0, "  SERVER_REQUEST_ID detected");
		if ($server_request_fixed_ip) {
			notify($ERRORS{'DEBUG'}, 0, "server_request_fixed_ip is set calling update_public_ip_address");
			if (!$self->os->server_request_set_fixed_ip()) {
				notify($ERRORS{'WARNING'}, 0, "failed to update IP address for $computer_short_name");
				insertloadlog($reservation_id, $computer_id, "failed", "unable to set public IP address on $computer_short_name possibly IP address is inuse");
				return;
			}
		}
	}	
	
	notify($ERRORS{'OK'}, 0, "returning 1");
	return 1;
} ## end sub reload_image