sub node_status()

in managementnode/lib/VCL/Module/Provisioning/openstack.pm [416:583]


sub node_status {
	my $self;

	# Get the argument
	my $argument = shift;

	# Check if this subroutine was called an an object method or an argument was passed
	if (ref($argument) =~ /VCL::Module/i) {
		$self = $argument;
	}
	elsif (!ref($argument) || ref($argument) eq 'HASH') {
		# An argument was passed, check its type and determine the computer ID
		my $computer_id;
		if (ref($argument)) {
			# Hash reference was passed
			$computer_id = $argument->{id};
		}
		elsif ($argument =~ /^\d+$/) {
			# Computer ID was passed
			$computer_id = $argument;
		}
		else {
			# Computer name was passed
			($computer_id) = get_computer_ids($argument);
		}

		if ($computer_id) {
			notify($ERRORS{'DEBUG'}, 0, "computer ID: $computer_id");
		}

		else {
			notify($ERRORS{'WARNING'}, 0, "unable to determine computer ID from argument:\n" . format_data($argument));
			return;
		}

		# Create a DataStructure object containing data for the computer specified as the argument
		my $data;
		eval {
			$data= new VCL::DataStructure({computer_identifier => $computer_id});
		};
		if ($EVAL_ERROR) {
			notify($ERRORS{'WARNING'}, 0, "failed to create DataStructure object for computer ID: $computer_id, error: $EVAL_ERROR");
			return;
		}
		elsif (!$data) {
			notify($ERRORS{'WARNING'}, 0, "failed to create DataStructure object for computer ID: $computer_id, DataStructure object is not defined");
			return;
		}
		else {
			notify($ERRORS{'DEBUG'}, 0, "created DataStructure object  for computer ID: $computer_id");
		}

		# Create a VMware object
		my $object_type = 'VCL::Module::Provisioning::openstack';
		if ($self = ($object_type)->new({data_structure => $data})) {
			notify($ERRORS{'DEBUG'}, 0, "created $object_type object to check the status of computer ID: $computer_id");
		}
		else {
			notify($ERRORS{'WARNING'}, 0, "failed to create $object_type object to check the status of computer ID: $computer_id");
			return;
		}

		# Create an OS object for the VMware object to access
		if (!$self->create_os_object()) {
			notify($ERRORS{'WARNING'}, 0, "failed to create OS object");
			return;
		}
	}

	my $reservation_id = $self->data->get_reservation_id();
	my $computer_name = $self->data->get_computer_node_name();
	my $image_name = $self->data->get_image_name();
	my $request_forimaging = $self->data->get_request_forimaging();
	my $imagerevision_id = $self->data->get_imagerevision_id();
	my $computer_private_ip_address = $self->data->get_computer_private_ip_address();


	notify($ERRORS{'DEBUG'}, 0, "attempting to check the status of computer $computer_name, image: $image_name");

	# Create a hash reference and populate it with the default values
	my $status;
	$status->{currentimage} = '';
	$status->{ssh} = 0;
	$status->{image_match} = 0;
	$status->{status} = 'RELOAD';

	# Check if node is pingable and retrieve the power status if the reservation ID is 0
	# The reservation ID will be 0 is this subroutine was not called as an object method, but with a computer ID argument
	# The reservation ID will be 0 when called from healthcheck.pm
	# The reservation ID will be > 0 if called from a normal VCL reservation
	# Skip the ping and power status checks for a normal reservation to speed things up
	if (!$reservation_id) {
		if (_pingnode($computer_private_ip_address)) {
			notify($ERRORS{'DEBUG'}, 0, "VM $computer_name is pingable");
			$status->{ping} = 1;
		}
		else {
			notify($ERRORS{'DEBUG'}, 0, "VM $computer_name is not pingable");
			$status->{ping} = 0;
		}

	}

	notify($ERRORS{'DEBUG'}, 0, "Trying to ssh...");
	# Check if SSH is available
	if ($self->os->is_ssh_responding()) {
		notify($ERRORS{'DEBUG'}, 0, "VM $computer_name is responding to SSH");
		$status->{ssh} = 1;
	}
	else {
		notify($ERRORS{'OK'}, 0, "VM $computer_name is not responding to SSH, returning 'RELOAD'");
		$status->{status} = 'RELOAD';
		$status->{ssh} = 0;

		# Skip remaining checks if SSH isn't available
		return $status;
	}

	my $current_image_revision_id = $self->os->get_current_imagerevision_id();
	$status->{currentimagerevision_id} = $current_image_revision_id;

	$status->{currentimage} = $self->data->get_computer_currentimage_name();
	my $current_image_name = $status->{currentimage};
	my $vcld_post_load_status = $self->os->get_post_load_status();

	if (!$current_image_revision_id) {
		notify($ERRORS{'OK'}, 0, "unable to retrieve image name from currentimage.txt on VM $computer_name, returning 'RELOAD'");
		return $status;
	}
	elsif ($current_image_revision_id eq $imagerevision_id) {
		notify($ERRORS{'OK'}, 0, "currentimage.txt image $current_image_revision_id ($current_image_name) matches requested imagerevision_id $imagerevision_id  on VM $computer_name");
		$status->{image_match} = 1;
	}
	else {
		notify($ERRORS{'OK'}, 0, "currentimage.txt imagerevision_id $current_image_revision_id ($current_image_name) does not match requested imagerevision_id $imagerevision_id on VM $computer_name, returning 'RELOAD'");
		return $status;
	}


	# Determine the overall machine status based on the individual status results
	if ($status->{ssh} && $status->{image_match}) {
		$status->{status} = 'READY';
	}
	else {
		$status->{status} = 'RELOAD';
	}

	notify($ERRORS{'DEBUG'}, 0, "status set to $status->{status}");


	if ($request_forimaging) {
		$status->{status} = 'RELOAD';
		notify($ERRORS{'OK'}, 0, "request_forimaging set, setting status to RELOAD");
	}

	if ($vcld_post_load_status) {
		notify($ERRORS{'DEBUG'}, 0, "OS module post_load tasks have been completed on VM $computer_name");
		$status->{status} = 'READY';
	}
	else {
		notify($ERRORS{'OK'}, 0, "OS module post_load tasks have not been completed on VM $computer_name, returning 'POST_LOAD'");
		$status->{status} = 'POST_LOAD';
	}

	notify($ERRORS{'DEBUG'}, 0, "returning node status hash reference (\$node_status->{status}=$status->{status})");
	return $status;

} ## end sub node_status