You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by ar...@apache.org on 2010/10/28 19:17:55 UTC

svn commit: r1028392 - in /incubator/vcl/trunk/managementnode/lib/VCL: DataStructure.pm Module.pm Module/OS.pm Module/Provisioning.pm Module/State.pm utils.pm

Author: arkurth
Date: Thu Oct 28 17:17:54 2010
New Revision: 1028392

URL: http://svn.apache.org/viewvc?rev=1028392&view=rev
Log:
VCL-394
Updated core modules to allow a DataStructure and provisioning object to be created without a corresponding reservation.  This allows provisioning modules to implement a node_status which can be called as a regular non-object function, while the node_status subroutine uses the DataStructure and other object-oriented functions in the same manner as normal reservations.

Updated DataStructure.pm to allow objects to be created by passing an imagerevision ID.  Updated this module to populate the image and imagerevision data if it was passed an image, imagerevision, or computer ID argument.

Moved subroutines from set_os and os subroutines from Provisioning.pm to Module.pm.  Moved set_provisioner and provisioner subroutines to Module.pm.  This allows them to be available to all types of modules.

Added Module.pm::create_provisioning_object and create_os_object.  These are called by State.pm::initialize rather than having the code directly in State.pm::initialize.  This allows other objects to create an OS or provisioning object if necessary.

Other
Updated DataStructure.pm::get_reservation_info_string to display additional data.

Removed utils.pm::getdynamicaddress.  It has been replaced by code in the OS modules.

Updated utils.pm::get_computer_info to add the VM host data under the 'computer' key in the hash it returns.  This allows the data it returns to match get_request_info.

Modified:
    incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm
    incubator/vcl/trunk/managementnode/lib/VCL/Module.pm
    incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm
    incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm
    incubator/vcl/trunk/managementnode/lib/VCL/Module/State.pm
    incubator/vcl/trunk/managementnode/lib/VCL/utils.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=1028392&r1=1028391&r2=1028392&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm Thu Oct 28 17:17:54 2010
@@ -489,7 +489,7 @@ $SUBROUTINE_MAPPINGS{management_node_pre
 
 =cut
 
-my @request_id : Field : Arg('Name' => 'request_id') : Type(scalar) : Get('Name' => 'request_id', 'Private' => 1);
+my @request_id : Field : Arg('Name' => 'request_id', 'Default' => 0) : Type(scalar) : Get('Name' => 'request_id', 'Private' => 1);
 
 =head3 @reservation_id
 
@@ -498,7 +498,7 @@ my @request_id : Field : Arg('Name' => '
 
 =cut
 
-my @reservation_id : Field : Arg('Name' => 'reservation_id') : Type(scalar) : Get('Name' => 'reservation_id', 'Private' => 1);
+my @reservation_id : Field : Arg('Name' => 'reservation_id', 'Default' => 0) : Type(scalar) : Get('Name' => 'reservation_id', 'Private' => 1);
 
 =head3 @blockrequest_id
 
@@ -555,6 +555,15 @@ my @computer_id : Field : Arg('Name' => 
 
 my @image_id : Field : Arg('Name' => 'image_id') : Type(scalar) : Get('Name' => 'image_id', 'Private' => 1);
 
+=head3 @imagerevision_id
+
+ Data type   : array of scalars
+ Description :
+
+=cut
+
+my @imagerevision_id : Field : Arg('Name' => 'imagerevision_id') : Type(scalar) : Get('Name' => 'imagerevision_id', 'Private' => 1);
+
 ##############################################################################
 
 =head1 PRIVATE OBJECT METHODS
@@ -587,15 +596,27 @@ sub _initialize : Init {
 	# If not deep copied, the separate objects will alter each other's data
 	$self->refresh_request_data(dclone($self->request_data)) if $self->request_data;
 	
+	# Set the request and reservation IDs in the request data hash if they are undefined
+	$self->request_data->{id} = ($self->request_id || 0) if (!defined($self->request_data->{id}));
+	$self->request_data->{RESERVATIONID} = ($self->reservation_id || 0) if (!defined($self->request_data->{RESERVATIONID}));
+	
+	my $computer_id = $self->computer_id;
+	my $image_id = $self->image_id;
+	my $imagerevision_id = $self->imagerevision_id;
+	
 	# Get the computer info if the computer_id argument was specified and add it to this object
-	if ($self->computer_id) {
-		my $vmhost_info_save = $self->request_data->{reservation}{$self->reservation_id}{computer}{vmhost};
+	if ($computer_id) {
+		my $vmhost_info_save;
+		if (defined($self->request_data->{reservation}{$self->reservation_id}{computer}{vmhost})) {
+			$vmhost_info_save = $self->request_data->{reservation}{$self->reservation_id}{computer}{vmhost};
+		}
 		
 		notify($ERRORS{'DEBUG'}, 0, "computer ID argument was specified, retrieving data for computer ID: " . $self->computer_id);
 		my $computer_info = get_computer_info($self->computer_id);
 		if (!$computer_info) {
 			notify($ERRORS{'WARNING'}, 0, "DataStructure object could not be initialized, failed to retrieve data for computer ID: " . $self->computer_id);
 			
+			# Throw an exception because simply returning undefined (return;) does not result in this DataStructure object being undefined
 			Exception::Class::Base->throw( error => "DataStructure object could not be initialized, failed to retrieve data for computer ID: " . $self->computer_id);
 			return;
 		}
@@ -609,27 +630,55 @@ sub _initialize : Init {
 		$self->request_data->{reservation}{$self->reservation_id}{computer} = $computer_info->{computer};
 	}
 	
-	# Get the image and imagerevision info if the image_id argument was specified
-	if ($self->image_id) {
-		my %image_info = get_image_info($self->image_id);
-		if (%image_info) {
-			$self->request_data->{reservation}{$self->reservation_id}{image} = \%image_info;
+	
+	# If either the computer ID, image ID, or imagerevision ID arguments are specified, retrieve appropriate image and imagerevision data
+	if ($imagerevision_id || $image_id || $computer_id) {
+		my %imagerevision_info;
+		
+		if ($imagerevision_id) {
+			notify($ERRORS{'DEBUG'}, 0, "imagerevision ID argument was specified: $imagerevision_id, DataStructure object will contain image information for this imagerevision ID: $imagerevision_id");
+			%imagerevision_info = get_imagerevision_info($imagerevision_id);
 		}
-		else {
-			notify($ERRORS{'WARNING'}, 0, "DataStructure object could not be initialized, failed to retrieve data for image ID: " . $self->image_id);
-			
-			Exception::Class::Base->throw( error => "DataStructure object could not be initialized, failed to retrieve data for image ID: " . $self->image_id);
-			return;
+		
+		elsif ($image_id) {
+			notify($ERRORS{'DEBUG'}, 0, "image ID argument was specified: $image_id, DataStructure object will contain image information for the production imagerevision of this image");
+			%imagerevision_info = get_production_imagerevision_info($image_id);
+		}
+		
+		elsif ($computer_id) {
+			if ($imagerevision_id = $self->get_computer_imagerevision_id()) {
+				notify($ERRORS{'DEBUG'}, 0, "computer ID argument was specified ($computer_id) but image and imagerevision ID arguments were not, DataStructure object will contain image information for the computer's current imagerevision ID: $imagerevision_id");
+			}
+			else {
+				Exception::Class::Base->throw( error => "DataStructure object could not be initialized, computer's current imagerevision ID could not be retrieved from the current DataStructure data:\n" . format_data($self->get_request_data));
+				return;
+			}
+			%imagerevision_info = get_imagerevision_info($imagerevision_id);
 		}
 		
-		my %imagerevision_info = get_production_imagerevision_info($self->image_id);
 		if (%imagerevision_info) {
+			$imagerevision_id = $imagerevision_info{id};
+			notify($ERRORS{'DEBUG'}, 0, "retrieved data for imagerevision ID: $imagerevision_id");
 			$self->request_data->{reservation}{$self->reservation_id}{imagerevision} = \%imagerevision_info;
 		}
 		else {
-			notify($ERRORS{'WARNING'}, 0, "DataStructure object could not be initialized, failed to retrieve production imagerevision data for image ID: " . $self->image_id);
-			
-			Exception::Class::Base->throw( error => "DataStructure object could not be initialized, failed to retrieve production imagerevision data for image ID: " . $self->image_id);
+			Exception::Class::Base->throw( error => "DataStructure object could not be initialized, failed to retrieve imagerevision data: ");
+			return;
+		}
+		
+		$image_id = $imagerevision_info{imageid};
+		if (!defined($image_id)) {
+			Exception::Class::Base->throw( error => "DataStructure object could not be initialized, failed to retrieve image ID from the imagerevision data retrieved for imagerevision ID $imagerevision_id:\n" . format_data(\%imagerevision_info));
+			return;
+		}
+		
+		my %image_info = get_image_info($image_id);
+		if (%image_info) {
+			notify($ERRORS{'DEBUG'}, 0, "retrieved data for image ID: $image_id");
+			$self->request_data->{reservation}{$self->reservation_id}{image} = \%image_info;
+		}
+		else {
+			Exception::Class::Base->throw( error => "DataStructure object could not be initialized, failed to retrieve data for image ID: " . $self->image_id);
 			return;
 		}
 	}
@@ -698,17 +747,17 @@ sub _automethod : Automethod {
 
 	# Replace RESERVATION_ID with the actual reservation ID if it exists in the hash path
 	my $reservation_id = $self->reservation_id;
-	$reservation_id = 'undefined' if !$reservation_id;
+	$reservation_id = 'undefined' if !defined($reservation_id);
 	$hash_path =~ s/RESERVATION_ID/$reservation_id/;
 
 	# Replace BLOCKREQUEST_ID with the actual blockrequest ID if it exists in the hash path
 	my $blockrequest_id = $self->blockrequest_id;
-	$blockrequest_id = 'undefined' if !$blockrequest_id;
+	$blockrequest_id = 'undefined' if !defined($blockrequest_id);
 	$hash_path =~ s/BLOCKREQUEST_ID/$blockrequest_id/;
 
 	# Replace BLOCKTIME_ID with the actual blocktime ID if it exists in the hash path
 	my $blocktime_id = $self->blocktime_id;
-	$$blocktime_id = 'undefined' if !$blocktime_id;
+	$blocktime_id = 'undefined' if !defined($blocktime_id);
 	$hash_path =~ s/BLOCKTIME_ID/$blocktime_id/;
 
 	if ($mode =~ /get/) {
@@ -2286,38 +2335,79 @@ sub get_reservation_info_string {
 	}
 
 	my $string;
-	$string .= "request: " . $self->get_request_id() . "\n";
-	$string .= "reservation: " . $self->get_reservation_id() . "\n";
-	$string .= "state/laststate: " . $self->get_request_state_name() . "/" . $self->get_request_laststate_name() . "\n";
+	
+	$string .= "management node: " . (defined($_ = $self->get_management_node_hostname(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "reservation process PID: $PID\n";
+	$string .= "parent vcld process PID: " . (defined($_ = getppid()) ? $_ : '<undefined>') . "\n";
+	
 	$string .= "\n";
 	
-	$string .= "management node: " . $self->get_management_node_hostname() . "\n";
-	$string .= "PID: $PID\n";
+	$string .= "request ID: " . (defined($_ = $self->get_request_id(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "reservation ID: " . (defined($_ = $self->get_reservation_id(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "request state/laststate: " . (defined($_ = $self->get_request_state_name(0)) ? $_ : '<undefined>') . "/" . (defined($_ = $self->get_request_laststate_name(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "request start time: " . (defined($_ = $self->get_request_start_time(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "request end time: " . (defined($_ = $self->get_request_end_time(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "reservation count: " . (defined($_ = $self->get_request_reservation_count(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "parent reservation: " . (defined($_ = $self->get_request_is_cluster_parent(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "for imaging: " . (defined($_ = $self->get_request_forimaging(0)) ? ($_ ? 'yes' : 'no') : '<undefined>') . "\n";
+	$string .= "log ID: " . (defined($_ = $self->get_request_log_id(0)) ? $_ : '<undefined>') . "\n";
+	
+	$string .= "\n";
+	
+	$string .= "user ID: " . (defined($_ = $self->get_user_id(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "user name: " . (defined($_ = $self->get_user_firstname(0)) ? $_ : '<undefined>') . " " . (defined($_ = $self->get_user_lastname(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "user login ID: " . (defined($_ = $self->get_user_login_id(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "user affiliation: " . (defined($_ = $self->get_user_affiliation_name(0)) ? $_ : '<undefined>') . "\n";
+	
 	$string .= "\n";
 	
-	$string .= "computer name: " . $self->get_computer_host_name() . " (id: " . $self->get_computer_id() . ")\n";
-	my $computer_type = $self->get_computer_type();
-	$string .= "computer type: $computer_type\n";
+	$string .= "computer id: " . (defined($_ = $self->get_computer_id(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "computer name: " . (defined($_ = $self->get_computer_hostname(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "computer type: " . (defined($_ = $self->get_computer_type(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "computer eth0 MAC address: " . (defined($_ = $self->get_computer_eth0_mac_address(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "computer eth1 MAC address: " . (defined($_ = $self->get_computer_eth1_mac_address(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "computer private IP address: " . (defined($_ = $self->get_computer_private_ip_address(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "computer public IP address: " . (defined($_ = $self->get_computer_ip_address(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "computer in block allocation: " . (defined($_ = is_inblockrequest($self->get_computer_id(0))) ? ($_ ? 'yes' : 'no') : '<undefined>') . "\n";
+	
 	$string .= "\n";
 	
-	if ($computer_type eq 'virtualmachine') {
-		$string .= "vm host: " . $self->get_vmhost_hostname() . " (vmhost id: " . $self->get_vmhost_id() . ")\n";
-		$string .= "vm host profile: " . $self->get_vmhost_profile_name() . "\n";
+	$string .= "provisioning module name: " . (defined($_ = $self->get_computer_provisioning_module_pretty_name(0)) ? $_ : '<undefined>') . " (" . (defined($_ = $self->get_computer_provisioning_module_name(0)) ? $_ : '<undefined>') . ")\n";
+	$string .= "provisioning module Perl package: " . (defined($_ = $self->get_computer_provisioning_module_perl_package(0)) ? $_ : '<undefined>') . "\n";
+	
+	if ((defined($_ = $self->get_computer_type(0)) ? $_ : '<undefined>') eq 'virtualmachine') {
 		$string .= "\n";
+		$string .= "vm host ID: " . (defined($_ = $self->get_vmhost_id(0)) ? $_ : '<undefined>') . "\n";
+		$string .= "vm host computer ID: " . (defined($_ = $self->get_vmhost_computer_id(0)) ? $_ : '<undefined>') . "\n";
+		$string .= "vm host name: " . (defined($_ = $self->get_vmhost_hostname(0)) ? $_ : '<undefined>') . "\n";
+		$string .= "vm profile: " . (defined($_ = $self->get_vmhost_profile_name(0)) ? $_ : '<undefined>') . "\n";
+		$string .= "vm profile VM path: " . (defined($_ = $self->get_vmhost_profile_vmpath(0)) ? $_ : '<undefined>') . "\n";
+		$string .= "vm profile repository path: " . (defined($_ = $self->get_vmhost_profile_repository_path(0)) ? $_ : '<undefined>') . "\n";
+		$string .= "vm profile datastore path: " . (defined($_ = $self->get_vmhost_profile_datastore_path(0)) ? $_ : '<undefined>') . "\n";
+		$string .= "vm profile disk type: " . (defined($_ = $self->get_vmhost_profile_vmdisk(0)) ? $_ : '<undefined>') . "\n";
 	}
 	
-	$string .= "user name: " . $self->get_user_login_id() . " (id: " . $self->get_user_id() . ")\n";
-	$string .= "user affiliation: " . $self->get_user_affiliation_name() . "\n";
 	$string .= "\n";
 	
-	$string .= "image: " . $self->get_image_name() . " (id: " . $self->get_image_id() . ")\n";
-	$string .= "image prettyname: " . $self->get_image_prettyname() . "\n";
-	$string .= "image size: " . $self->get_image_size() . "\n";
-	$string .= "image affiliation: " . $self->get_image_affiliation_name() . "\n";
-	$string .= "image revision ID: " . $self->get_imagerevision_id() . "\n";
-	$string .= "image revision comments: " . ($self->get_imagerevision_comments(0) || 'none') . "\n";
-	$string .= "image revision created: " . $self->get_imagerevision_date_created() . "\n";
-	$string .= "image revision production: " . $self->get_imagerevision_production();
+	$string .= "image ID: " . (defined($_ = $self->get_image_id(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "image revision ID: " . (defined($_ = $self->get_imagerevision_id(0)) ? $_ : '<undefined>') . "\n";
+	
+	$string .= "image name: " . (defined($_ = $self->get_image_name(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "image display name: " . (defined($_ = $self->get_image_prettyname(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "image size: " . (defined($_ = $self->get_image_size(0)) ? $_ : '<undefined>') . " MB\n";
+	$string .= "use Sysprep: " . (defined($_ = $self->get_imagemeta_sysprep(0)) ? ($_ ? 'yes' : 'no') : '<undefined>') . "\n";
+	$string .= "root access: " . (defined($_ = $self->get_imagemeta_rootaccess(0)) ? ($_ ? 'yes' : 'no') : '<undefined>') . "\n";
+	$string .= "image owner affiliation: " . (defined($_ = $self->get_image_affiliation_name(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "image revision date created: " . (defined($_ = $self->get_imagerevision_date_created(0)) ? $_ : '<undefined>') . "\n";
+	$string .= "image revision production: " . (defined($_ = $self->get_imagerevision_production(0)) ? ($_ ? 'yes' : 'no') : '<undefined>') . "\n";
+	$string .= "image revision comments: " . (defined($_ = $self->get_imagerevision_comments(0)) ? $_ : '<undefined>') . "\n";
+	
+	$string .= "\n";
+	
+	$string .= "OS module name: " . (defined($_ = $self->get_image_os_module_pretty_name(0)) ? $_ : '<undefined>') . " (" . (defined($_ = $self->get_image_os_module_name(0)) ? $_ : '<undefined>') . ")\n";
+	$string .= "OS module Perl package: " . (defined($_ = $self->get_image_os_module_perl_package(0)) ? $_ : '<undefined>') . "\n";
+	
+	$string .= "\n";
 	
 	return $string;
 }

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module.pm?rev=1028392&r1=1028391&r2=1028392&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module.pm Thu Oct 28 17:17:54 2010
@@ -130,11 +130,9 @@ use VCL::Module::Semaphore;
 sub new {
 	my $class = shift;
 	my $args  = shift;
-
-	notify($ERRORS{'DEBUG'}, 0, "$class constructor called");
 	
 	# Create a variable to store the newly created class object
-	my $class_object;
+	my $self;
 	
 	# Make sure the data structure was passed as an argument called 'data_structure'
 	if (!defined $args->{data_structure}) {
@@ -149,20 +147,39 @@ sub new {
 	}
 	
 	# Add the DataStructure reference to the class object
-	$class_object->{data} = $args->{data_structure};
+	$self->{data} = $args->{data_structure};
 
 	# Bless the object as the class which new was called with
-	bless $class_object, $class;
-	notify($ERRORS{'DEBUG'}, 0, "$class object created");
+	bless $self, $class;
+	
+	# Get the memory address of this newly created object - useful for debugging object creation problems
+	my $address = sprintf('%x', $self);
+	
+	# Display a message based on the type of object created
+	if ($self->isa('VCL::Module::State')) {
+		my $request_state_name = $self->data->get_request_state_name(0) || '<not set>';
+		notify($ERRORS{'DEBUG'}, 0, ref($self) . " object created for state $request_state_name, address: $address");
+	}
+	elsif ($self->isa('VCL::Module::OS')) {
+		my $image_name = $self->data->get_image_name(0) || '<not set>';
+		notify($ERRORS{'DEBUG'}, 0, ref($self) . " object created for image $image_name, address: $address");
+	}
+	elsif ($self->isa('VCL::Module::Provisioning')) {
+		my $computer_name = $self->data->get_computer_short_name(0) || '<not set>';
+		notify($ERRORS{'DEBUG'}, 0, ref($self) . " object created for computer $computer_name, address: $address");
+	}
+	else {
+		notify($ERRORS{'DEBUG'}, 0, ref($self) . " object created, address: $address");
+	}
 
 	# Check if not running in setup mode and if initialize() subroutine is defined for this module
-	if (!$SETUP_MODE && $class_object->can("initialize")) {
+	if (!$SETUP_MODE && $self->can("initialize")) {
 		# Call the initialize() subroutine, if it returns 0, return 0
 		# If it doesn't return 0, return the object reference
-		return if (!$class_object->initialize($args));
+		return if (!$self->initialize($args));
 	}
 
-	return $class_object;
+	return $self;
 } ## end sub new
 
 ##############################################################################
@@ -204,6 +221,205 @@ sub data {
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 create_os_object
+
+ Parameters  : None
+ Returns     : boolean
+ Description : Creates an OS object if one has not already been created for the
+               calling object.
+
+=cut
+
+sub create_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;
+	}
+	
+	# 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");
+		return;
+	}
+	
+	# Check if an OS object has already been stored in the calling object
+	if ($self->{os}) {
+		my $os_address = sprintf('%x', $self->{os});
+		my $os_image_name = $self->{os}->data->get_image_name();
+		notify($ERRORS{'DEBUG'}, 0, "OS object has already been created for $os_image_name, address: $os_address, returning 1");
+		return 1;
+	}
+	
+	# Get the Perl package for the OS
+	my $os_perl_package = $self->data->get_image_os_module_perl_package();
+	if (!$os_perl_package) {
+		notify($ERRORS{'WARNING'}, 0, "OS object could not be created, OS module Perl package could not be retrieved");
+		return;
+	}
+	
+	# Attempt to load the OS module
+	eval "use $os_perl_package";
+	if ($EVAL_ERROR) {
+		notify($ERRORS{'WARNING'}, 0, "$os_perl_package module could not be loaded, returning 0");
+		return 0;
+	}
+	notify($ERRORS{'DEBUG'}, 0, "$os_perl_package module loaded");
+	
+	# Attempt to create the object
+	if (my $os = ($os_perl_package)->new({data_structure => $self->data})) {
+		my $os_address = sprintf('%x', $os);
+		my $os_image_name = $os->data->get_image_name();
+		notify($ERRORS{'OK'}, 0, "$os_perl_package OS object created for $os_image_name, address: $os_address");
+		$self->set_os($os);
+		return 1;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to create OS object");
+		return;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 create_provisioning_object
+
+ Parameters  : None
+ Returns     : 
+ Description : 
+
+=cut
+
+sub create_provisioning_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;
+	}
+	
+	# Make sure calling object isn't a provisioning module to avoid an infinite loop
+	if ($self->isa('VCL::Module::Provisioning')) {
+		notify($ERRORS{'WARNING'}, 0, "this subroutine cannot be called from an existing provisioning module");
+		return;
+	}
+	
+	# Check if an OS object has already been stored in the calling object
+	if ($self->{provisioner}) {
+		my $address = sprintf('%x', $self->{provisioner});
+		my $provisioner_computer_name = $self->{provisioner}->data->get_computer_short_name();
+		notify($ERRORS{'DEBUG'}, 0, "provisioning object has already been created, address: $address, returning 1");
+		return 1;
+	}
+	
+	# Get the Perl package for the provisioning module
+	my $provisioning_perl_package = $self->data->get_computer_provisioning_module_perl_package();
+	if (!$provisioning_perl_package) {
+		notify($ERRORS{'WARNING'}, 0, "provisioning object could not be created, provisioning module Perl package could not be retrieved");
+		return;
+	}
+	
+	# Attempt to load the computer provisioning module
+	eval "use $provisioning_perl_package";
+	if ($EVAL_ERROR) {
+		notify($ERRORS{'WARNING'}, 0, "$provisioning_perl_package module could not be loaded, returning 0");
+		return 0;
+	}
+	notify($ERRORS{'DEBUG'}, 0, "$provisioning_perl_package module loaded");
+
+	# Create provisioner object
+	if (my $provisioner = ($provisioning_perl_package)->new({data_structure => $self->data})) {
+		my $provisioner_address = sprintf('%x', $provisioner);
+		my $provisioner_computer_name = $provisioner->data->get_computer_short_name();
+		notify($ERRORS{'OK'}, 0, "$provisioning_perl_package provisioner object created for $provisioner_computer_name, address: $provisioner_address");
+		$self->set_provisioner($provisioner);
+		return 1;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "provisioning object could not be created, returning 0");
+		return 0;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 os
+
+ Parameters  : None
+ Returns     : Process's OS object
+ Description : Allows provisioning modules to access the reservation's OS
+               object.
+
+=cut
+
+sub os {
+	my $self = shift;
+	
+	if (!$self->{os}) {
+		notify($ERRORS{'WARNING'}, 0, "unable to return OS object, \$self->{os} is not set");
+		return;
+	}
+	else {
+		return $self->{os};
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 provisioner
+
+ Parameters  : None
+ Returns     : Process's provisioner object
+ Description : Allows OS modules to access the reservation's provisioner
+               object.
+
+=cut
+
+sub provisioner {
+	my $self = shift;
+	
+	if (!$self->{provisioner}) {
+		notify($ERRORS{'WARNING'}, 0, "unable to return provisioner object, \$self->{provisioner} is not set");
+		return;
+	}
+	else {
+		return $self->{provisioner};
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 set_os
+
+ Parameters  : None
+ Returns     : Process's OS object
+ Description : Sets the OS object for the module to access.
+
+=cut
+
+sub set_os {
+	my $self = shift;
+	my $os = shift;
+	$self->{os} = $os;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 set_provisioner
+
+ Parameters  : None
+ Returns     : Process's provisioner object
+ Description : Sets the provisioner object for the module to access.
+
+=cut
+
+sub set_provisioner {
+	my $self = shift;
+	my $provisioner = shift;
+	$self->{provisioner} = $provisioner;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 get_package_hierarchy
 
  Parameters  : String containing the name of a Perl package

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=1028392&r1=1028391&r2=1028392&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm Thu Oct 28 17:17:54 2010
@@ -62,45 +62,6 @@ use VCL::utils;
 
 #/////////////////////////////////////////////////////////////////////////////
 
-=head2 set_provisioner
-
- Parameters  : None
- Returns     : Process's provisioner object
- Description : Sets the provisioner object for the OS module to access.
-
-=cut
-
-sub set_provisioner {
-	my $self = shift;
-	my $provisioner = shift;
-	$self->{provisioner} = $provisioner;
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 provisioner
-
- Parameters  : None
- Returns     : Process's provisioner object
- Description : Allows OS modules to access the reservation's provisioner
-               object.
-
-=cut
-
-sub provisioner {
-	my $self = shift;
-	
-	if (!$self->{provisioner}) {
-		notify($ERRORS{'WARNING'}, 0, "unable to return provisioner object, \$self->{provisioner} is not set");
-		return;
-	}
-	else {
-		return $self->{provisioner};
-	}
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
 =head2 get_source_configuration_directories
 
  Parameters  : None
@@ -440,7 +401,7 @@ sub is_ssh_responding {
 
 =head2 wait_for_response
 
- Parameters  : Initial delay seconds (optional), SSH response timeout seconds (optional)
+ Parameters  : Initial delay seconds (optional), SSH response timeout seconds (optional), SSH attempt delay seconds (optional)
  Returns     : If successful: true
                If failed: false
  Description : Waits for the reservation computer to respond to SSH after it
@@ -471,6 +432,11 @@ sub wait_for_response {
 		$ssh_response_timeout_seconds = 600;
 	}
 	
+	my $ssh_attempt_delay_seconds = shift;
+	if (!defined $ssh_attempt_delay_seconds) {
+		$ssh_response_timeout_seconds = 15;
+	}
+	
 	# Sleep for the initial delay value if it has been set
 	# Check SSH once to bypass the initial delay if SSH is already responding
 	if ($initial_delay_seconds && !$self->is_ssh_responding()) {
@@ -481,7 +447,7 @@ sub wait_for_response {
 	
 	# Wait for SSH to respond, loop until timeout is reached
 	notify($ERRORS{'OK'}, 0, "waiting for $computer_node_name to respond to SSH, maximum of $ssh_response_timeout_seconds seconds");
-	if (!$self->wait_for_ssh($ssh_response_timeout_seconds)) {
+	if (!$self->wait_for_ssh($ssh_response_timeout_seconds, $ssh_attempt_delay_seconds)) {
 		notify($ERRORS{'WARNING'}, 0, "failed to connect to $computer_node_name via SSH after $ssh_response_timeout_seconds seconds");
 		return;
 	}
@@ -617,11 +583,12 @@ sub update_public_ip_address {
 		my $public_ip_address;
 		
 		# Try to retrieve the public IP address from the OS module
-		if ($self->can("get_public_ip_address") && ($public_ip_address = $self->get_public_ip_address())) {
-			notify($ERRORS{'DEBUG'}, 0, "retrieved public IP address from $computer_node_name using the OS module: $public_ip_address");
+		if (!$self->can("get_public_ip_address")) {
+			notify($ERRORS{'WARNING'}, 0, "unable to retrieve public IP address from $computer_node_name, OS module " . ref($self) . " does not implement a 'get_public_ip_address' subroutine");
+			return;
 		}
-		elsif ($public_ip_address = getdynamicaddress($computer_node_name, $image_os_name, $image_os_type)) {
-			notify($ERRORS{'DEBUG'}, 0, "retrieved public IP address from $computer_node_name using utils.pm::getdynamicaddress: $public_ip_address");
+		elsif ($public_ip_address = $self->get_public_ip_address()) {
+			notify($ERRORS{'DEBUG'}, 0, "retrieved public IP address from $computer_node_name using the OS module: $public_ip_address");
 		}
 		else {
 			notify($ERRORS{'WARNING'}, 0, "failed to retrieve dynamic public IP address from $computer_node_name");

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm?rev=1028392&r1=1028391&r2=1028392&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm Thu Oct 28 17:17:54 2010
@@ -62,22 +62,6 @@ use VCL::utils;
 
 #/////////////////////////////////////////////////////////////////////////////
 
-=head2 set_os
-
- Parameters  : None
- Returns     : Process's OS object
- Description : Sets the OS object for the provisioner module to access.
-
-=cut
-
-sub set_os {
-	my $self = shift;
-	my $os = shift;
-	$self->{os} = $os;
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
 =head2 set_vmhost_os
 
  Parameters  : None
@@ -94,29 +78,6 @@ sub set_vmhost_os {
 
 #/////////////////////////////////////////////////////////////////////////////
 
-=head2 os
-
- Parameters  : None
- Returns     : Process's OS object
- Description : Allows provisioning modules to access the reservation's OS
-               object.
-
-=cut
-
-sub os {
-	my $self = shift;
-	
-	if (!$self->{os}) {
-		notify($ERRORS{'WARNING'}, 0, "unable to return OS object, \$self->{os} is not set");
-		return;
-	}
-	else {
-		return $self->{os};
-	}
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
 =head2 vmhost_os
 
  Parameters  : None
@@ -236,9 +197,9 @@ sub retrieve_image {
 		
 		# Run du to get the size of the image files on the partner if the image exists in any of the search paths
 		my $du_command = "du -b " . join(" ", @{$partner_info{$partner}{search_paths}});
-		my ($du_exit_status, $du_output) = run_ssh_command($partner, $partner_info{$partner}{identity_key}, $du_command, $partner_info{$partner}{user}, $partner_info{$partner}{port}, 0);
+		my ($du_exit_status, $du_output) = run_ssh_command($partner, $partner_info{$partner}{identity_key}, $du_command, $partner_info{$partner}{user}, $partner_info{$partner}{port}, 1);
 		if (!defined($du_output)) {
-			notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to determine if image $image_name exists on $partner_info{$partner}{hostname}");
+			notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to determine if image $image_name exists on $partner_info{$partner}{hostname}: $du_command");
 			next;
 		}
 		

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=1028392&r1=1028391&r2=1028392&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/State.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/State.pm Thu Oct 28 17:17:54 2010
@@ -76,8 +76,7 @@ use VCL::DataStructure;
 
 sub initialize {
 	my $self = shift;
-	my ($package, $filename, $line, $sub) = caller(0);
-
+	
 	# Initialize the database handle count
 	$ENV{dbh_count} = 0;
 
@@ -88,20 +87,13 @@ sub initialize {
 	else {
 		notify($ERRORS{'WARNING'}, 0, "unable to obtain a database handle for this state process");
 	}
-
+	
 	# Check the image OS before creating OS object
 	if (!$self->check_image_os()) {
 		notify($ERRORS{'WARNING'}, 0, "failed to check if image OS is correct");
 		$self->reservation_failed();
 	}
-
-	# Store some hash variables into local variables
-	my $request_id                = $self->data->get_request_id();
-	my $reservation_id            = $self->data->get_reservation_id();
-	my $provisioning_perl_package = $self->data->get_computer_provisioning_module_perl_package();
-	my $os_perl_package           = $self->data->get_image_os_module_perl_package();
-	#my $predictive_perl_package   = $self->data->get_management_node_predictive_module_perl_package();
-
+	
 	# Rename this process to include some request info
 	rename_vcld_process($self->data);
 
@@ -112,57 +104,23 @@ sub initialize {
 
 	# Set the parent PID and this process's PID in the hash
 	set_hash_process_id($self->data->get_request_data);
-
-	# Attempt to load the computer provisioning module
-	if ($provisioning_perl_package) {
-		notify($ERRORS{'DEBUG'}, 0, "attempting to load provisioning module: $provisioning_perl_package");
-		eval "use $provisioning_perl_package";
-		if ($EVAL_ERROR) {
-			notify($ERRORS{'WARNING'}, 0, "$provisioning_perl_package module could not be loaded, returning 0");
-			return 0;
-		}
-		notify($ERRORS{'DEBUG'}, 0, "$provisioning_perl_package module loaded");
-
-		# Create provisioner object
-		if (my $provisioner = ($provisioning_perl_package)->new({data_structure => $self->data})) {
-			notify($ERRORS{'OK'}, 0, ref($provisioner) . " provisioner object created");
-			$self->{provisioner} = $provisioner;
-		}
-		else {
-			notify($ERRORS{'WARNING'}, 0, "provisioning object could not be created, returning 0");
-			return 0;
-		}
-	} ## end if ($provisioning_perl_package)
-	else {
-		notify($ERRORS{'OK'}, 0, "provisioning module not loaded, Perl package is not defined");
+	
+	# Create an OS object
+	if (!$self->create_os_object()) {
+		notify($ERRORS{'WARNING'}, 0, "failed to create OS object");
+		return;
 	}
-
-	# Attempt to load the OS module
-	if ($os_perl_package) {
-		notify($ERRORS{'DEBUG'}, 0, "attempting to load OS module: $os_perl_package");
-		eval "use $os_perl_package";
-		if ($EVAL_ERROR) {
-			notify($ERRORS{'WARNING'}, 0, "$os_perl_package module could not be loaded, returning 0");
-			return 0;
-		}
-		notify($ERRORS{'DEBUG'}, 0, "$os_perl_package module loaded");
-
-		if (my $os = ($os_perl_package)->new({data_structure => $self->data})) {
-			notify($ERRORS{'OK'}, 0, ref($os) . " OS object created");
-			$self->{os} = $os;
-		}
-		else {
-			notify($ERRORS{'WARNING'}, 0, "OS object could not be created, returning 0");
-			return 0;
-		}
-	} ## end if ($os_perl_package)
-	else {
-		notify($ERRORS{'OK'}, 0, "OS module not loaded, Perl package is not defined");
+	
+	# Create a provisioning object
+	if (!$self->create_provisioning_object()) {
+		notify($ERRORS{'WARNING'}, 0, "failed to create provisioning object");
+		return;
 	}
 	
+	# Allow the provisioning object to access the OS object and vice-versa
 	$self->{provisioner}->set_os($self->{os});
 	$self->{os}->set_provisioner($self->{provisioner});
-
+	
 	notify($ERRORS{'DEBUG'}, 0, "returning 1");
 	return 1;
 
@@ -170,40 +128,6 @@ sub initialize {
 
 #/////////////////////////////////////////////////////////////////////////////
 
-=head2 provisioner
-
- Parameters  : None
- Returns     : Object's provisioner object
- Description : Returns this objects provisioner object, which is stored in
-               $self->{provisioner}.  This method allows it to accessed using
-					$self->provisioner.
-
-=cut
-
-sub provisioner {
-	my $self = shift;
-	return $self->{provisioner};
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 os
-
- Parameters  : None
- Returns     : Object's OS object
- Description : Returns this objects OS object, which is stored in
-               $self->{os}.  This method allows it to accessed using
-					$self->os.
-
-=cut
-
-sub os {
-	my $self = shift;
-	return $self->{os};
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
 =head2 predictor
 
  Parameters  : None
@@ -899,20 +823,21 @@ sub check_image_os {
 sub DESTROY {
 	my $self = shift;
 	
-	notify($ERRORS{'DEBUG'}, 0, "ref($self) destructor called");
+	my $address = sprintf('%x', $self);
+	notify($ERRORS{'DEBUG'}, 0, ref($self) . " destructor called, address: $address");
 	
 	# If not a blockrequest, delete computerloadlog entry
 	if ($self && $self->data && !$self->data->is_blockrequest()) {
 		my $reservation_id = $self->data->get_reservation_id();
 		
-		# Delete all computerloadlog rows with loadstatename = 'begin' for thie reservation
+		# Delete all computerloadlog rows with loadstatename = 'begin' for this reservation
 		if ($reservation_id && delete_computerloadlog_reservation($reservation_id, 'begin')) {
-			notify($ERRORS{'DEBUG'}, 0, "removed computerloadlog rows with loadstate=begin for reservation");
+			#notify($ERRORS{'DEBUG'}, 0, "removed computerloadlog rows with loadstate=begin for reservation");
 		}
-		elsif (!$reservation_id) {
+		elsif (!defined($reservation_id)) {
 			notify($ERRORS{'WARNING'}, 0, "failed to retrieve the reservation id, computerloadlog rows not removed");
 		}
-		else {
+		elsif ($reservation_id) {
 			notify($ERRORS{'WARNING'}, 0, "failed to remove computerloadlog rows with loadstate=begin for reservation");
 		}
 	}
@@ -927,17 +852,17 @@ sub DESTROY {
 
 	# Close the database handle
 	if (defined $ENV{dbh}) {
-		notify($ERRORS{'DEBUG'}, 0, "process has a database handle stored in \$ENV{dbh}, attempting disconnect");
+		#notify($ERRORS{'DEBUG'}, 0, "process has a database handle stored in \$ENV{dbh}, attempting disconnect");
 
 		if ($ENV{dbh}->disconnect) {
-			notify($ERRORS{'DEBUG'}, 0, "\$ENV{dbh}: database disconnect successful");
+			#notify($ERRORS{'DEBUG'}, 0, "\$ENV{dbh}: database disconnect successful");
 		}
 		else {
 			notify($ERRORS{'WARNING'}, 0, "\$ENV{dbh}: database disconnect failed, " . DBI::errstr());
 		}
 	} ## end if (defined $ENV{dbh})
 	else {
-		notify($ERRORS{'DEBUG'}, 0, "process does not have a database handle stored in \$ENV{dbh}");
+		#notify($ERRORS{'DEBUG'}, 0, "process does not have a database handle stored in \$ENV{dbh}");
 	}
 
 	# Check for an overridden destructor

Modified: incubator/vcl/trunk/managementnode/lib/VCL/utils.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/utils.pm?rev=1028392&r1=1028391&r2=1028392&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/utils.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/utils.pm Thu Oct 28 17:17:54 2010
@@ -139,7 +139,6 @@ our @EXPORT = qw(
   get_managable_resource_groups
   get_user_info
   get_vmhost_info
-  getdynamicaddress
   getimagesize
   getnewdbh
   getpw
@@ -1481,85 +1480,6 @@ sub setstaticaddress {
 
 #/////////////////////////////////////////////////////////////////////////////
 
-=head2 getdynamicaddress
-
- Parameters  : $node, $osname
- Returns     : assigned ipaddress
- Description : collects the dynamically assigned ipaddress
-=cut
-
-sub getdynamicaddress {
-	my ($node, $osname, $image_os_type) = @_;
-	my ($package, $filename, $line, $sub) = caller(0);
-	notify($ERRORS{'OK'}, 0, "nodename not set") if (!defined($node));
-	notify($ERRORS{'OK'}, 0, "osname not set")   if (!defined($osname));
-	notify($ERRORS{'OK'}, 0, "image_os_type not set")   if (!defined($image_os_type));
-
-	#collect private address -- read hosts file only useful if running
-	# xcat setup and private addresses are listsed in the local
-	# /etc/hosts file
-	#should also store/pull private address from the database
-	my $privateIP;
-	my @sshcmd;
-	if (open(HOSTS, "/etc/hosts")) {
-		my @hosts = <HOSTS>;
-		close(HOSTS);
-		foreach my $line (@hosts) {
-			if ($line =~ /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s+($node)/) {
-				$privateIP = $1;
-				notify($ERRORS{'OK'}, 0, "PrivateIP address for $node collected $privateIP");
-				last;
-			}
-		}
-	} ## end if (open(HOSTS, "/etc/hosts"))
-	if (!defined($privateIP)) {
-		notify($ERRORS{'WARNING'}, 0, "private IP address not found for $node, possible issue with regex");
-	}
-
-	my $identity_keys = $ENV{management_node_info}{keys};
-	my $dynaIPaddress = 0;
-	my $ip_address;
-	if ($image_os_type =~ /windows/i) {
-
-		@sshcmd = run_ssh_command($node, $identity_keys, "ipconfig", "root");
-		for my $l (@{$sshcmd[1]}) {
-			# skip class a,b,c private addresses
-                        next if ($l !~ /IP(.*)?Address[\s\.:]*([\d\.]*)/);
-                        my $ip_address_found = $2;
-                        next if ($ip_address_found =~ /^(10|127|192\.168|172\.(1[6-9]|2[0-9]|3[0-1]))\./);
-                        next if ($ip_address_found =~ /$privateIP/);
-                        $ip_address = $ip_address_found;
-                }
-                $dynaIPaddress = $ip_address;
-
-	} ## end if ($osname =~ /windows/)
-	elsif ($image_os_type =~ /linux/) {
-		#$identity = $ENV{management_node_info}{keys};
-		undef @sshcmd;
-		@sshcmd = run_ssh_command($node, $identity_keys, "/sbin/ifconfig \|grep inet", "root");
-		for my $l (@{$sshcmd[1]}) {
-			# skip class a,b,c private addresses
-			next if ($l !~ /inet addr:([\d\.]*)/);
-                        my $ip_address_found = $1;
-                        next if ($ip_address_found =~ /^(10|127|192\.168|172\.(1[6-9]|2[0-9]|3[0-1]))\./);
-                        next if ($ip_address_found =~ /$privateIP/);
-                        $ip_address = $ip_address_found;
-		}
-		$dynaIPaddress = $ip_address;
-
-	} ## end elsif ($image_os_type =~ /linux/)  [ if ($image_os_type =~ /windows/)
-	else {
-		notify($ERRORS{'WARNING'}, 0, "OStype $image_os_type not supported ");
-		return 0;
-	}
-	
-	notify($ERRORS{'OK'}, 0, "dynamic IP address for $node collected: $dynaIPaddress");
-	return $dynaIPaddress;
-
-} ## end sub getdynamicaddress
-
-#/////////////////////////////////////////////////////////////////////////////
-
 =head2 _checknstartservice
 
  Parameters  : $service name
@@ -8233,15 +8153,16 @@ EOF
 	
 	# Check if the computer associated with this reservation has a vmhostid set
 	if ($computer_row{computer_vmhostid}) {
-		 my %vmhost_info = get_vmhost_info($computer_row{computer_vmhostid});
-		 # Make sure vmhost was located if vmhostid was specified for the image
-		 if (!%vmhost_info) {
-			 notify($ERRORS{'WARNING'}, 0, "vmhostid=" . $computer_row{computer_vmhostid} . " was specified for computer id=" . $computer_row{computer_id} . " but vmhost could not be found");
-		 }
-		 else {
-			 # Image meta data found, add it to the hash
-			 $comp_info{vmhost} = \%vmhost_info;
-		 }
+		my %vmhost_info = get_vmhost_info($computer_row{computer_vmhostid});
+		# Make sure vmhost was located if vmhostid was specified for the image
+		if (!%vmhost_info) {
+			notify($ERRORS{'WARNING'}, 0, "vmhostid=" . $computer_row{computer_vmhostid} . " was specified for computer id=" . $computer_row{computer_id} . " but vmhost could not be found");
+		}
+		else {
+			# Image meta data found, add it to the hash
+			$comp_info{vmhost} = \%vmhost_info;
+			$comp_info{computer}{vmhost} = \%vmhost_info;
+		}
 	} ## end if ($reservation_row{computer_vmhostid})