You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by ar...@apache.org on 2017/03/21 21:40:25 UTC

svn commit: r1788029 - in /vcl/trunk/managementnode/lib/VCL: Module.pm Module/OS.pm Module/OS/Windows.pm new.pm

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");