vcl-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From arku...@apache.org
Subject svn commit: r1152223 - /incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
Date Fri, 29 Jul 2011 13:55:36 GMT
Author: arkurth
Date: Fri Jul 29 13:55:36 2011
New Revision: 1152223

URL: http://svn.apache.org/viewvc?rev=1152223&view=rev
Log:
VCL-384
Added enable_dhcp subroutine to Linux.pm. This is called from pre_capture. It resolves the
problem caused by MAC addresses remaining in the ifcfg-eth* files when an image is captured.

Other
Cleaned up pre_capture. Created shutdown subroutine. Also created restart_network_interface
subroutine.

Modified:
    incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm?rev=1152223&r1=1152222&r2=1152223&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm Fri Jul 29 13:55:36 2011
@@ -105,93 +105,65 @@ sub get_node_configuration_directory {
 
 sub pre_capture {
 	my $self = shift;
-	if (ref($self) !~ /linux/i) {
+	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 0;
+		return;
 	}
-
-	my $request_id               = $self->data->get_request_id();
-	my $reservation_id           = $self->data->get_reservation_id();
-	my $image_id                 = $self->data->get_image_id();
-	my $image_os_name            = $self->data->get_image_os_name();
-	my $management_node_keys     = $self->data->get_management_node_keys();
-	my $image_os_type            = $self->data->get_image_os_type();
-	my $image_name               = $self->data->get_image_name();
-	my $computer_id              = $self->data->get_computer_id();
-	my $computer_short_name      = $self->data->get_computer_short_name();
+	
 	my $computer_node_name       = $self->data->get_computer_node_name();
-	my $computer_type            = $self->data->get_computer_type();
-	my $user_id                  = $self->data->get_user_id();
-	my $user_unityid             = $self->data->get_user_login_id();
-	my $managementnode_shortname = $self->data->get_management_node_short_name();
-	my $computer_private_ip      = $self->data->get_computer_private_ip_address();
-	my $ip_configuration 	     = $self->data->get_management_node_public_ip_configuration();
-
-	notify($ERRORS{'OK'}, 0, "beginning Linux-specific image capture preparation tasks: $image_name
on $computer_short_name");
-
-	my @sshcmd;
-
+	notify($ERRORS{'OK'}, 0, "beginning Linux-specific image capture preparation tasks");
+	
 	# Force user off computer 
-	if ($self->logoff_user()){
-		notify($ERRORS{'OK'}, 0, "forced $user_unityid off $computer_node_name");
+	if (!$self->logoff_user()) {
+		notify($ERRORS{'WARNING'}, 0, "unable to log user off $computer_node_name");
 	}
 
 	# Remove user and clean external ssh file
 	if ($self->delete_user()) {
-		notify($ERRORS{'OK'}, 0, "$user_unityid deleted from $computer_node_name");
+		notify($ERRORS{'OK'}, 0, "deleted user from $computer_node_name");
 	}
 
-	# try to clear /tmp
-	if (run_ssh_command($computer_node_name, $management_node_keys, "/usr/sbin/tmpwatch -f 0
/tmp; /bin/cp /dev/null /var/log/wtmp", "root")) {
-		notify($ERRORS{'DEBUG'}, 0, "cleartmp precapture $computer_node_name ");
+	# Try to clear /tmp
+	if ($self->execute("/usr/sbin/tmpwatch -f 0 /tmp; /bin/cp /dev/null /var/log/wtmp"))
{
+		notify($ERRORS{'DEBUG'}, 0, "cleared /tmp on $computer_node_name");
 	}
 
-	# Clear ssh idenity keys from /root/.ssh 
+	# Clear SSH idenity keys from /root/.ssh 
 	if (!$self->clear_private_keys()) {
 		notify($ERRORS{'WARNING'}, 0, "unable to clear known identity keys");
 	}
 
-	if ($ip_configuration eq "static") {
-		if ($self->can("set_static_public_address") && $self->set_static_public_address())
{
-			notify($ERRORS{'DEBUG'}, 0, "set static public IP address on $computer_node_name using
set_static_public_address() method");
-		}
-	} ## end if ($ip_configuration eq "static")
-
 	# Write /etc/rc.local script
-	if(!$self->generate_rc_local()){
+	if (!$self->generate_rc_local()){
 		notify($ERRORS{'WARNING'}, 0, "unable to generate /etc/rc.local script on $computer_node_name");
-		return 0;
+		return;
 	}
 
 	# Generate external_sshd_config
 	if(!$self->generate_ext_sshd_config()){
 		notify($ERRORS{'WARNING'}, 0, "unable to generate /etc/ssh/external_sshd_config on $computer_node_name");
-		return 0;
+		return;
 	}
 
 	# Generate ext_sshd init script
 	if(!$self->generate_ext_sshd_init()){
 		notify($ERRORS{'WARNING'}, 0, "unable to generate /etc/init.d/ext_sshd on $computer_node_name");
-		return 0;
+		return;
 	}
-
-	# Shutdown node
-	notify($ERRORS{'OK'}, 0, "shutting down node for Linux imaging sequence");
-	run_ssh_command($computer_node_name, $management_node_keys, "/sbin/shutdown -h now", "root");
 	
-	# Wait maximum of 5 minutes for computer to power off
-	my $power_off = $self->provisioner->wait_for_power_off(120, 3, 3);
-	if (!defined($power_off)) {
-		# wait_for_power_off result will be undefined if the provisioning module doesn't implement
a power_status subroutine
-		notify($ERRORS{'OK'}, 0, "unable to determine power status of $computer_node_name from
provisioning module, sleeping 1 minute to allow computer time to shutdown");
-		sleep 60;
+	# Configure the private and public interfaces to use DHCP
+	if (!$self->enable_dhcp()) {
+		notify($ERRORS{'WARNING'}, 0, "failed to enable DHCP on the public and private interfaces");
+		return 0;
 	}
-	elsif (!$power_off) {
-		notify($ERRORS{'WARNING'}, 0, "$computer_node_name never powered off");
-		return;
+	
+	# Shut the computer down
+	if (!$self->shutdown()) {
+		notify($ERRORS{'WARNING'}, 0, "failed to shut down $computer_node_name");
+		return 0;
 	}
 
-	notify($ERRORS{'OK'}, 0, "returning 1");
+	notify($ERRORS{'OK'}, 0, "Linux pre-capture steps complete");
 	return 1;
 }
 
@@ -539,20 +511,10 @@ EOF
 	}
 	
 	# Restart the interface
-	notify($ERRORS{'DEBUG'}, 0, "attempting to restart public interface $interface_name on $computer_name");
-	my $interface_restart_command = "$network_scripts_path/ifdown $interface_name ; $network_scripts_path/ifup
$interface_name";
-	my ($interface_restart_exit_status, $interface_restart_output) = $self->execute($interface_restart_command);
-	if (!defined($interface_restart_output)) {
-		notify($ERRORS{'WARNING'}, 0, "failed to run command to restart public interface $interface_name
on $computer_name: '$interface_restart_command'");
+	if (!$self->restart_network_interface($interface_name)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to restart public interface $interface_name on $computer_name");
 		return;
 	}
-	elsif ($interface_restart_exit_status) {
-		notify($ERRORS{'WARNING'}, 0, "failed to restart public interface $interface_name on $computer_name,
exit status: $interface_restart_exit_status, command: '$interface_restart_command', output:\n"
. join("\n", @$interface_restart_output));
-		return;
-	}
-	else {
-		notify($ERRORS{'DEBUG'}, 0, "restarted public interface $interface_name on $computer_name");
-	}
 	
 	# Delete existing default route
 	my $route_del_command = "/sbin/route del default";
@@ -664,6 +626,51 @@ EOF
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 restart_network_interface
+
+ Parameters  : $interface_name
+ Returns     :
+ Description : Calls ifdown and then ifup on the network interface.
+
+=cut
+
+sub restart_network_interface {
+	my $self = shift;
+	if (ref($self) !~ /linux/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called
as a class method");
+		return 0;
+	}
+	
+	my $interface_name = shift;
+	if (!$interface_name) {
+		notify($ERRORS{'WARNING'}, 0, "unable to restart network interface, interface name argument
was not supplied");
+		return;
+	}
+	
+	my $computer_name = $self->data->get_computer_short_name();
+	my $network_scripts_path = "/etc/sysconfig/network-scripts";
+	
+	# Restart the interface
+	notify($ERRORS{'DEBUG'}, 0, "attempting to restart network interface $interface_name on
$computer_name");
+	my $interface_restart_command = "$network_scripts_path/ifdown $interface_name ; $network_scripts_path/ifup
$interface_name";
+	my ($interface_restart_exit_status, $interface_restart_output) = $self->execute($interface_restart_command);
+	if (!defined($interface_restart_output)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to run command to restart interface $interface_name
on $computer_name: '$interface_restart_command'");
+		return;
+	}
+	elsif ($interface_restart_exit_status) {
+		notify($ERRORS{'WARNING'}, 0, "failed to restart network interface $interface_name on $computer_name,
exit status: $interface_restart_exit_status, command: '$interface_restart_command', output:\n"
. join("\n", @$interface_restart_output));
+		return;
+	}
+	else {
+		notify($ERRORS{'DEBUG'}, 0, "restarted network interface $interface_name on $computer_name");
+	}
+	
+	return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 logoff_user
 
  Parameters  :
@@ -2600,7 +2607,6 @@ sub get_network_configuration {
 
 #/////////////////////////////////////////////////////////////////////////////
 
-
 =head2 reboot
 
  Parameters  : $wait_for_reboot
@@ -2610,98 +2616,162 @@ sub get_network_configuration {
 =cut
 
 sub reboot {
-        my $self = shift;
-        if (ref($self) !~ /linux/i) {
-                notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must
be called as a class method");
-                return;
-        }
-
-        my $management_node_keys = $self->data->get_management_node_keys();
-        my $computer_node_name   = $self->data->get_computer_node_name();
-
-        # Check if an argument was supplied
-        my $wait_for_reboot = shift;
-        if (!defined($wait_for_reboot) || $wait_for_reboot !~ /0/) {
-                notify($ERRORS{'DEBUG'}, 0, "rebooting $computer_node_name and waiting for
ssh to become active");
-                $wait_for_reboot = 1;
-        }
-        else {
-                notify($ERRORS{'DEBUG'}, 0, "rebooting $computer_node_name and NOT waiting");
-                $wait_for_reboot = 0;
-        }
+	my $self = shift;
+	if (ref($self) !~ /linux/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called
as a class method");
+		return;
+	}
+	
+	my $computer_node_name   = $self->data->get_computer_node_name();
+	
+	# Check if an argument was supplied
+	my $wait_for_reboot = shift || 1;
+	if ($wait_for_reboot) {
+		notify($ERRORS{'DEBUG'}, 0, "rebooting $computer_node_name and waiting for SSH to become
active");
+	}
+	else {
+		notify($ERRORS{'DEBUG'}, 0, "rebooting $computer_node_name and NOT waiting");
+	}
+	
+	my $reboot_start_time = time();
+	
+	# Check if computer responds to ssh before preparing for reboot
+	if ($self->wait_for_ssh(0)) {
+		# Check if shutdown exists on the computer
+		my $reboot_command;
+		if ($self->file_exists("/sbin/shutdown")) {
+			$reboot_command = "/sbin/shutdown -r now";
+		}
+		else {
+			notify($ERRORS{'WARNING'}, 0, "reboot not attempted, /sbin/shutdown did not exists on
$computer_node_name");
+			return;
+		}
+		
+		my ($reboot_exit_status, $reboot_output) = $self->execute($reboot_command);
+		if (!defined($reboot_output)) {
+			notify($ERRORS{'WARNING'}, 0, "failed to execute command to reboot $computer_node_name");
+			return;
+		}
+		elsif ($reboot_exit_status == 0) {
+			notify($ERRORS{'OK'}, 0, "executed reboot command on $computer_node_name");
+		}
+		else {
+			notify($ERRORS{'WARNING'}, 0, "failed to reboot $computer_node_name, attempting power
reset, output:\n" . join("\n", @$reboot_output));
+			
+			# Call provisioning module's power_reset() subroutine
+			if ($self->provisioner->power_reset()) {
+				notify($ERRORS{'OK'}, 0, "initiated power reset on $computer_node_name");
+			}
+			else {
+				notify($ERRORS{'WARNING'}, 0, "reboot failed, failed to initiate power reset on $computer_node_name");
+				return;
+			}
+		}
+	}
+	else {
+		# Computer did not respond to SSH
+		notify($ERRORS{'WARNING'}, 0, "$computer_node_name is not responding to SSH, graceful reboot
cannot be performed, attempting hard reset");
+		
+		# Call provisioning module's power_reset() subroutine
+		if ($self->provisioner->power_reset()) {
+			notify($ERRORS{'OK'}, 0, "initiated power reset on $computer_node_name");
+		}
+		else {
+			notify($ERRORS{'WARNING'}, 0, "reboot failed, failed to initiate power reset on $computer_node_name");
+			return;
+		}
+	}
+	
+	# Check if wait for reboot is set
+	if (!$wait_for_reboot) {
+		return 1;
+	}
+	
+	my $wait_attempt_limit = 2;
+	if ($self->wait_for_reboot($wait_attempt_limit)){
+		# Reboot was successful, calculate how long reboot took
+		my $reboot_end_time = time();
+		my $reboot_duration = ($reboot_end_time - $reboot_start_time);
+		notify($ERRORS{'OK'}, 0, "reboot complete on $computer_node_name, took $reboot_duration
seconds");
+		return 1;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "reboot failed on $computer_node_name, made $wait_attempt_limit
attempts");
+		return 0;
+	}
 
-        my $reboot_start_time = time();
-        notify($ERRORS{'DEBUG'}, 0, "reboot will be attempted on $computer_node_name");
+}
 
-        # Check if computer responds to ssh before preparing for reboot
-        if ($self->wait_for_ssh(0)) {
+#/////////////////////////////////////////////////////////////////////////////
 
-                # Check if shutdown exists on the computer
-                my $reboot_command;
-                if ( $self->file_exists("/sbin/shutdown")) {
-                        $reboot_command = "/sbin/shutdown -r now";
-                }
-                else {
-                        notify($ERRORS{'WARNING'}, 0, "reboot not attempted, /sbin/shutdown
did not exists on OS");
-                        return 0;
-                }
+=head2 shutdown
 
-                my ($reboot_exit_status, $reboot_output) = run_ssh_command($computer_node_name,
$management_node_keys, $reboot_command);
-                if (!defined($reboot_output)) {
-                        notify($ERRORS{'WARNING'}, 0, "failed to execute ssh command to reboot
$computer_node_name");
-                        return;
-                }
+ Parameters  : 
+ Returns     : 
+ Description : 
 
-                if ($reboot_exit_status == 0) {
-                        notify($ERRORS{'OK'}, 0, "executed reboot command on $computer_node_name");
-                }
-                else {
-                        notify($ERRORS{'WARNING'}, 0, "failed to reboot $computer_node_name,
attempting power reset, output:\n" . join("\n", @$reboot_output));
+=cut
 
-                        # Call provisioning module's power_reset() subroutine
-                        if ($self->provisioner->power_reset()) {
-                                notify($ERRORS{'OK'}, 0, "initiated power reset on $computer_node_name");
-                        }
-                        else {
-                                notify($ERRORS{'WARNING'}, 0, "reboot failed, failed to initiate
power reset on $computer_node_name");
-                                return;
-                        }
-                }
-        }
-        else {
-                # Computer did not respond to ssh
-                notify($ERRORS{'WARNING'}, 0, "$computer_node_name did not respond to ssh,
graceful reboot cannot be performed, attempting hard reset");
-
-                # Call provisioning module's power_reset() subroutine
-                if ($self->provisioner->power_reset()) {
-                        notify($ERRORS{'OK'}, 0, "initiated power reset on $computer_node_name");
-                }
-                else {
-                        notify($ERRORS{'WARNING'}, 0, "reboot failed, failed to initiate
power reset on $computer_node_name");
-                        return 0;
-                }
-        } ## end else [ if ($self->wait_for_ssh(0))
+sub shutdown {
+	my $self = shift;
+	if (ref($self) !~ /linux/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called
as a class method");
+		return;
+	}
 	
-	my $wait_attempt_limit = 2;
-        # Check if wait for reboot is set
-        if (!$wait_for_reboot) {
-                return 1;
-        }
+	my $computer_node_name   = $self->data->get_computer_node_name();
+	
+	# Check if an argument was supplied
+	my $wait_for_power_off = shift || 1;
+	if ($wait_for_power_off) {
+		notify($ERRORS{'DEBUG'}, 0, "shutting down $computer_node_name and waiting for power off");
+	}
 	else {
-		if($self->wait_for_reboot($wait_attempt_limit)){
-			# Reboot was successful, calculate how long reboot took
-                	my $reboot_end_time = time();
-                	my $reboot_duration = ($reboot_end_time - $reboot_start_time);
-                	notify($ERRORS{'OK'}, 0, "reboot complete on $computer_node_name, took $reboot_duration
seconds");
-			return 1;
+		notify($ERRORS{'DEBUG'}, 0, "shutting down $computer_node_name and NOT waiting for power
off");
+	}
+	
+	# Check if computer responds to ssh before preparing for shut down
+	if ($self->wait_for_ssh(0)) {
+		my $command = '/sbin/shutdown -h now';
+		
+		my ($exit_status, $output) = $self->execute($command);
+		
+		if (defined $exit_status && $exit_status == 0) {
+			notify($ERRORS{'DEBUG'}, 0, "executed command to shut down $computer_node_name");
 		}
 		else {
-        		notify($ERRORS{'WARNING'}, 0, "reboot failed on $computer_node_name, made $wait_attempt_limit
attempts");
-			return 0;
+			if (!defined($output)) {
+				notify($ERRORS{'WARNING'}, 0, "failed to execute command to shut down $computer_node_name,
attempting power off");
+			}
+			else {
+				notify($ERRORS{'WARNING'}, 0, "failed to shut down $computer_node_name, attempting power
off, output:\n" . join("\n", @$output));
+			}
+			
+			# Call provisioning module's power_off() subroutine
+			if (!$self->provisioner->power_off()) {
+				notify($ERRORS{'WARNING'}, 0, "failed to shut down $computer_node_name, failed to initiate
power off");
+				return;
+			}
 		}
 	}
-
-} ## end sub reboot
+	else {
+		notify($ERRORS{'DEBUG'}, 0, "$computer_node_name is not responding to SSH, attempting power
off");
+		
+		# Call provisioning module's power_off() subroutine
+		if (!$self->provisioner->power_off()) {
+			notify($ERRORS{'WARNING'}, 0, "failed to shut down $computer_node_name, failed to initiate
power off");
+			return;
+		}
+	}
+	
+	if (!$wait_for_power_off || $self->provisioner->wait_for_power_off(300, 10)) {
+		return 1;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to shut down $computer_node_name, computer never
powered off");
+		return;
+	}
+}
 
 #/////////////////////////////////////////////////////////////////////////////
 
@@ -2837,6 +2907,74 @@ sub update_server_access {
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 enable_dhcp
+
+ Parameters  : $interface_name (optional)
+ Returns     : boolean
+ Description : Configures the ifcfg-* file(s) to use DHCP. If an interface name
+               argument is specified, only the ifcfg file for that interface
+               will be configured. If no argument is specified, the files for
+               the public and private interfaces will be configured.
+
+=cut
+
+sub enable_dhcp {
+	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_node_name   = $self->data->get_computer_node_name();
+	
+	my $interface_name_argument = shift;
+	my @interface_names;
+	if (!$interface_name_argument) {
+		push(@interface_names, $self->get_private_interface_name());
+		push(@interface_names, $self->get_public_interface_name());
+	}
+	elsif ($interface_name_argument =~ /private/i) {
+		push(@interface_names, $self->get_private_interface_name());
+	}
+	elsif ($interface_name_argument =~ /public/i) {
+		push(@interface_names, $self->get_public_interface_name());
+	}
+	else {
+		push(@interface_names, $interface_name_argument);
+	}
+	
+	for my $interface_name (@interface_names) {
+print "\n\n" . '-' x 100 . "\n\n";
+		my $ifcfg_file_path = "/etc/sysconfig/network-scripts/ifcfg-$interface_name";
+		notify($ERRORS{'DEBUG'}, 0, "attempting to enable DHCP on interface: $interface_name\nifcfg
file path: $ifcfg_file_path");
+		
+		my $ifcfg_file_contents = <<EOF;
+DEVICE=$interface_name
+BOOTPROTO=dhcp
+ONBOOT=yes
+EOF
+		
+		# Remove the last newline
+		$ifcfg_file_contents =~ s/\n$//s;
+		
+		# Write the contents to the ifcfg file
+		if ($self->create_text_file($ifcfg_file_path, $ifcfg_file_contents)) {
+			notify($ERRORS{'DEBUG'}, 0, "updated $ifcfg_file_path:\n$ifcfg_file_contents");
+		}
+		else {
+			notify($ERRORS{'WARNING'}, 0, "failed to update $ifcfg_file_path");
+			return;
+		}
+		
+		# Remove any leftover ifcfg-*.bak files
+		$self->delete_file('/etc/sysconfig/network-scripts/ifcfg-eth*.bak');
+	}
+	
+	return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 1;
 __END__
 



Mime
View raw message