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__
 


Reply via email to