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 2014/06/30 18:57:43 UTC

svn commit: r1606838 - in /vcl/trunk/managementnode/lib/VCL: DataStructure.pm Module/OS.pm Module/OS/Linux/ManagementNode.pm Module/Provisioning/VMware/VMware.pm Module/Provisioning/libvirt.pm Module/Provisioning/vbox.pm image.pm utils.pm

Author: arkurth
Date: Mon Jun 30 16:57:42 2014
New Revision: 1606838

URL: http://svn.apache.org/r1606838
Log:
VCL-584
Added functionality to backend to allow an image to be captured and then the reservation continued.

Added check to determine if request state is 'checkpoint' in image.pm::process. If the state is checkpoint, the computer isn't reloaded at the end of the capture. Instead, the computer is powered on and OS module's post_load and reserve subroutines are called. The request state is then changed to reserved.

Added utils.pm::update_request_checkuser. This is called from image.pm for checkpoint captures to prevent the reservation from timing out after the capture os complete in case anything went wrong.

Updated capture subroutines in libvirt.pm, VMware.pm, and vbox.pm to not delete the VM after an image is captured if the state is checkpoint.


VCL-767
Updated utils.pm::update_computer_private_ip_address to allow either a computer ID or hostname argument to be specified.

Added utils.pm::get_computer_private_ip_address_info. It is used to retrieve all of the private IP addresses from the database.

Added utils.pm::hostname_to_ip_address. It calls gethostbyname. It will be used to check if the private IP addresses in the database match what the hostnames resolve to. It is also used to determine the management node's private IP address instead of reading /etc/hosts.


Other
Added argument to get_user_sshPublicKeys in OS.pm so a warning isn't displayed if the value is not set for a user.

Modified:
    vcl/trunk/managementnode/lib/VCL/DataStructure.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/ManagementNode.pm
    vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm
    vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm
    vcl/trunk/managementnode/lib/VCL/Module/Provisioning/vbox.pm
    vcl/trunk/managementnode/lib/VCL/image.pm
    vcl/trunk/managementnode/lib/VCL/utils.pm

Modified: vcl/trunk/managementnode/lib/VCL/DataStructure.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/DataStructure.pm?rev=1606838&r1=1606837&r2=1606838&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/DataStructure.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/DataStructure.pm Mon Jun 30 16:57:42 2014
@@ -1702,9 +1702,14 @@ sub set_computer_private_ip_address {
 	}
 	
 	my $computer_id = $self->get_computer_id();
+	if (!defined($computer_id)) {
+		notify($ERRORS{'WARNING'}, 0, "computer ID is not stored in this DataStructure object");
+		return;
+	}
+	
 	my $computer_hostname = $self->get_computer_hostname();
-	if (!$computer_id || !$computer_hostname) {
-		notify($ERRORS{'WARNING'}, 0, "computer hostname and ID are not stored in this DataStructure object");
+	if (!$computer_hostname) {
+		notify($ERRORS{'WARNING'}, 0, "computer hostname is not stored in this DataStructure object");
 		return;
 	}
 	

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=1606838&r1=1606837&r2=1606838&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS.pm Mon Jun 30 16:57:42 2014
@@ -2518,7 +2518,7 @@ sub manage_server_access {
 	my $server_request_admingroupid = $self->data->get_server_request_admingroupid();
 	my $server_request_logingroupid = $self->data->get_server_request_logingroupid();
 	my $user_login_id_owner         = $self->data->get_user_login_id();
-	my $user_sshPublicKeys 			  = $self->data->get_user_sshPublicKeys();
+	my $user_sshPublicKeys 			  = $self->data->get_user_sshPublicKeys(0);
 	my $user_id_owner		           = $self->data->get_user_id();
 	my $image_os_type 				  = $self->data->get_image_os_type();
 	my $request_laststate_name      = $self->data->get_request_laststate_name();

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/ManagementNode.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/ManagementNode.pm?rev=1606838&r1=1606837&r2=1606838&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/ManagementNode.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/ManagementNode.pm Mon Jun 30 16:57:42 2014
@@ -82,10 +82,18 @@ sub initialize {
 	my $management_node_short_name = $self->data->get_management_node_short_name() || return;
 	my $management_node_ip_address = $self->data->get_management_node_ipaddress() || return;
 	
+	my $management_node_private_ip_address = hostname_to_ip_address($management_node_hostname);
+	if (!$management_node_private_ip_address) {
+		notify($ERRORS{'WARNING'}, 0, "failed to initialize management node OS object, unable to resolve hostname '$management_node_hostname'");
+		return;
+	}
+	
+	$self->data->set_computer_id(0);
 	$self->data->set_computer_hostname($management_node_hostname);
 	$self->data->set_computer_node_name($management_node_short_name);
 	$self->data->set_computer_short_name($management_node_short_name);
 	$self->data->set_computer_public_ip_address($management_node_ip_address);
+	$self->data->set_computer_private_ip_address($management_node_private_ip_address);
 	
 	#print "\n\n" . format_data($self->data->get_request_data()) . "\n\n";
 	return 1;
@@ -160,6 +168,7 @@ sub copy_file_to {
 	return $self->copy_file($source, $destination);
 }
 
+#/////////////////////////////////////////////////////////////////////////////
 
 #/////////////////////////////////////////////////////////////////////////////
 

Modified: vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm?rev=1606838&r1=1606837&r2=1606838&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm Mon Jun 30 16:57:42 2014
@@ -614,6 +614,7 @@ sub capture {
 		return;
 	}
 	
+	my $request_state_name = $self->data->get_request_state_name();
 	my $computer_name = $self->data->get_computer_short_name();
 	my $image_name = $self->data->get_image_name();
 	my $vmhost_name = $self->data->get_vmhost_short_name();
@@ -916,6 +917,9 @@ sub capture {
 	elsif ($vmdk_directory_path_original eq $vmdk_directory_path_renamed) {
 		notify($ERRORS{'WARNING'}, 0, "VM will NOT be deleted because the VM's vmdk directory path configured in the vmx file matches the captured vmdk directory path: '$vmdk_directory_path_renamed'");
 	}
+	elsif ($request_state_name !~ /^(image)$/) {
+		notify($ERRORS{'OK'}, 0, "VM will NOT be deleted because the request state is '$request_state_name'");
+	}
 	else {
 		# Delete the VM
 		if (!$self->delete_vm($vmx_file_path_original)) {
@@ -6806,7 +6810,7 @@ sub _get_datastore_path {
 		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
 		return;
 	}
-	
+
 	# Get the path argument
 	my $path_argument = shift;
 	if (!$path_argument) {
@@ -7151,7 +7155,7 @@ sub _get_parent_directory_name {
 		notify($ERRORS{'WARNING'}, 0, "unable to determine parent directory name, path argument could not be converted to a datastore path: '$path_argument'");
 		return;
 	}
-	
+
 	if ($datastore_path =~ /^\[.+\]$/) {
 		notify($ERRORS{'WARNING'}, 0, "unable to determine parent directory name, path argument is the root path of a datastore: '$path_argument'");
 		return;
@@ -8387,7 +8391,7 @@ sub get_datastore_imagerevision_names {
 		print "$ignored_count files and/or directories ignored, image revision not found in database:\n" . join("\n", @ignored) . "\n\n";
 	}
 	print "$datastore_imagerevision_name_count images found in datastore '$datastore_base_path'\n";
-	
+
 	return @datastore_imagerevision_names;
 }
 

Modified: vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm?rev=1606838&r1=1606837&r2=1606838&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm Mon Jun 30 16:57:42 2014
@@ -307,6 +307,7 @@ sub capture {
 	my $new_image_name = $self->get_new_image_name();
 	$self->data->set_image_name($new_image_name);
 	
+	my $request_state_name = $self->data->get_request_state_name();
 	my $image_id = $self->data->get_image_id();
 	my $imagerevision_id = $self->data->get_imagerevision_id();
 	my $image_type = $self->data->get_imagetype_name();
@@ -490,8 +491,13 @@ EOF
 		}
 	}
 	
-	# Image has been captured, delete the domain
-	$self->delete_domain($domain_name);
+	if ($request_state_name !~ /^(image)$/) {
+		notify($ERRORS{'OK'}, 0, "domain will NOT be deleted because the request state is '$request_state_name'");
+	}
+	else {
+		# Image has been captured, delete the domain
+		$self->delete_domain($domain_name);
+	}
 	
 	return 1;
 } ## end sub capture

Modified: vcl/trunk/managementnode/lib/VCL/Module/Provisioning/vbox.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/vbox.pm?rev=1606838&r1=1606837&r2=1606838&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/Provisioning/vbox.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/Provisioning/vbox.pm Mon Jun 30 16:57:42 2014
@@ -458,8 +458,9 @@ sub capture { ## This is going to need t
 		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
 		return 0;
 	}
-	my $request_id     = $self->data->get_request_id;
-	my $reservation_id = $self->data->get_reservation_id;
+	my $request_id         = $self->data->get_request_id;
+	my $request_state_name = $self->data->get_request_state_name();
+	my $reservation_id     = $self->data->get_reservation_id;
 	my $management_node_keys     = $self->data->get_management_node_keys();
 
 	my $requestedimagename = $self->data->get_image_name;
@@ -575,10 +576,13 @@ sub capture { ## This is going to need t
 			notify($ERRORS{'CRITICAL'}, 0, "failed to copy .vdi file to image repository");
 			return 0;
 		}
-
-		notify($ERRORS{'OK'}, 0, "Removing VM");
-		if ($self->control_VM("remove")) {
-			notify($ERRORS{'OK'}, 0, "removed node $computer_shortname from vmhost $hostnodename");
+		
+		if ($request_state_name !~ /^(image)$/) {
+			notify($ERRORS{'OK'}, 0, "VM will NOT be deleted because the request state is '$request_state_name'");
+		}
+		else {
+			# Image has been captured, remove the VM
+			$self->control_VM("remove");
 		}
 	} elsif ($vmprofile_vmdisk =~ /shared/) { ## end if ($vmprofile_vmdisk =~ /(local|dedicated)/)
 		

Modified: vcl/trunk/managementnode/lib/VCL/image.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/image.pm?rev=1606838&r1=1606837&r2=1606838&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/image.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/image.pm Mon Jun 30 16:57:42 2014
@@ -98,6 +98,7 @@ sub process {
 	}
 	
 	my $request_id                 = $self->data->get_request_id();
+	my $request_state_name         = $self->data->get_request_state_name();
 	my $reservation_id             = $self->data->get_reservation_id();
 	my $user_id                    = $self->data->get_user_id();
 	my $user_unityid               = $self->data->get_user_login_id();
@@ -160,123 +161,87 @@ END
 	$self->data->set_image_lastupdate($timestamp);
 	$self->data->set_imagerevision_date_created($timestamp);
 	
-	my $create_image_result;
-	
-	# --- BEGIN NEW MODULARIZED METHOD ---
 	# Check if capture() subroutine has been implemented by the provisioning module
-	if ($self->provisioner->can("capture")) {
-		# Call the provisioning modules's capture() subroutine
-		# The provisioning module should do everything necessary to capture the image
-		notify($ERRORS{'OK'}, 0, "calling provisioning module's capture() subroutine");
-		if ($create_image_result = $self->provisioner->capture()) {
-			notify($ERRORS{'OK'}, 0, "$image_name image was successfully captured by the provisioning module");
-		}
-		else {
-			notify($ERRORS{'WARNING'}, 0, "$image_name image failed to be captured by provisioning module");
-			$self->reservation_failed();
-		}
+	if (!$self->provisioner->can("capture")) {
+		notify($ERRORS{'CRITICAL'}, 0, "failed to capture image, " . ref($self->provisioner) . " provisioning module does not implement a 'capture' subroutine");
+		$self->reservation_failed();
 	}
-	# --- END NEW MODULARIZED METHOD ---
-
-	elsif ($computer_type eq "blade" && $self->os) {
-		$create_image_result = 1;
-
-		notify($ERRORS{'OK'}, 0, "OS modularization supported, beginning OS module capture prepare");
-		if (!$self->os->capture_prepare()) {
-			notify($ERRORS{'WARNING'}, 0, "OS module capture prepare failed");
-			$self->reservation_failed();
-		}
-
-		notify($ERRORS{'OK'}, 0, "beginning provisioning module capture prepare");
-		if (!$self->provisioner->capture_prepare()) {
-			notify($ERRORS{'WARNING'}, 0, "provisioning module capture prepare failed");
+	
+	# If this was a checkpoint, make sure the provisioning module implements a power_on subroutine
+	if ($request_state_name eq 'checkpoint' && !$self->provisioner->can('power_on')) {
+		notify($ERRORS{'CRITICAL'}, 0, "failed to create checkpoint of image, " . ref($self->provisioner) . " provisioning module does not implement a 'power_on' subroutine, won't be able to power the computer back on after image is captured in order to return it to a usable state for the user");
+		$self->reservation_failed();
+	}
+	
+	# Call the provisioning modules's capture() subroutine
+	# The provisioning module should do everything necessary to capture the image
+	notify($ERRORS{'OK'}, 0, "calling provisioning module's capture() subroutine");
+	if ($self->provisioner->capture()) {
+		notify($ERRORS{'OK'}, 0, "$image_name image was successfully captured by the provisioning module");
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "$image_name image failed to be captured by provisioning module");
+		$self->reservation_failed();
+	}
+	
+	# If this was a checkpoint, power the computer back on and wait for it to respond
+	if ($request_state_name eq 'checkpoint') {
+		if (!$self->provisioner->power_on()) {
+			notify($ERRORS{'CRITICAL'}, 0, "failed to create checkpoint of image, failed to power $computer_shortname back on after image was captured");
 			$self->reservation_failed();
 		}
 		
-		notify($ERRORS{'OK'}, 0, "beginning OS module capture start");
-		if (!$self->os->capture_start()) {
-			notify($ERRORS{'WARNING'}, 0, "OS module capture start failed");
+		if (!$self->os->post_load()) {
+			notify($ERRORS{'CRITICAL'}, 0, "failed to create checkpoint of image, unable to complete OS post-load tasks on $computer_shortname after image was captured and computer was powered on");
 			$self->reservation_failed();
 		}
-
-		notify($ERRORS{'OK'}, 0, "beginning provisioning module capture monitor");
-		if (!$self->provisioner->capture_monitor()) {
-			notify($ERRORS{'WARNING'}, 0, "provisioning module capture monitor failed");
+		
+		if (!$self->os->reserve()) {
+			notify($ERRORS{'CRITICAL'}, 0, "failed to create checkpoint of image, unable to complete OS reserve tasks on $computer_shortname");
 			$self->reservation_failed();
 		}
-
-	} ## end if ($computer_type eq "blade" && $self->os)
-	
-	elsif ($computer_type eq "blade") {
-		$create_image_result = $self->provisioner->capture_prepare();
-
-		if ($create_image_result) {
-			$create_image_result = $self->provisioner->capture_monitor();
-		}
+		
+		# Disable user connection checking for this request to prevent timeouts
+		update_request_checkuser($request_id, 0);
 	}
-	elsif ($computer_type eq "virtualmachine") {
-		$create_image_result = $self->provisioner->capture();
+	
+	# Get the new image size
+	my $image_size_new;
+	if ($image_size_new = $self->provisioner->get_image_size($image_name)) {
+		notify($ERRORS{'OK'}, 0, "size of $image_name: $image_size_new");
 	}
 	else {
-		notify($ERRORS{'CRITICAL'}, 0, "unsupported computer type: $computer_type");
-		$self->reservation_failed();
+		notify($ERRORS{'WARNING'}, 0, "unable to retrieve size of new revision: $image_name, old size will be used");
+		$image_size_new = $image_size;
 	}
-
-	# Image creation was successful, proceed to update database tables
-	if ($create_image_result) {
-		# Success
-		notify($ERRORS{'OK'}, 0, "$image_name image files successfully saved");
-		
-		# Get the new image size
-		my $image_size_new;
-		if ($image_size_new = $self->provisioner->get_image_size($image_name)) {
-			notify($ERRORS{'OK'}, 0, "size of $image_name: $image_size_new");
-		}
-		else {
-			notify($ERRORS{'WARNING'}, 0, "unable to retrieve size of new revision: $image_name, old size will be used");
-			$image_size_new = $image_size;
-		}
-		$self->data->set_image_size($image_size_new);
-
-		# Update image timestamp, clear deleted flag
-		# Set test flag if according to whether this image is new or updated
-		# Update the image size
-		my $update_image_statement = "
-		UPDATE
-		image,
-		imagerevision
-		SET
-		image.lastupdate = \'$timestamp\',
-		image.deleted = \'0\',
-		image.size = \'$image_size_new\',
-		image.name = \'$image_name\',
-		imagerevision.deleted = \'0\',
-		imagerevision.datecreated = \'$timestamp\'
-		WHERE
-		image.id = $image_id
-		AND imagerevision.id = $imagerevision_id
-		";
-
-		# Execute the image update statement
-		if (database_execute($update_image_statement)) {
-			notify($ERRORS{'OK'}, 0, "image and imagerevision tables updated for image=$image_id, imagerevision=$imagerevision_id, name=$image_name, lastupdate=$timestamp, deleted=0, size=$image_size_new");
-		}
-		else {
-			notify($ERRORS{'WARNING'}, 0, "image table could not be updated for image=$image_id");
-		}
-	} ## end if ($create_image_result)
-
-	# Check if image creation was successful and database tables were successfully updated
-	# Notify user and admins of the results
-	if ($create_image_result) {
-		$self->reservation_successful($image_size);
+	$self->data->set_image_size($image_size_new);
+	
+	# Update image timestamp, image size, clear deleted flag
+	my $update_image_statement = <<EOF;
+UPDATE
+image,
+imagerevision
+SET
+image.lastupdate = '$timestamp',
+image.deleted = '0',
+image.size = '$image_size_new',
+image.name = '$image_name',
+imagerevision.deleted = '0',
+imagerevision.datecreated = '$timestamp'
+WHERE
+image.id = $image_id
+AND imagerevision.id = $imagerevision_id
+EOF
+	
+	# Execute the image update statement
+	if (database_execute($update_image_statement)) {
+		notify($ERRORS{'OK'}, 0, "image and imagerevision tables updated for image=$image_id, imagerevision=$imagerevision_id, name=$image_name, lastupdate=$timestamp, deleted=0, size=$image_size_new");
 	}
-
 	else {
-		notify($ERRORS{'CRITICAL'}, 0, "image creation failed, see previous log messages");
-		$self->reservation_failed();
+		notify($ERRORS{'WARNING'}, 0, "image table could not be updated for image=$image_id");
 	}
-
+	
+	$self->reservation_successful($image_size);
 } ## end sub process
 
 #/////////////////////////////////////////////////////////////////////////////
@@ -298,6 +263,7 @@ sub reservation_successful {
 
 	my $request_data               = $self->data->get_request_data();
 	my $request_id                 = $self->data->get_request_id();
+	my $request_state_name         = $self->data->get_request_state_name();
 	my $reservation_id             = $self->data->get_reservation_id();
 	my $user_id                    = $self->data->get_user_id();
 	my $user_unityid               = $self->data->get_user_login_id();
@@ -316,20 +282,49 @@ sub reservation_successful {
 	my $sysadmin_mail_address      = $self->data->get_management_node_sysadmin_email(0);
 
 	# Send image creation successful email to user
-	my $body_user = <<"END";
+	my $subject_user;
+	my $body_user;
+	
+	if ($request_state_name eq 'checkpoint') {
+		$subject_user = "VCL -- $image_prettyname Image Checkpoint Succeeded";
+		$body_user = <<"END";
 
-Your VCL image creation request for $image_prettyname has
-succeeded.  Please visit $affiliation_sitewwwaddress and
-you should see an image called $image_prettyname.
-Please test this image to confirm it works correctly.
+Your VCL image checkpoint creation request for $image_prettyname has succeeded.
+
+You will need to visit the "Current Reservations" page and click "Connect" in order to be able to reconnect to the computer.
 
 Thank You,
 VCL Team
 END
-	mail($user_email, "VCL -- $image_prettyname Image Creation Succeeded", $body_user, $affiliation_helpaddress);
+	}
+	else {
+		$subject_user = "VCL -- $image_prettyname Image Creation Succeeded";
+		$body_user = <<"END";
+
+Your VCL image creation request for $image_prettyname has succeeded.
 
+Please visit $affiliation_sitewwwaddress and you should see an image called $image_prettyname.
+
+Please test this image to confirm it works correctly.
+
+Thank You,
+VCL Team
+END
+	}
+	
+	mail($user_email, $subject_user, $body_user, $affiliation_helpaddress);
+	
+	
 	# Send mail to $sysadmin_mail_address
 	if ($sysadmin_mail_address) {
+		my $subject_admin;
+		if ($request_state_name eq 'checkpoint') {
+			$subject_admin = "VCL IMAGE Checkpoint Completed: $image_name"
+		}
+		else {
+			$subject_admin = "VCL IMAGE Creation Completed: $image_name"
+		}
+		
 		my $body_admin = <<"END";
 VCL Image Creation Completed
 
@@ -354,16 +349,22 @@ Computer name: $computer_shortname
 Use Sysprep: $imagemeta_sysprep
 END
 
-		mail($sysadmin_mail_address, "VCL IMAGE Creation Completed: $image_name", $body_admin, $affiliation_helpaddress);
+		mail($sysadmin_mail_address, $subject_admin, $body_admin, $affiliation_helpaddress);
 	}
 	
-	# Insert reload request data into the datbase
-	if (!insert_reload_request($request_data)) {
-		notify($ERRORS{'CRITICAL'}, 0, "failed to insert reload request into database for computer id=$computer_id");
+	if ($request_state_name eq 'checkpoint') {
+		switch_state($request_data, 'reserved', 'checkpoint');
+	}
+	else {
+		# Insert reload request data into the datbase
+		if (!insert_reload_request($request_data)) {
+			notify($ERRORS{'CRITICAL'}, 0, "failed to insert reload request into database for computer id=$computer_id");
+		}
+		
+		# Switch the request state to complete, leave the computer state as is, update log ending to EOR, exit
+		switch_state($request_data, 'complete', '', 'EOR', '1');
 	}
 	
-	# Switch the request state to complete, leave the computer state as is, update log ending to EOR, exit
-	switch_state($request_data, 'complete', '', 'EOR', '1');
 	exit;
 } ## end sub reservation_successful
 

Modified: vcl/trunk/managementnode/lib/VCL/utils.pm
URL: http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/utils.pm?rev=1606838&r1=1606837&r2=1606838&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/utils.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/utils.pm Mon Jun 30 16:57:42 2014
@@ -77,6 +77,7 @@ use XML::Simple;
 use Time::HiRes qw(gettimeofday tv_interval);
 use Crypt::OpenSSL::RSA;
 use B qw(svref_2object);
+use Socket qw(inet_ntoa);
 
 require Exporter;
 our @ISA = qw(Exporter);
@@ -114,6 +115,7 @@ our @EXPORT = qw(
 	get_computer_grp_members
 	get_computer_ids
 	get_computer_info
+	get_computer_private_ip_address_info
 	get_computers_controlled_by_mn
 	get_connect_method_info
 	get_connectlog_info
@@ -167,6 +169,7 @@ our @EXPORT = qw(
 	getusergroupmembers
 	hash_to_xml_string
 	help
+	hostname_to_ip_address
 	insert_reload_request
 	insert_request
 	insertloadlog
@@ -240,6 +243,7 @@ our @EXPORT = qw(
 	update_log_ending
 	update_log_loaded_time
 	update_preload_flag
+	update_request_checkuser
 	update_request_state
 	update_reservation_accounts
 	update_reservation_lastcheck
@@ -4994,19 +4998,21 @@ sub update_lastcheckin {
 
 =head2 update_computer_private_ip_address
 
- Parameters  : $computer_id, $private_ip_address
+ Parameters  : $computer_identifier, $private_ip_address
  Returns     : boolean
  Description : Updates the computer.privateIPaddress value of the computer
                specified by the argument. The value can be set to null by
-               passing 'null' as the argument.
+               passing 'null' as the argument. The $computer_identifier argument
+               may either be the numeric computer.id value or the
+               computer.hostname value.
 
 =cut
 
 sub update_computer_private_ip_address {
-	my ($computer_id, $private_ip_address) = @_;
+	my ($computer_identifier, $private_ip_address) = @_;
 	
-	if (!defined($computer_id)) {
-		notify($ERRORS{'WARNING'}, 0, "computer ID argument was not specified");
+	if (!defined($computer_identifier)) {
+		notify($ERRORS{'WARNING'}, 0, "computer identifier argument was not specified");
 		return;
 	}
 	if (!defined($private_ip_address)) {
@@ -5029,16 +5035,26 @@ computer
 SET
 privateIPaddress = $private_ip_address_text
 WHERE
-id = $computer_id
+computer.deleted != '1'
+AND 
 EOF
 
+	# If the computer identifier is all digits match it to computer.id
+	# Otherwise, match computer.hostname
+	if ($computer_identifier =~ /^\d+$/) {
+		$update_statement .= "computer.id = \'$computer_identifier\'";
+	}
+	else {
+		$update_statement .= "computer.hostname REGEXP '$computer_identifier(\\\\.|\$)'";
+	}
+
 	# Call the database execute subroutine
 	if (database_execute($update_statement)) {
-		notify($ERRORS{'OK'}, 0, "updated private IP address of computer $computer_id in database: $private_ip_address");
+		notify($ERRORS{'OK'}, 0, "updated private IP address of computer $computer_identifier in database: $private_ip_address");
 		return 1;
 	}
 	else {
-		notify($ERRORS{'WARNING'}, 0, "failed to update private IP address of computer $computer_id in database: $private_ip_address");
+		notify($ERRORS{'WARNING'}, 0, "failed to update private IP address of computer $computer_identifier in database: $private_ip_address");
 		return;
 	}
 }
@@ -9890,7 +9906,7 @@ sub stopwatch {
 =cut
 
 sub get_management_node_computer_ids {
-	my $management_node_identifier = shift;
+	my $management_node_identifier = shift || get_management_node_id{};
 	if (!$management_node_identifier) {
 		notify($ERRORS{'WARNING'}, 0, "management node identifier argument was not supplied");
 		return;
@@ -11519,6 +11535,134 @@ EOF
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 get_computer_private_ip_address_info
+
+ Parameters  : @computer_ids (optional)
+ Returns     : hash reference
+ Description : Retrieves the privateIPaddress value from the computer table for
+               all computers in the database. Deleted computers are not
+               included. A hash is constructed:
+               {
+                  "vcl-46.vcl.edu" => "10.10.7.46",
+                  "vcl-47.vcl.edu" => "10.10.7.47",
+                  "vcl-48.vcl.edu" => "10.10.7.48",
+                  "vcl-49.vcl.edu" => "10.10.7.49",
+                  "vcl-50.vcl.edu" => "10.10.7.50",
+               }
+
+=cut
+
+sub get_computer_private_ip_address_info {
+	my @computer_ids = @_;
+	if (@computer_ids) {
+		my @invalid_computer_ids = grep { $_ !~ /^\d+$/ } @computer_ids;
+		if (@invalid_computer_ids) {
+			notify($ERRORS{'WARNING'}, 0, "argument may only contain numberic computer IDs, the following values are not valid:\n" . join("\n", @invalid_computer_ids));
+			return;
+		}
+	}
+	
+	
+	my $select_statement = <<EOF;
+SELECT
+computer.hostname,
+computer.privateIPaddress
+FROM
+computer
+WHERE
+computer.deleted = 0
+EOF
+	
+	if (@computer_ids) {
+		my $computer_id_string = join(', ', @computer_ids);
+		$select_statement .= "AND computer.id IN ($computer_id_string)"
+	}
+
+	my $private_ip_address_info = {};
+	my @rows = database_select($select_statement);
+	for my $row (@rows) {
+		my $hostname = $row->{hostname};
+		my $private_ip_address = $row->{privateIPaddress};
+		$private_ip_address_info->{$hostname} = $private_ip_address;
+	}
+	
+	my $count = scalar(keys %$private_ip_address_info);
+	notify($ERRORS{'DEBUG'}, 0, "retrieved private IP addresses for $count computers from the database");
+	return $private_ip_address_info;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 hostname_to_ip_address
+
+ Parameters  : $hostname
+ Returns     : string
+ Description : Calls gethostbyname on the management node to determine the IP
+               address the hostname resolves to. The IP address is returned. If
+               the hostname cannot be resolved or if an error occurs, null is
+               returned.
+
+=cut
+
+sub hostname_to_ip_address {
+	my ($hostname) = @_;
+	
+	my $packed_ip_address = gethostbyname($hostname);
+	if (defined $packed_ip_address) {
+		my $ip_address = inet_ntoa($packed_ip_address);
+		#notify($ERRORS{'DEBUG'}, 0, "determined IP address hostname $hostname resolves to: $ip_address");
+		return $ip_address;
+	}
+	else {
+		notify($ERRORS{'DEBUG'}, 0, "unable to determined IP address hostname $hostname resolves to");
+		return;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 update_request_checkuser
+
+ Parameters  : $request_id, $checkuser
+ Returns     : boolean
+ Description : Updates the request.checkuser value. This allows modules to
+               disable user connection checking.
+
+=cut
+
+sub update_request_checkuser {
+	my ($request_id, $checkuser) = @_;
+	if (!defined($request_id)) {
+		notify($ERRORS{'WARNING'}, 0, "request ID argument was not supplied");
+		return;
+	}
+	if (!defined($checkuser)) {
+		$checkuser = 0;
+	}
+
+	# Construct the SQL statement
+	my $sql_statement = <<EOF;
+UPDATE
+request
+SET
+checkuser = $checkuser
+WHERE
+request.id = $request_id
+EOF
+
+	# Call the database execute subroutine
+	if (database_execute($sql_statement)) {
+		notify($ERRORS{'OK'}, 0, "updated request.checkuser to $checkuser for request $request_id");
+		return 1;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to update request.checkuser to $checkuser for request $request_id");
+		return;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 1;
 __END__