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__