sub create_vmhost_os_object()

in managementnode/lib/VCL/Module.pm [566:695]


sub create_vmhost_os_object {
	my $self = shift;
	unless (ref($self) && $self->isa('VCL::Module')) {
		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
		return;
	}
	
	my $vmhost_identifier = shift;
	
	if (!$vmhost_identifier) {
		# Check if an OS object has already been stored in the calling object
		if (my $vmhost_os = $self->vmhost_os(0)) {
			my $address = sprintf('%x', $vmhost_os);
			notify($ERRORS{'DEBUG'}, 0, "returning existing VM host OS object ($address)");
			return $vmhost_os;
		}
	}
	
	# Make sure calling object isn't an OS module to avoid an infinite loop
	if ($self->isa('VCL::Module::OS')) {
		notify($ERRORS{'WARNING'}, 0, "this subroutine cannot be called from an existing OS module: " . ref($self));
		return;
	}
	
	my $request_data = $self->data->get_request_data();
	my $reservation_id = $self->data->get_reservation_id();
	
	my $vmhost_computer_id;
	my $vmhost_hostname;
	my $vmhost_profile_image_id;
	if ($vmhost_identifier) {
		my $vmhost_info = get_vmhost_info($vmhost_identifier);
		if (!$vmhost_info) {
			notify($ERRORS{'WARNING'}, 0, "unable to create VM host OS object for host specified by argument: $vmhost_identifier, VM host info could not be retrieved");
			return;
		}
		
		$vmhost_computer_id = $vmhost_info->{computerid};
		if (!$vmhost_computer_id) {
			notify($ERRORS{'WARNING'}, 0, "unable to create VM host OS object for host specified by argument: $vmhost_identifier, VM host computer ID could not be determined from VM host info:\n" . format_data($vmhost_info));
			return;
		}
		
		$vmhost_hostname = $vmhost_info->{computer}{hostname};
		if (!$vmhost_hostname) {
			notify($ERRORS{'WARNING'}, 0, "unable to create VM host OS object for host specified by argument: $vmhost_identifier, VM host computer hostname could not be determined from VM host info:\n" . format_data($vmhost_info));
			return;
		}
		
		$vmhost_profile_image_id = $vmhost_info->{vmprofile}{imageid};
		if (!$vmhost_profile_image_id) {
			notify($ERRORS{'WARNING'}, 0, "unable to create VM host OS object for host specified by argument: $vmhost_identifier, VM host profile image ID could not be determined from VM host info:\n" . format_data($vmhost_info));
			return;
		}
	}
	else {
		# Argument was not supplied, use reservation data
		$vmhost_computer_id = $self->data->get_vmhost_computer_id();
		$vmhost_hostname = $self->data->get_vmhost_hostname();
		$vmhost_profile_image_id = $self->data->get_vmhost_profile_image_id();
		if (!$vmhost_computer_id || !$vmhost_hostname || !defined($vmhost_profile_image_id)) {
			notify($ERRORS{'WARNING'}, 0, "unable to create VM host OS object, VM host computer ID, hostname, and profile image ID could not be determined from reservation data");
			return;
		}
	}
	
	# Create a DataStructure object containing computer data for the VM host
	my $vmhost_data;
	eval {
		$vmhost_data = new VCL::DataStructure({
			request_data => $request_data,
			reservation_id => $reservation_id,
			computer_identifier => $vmhost_computer_id,
			image_identifier => $vmhost_profile_image_id
			}
		);
	};
	
	if ($EVAL_ERROR) {
		notify($ERRORS{'WARNING'}, 0, "unable to create DataStructure object for VM host, error: $EVAL_ERROR");
		return;
	}
	elsif (!$vmhost_data) {
		notify($ERRORS{'WARNING'}, 0, "unable to create DataStructure object for VM host, DataStructure object is not defined");
		return;
	}
	
	# Get the VM host OS module Perl package name
	my $vmhost_os_perl_package = $vmhost_data->get_image_os_module_perl_package();
	if (!$vmhost_os_perl_package) {
		notify($ERRORS{'WARNING'}, 0, "unable to create DataStructure or OS object for VM host, failed to retrieve VM host image OS module Perl package name");
		return;
	}
	
	# Do not try to load the UnixLab module for VM hosts -- most likely not the intended OS module
	# TODO: add additional checks here, VM host image may be something like XP
	if ($vmhost_os_perl_package =~ /(UnixLab|2003|XP|Vista)/i || $vmhost_os_perl_package =~ /^VCL::Module::OS$/) {
		my $vmhost_os_perl_package_override = 'VCL::Module::OS::Linux';
		notify($ERRORS{'OK'}, 0, "VM host OS image Perl package is $vmhost_os_perl_package, most likely will not work correctly, changing to Linux");
		$vmhost_os_perl_package = $vmhost_os_perl_package_override;
	}
	
	# Load the VM host OS module
	notify($ERRORS{'DEBUG'}, 0, "attempting to load VM host OS module: $vmhost_os_perl_package (image: $vmhost_profile_image_id)");
	eval "use $vmhost_os_perl_package";
	if ($EVAL_ERROR) {
		notify($ERRORS{'WARNING'}, 0, "VM host OS module could NOT be loaded: $vmhost_os_perl_package, error: $EVAL_ERROR");
		return;
	}
	notify($ERRORS{'DEBUG'}, 0, "VM host OS module loaded: $vmhost_os_perl_package");
	
	# Attempt to create the object
	my $vmhost_os;
	if (my $mn_os = $self->mn_os(0)) {
		$vmhost_os = ($vmhost_os_perl_package)->new({data_structure => $vmhost_data, mn_os => $mn_os});
	}
	else {
		$vmhost_os = ($vmhost_os_perl_package)->new({data_structure => $vmhost_data})
	}
	
	if ($vmhost_os) {
		my $address = sprintf('%x', $vmhost_os);
		notify($ERRORS{'DEBUG'}, 0, "$vmhost_os_perl_package OS object created, address: $address");
		return $vmhost_os;
	}
	else {
		notify($ERRORS{'WARNING'}, 0, "failed to create VM host OS object");
		return;
	}
}