Author: arkurth
Date: Tue Mar 21 21:40:25 2017
New Revision: 1788029

URL: http://svn.apache.org/viewvc?rev=1788029&view=rev
Log:
VCL-867
Added Windows.pm::pre_reload. This deletes a computer object from AD before a 
domain-joined computer gets reloaded, preventing orphaned objects.

Added $self->can check and call to pre_reload in new.pm::reload_image.

Updated OS.pm::get_os_perl_package to try to reuse the module object used to 
call it if appropriate.

Added Module.pm::create_current_os_object.

Modified:
    vcl/trunk/managementnode/lib/VCL/Module.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
    vcl/trunk/managementnode/lib/VCL/new.pm

Modified: vcl/trunk/managementnode/lib/VCL/Module.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module.pm?rev=1788029&r1=1788028&r2=1788029&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module.pm Tue Mar 21 21:40:25 2017
@@ -470,6 +470,34 @@ sub create_os_object {
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 create_current_os_object
+
+ Parameters  : $computer_identifier (optional)
+ Returns     : string
+ Description : Attempts to determine the Perl package which should be used to
+               control the computer.
+
+=cut
+
+sub create_current_os_object {
+       my ($self, $computer_identifier, $suppress_warning) = @_;
+       
+       my $os_perl_package = VCL::Module::OS::get_os_perl_package(@_);
+       if (!$os_perl_package) {
+               notify($ERRORS{'WARNING'}, 0, "failed to create object for OS 
currently loaded on computer, correct Perl package path could not be 
determined") unless $suppress_warning;
+               return;
+       }
+       
+       if (ref($self) && ref($self) eq $os_perl_package) {
+               notify($ERRORS{'DEBUG'}, 0, "returning object used to call this 
subroutine becuase it is the correct module type: " . ref($self));
+               return $self;
+       }
+       
+       return $self->create_os_object($os_perl_package);
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 create_mn_os_object
 
  Parameters  : none

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=1788029&r1=1788028&r2=1788029&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS.pm Tue Mar 21 21:40:25 2017
@@ -3406,7 +3406,7 @@ sub get_os_type {
 
 =head2 get_os_perl_package
 
- Parameters  : $computer_name
+ Parameters  : $computer_identifier (optional), $suppress_warning (optional)
  Returns     : string
  Description : Attempts to determine the Perl package which should be used to
                control the computer.
@@ -3414,48 +3414,96 @@ sub get_os_type {
 =cut
 
 sub get_os_perl_package {
-       my $computer_identifier = shift;
-       if (ref($computer_identifier)) {
-               $computer_identifier = shift
+       my $argument = shift;
+       
+       my $self;
+       my $computer_identifier;
+       
+       my $argument_type = ref($argument);
+       if ($argument_type) {
+               if ($argument->isa('VCL::Module')) {
+                       $self = $argument;
+                       $computer_identifier = shift || 
$self->data->get_computer_id();
+               }
+               else {
+                       notify($ERRORS{'WARNING'}, 0, "invalid first argument 
type: $argument_type, it must either be a reference to a VCL::Module object or 
a scalar representing the computer identifier");
+                       return;
+               }
+       }
+       else {
+               $computer_identifier = $argument;
        }
        if (!$computer_identifier) {
                notify($ERRORS{'WARNING'}, 0, "computer identifier argument not 
specified");
                return;
        }
        
-       my $os = VCL::Module::create_object('VCL::Module::OS', { 
computer_identifier => $computer_identifier});
+       my $suppress_warning = shift;
+       
+       notify($ERRORS{'DEBUG'}, 0, "attempting to determine Perl package name 
to use for OS currently loaded on computer: $computer_identifier");
+       
+       my $os;
+       
+       # Try to avoid creating a separate OS object
+       # Check if called by $self-> and if $self's DataStructure matches 
computer identifier
+       if ($self && $self->isa('VCL::Module::OS') && $self->data()) {
+               my $self_computer_short_name = 
$self->data->get_computer_short_name();
+               if ($self->data->get_computer_id() eq $computer_identifier || 
$computer_identifier =~ /^$self_computer_short_name/) {
+                       $os = $self;
+               }
+       }
        if (!$os) {
-               notify($ERRORS{'WARNING'}, 0, "unable to determine perl package 
to use for OS installed on $computer_identifier, OS object could not be 
created");
-               return;
+               $os = VCL::Module::create_object('VCL::Module::OS::Windows', { 
computer_identifier => $computer_identifier});
+               if (!$os) {
+                       notify($ERRORS{'WARNING'}, 0, "unable to determine perl 
package to use for OS installed on $computer_identifier, OS object could not be 
created");
+                       return;
+               }
        }
        
-       
        my $command = "uname -a";
-       my ($exit_status, $output) = $os->execute($command);
+       my ($exit_status, $output) = $os->execute({
+               command => $command,
+               max_attempts => 1,
+               display_output => 0,
+       });
        if (!defined($output)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to execute command to 
determine OS installed on $computer_identifier");
+               if ($suppress_warning) {
+                       notify($ERRORS{'DEBUG'}, 0, "unable to determine OS 
installed on computer $computer_identifier, computer may not be responding");
+               }
+               else {
+                       notify($ERRORS{'WARNING'}, 0, "failed to execute 
command to determine OS installed on $computer_identifier");
+               }
                return;
        }
        
        my $os_perl_package;
        if (grep(/Cygwin/i, @$output)) {
-               my $windows_os = 
VCL::Module::create_object('VCL::Module::OS::Windows', { computer_identifier => 
$computer_identifier});
-               if (!$windows_os) {
-                       notify($ERRORS{'WARNING'}, 0, "unable to determine perl 
package to use for OS installed on $computer_identifier, Windows OS object 
could not be created");
-                       return;
+               my $windows_os;
+               if ($os->isa('VCL::Module::OS::Windows')) {
+                       $windows_os = $os;
                }
-               return $windows_os->_get_os_perl_package($os);
+               else {
+                       $windows_os = 
VCL::Module::create_object('VCL::Module::OS::Windows', { computer_identifier => 
$computer_identifier});
+                       if (!$windows_os) {
+                               notify($ERRORS{'WARNING'}, 0, "unable to 
determine perl package to use for OS installed on $computer_identifier, Windows 
OS object could not be created");
+                               return;
+                       }
+               }
+               $os_perl_package = $windows_os->_get_os_perl_package($os) || 
return;
        }
        elsif (grep(/Ubuntu/i, @$output)) {
-               return "VCL::Module::OS::Linux::Ubuntu"
+               $os_perl_package = "VCL::Module::OS::Linux::Ubuntu"
        }
        elsif (grep(/Linux/i, @$output)) {
-               return "VCL::Module::OS::Linux"
+               $os_perl_package = "VCL::Module::OS::Linux"
        }
        else {
                notify($ERRORS{'WARNING'}, 0, "failed to determine OS installed 
on $computer_identifier, unsupported output returned from '$command':\n" . 
join("\n", @$output));
                return;
        }
+       
+       notify($ERRORS{'DEBUG'}, 0, "determined OS Perl package to use for OS 
installed on computer $computer_identifier: $os_perl_package");
+       return $os_perl_package;
 }
 
 #/////////////////////////////////////////////////////////////////////////////

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=1788029&r1=1788028&r2=1788029&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm Tue Mar 21 21:40:25 
2017
@@ -1084,13 +1084,42 @@ sub post_reservation {
        
        # Check if custom post_reservation script exists in image
        my $script_path = '$SYSTEMROOT/vcl_post_reservation.cmd';
-       if (!$self->file_exists($script_path)) {
+       if ($self->file_exists($script_path)) {
+               # Run the post_reservation script
+               $self->run_script($script_path);
+       }
+       else {
                notify($ERRORS{'DEBUG'}, 0, "custom post_reservation script 
does NOT exist in image: $script_path");
-               return 1;
        }
        
-       # Run the post_reservation script
-       $self->run_script($script_path);
+       return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 pre_reload
+
+ Parameters  : none
+ Returns     : true
+ Description : Unjoins the computer from an Active Directory domain if
+               previously joined. This helps avoid orphaned computer objects.
+
+=cut
+
+sub pre_reload {
+       my $self = shift;
+       if (ref($self) !~ /windows/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return 0;
+       }
+       
+       my $computer_name = $self->data->get_computer_short_name();
+       
+       # Check if the computer is joined to any AD domain
+       my $computer_current_domain_name = $self->ad_get_current_domain();
+       if ($computer_current_domain_name) {
+               $self->ad_delete_computer($computer_name, 
$computer_current_domain_name);
+       }
        
        return 1;
 }

Modified: vcl/trunk/managementnode/lib/VCL/new.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/new.pm?rev=1788029&r1=1788028&r2=1788029&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/new.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/new.pm Tue Mar 21 21:40:25 2017
@@ -565,6 +565,13 @@ sub reload_image {
                        notify($ERRORS{'OK'}, 0, "unable to check if image 
exists, does_image_exist() not implemented by " . ref($self->provisioner));
                }
                
+               # OS currently installed on computer may not be the same type 
as $self->os
+               # Attempt to create a new OS object representing OS currently 
installed and check if that object implements a 'pre_reload' subroutine
+               my $computer_current_os = 
$self->create_current_os_object($computer_id, 1);
+               if ($computer_current_os && 
$computer_current_os->can('pre_reload')) {
+                       $computer_current_os->pre_reload();
+               }
+               
                # Update the computer state to reloading
                if (update_computer_state($computer_id, "reloading")) {
                        notify($ERRORS{'OK'}, 0, "computer $computer_short_name 
state set to reloading");


Reply via email to