Author: arkurth
Date: Wed Jul 13 19:34:49 2016
New Revision: 1752533

URL: http://svn.apache.org/viewvc?rev=1752533&view=rev
Log:
VCL-862
Added subroutines to OS.pm:
get_current_image_tag
set_current_image_tag
set_post_load_status
get_post_load_status
set_tainted_status
get_tainted_status

Removed subroutine from OS.pm:
set_vcld_post_load_status

Removed call to set_vcld_post_load_status from each OS module.

Added call to set_post_load_status in image.pm after post_load is called when a 
checkpoint is saved.

Added call to set_tainted_status in reserved.pm::process after the user 
connection check is successful.

Added call to set_tainted_status in OS.pm::run_management_node_tools_scripts if 
a post_reserve script gets executed. The logic is that the post_reserve script 
does something specific to the reservation that may not be reverted if the 
computer is sanitized.  Added call to set_tainted_status to 
Linux.pm::post_reserve and Windows.pm::post_reserve for the same reason.

Added call to get_tainted_status in reclaim.pm::process. If true, node is 
always reloaded.

Removed 'computer_currentimage_vcld_post_load' from DataStructure.pm. It is no 
longer being used. Removed call to 
$self->data->set_computer_currentimage_vcld_post_load from 
OS.pm::get_current_image_info.

Updated Provisioning.pm::node_status to call get_tainted_status and return 
RELOAD if it is set. Reworked node_status and new.pm::reload_image to clean 
things up.

Other
Added optional $suppress_key_missing_error argument to Windows.pm::reg_query. 
Also added check for key or value which doesn't exist.

Added currently unused NFS-related subroutines to Windows.pm.

Modified:
    vcl/trunk/managementnode/lib/VCL/DataStructure.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/ESXi.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/UnixLab.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS/OSX.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_5.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_6.pm
    vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm
    vcl/trunk/managementnode/lib/VCL/Module/Provisioning/openstack.pm
    vcl/trunk/managementnode/lib/VCL/image.pm
    vcl/trunk/managementnode/lib/VCL/new.pm
    vcl/trunk/managementnode/lib/VCL/reclaim.pm
    vcl/trunk/managementnode/lib/VCL/reserved.pm

Modified: vcl/trunk/managementnode/lib/VCL/DataStructure.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/DataStructure.pm?rev=1752533&r1=1752532&r2=1752533&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/DataStructure.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/DataStructure.pm Wed Jul 13 19:34:49 2016
@@ -311,7 +311,6 @@ $SUBROUTINE_MAPPINGS{computer_currentima
 $SUBROUTINE_MAPPINGS{computer_currentimage_reloadtime} = 
'$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{reloadtime}';
 $SUBROUTINE_MAPPINGS{computer_currentimage_size} = 
'$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{size}';
 $SUBROUTINE_MAPPINGS{computer_currentimage_test} = 
'$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{test}';
-$SUBROUTINE_MAPPINGS{computer_currentimage_vcld_post_load} = 
'$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{vcld_post_load}';
  
 $SUBROUTINE_MAPPINGS{computer_currentimagerevision_comments} = 
'$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimagerevision}{comments}';
 $SUBROUTINE_MAPPINGS{computer_currentimagerevision_datecreated} = 
'$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimagerevision}{datecreated}';
 $SUBROUTINE_MAPPINGS{computer_currentimagerevision_deleted} = 
'$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimagerevision}{deleted}';

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=1752533&r1=1752532&r2=1752533&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS.pm Wed Jul 13 19:34:49 2016
@@ -599,14 +599,10 @@ sub get_current_image_info {
        # Make sure an empty hash wasn't returned
        if (defined $current_image_txt_contents{imagerevision_id}) {
                notify($ERRORS{'DEBUG'}, 0, "user selected content of image 
currently loaded on $computer_node_name: 
$current_image_txt_contents{current_image_name}");
-       
+               
                if (my $imagerevision_info = 
get_imagerevision_info($current_image_txt_contents{imagerevision_id})) {
                        
$self->data->set_computer_currentimage_data($imagerevision_info->{image});
                        
$self->data->set_computer_currentimagerevision_data($imagerevision_info);
-                       
-                       if (defined 
$current_image_txt_contents{"vcld_post_load"}) {
-                               
$self->data->set_computer_currentimage_vcld_post_load($current_image_txt_contents{vcld_post_load});
-                       }
                }
                
                if (defined($current_image_txt_contents{$input})) {
@@ -948,7 +944,7 @@ sub is_ssh_responding {
                        command => "echo \"testing ssh on 
$computer_node_name\"",
                        max_attempts => $max_attempts,
                        display_output => 0,
-                       timeout_seconds => 10,
+                       timeout_seconds => 15,
                });
                
                # The exit status will be 0 if the command succeeded
@@ -1344,14 +1340,99 @@ sub update_public_ip_address {
 
 #/////////////////////////////////////////////////////////////////////////////
 
-=head2 set_vcld_post_load_status
+=head2 get_current_image_tag
 
- Parameters  : none
+ Parameters  : $tag_name
+ Returns     : string or array
+ Description : Reads currentimage.txt and attempts to locate a line beginning
+               with the tag name specified by the argument.
+               
+               If found and called in scalar context, the tag value following
+               the = sign is returned. Example currentimage.txt line:
+               mytag=0 (Wed Jun 29 17:47:36 2016)
+               
+               my $x = get_current_image_tag('mytag');
+               $x = 0
+               
+               my ($x, $y) = get_current_image_tag('mytag');
+               $x = 0
+               $y = 'Wed Jun 29 17:47:36 2016'
+               
+               Null is returned if a line with the tag name doesn't exist.
+
+=cut
+
+sub get_current_image_tag {
+       my $self = shift;
+       if (ref($self) !~ /VCL::Module/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       
+       my ($tag_name) = @_;
+       if (!defined($tag_name)) {
+               notify($ERRORS{'WARNING'}, 0, "property argument was not 
specified");
+               return;
+       }
+       
+       my $computer_name = $self->data->get_computer_short_name();
+       
+       my $current_image_file_path = 'currentimage.txt';
+       
+       my @lines = $self->get_file_contents($current_image_file_path);
+       for my $line (@lines) {
+               my ($tag_value, $timestamp) = $line =~ 
/^$tag_name=(.+)\s\((.+)\)$/g;
+               if (defined($tag_value)) {
+                       if (wantarray) {
+                               notify($ERRORS{'DEBUG'}, 0, "found '$tag_name' 
tag line in $current_image_file_path: '$line', returning array: ('$tag_value', 
'$timestamp')");
+                               return ($tag_value, $timestamp);
+                       }
+                       else {
+                               notify($ERRORS{'DEBUG'}, 0, "found '$tag_name' 
tag line in $current_image_file_path: '$line', returning tag value: 
'$tag_value'");
+                               return $tag_value;
+                       }
+               }
+       }
+       
+       notify($ERRORS{'DEBUG'}, 0, "'$tag_name' tag is not set in 
$current_image_file_path, returning null");
+       return;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 set_current_image_tag
+
+ Parameters  : $tag_name, $tag_value
  Returns     : boolean
- Description : Adds a line to currentimage.txt indicating the vcld OS post_load
-               tasks have run. The format of the line added is:
-               vcld_post_load=success (<time>)
+ Description : Adds a line to currentimage.txt in the format:
+               <tag name>=<tag value> (timestamp)
+                                       
+                                       The tag value must be a non-empty 
string and may be the integer
+                                       0. Example:
+                                       set_current_image_tag('mytag');
+                                       
+                                       Line added:
+                                       mytag=0 (Wed Jun 29 17:47:36 2016)
+                                       
+                                       Any lines which already exist beginning 
with an identical tag
+                                       name are removed.
+               
+                                       indicating a loaded computer is
+                                       tainted and must be reloaded for any 
subsequent reservations. The
+                                       format of the line added is:
+               vcld_tainted=true (<time>)
                
+                                       This line is added as a safety measure 
to prevent a computer
+                                       which was used for one reservation to 
ever be reserved for
+                                       another reservation without being 
reloaded.
+                                       
+                                       This line should be added whenever a 
user has been given the
+                                       connection information and had a chance 
to connect. It's assumed
+                                       a user connected and the computer is 
tainted whether or not an
+                                       actual logged in connection was 
detected. This is done for
+                                       safety. The connection/logged in 
checking mechanisms of different
+                                       OS's may not be perfect.
+                                       
                This line is checked when a computer is reserved to make sure 
the
                post_load tasks have run. A computer may be loaded but the
                post_load tasks may not run if it is loaded manually or by some
@@ -1359,28 +1440,173 @@ sub update_public_ip_address {
 
 =cut
 
-sub set_vcld_post_load_status {
+sub set_current_image_tag {
        my $self = shift;
        if (ref($self) !~ /VCL::Module/i) {
                notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
                return;
        }
        
-       my $file_path = 'currentimage.txt';
+       my ($tag_name, $tag_value) = @_;
+       if (!$tag_name) {
+               notify($ERRORS{'WARNING'}, 0, "tag name argument was not 
specified");
+               return;
+       }
+       elsif (!defined($tag_value)) {
+               notify($ERRORS{'WARNING'}, 0, "tag value argument was not 
specified");
+               return;
+       }
+       elsif (!length($tag_value)) {
+               notify($ERRORS{'WARNING'}, 0, "tag value argument specified is 
an empty string");
+               return;
+       }
+       
+       my $computer_name = $self->data->get_computer_short_name();
        
-       my $time = localtime;
-       my $post_load_line = "vcld_post_load=success ($time)";
+       my $current_image_file_path = 'currentimage.txt';
+       my $timestamp = localtime;
+       my $tag_line = "$tag_name=$tag_value ($timestamp)";
+       my $updated_contents = '';
        
-       my $file_contents;
-       my @existing_lines = $self->get_file_contents($file_path);
+       my @existing_lines = $self->get_file_contents($current_image_file_path);
        for my $existing_line (@existing_lines) {
-               if ($existing_line !~ /\w/ || $existing_line =~ 
/^vcld_post_load/) {
+               # Skip blank lines and lines matching the tag name
+               if ($existing_line !~ /\w/ || $existing_line =~ /^$tag_name=/) {
                        next;
                }
-               $file_contents .= "$existing_line\n";
+               $updated_contents .= "$existing_line\n";
+       }
+       $updated_contents .= $tag_line;
+       
+       if ($self->create_text_file($current_image_file_path, 
$updated_contents)) {
+               notify($ERRORS{'DEBUG'}, 0, "set '$tag_name' tag in 
$current_image_file_path on $computer_name:\n$updated_contents");
+               return 1;
+       }
+       else {
+               notify($ERRORS{'WARNING'}, 0, "failed to set '$tag_name' tag in 
$current_image_file_path on $computer_name");
+               return 0;
+       }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 set_post_load_status
+
+ Parameters  : none
+ Returns     : boolean
+ Description : Adds a line to currentimage.txt indicating the post-load tasks
+               have successfully been completed on a loaded computer. The
+               format of the line is:
+               tainted=true (Wed Jun 29 18:00:55 2016)
+
+=cut
+
+sub set_post_load_status {
+       my $self = shift;
+       if (ref($self) !~ /VCL::Module/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       
+       return $self->set_current_image_tag('vcld_post_load', 'success');
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_post_load_status
+
+ Parameters  : none
+ Returns     : boolean
+ Description : Checks if a 'vcld_post_load' line exists in currentimage.txt.
+
+=cut
+
+sub get_post_load_status {
+       my $self = shift;
+       if (ref($self) !~ /VCL::Module/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       
+       my $computer_name = $self->data->get_computer_short_name();
+       
+       my ($post_load_value, $timestamp) = 
$self->get_current_image_tag('vcld_post_load');
+       if (defined($post_load_value)) {
+               notify($ERRORS{'DEBUG'}, 0, "post-load tasks have been 
completed on $computer_name: $post_load_value ($timestamp)");
+               return 1;
+       }
+       else {
+               notify($ERRORS{'DEBUG'}, 0, "post-load tasks have NOT been 
completed on $computer_name");
+               return 0;
+       }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 set_tainted_status
+
+ Parameters  : none
+ Returns     : boolean
+ Description : Adds a line to currentimage.txt indicating a loaded computer is
+               tainted and must be reloaded for any subsequent reservations.
+               
+               This line is added as a safety measure to prevent a computer
+               which was used for one reservation to ever be reserved for
+               another reservation without being reloaded.
+               
+               This line should be added whenever a user has been given the
+               connection information and had a chance to connect. It's assumed
+               a user connected and the computer is tainted whether or not an
+               actual logged in connection was detected. This is done for
+               safety. The connection/logged in checking mechanisms of 
different
+               OS's may not be perfect.
+               
+               This line is checked when a computer is reserved to make sure 
the
+               post_load tasks have run. A computer may be loaded but the
+               post_load tasks may not run if it is loaded manually or by some
+               other means not controlled by vcld.
+
+=cut
+
+sub set_tainted_status {
+       my $self = shift;
+       if (ref($self) !~ /VCL::Module/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       
+       return $self->set_current_image_tag('vcld_tainted', 'true');
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_tainted_status
+
+ Parameters  : none
+ Returns     : boolean
+ Description : Checks if a line exists in currentimage.txt indicated a user may
+               have logged in.
+
+=cut
+
+sub get_tainted_status {
+       my $self = shift;
+       if (ref($self) !~ /VCL::Module/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       
+       my $computer_name = $self->data->get_computer_short_name();
+       
+       my ($tainted_value, $timestamp) = 
$self->get_current_image_tag('vcld_tainted');
+       if (defined($tainted_value)) {
+               notify($ERRORS{'DEBUG'}, 0, "image currently loaded on 
$computer_name has been tainted: $tainted_value ($timestamp)");
+               return 1;
+       }
+       else {
+               notify($ERRORS{'DEBUG'}, 0, "image currently loaded on 
$computer_name has NOT been tainted");
+               return 0;
        }
-       $file_contents .= $post_load_line;
-       return $self->create_text_file($file_path, $file_contents);
 }
 
 #/////////////////////////////////////////////////////////////////////////////
@@ -3954,6 +4180,13 @@ sub run_management_node_tools_scripts {
                return 1;
        }
        
+       # If post_reserve script exists, assume it does user or 
reservation-specific actions
+       # If the user never connects and the reservation times out, there's no 
way to revert these actions in order to clean the computer for another user
+       # Tag the image as tainted so it is reloaded
+       if ($stage =~ /(post_reserve)/) {
+               $self->set_tainted_status();
+       }
+       
        notify($ERRORS{'DEBUG'}, 0, "attempting to execute custom scripts 
residing on the management node for $image_name on $computer_node_name:\n" . 
join("\n", @computer_tools_files));
        for my $computer_tools_file_path (@computer_tools_files) {
                notify($ERRORS{'DEBUG'}, 0, "executing script on 
$computer_node_name: $computer_tools_file_path");

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm?rev=1752533&r1=1752532&r2=1752533&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm Wed Jul 13 19:34:49 2016
@@ -533,9 +533,6 @@ sub post_load {
                }
        }
        
-       # Add a line to currentimage.txt indicating post_load has run
-       $self->set_vcld_post_load_status();
-       
        return 1;
 } ## end sub post_load
 
@@ -556,9 +553,9 @@ sub post_reserve {
                return 0;
        }
        
+       my $reservation_id = $self->data->get_reservation_id();
        my $image_name = $self->data->get_image_name();
        my $computer_short_name = $self->data->get_computer_short_name();
-       my @post_reserve_script_paths = ('/usr/local/vcl/vcl_post_reserve', 
'/etc/init.d/vcl_post_reserve');
        
        notify($ERRORS{'OK'}, 0, "initiating Linux post_reserve: $image_name on 
$computer_short_name");
        
@@ -571,12 +568,9 @@ sub post_reserve {
        # write contents to local temp file 
/tmp/resrvationid_post_reserve_userdata
        # scp tmpfile to ‘/root/.vclcontrol/post_reserve_userdata’
        # assumes the image has the call in vcl_post_reserve to import/read the 
user data file
-       
-       my $reservation_id = $self->data->get_reservation_id();
        my $variable_name = "userdata|$reservation_id"; 
        my $variable_data;
        my $target_location = "/root/.vclcontrol/post_reserve_userdata";
-
        if ($self->data->is_variable_set($variable_name)) {
                $variable_data = $self->data->get_variable($variable_name);
                
@@ -600,9 +594,14 @@ sub post_reserve {
        }
        
        # Check if script exists
+       my @post_reserve_script_paths = ('/usr/local/vcl/vcl_post_reserve', 
'/etc/init.d/vcl_post_reserve');
        foreach my $script_path (@post_reserve_script_paths) {
-                       notify($ERRORS{'DEBUG'}, 0, "script_path $script_path");
                if ($self->file_exists($script_path)) {
+                       # If post_reserve script exists, assume it does user or 
reservation-specific actions
+                       # If the user never connects and the reservation times 
out, there's no way to revert these actions in order to clean the computer for 
another user
+                       # Tag the image as tainted so it is reloaded
+                       $self->set_tainted_status();
+                       
                        # Run the vcl_post_reserve script if it exists in the 
image
                        my $result = $self->run_script($script_path, '1', 
'300', '1');
                        if (!defined($result)) {

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/ESXi.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/ESXi.pm?rev=1752533&r1=1752532&r2=1752533&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/ESXi.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/ESXi.pm Wed Jul 13 
19:34:49 2016
@@ -92,8 +92,6 @@ sub post_load {
                return 0;
        }
        
-       $self->set_vcld_post_load_status();
-       
        return 1;
 }
 

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/UnixLab.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/UnixLab.pm?rev=1752533&r1=1752532&r2=1752533&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/UnixLab.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/UnixLab.pm Wed Jul 13 
19:34:49 2016
@@ -604,10 +604,6 @@ sub get_current_image_info {
                if (my $imagerevision_info = 
get_imagerevision_info($current_image_txt_contents{imagerevision_id})) {
                        
$self->data->set_computer_currentimage_data($imagerevision_info->{image});
                        
$self->data->set_computer_currentimagerevision_data($imagerevision_info);
-                       
-                       if (defined 
$current_image_txt_contents{"vcld_post_load"}) {
-                               
$self->data->set_computer_currentimage_vcld_post_load($current_image_txt_contents{vcld_post_load});
-                       }
                }
                
                if (defined($current_image_txt_contents{$input})) {

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/OSX.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/OSX.pm?rev=1752533&r1=1752532&r2=1752533&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/OSX.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/OSX.pm Wed Jul 13 19:34:49 2016
@@ -276,9 +276,6 @@ sub post_load {
        
        $self->activate_irapp();
        
-       # Add a line to currentimage.txt indicating post_load has run
-       $self->set_vcld_post_load_status();
-       
        notify($ERRORS{'OK'}, 0, "returning 1");
        return 1;
 
@@ -1650,7 +1647,7 @@ sub get_network_configuration {
 
 #/////////////////////////////////////////////////////////////////////////////
 
-=head2 set_vcld_post_load_status
+=head2 set_post_load_status
 
  Parameters  : none
  Returns     : boolean
@@ -1665,7 +1662,7 @@ sub get_network_configuration {
 
 =cut
 
-sub set_vcld_post_load_status {
+sub set_post_load_status {
        my $self = shift;
        if (ref($self) !~ /VCL::Module/i) {
                notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm?rev=1752533&r1=1752532&r2=1752533&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm Wed Jul 13 19:34:49 
2016
@@ -1008,6 +1008,11 @@ sub post_reserve {
                return 1;
        }
        else {
+               # If post_reserve script exists, assume it does user or 
reservation-specific actions
+               # If the user never connects and the reservation times out, 
there's no way to revert these actions in order to clean the computer for 
another user
+               # Tag the image as tainted so it is reloaded
+               $self->set_tainted_status();
+               
                # Run the post_reserve script
                $self->run_script($script_path);
        }
@@ -2413,7 +2418,7 @@ sub import_registry_string {
 
 =head2 reg_query
 
- Parameters  : $registry_key, $registry_value (optional)
+ Parameters  : $registry_key, $registry_value (optional), 
$suppress_key_missing_error (optional)
  Returns     : If $registry_value argument is specified: scalar
                If $registry_value argument is specified: hash reference
  Description : Queries the registry on the Windows computer. The $registry_key
@@ -2462,6 +2467,8 @@ sub reg_query {
        }
        my $value_argument = shift;
        
+       my $suppress_key_missing_error = shift;
+       
        # Replace forward slashes and double backslashes with a single 
backslashes
        $key_argument =~ s/[\\\/]+/\\/g;
        
@@ -2503,6 +2510,15 @@ sub reg_query {
                notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to 
query registry key: $key_argument");
                return;
        }
+       elsif (grep(/unable to find the specified registry/, @$output)) {
+               my $message = "registry key or value does not exist:\nkey: 
'$key_argument'\n";
+               $message .= "value: '$value_argument'\n" if 
defined($value_argument);
+               $message .= "command: '$command'\n";
+               $message .= "exit status: $exit_status\n";
+               $message .= "output:\n" . join("\n", @{$output});
+               notify($ERRORS{'WARNING'}, 0, $message) unless 
$suppress_key_missing_error;
+               return;
+       }
        elsif (!grep(/REG.EXE VERSION|HKEY/, @$output)) {
                my $message = "failed to query registry:\nkey: 
'$key_argument'\n";
                $message .= "value: '$value_argument'\n" if 
defined($value_argument);
@@ -3074,7 +3090,7 @@ EOF
 
 #/////////////////////////////////////////////////////////////////////////////
 
-=head2 delete_hklm_run_registry_value
+=head2 delete_hklm_run_registry_key
 
  Parameters  :
  Returns     :
@@ -12216,6 +12232,181 @@ sub _get_os_perl_package {
        return $perl_package;
 }
 
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 mount_nfs_windows
+
+ Parameters  : $remote_nfs_share, $drive_letter (optional), $options (optional)
+ Returns     : boolean
+ Description : Mounts an NFS share on the computer using the Windows NFS 
client.
+
+=cut
+
+sub mount_nfs_windows {
+       my $self = shift;
+       if (ref($self) !~ /VCL::Module/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       
+       my ($remote_nfs_share, $drive_letter, $options) = @_;
+       if (!defined($remote_nfs_share)) {
+               notify($ERRORS{'WARNING'}, 0, "remote target argument was not 
supplied");
+               return;
+       }
+       
+       my $system32_path = $self->get_system32_path() || return;
+       my $computer_name = $self->data->get_computer_node_name();
+
+       # Usage:  mount [-o options] [-u:username] [-p:<password | *>] 
<\\computername\sharename> <devicename | *>
+       # 
+       # -o rsize=size               To set the size of the read buffer in 
kilobytes.
+       # -o wsize=size               To set the size of the write buffer in 
kilobytes.
+       # -o timeout=time             To set the timeout value in seconds for 
an RPC call.
+       # -o retry=number             To set the number of retries for a soft 
mount.
+       # -o mtype=soft|hard          To set the mount type.
+       # -o lang=euc-jp|euc-tw|euc-kr|shift-jis|big5|ksc5601|gb2312-80|ansi
+       #                             To specify the encoding used for file and 
directory
+       #                             names.
+       # -o fileaccess=mode          To specify the permission mode of the 
file.
+       #                             These are used for new files created on 
NFS
+       #                             servers. Specified using UNIX style mode 
bits.
+       # -o anon                     To mount as an anonymous user.
+       # -o nolock                   To disable locking.
+       # -o casesensitive=yes|no     To specify case sensitivity of file 
lookup on server.
+       # -o sec=sys|krb5|krb5i
+
+       # These formats work:
+       #    mount x.x.x.x:/sharename n:
+       #    mount \\x.x.x.x\sharename n:
+       
+       # Windows can't mount directly to a directory, check if a drive letter 
was passed
+       if (!$drive_letter) {
+               $drive_letter = '*';
+       }
+       elsif ($drive_letter !~ /^[a-z]:?$/i) {
+               notify($ERRORS{'WARNING'}, 0, "invalid drive letter argument 
was specified: $drive_letter, using next available drive letter");
+               $drive_letter = '*';
+       }
+       
+       # Add a trailing colon
+       $drive_letter =~ s/:*$/:/;
+       
+       my $command = "$system32_path/mount.exe";
+       
+       # Figure out which options to use       
+       # If using Netapp, see: 
https://library.netapp.com/ecmdocs/ECMP12365051/html/GUID-B7080A75-610D-46E1-A0EE-6CF1716636A0.html
+       # According to doc, must use hard mounts for Netapp
+       if ($options) {
+               # Check if mtype was specified, don't override
+               if ($options !~ /mtype/) {
+                       $options .= ",mtype=hard";
+               }
+       }
+       else {
+               $options = "mtype=hard";
+       }
+       $command .= " -o $options";
+       $command .= " $remote_nfs_share $drive_letter";
+       
+       # Escape *
+       $command =~ s/\*/\\\*/g;
+       
+       notify($ERRORS{'DEBUG'}, 0, "attempting to mount NFS share on 
$computer_name: '$command'");
+       my ($exit_status, $output) = $self->execute($command);
+       if (!defined($output)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to execute command on 
$computer_name: '$command'");
+               return;
+       }
+       elsif ($exit_status ne '0') {
+               notify($ERRORS{'WARNING'}, 0, "failed to mount Windows client 
NFS share on $computer_name, exit status: $exit_status, 
command:\n$command\noutput:\n" . join("\n", @$output));
+               return 0;
+       }
+       else {
+               notify($ERRORS{'OK'}, 0, "mounted Windows client NFS share on 
$computer_name: '$command'\noutput:\n" . join("\n", @$output));
+               return 1;
+       }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 unmount_nfs_windows
+
+ Parameters  : none
+ Returns     : boolean
+ Description : Unmounts all NFS shares on the computer using the Windows NFS
+               client.
+
+=cut
+
+sub unmount_nfs_windows {
+       my $self = shift;
+       if (ref($self) !~ /VCL::Module/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       
+       my $system32_path = $self->get_system32_path() || return;
+       my $computer_name = $self->data->get_computer_node_name();
+
+       # Usage:  [-f] <-a | drive_letters | network_mounts>
+       # -a      Delete all NFS network mount points
+       # -f      Force delete NFS network mount points
+
+       my $command = "$system32_path/umount.exe -a -f";
+       my ($exit_status, $output) = $self->execute($command);
+       if (!defined($output)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to execute command on 
$computer_name: $command");
+               return;
+       }
+       elsif ($exit_status ne '0') {
+               notify($ERRORS{'WARNING'}, 0, "failed to unmount Windows client 
NFS shares on $computer_name, exit status: $exit_status, 
command:\n$command\noutput:\n" . join("\n", @$output));
+               return 0;
+       }
+       else {
+               notify($ERRORS{'OK'}, 0, "unmounted Windows client NFS shares 
on $computer_name: '$command'\noutput:\n" . join("\n", @$output));
+               return 1;
+       }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_nfs_mounts_windows
+
+ Parameters  : none
+ Returns     : 
+ Description : Retrieves all currently mounted NFS shares on the computer using
+               the Windows NFS client.
+
+=cut
+
+sub get_nfs_mounts_windows {
+       my $self = shift;
+       if (ref($self) !~ /VCL::Module/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       
+       my $system32_path = $self->get_system32_path() || return;
+       my $computer_name = $self->data->get_computer_node_name();
+       
+       my $command = "$system32_path/mount.exe";
+       my ($exit_status, $output) = $self->execute($command);
+       if (!defined($output)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to execute command on 
$computer_name: $command");
+               return;
+       }
+       elsif ($exit_status ne '0') {
+               notify($ERRORS{'WARNING'}, 0, "failed to retrieve mounted 
Windows client NFS shares on $computer_name, exit status: $exit_status, 
command:\n$command\noutput:\n" . join("\n", @$output));
+               return 0;
+       }
+       else {
+               notify($ERRORS{'OK'}, 0, "retrieved mounted Windows client NFS 
shares on $computer_name, command: '$command', output:\n" . join("\n", 
@$output));
+               return 1;
+       }
+}
+
 #/////////////////////////////////////////////////////////////////////////////
 
 1;

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_5.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_5.pm?rev=1752533&r1=1752532&r2=1752533&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_5.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_5.pm Wed Jul 13 
19:34:49 2016
@@ -178,18 +178,9 @@ sub post_load {
                notify($ERRORS{'DEBUG'}, 0, "custom post_load script does NOT 
exist in image: $script_path");
        }
        else {
-               # Run the post_reserve script
                $self->run_script($script_path);
        }
 
-=item *
-
- Add a line to currentimage.txt indicating post_load has run
-
-=cut
-
-       $self->set_vcld_post_load_status();
-
 =back
 
 =cut

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_6.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_6.pm?rev=1752533&r1=1752532&r2=1752533&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_6.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Windows/Version_6.pm Wed Jul 13 
19:34:49 2016
@@ -291,18 +291,9 @@ sub post_load {
                notify($ERRORS{'DEBUG'}, 0, "custom post_load script does NOT 
exist in image: $script_path");
        }
        else {
-               # Run the post_reserve script
                $self->run_script($script_path);
        }
 
-=item *
-
- Add a line to currentimage.txt indicating post_load has run
-
-=cut
-
-       $self->set_vcld_post_load_status();
-
 =back
 
 =cut

Modified: vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm?rev=1752533&r1=1752532&r2=1752533&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/Provisioning.pm Wed Jul 13 19:34:49 
2016
@@ -66,7 +66,7 @@ use VCL::utils;
 
 =head2 node_status
 
- Parameters  : $computer_id (optional)
+ Parameters  : none
  Returns     : string
  Description : Checks the status of the computer in order to determine if the
                computer is ready to be reserved or needs to be reloaded. A
@@ -76,6 +76,7 @@ use VCL::utils;
                   * It is accessible
                   * It is loaded with the correct image
                   * OS module's post-load tasks have run
+                  * Computer has not been tagged with a tainted tag
                'POST_LOAD':
                   * Computer is loaded with the correct image
                   * OS module's post-load tasks have not run
@@ -86,135 +87,55 @@ use VCL::utils;
 =cut
 
 sub node_status {
-       my $self;
-       
-       # Get the argument
-       my $argument = shift;
-       
-       # Check if this subroutine was called an an object method or an 
argument was passed
-       if (ref($argument) =~ /VCL::Module/i) {
-               $self = $argument;
-       }
-       elsif (!ref($argument) || ref($argument) eq 'HASH') {
-               # An argument was passed, check its type and determine the 
computer ID
-               my $computer_id;
-               if (ref($argument)) {
-                       # Hash reference was passed
-                       $computer_id = $argument->{id};
-               }
-               elsif ($argument =~ /^\d+$/) {
-                       # Computer ID was passed
-                       $computer_id = $argument;
-               }
-               else {
-                       # Computer name was passed
-                       ($computer_id) = get_computer_ids($argument);
-               }
-               
-               if ($computer_id) {
-                       notify($ERRORS{'DEBUG'}, 0, "computer ID: 
$computer_id");
-               }
-               else {
-                       notify($ERRORS{'DEBUG'}, 0, "unable to determine 
computer ID from argument:\n" . format_data($argument));
-                       return;
-               }
-               
-               # Create a DataStructure object containing data for the 
computer specified as the argument
-               my $data;
-               eval {
-                       $data= new VCL::DataStructure({computer_identifier => 
$computer_id});
-               };
-               if ($EVAL_ERROR) {
-                       notify($ERRORS{'WARNING'}, 0, "failed to create 
DataStructure object for computer ID: $computer_id, error: $EVAL_ERROR");
-                       return;
-               }
-               elsif (!$data) {
-                       notify($ERRORS{'WARNING'}, 0, "failed to create 
DataStructure object for computer ID: $computer_id, DataStructure object is not 
defined");
-                       return;
-               }
-               else {
-                       notify($ERRORS{'DEBUG'}, 0, "created DataStructure 
object  for computer ID: $computer_id");
-               }
-               
-               # Create a provisioning object
-               my $provisioning_module_perl_package = 
$data->get_computer_provisioning_module_perl_package();
-               if ($self = 
($provisioning_module_perl_package)->new({data_structure => $data})) {
-                       notify($ERRORS{'DEBUG'}, 0, "created 
$provisioning_module_perl_package object to check the status of computer ID: 
$computer_id");
-               }
-               else {
-                       notify($ERRORS{'WARNING'}, 0, "failed to create 
$provisioning_module_perl_package object to check the status of computer ID: 
$computer_id");
-                       return;
-               }
-               
-               # Create an OS object for the provisioning object to access
-               if (!$self->create_os_object()) {
-                       notify($ERRORS{'WARNING'}, 0, "failed to create OS 
object");
-                       return;
-               }
+       my $self = shift;
+       unless (ref($self) && $self->isa('VCL::Module')) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
        }
        
-       my $reservation_id = $self->data->get_reservation_id();
        my $computer_name = $self->data->get_computer_node_name();
        my $image_name = $self->data->get_image_name();
-       my $request_forimaging = $self->data->get_request_forimaging();
-       my $imagerevision_id = $self->data->get_imagerevision_id();
-       
-       notify($ERRORS{'DEBUG'}, 0, "attempting to check the status of computer 
$computer_name, image: $image_name imagerevision_id; $imagerevision_id");
+       my $reservation_imagerevision_id = $self->data->get_imagerevision_id();
        
-       # Create a hash reference and populate it with the default values
-       my $status;
-       $status->{currentimage} = '';
-       $status->{ssh} = 0;
-       $status->{image_match} = 0;
-       $status->{status} = 'RELOAD';
+       notify($ERRORS{'DEBUG'}, 0, "checking if $computer_name is responding 
and loaded with $image_name, imagerevision ID: $reservation_imagerevision_id");
        
        # Check if SSH is available
-       if ($self->os->is_ssh_responding()) {
-               notify($ERRORS{'DEBUG'}, 0, "$computer_name is responding to 
SSH");
-               $status->{ssh} = 1;
-       }
-       else {
+       if (!$self->os->is_ssh_responding()) {
                notify($ERRORS{'OK'}, 0, "$computer_name is not responding to 
SSH, returning 'RELOAD'");
-               $status->{status} = 'RELOAD';
-               $status->{ssh} = 0;
-               
-               # Skip remaining checks if SSH isn't available
-               return $status;
+               return 'RELOAD';
        }
        
-       # Get the contents of currentimage.txt and check if currentimage.txt 
matches the requested image name
+       # Check if the imagerevision ID loaded on the computer matches the 
reservation
        my $current_image_revision_id = $self->os->get_current_image_info();
-       $status->{currentimagerevision_id} = $current_image_revision_id;
-
-       $status->{currentimage} = $self->data->get_computer_currentimage_name();
-       my $vcld_post_load_status = 
$self->data->get_computer_currentimage_vcld_post_load(0);
-       
        if (!$current_image_revision_id) {
-               notify($ERRORS{'OK'}, 0, "unable to retrieve currentimage.txt 
contents on $computer_name, returning 'RELOAD'");
-               return $status;
+               notify($ERRORS{'OK'}, 0, "unable to retrieve imagerevision ID 
from $computer_name, returning 'RELOAD'");
+               return 'RELOAD';
        }
-       #elsif ($current_image_name eq $image_name) {
-       elsif ($current_image_revision_id eq $imagerevision_id) {
-               notify($ERRORS{'DEBUG'}, 0, "currentimage.txt image 
$current_image_revision_id ($status->{currentimage}) matches requested image 
$imagerevision_id ($image_name) on $computer_name");
-               $status->{image_match} = 1;
+       elsif ($current_image_revision_id ne $reservation_imagerevision_id) {
+               notify($ERRORS{'OK'}, 0, "$computer_name is loaded with 
imagerevision ID: $current_image_revision_id, not 
$reservation_imagerevision_id, returning 'RELOAD'");
+               return 'RELOAD';
        }
        else {
-               notify($ERRORS{'OK'}, 0, "currentimage.txt image 
$current_image_revision_id ($status->{currentimage}) does not match requested 
image name $imagerevision_id ($image_name) on $computer_name, returning 
'RELOAD'");
-               return $status;
+               notify($ERRORS{'DEBUG'}, 0, "$computer_name is loaded with the 
correct imagerevision ID: $current_image_revision_id");
        }
        
-       # Check if the OS post_load tasks have run
-       if ($vcld_post_load_status) {
-               notify($ERRORS{'DEBUG'}, 0, "OS module post_load tasks have 
been completed on $computer_name");
-               $status->{status} = 'READY';
+       # Check if current image has been tagged as tainted
+       my $tainted_status = $self->os->get_tainted_status();
+       if ($tainted_status) {
+               notify($ERRORS{'WARNING'}, 0, "user may have previously had the 
ability to log in to the image currently loaded on $computer_name, current 
image is tagged as tainted, returning 'RELOAD'");
+               return 'RELOAD';
+       }
+       
+       # Check if the post-load tasks have been completed
+       my $post_load_status = $self->os->get_post_load_status();
+       if ($post_load_status) {
+               notify($ERRORS{'OK'}, 0, "OS module post_load tasks have been 
completed on $computer_name, returning 'READY'");
+               return 'READY';
        }
        else {
-               notify($ERRORS{'DEBUG'}, 0, "OS module post_load tasks have not 
been completed on $computer_name, returning 'POST_LOAD'");
-               $status->{status} = 'POST_LOAD';
+               notify($ERRORS{'DEBUG'}, 0, "OS module post_load tasks have NOT 
been completed on $computer_name, returning 'POST_LOAD'");
+               return 'POST_LOAD';
        }
-       
-       notify($ERRORS{'OK'}, 0, "status of $computer_name: $status->{status}");
-       return $status;
 }
 
 #/////////////////////////////////////////////////////////////////////////////

Modified: vcl/trunk/managementnode/lib/VCL/Module/Provisioning/openstack.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/openstack.pm?rev=1752533&r1=1752532&r2=1752533&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/Provisioning/openstack.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/Provisioning/openstack.pm Wed Jul 
13 19:34:49 2016
@@ -536,7 +536,7 @@ sub node_status {
 
        $status->{currentimage} = $self->data->get_computer_currentimage_name();
        my $current_image_name = $status->{currentimage};
-       my $vcld_post_load_status = 
$self->data->get_computer_currentimage_vcld_post_load();
+       my $vcld_post_load_status = $self->os->get_post_load_status();
 
        if (!$current_image_revision_id) {
                notify($ERRORS{'OK'}, 0, "unable to retrieve image name from 
currentimage.txt on VM $computer_name, returning 'RELOAD'");

Modified: vcl/trunk/managementnode/lib/VCL/image.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/image.pm?rev=1752533&r1=1752532&r2=1752533&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/image.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/image.pm Wed Jul 13 19:34:49 2016
@@ -174,7 +174,11 @@ sub process {
                
                # Check if the OS module implements a post_load subroutine
                if ($self->os->can('post_load')) {
-                       if (!$self->os->post_load()) {
+                       if ($self->os->post_load()) {
+                               # Add a line to currentimage.txt indicating 
post_load has run
+                               $self->os->set_post_load_status();
+                       }
+                       else {
                                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();
                        }

Modified: vcl/trunk/managementnode/lib/VCL/new.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/new.pm?rev=1752533&r1=1752532&r2=1752533&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/new.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/new.pm Wed Jul 13 19:34:49 2016
@@ -466,71 +466,18 @@ sub reload_image {
        my $server_request_id               = 
$self->data->get_server_request_id();
        my $server_request_fixed_ip         = 
$self->data->get_server_request_fixed_ip();
        
-       # Try to get the node status if the provisioning engine has implemented 
a node_status() subroutine
-       my $node_status;
-       my $node_status_string = '';
-       if ($self->provisioner->can("node_status")) {
-               notify($ERRORS{'DEBUG'}, 0, "calling " . 
ref($self->provisioner) . "->node_status()");
-               insertloadlog($reservation_id, $computer_id, "statuscheck", 
"checking status of node");
-               
-               # Call node_status(), check the return value
-               $node_status = $self->provisioner->node_status();
-               
-               # Make sure a return value is defined, an error occurred if it 
is undefined
-               if (!defined($node_status)) {
-                       notify($ERRORS{'CRITICAL'}, 0, ref($self->provisioner) 
. "->node_status() returned an undefined value, returning");
-                       return;
-               }
-               
-               # Check what node_status returned and try to get the "status" 
string
-               # First see if it returned a hashref
-               if (ref($node_status) eq 'HASH') {
-                       notify($ERRORS{'DEBUG'}, 0, "node_status returned a 
hash reference");
-                       
-                       # Check if the hash contains a key called "status"
-                       if (defined $node_status->{status}) {
-                               $node_status_string = $node_status->{status};
-                               notify($ERRORS{'DEBUG'}, 0, "node_status hash 
reference contains key {status}=$node_status_string");
-                       }
-                       else {
-                               notify($ERRORS{'DEBUG'}, 0, "node_status hash 
reference does not contain a key called 'status'");
-                       }
-               } ## end if (ref($node_status) eq 'HASH')
-               
-               # Check if node_status returned an array ref
-               elsif (ref($node_status) eq 'ARRAY') {
-                       notify($ERRORS{'DEBUG'}, 0, "node_status returned an 
array reference");
-                       
-                       # Check if the hash contains a key called "status"
-                       if (defined((@{$node_status})[0])) {
-                               $node_status_string = (@{$node_status})[0];
-                               notify($ERRORS{'DEBUG'}, 0, "node_status array 
reference contains index [0]=$node_status_string");
-                       }
-                       else {
-                               notify($ERRORS{'DEBUG'}, 0, "node_status array 
reference is empty");
-                       }
-               } ## end elsif (ref($node_status) eq 'ARRAY')  [ if 
(ref($node_status) eq 'HASH')
-               
-               # Check if node_status didn't return a reference
-               # Assume string was returned
-               elsif (!ref($node_status)) {
-                       # Use scalar value of node_status's return value
-                       $node_status_string = $node_status;
-                       notify($ERRORS{'DEBUG'}, 0, "node_status returned a 
scalar: $node_status");
-               }
-               
-               else {
-                       notify($ERRORS{'CRITICAL'}, 0, ref($self->provisioner) 
. "->node_status() returned an unsupported reference type: " . 
ref($node_status) . ", returning");
-                       insertloadlog($reservation_id, $computer_id, "failed", 
"node_status() returned an undefined value");
-                       return;
-               }
-       } ## end if ($self->provisioner->can("node_status"))
+       my $node_status_string;
+       insertloadlog($reservation_id, $computer_id, "statuscheck", "checking 
status of node");
+       
+       # If request state is 'reinstall' or computer state is 'reload', force 
reload
+       if ($request_state_name eq 'reinstall' || $computer_state_name eq 
'reload') {
+               $node_status_string = 'reload';
+               $computer_state_name = 'reload';
+       }
        else {
-               notify($ERRORS{'OK'}, 0, "node status not checked, 
node_status() not implemented by " . ref($self->provisioner) . ", assuming 
load=true");
+               $node_status_string = $self->provisioner->node_status() || 
'RELOAD';
        }
        
-       # If reinstall state - force reload state
-       $computer_state_name = 'reload' if ($request_state_name eq 'reinstall');
        
        if ($computer_state_name eq 'reload') {
                # Always call load() if state is reload regardless of 
node_status()
@@ -544,16 +491,16 @@ sub reload_image {
                # node_status returned 'ready'
                notify($ERRORS{'OK'}, 0, "node_status returned 
'$node_status_string', $computer_short_name will not be reloaded");
        }
-       
        elsif ($node_status_string =~ /^post_load/i) {
                notify($ERRORS{'OK'}, 0, "node_status returned 
'$node_status_string', OS post_load tasks will be performed on 
$computer_short_name");
                
-               # Check if the OS module implements a post_load subroutine and 
that post_load has been run
+               # Check if the OS module implements a post_load subroutine
                if ($self->os->can('post_load')) {
                        if ($self->os->post_load()) {
-                               # Add the vcld_post_load line to 
currentimage.txt
-                               $self->os->set_vcld_post_load_status();
                                $node_status_string = 'READY';
+                               
+                               # Add a line to currentimage.txt indicating 
post_load has run
+                               $self->os->set_post_load_status();
                        }
                        else {
                                notify($ERRORS{'WARNING'}, 0, "failed to 
execute OS module's post_load() subroutine, $computer_short_name will be 
reloaded");
@@ -561,7 +508,8 @@ sub reload_image {
                        }
                }
                else {
-                       notify($ERRORS{'WARNING'}, 0, "provisioning module's 
node_status subroutine returned '$node_status' but OS module " . ref($self->os) 
. " does not implement a post_load() subroutine, $computer_short_name will not 
be reloaded");
+                       $node_status_string = 'READY';
+                       notify($ERRORS{'WARNING'}, 0, "provisioning module's 
node_status subroutine returned '$node_status_string' but OS module " . 
ref($self->os) . " does not implement a post_load() subroutine, 
$computer_short_name will not be reloaded");
                }
        }
        
@@ -631,7 +579,10 @@ sub reload_image {
                # Call provisioning module's load() subroutine
                notify($ERRORS{'OK'}, 0, "calling " . ref($self->provisioner) . 
"->load() subroutine");
                insertloadlog($reservation_id, $computer_id, "info", "calling " 
. ref($self->provisioner) . "->load() subroutine");
-               if ($self->provisioner->load($node_status)) {
+               if ($self->provisioner->load()) {
+                       # Add a line to currentimage.txt indicating post_load 
has run
+                       $self->os->set_post_load_status();
+                       
                        notify($ERRORS{'OK'}, 0, "$image_name was successfully 
reloaded on $computer_short_name");
                        insertloadlog($reservation_id, $computer_id, 
"loadimagecomplete", "$image_name was successfully reloaded on 
$computer_short_name");
                }

Modified: vcl/trunk/managementnode/lib/VCL/reclaim.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/reclaim.pm?rev=1752533&r1=1752532&r2=1752533&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/reclaim.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/reclaim.pm Wed Jul 13 19:34:49 2016
@@ -177,6 +177,12 @@ sub process {
                #       $self->insert_reload_and_exit();
                #}
                
+               # Check if tainted tag was set in currently loaded image
+               if ($self->os->get_tainted_status()) {
+                       notify($ERRORS{'DEBUG'}, 0, "image currently loaded on 
$computer_shortname was tainted, computer will be reloaded");
+                       $self->insert_reload_and_exit();
+               }
+               
                # Make sure computer current image name was retrieved from the 
database
                if (!$computer_currentimage_name) {
                        notify($ERRORS{'WARNING'}, 0, "failed to retrieve 
computer current image name from the database, computer will be reloaded");

Modified: vcl/trunk/managementnode/lib/VCL/reserved.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/reserved.pm?rev=1752533&r1=1752532&r2=1752533&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/reserved.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/reserved.pm Wed Jul 13 19:34:49 2016
@@ -255,6 +255,9 @@ sub process {
                }
        }
        
+       # Add a line to currentimage.txt indicating it's possible a user logged 
on to the computer
+       $self->os->set_tainted_status();
+       
        # Update reservation lastcheck, otherwise inuse request will be 
processed immediately again
        update_reservation_lastcheck($reservation_id);
        


Reply via email to