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 2012/06/18 21:09:26 UTC

svn commit: r1351461 - in /incubator/vcl/trunk/managementnode/lib/VCL: Module/OS.pm Module/OS/Linux.pm Module/Provisioning/VMware/VIM_SSH.pm Module/Provisioning/libvirt.pm image.pm utils.pm

Author: arkurth
Date: Mon Jun 18 19:09:26 2012
New Revision: 1351461

URL: http://svn.apache.org/viewvc?rev=1351461&view=rev
Log:
VCL-545
Fixed problems with base image capture under KVM. Updated image.pm to correctly determine the installtype.

Added code to determine the running domain when capturing an image rather than relying on the domain name matching the computer name.

Changed capture code to no longer save a copy of the XML file which defines the domain in the datastore and repository directories. This can cause problems for the code used to find images. Instead, a copy is saved in the image. This isn't currently used but will be useful in the future to customize hardware based on what was actually in the captured image.


VCL-450
Added code to VIM_SSH.pm to check if the VM is already powered off before attempting to power it off.


Other
Updated Linux.pm::create_directory to detect if ~ was passed as the argument. It skips directory creation if this is the case. Otherwise, it was creating a '~' directory under the home directory.

Added $ignore_error argument to utils.pm.

Modified:
    incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm
    incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
    incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm
    incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm
    incubator/vcl/trunk/managementnode/lib/VCL/image.pm
    incubator/vcl/trunk/managementnode/lib/VCL/utils.pm

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=1351461&r1=1351460&r2=1351461&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm Mon Jun 18 19:09:26 2012
@@ -1757,7 +1757,7 @@ sub create_text_file {
 		$command .= " > $file_path";
 	}
 	
-	my ($exit_status, $output) = $self->execute($command,1);
+	my ($exit_status, $output) = $self->execute($command, 0);
 	if (!defined($output)) {
 		notify($ERRORS{'WARNING'}, 0, "failed to execute ssh command to create file on $computer_node_name: $file_path");
 		return;

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=1351461&r1=1351460&r2=1351461&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm Mon Jun 18 19:09:26 2012
@@ -1036,17 +1036,17 @@ sub sanitize {
 		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 $mn_private_ip         = $self->mn_os->get_private_ip_address();
-
+	
 	# Make sure user is not connected
 	if ($self->is_connected()) {
 		notify($ERRORS{'WARNING'}, 0, "user is connected to $computer_node_name, computer will be reloaded");
 		#return false - reclaim will reload
 		return 0;
 	}
-
+	
 	# Revoke access
 	if (!$self->revoke_access()) {
 		notify($ERRORS{'WARNING'}, 0, "failed to revoke access to $computer_node_name");
@@ -1434,6 +1434,10 @@ sub create_directory {
 	# Remove any quotes from the beginning and end of the path
 	$directory_path = normalize_file_path($directory_path);
 	
+	# If ~ is passed as the directory path, skip directory creation attempt
+	# The command will create a /root/~ directory since the path is enclosed in quotes
+	return 1 if $directory_path eq '~';
+	
 	my $computer_short_name = $self->data->get_computer_short_name();
 	
 	# Attempt to create the directory
@@ -2505,7 +2509,7 @@ EOF
                constructs a hash. The hash reference returned is formatted as
                follows:
                |--%{eth0}
-					   |--%{eth0}{default_gateway} '10.10.4.1'
+                  |--%{eth0}{default_gateway} '10.10.4.1'
                   |--%{eth0}{ip_address}
                      |--{eth0}{ip_address}{10.10.4.3} = '255.255.240.0'
                   |--{eth0}{name} = 'eth0'
@@ -2768,31 +2772,31 @@ sub shutdown {
 =cut
 
 sub create_user {
-        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 $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();
-        my $imagemeta_rootaccess = $self->data->get_imagemeta_rootaccess();
+	my $management_node_keys = $self->data->get_management_node_keys();
+	my $computer_node_name   = $self->data->get_computer_node_name();
+	my $imagemeta_rootaccess = $self->data->get_imagemeta_rootaccess();
 
-        # Attempt to get the username from the arguments
-        # If no argument was supplied, use the user specified in the DataStructure
-        my $username = shift;
-        my $password = shift;
+	# Attempt to get the username from the arguments
+	# If no argument was supplied, use the user specified in the DataStructure
+	my $username = shift;
+	my $password = shift;
 	my $user_uid = shift;
 	my $adminoverride = shift;
 	my $user_standalone = shift;
 	
-        if (!$username) {
-                $username = $self->data->get_user_login_id();
+	if (!$username) {
+		$username = $self->data->get_user_login_id();
 					notify($ERRORS{'OK'}, 0, "username not provided, pulling from datastructure");
-        }
-        if (!$password) {
-                $password = $self->data->get_reservation_password();
-        }
+	}
+	if (!$password) {
+		$password = $self->data->get_reservation_password();
+	}
 	if (!$adminoverride) {
 		$adminoverride = 0;	
 	}
@@ -2814,67 +2818,67 @@ sub create_user {
 		$imagemeta_rootaccess = 1;
 	}
 	elsif ($adminoverride eq '2') {
-                $imagemeta_rootaccess = 0;
+		$imagemeta_rootaccess = 0;
 	}
 	else {
 		#no override detected, do not change database value
 	}
 
 	my $useradd_string;
-        if(defined($user_uid) && $user_uid != 0){
-                $useradd_string = "/usr/sbin/useradd -u $user_uid -d /home/$username -m $username -g vcl";
-        }
-        else{
-                $useradd_string = "/usr/sbin/useradd -d /home/$username -m $username -g vcl";
-        }
+	if(defined($user_uid) && $user_uid != 0){
+		$useradd_string = "/usr/sbin/useradd -u $user_uid -d /home/$username -m $username -g vcl";
+	}
+	else{
+		$useradd_string = "/usr/sbin/useradd -d /home/$username -m $username -g vcl";
+	}
 
 
-        my @sshcmd = run_ssh_command($computer_node_name, $management_node_keys, $useradd_string, "root");
-        foreach my $l (@{$sshcmd[1]}) {
-                if ($l =~ /$username exists/) {
-                        notify($ERRORS{'OK'}, 0, "detected user already has account");
-                        if ($self->delete_user($username)) {
-                                notify($ERRORS{'OK'}, 0, "user has been deleted from $computer_node_name");
-                                @sshcmd = run_ssh_command($computer_node_name, $management_node_keys, $useradd_string, "root");
-                        }
-                }
-        }
+	my @sshcmd = run_ssh_command($computer_node_name, $management_node_keys, $useradd_string, "root");
+	foreach my $l (@{$sshcmd[1]}) {
+		if ($l =~ /$username exists/) {
+			notify($ERRORS{'OK'}, 0, "detected user already has account");
+			if ($self->delete_user($username)) {
+				notify($ERRORS{'OK'}, 0, "user has been deleted from $computer_node_name");
+				@sshcmd = run_ssh_command($computer_node_name, $management_node_keys, $useradd_string, "root");
+			}
+		}
+	}
 
-        if ($user_standalone) {
-                notify($ERRORS{'DEBUG'}, 0, "Standalone user setting single-use password");
+	if ($user_standalone) {
+		notify($ERRORS{'DEBUG'}, 0, "Standalone user setting single-use password");
 
-                #Set password
-                if ($self->changepasswd($computer_node_name, $username, $password)) {
-                        notify($ERRORS{'OK'}, 0, "Successfully set password on useracct: $username on $computer_node_name");
-                }
-                else {
-                        notify($ERRORS{'CRITICAL'}, 0, "Failed to set password on useracct: $username on $computer_node_name");
-                        return 0;
-                }
-        } ## end if ($user_standalone)
-
-
-        #Check image profile for allowed root access
-        if ($imagemeta_rootaccess) {
-                # Add to sudoers file
-                #clear user from sudoers file to prevent dups
-                my $clear_cmd = "sed -i -e \"/^$username .*/d\" /etc/sudoers";
-                if (run_ssh_command($computer_node_name, $management_node_keys, $clear_cmd, "root")) {
-                        notify($ERRORS{'DEBUG'}, 0, "cleared $username from /etc/sudoers");
-                }
-                else {
-                        notify($ERRORS{'CRITICAL'}, 0, "failed to clear $username from /etc/sudoers");
-                }
-                my $sudoers_cmd = "echo \"$username ALL= NOPASSWD: ALL\" >> /etc/sudoers";
-                if (run_ssh_command($computer_node_name, $management_node_keys, $sudoers_cmd, "root")) {
-                        notify($ERRORS{'DEBUG'}, 0, "added $username to /etc/sudoers");
-                }
-                else {
-                        notify($ERRORS{'CRITICAL'}, 0, "failed to add $username to /etc/sudoers");
-                }
-        } ## end if ($imagemeta_rootaccess)
+		#Set password
+		if ($self->changepasswd($computer_node_name, $username, $password)) {
+			notify($ERRORS{'OK'}, 0, "Successfully set password on useracct: $username on $computer_node_name");
+		}
+		else {
+			notify($ERRORS{'CRITICAL'}, 0, "Failed to set password on useracct: $username on $computer_node_name");
+			return 0;
+		}
+	} ## end if ($user_standalone)
+
+
+	#Check image profile for allowed root access
+	if ($imagemeta_rootaccess) {
+		# Add to sudoers file
+		#clear user from sudoers file to prevent dups
+		my $clear_cmd = "sed -i -e \"/^$username .*/d\" /etc/sudoers";
+		if (run_ssh_command($computer_node_name, $management_node_keys, $clear_cmd, "root")) {
+			notify($ERRORS{'DEBUG'}, 0, "cleared $username from /etc/sudoers");
+		}
+		else {
+			notify($ERRORS{'CRITICAL'}, 0, "failed to clear $username from /etc/sudoers");
+		}
+		my $sudoers_cmd = "echo \"$username ALL= NOPASSWD: ALL\" >> /etc/sudoers";
+		if (run_ssh_command($computer_node_name, $management_node_keys, $sudoers_cmd, "root")) {
+			notify($ERRORS{'DEBUG'}, 0, "added $username to /etc/sudoers");
+		}
+		else {
+			notify($ERRORS{'CRITICAL'}, 0, "failed to add $username to /etc/sudoers");
+		}
+	} ## end if ($imagemeta_rootaccess)
 
-        return 1;	
+	return 1;	
 } ## end sub create_user
 
 #/////////////////////////////////////////////////////////////////////////////
@@ -2888,48 +2892,45 @@ sub create_user {
 =cut
 
 sub update_server_access {
-	
 	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;
-        }
-
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+	
 	my ($server_allow_user_list) = shift;
-
-        my $computer_node_name = $self->data->get_computer_node_name();
-        my $identity           = $self->data->get_image_identity;
-
-
+	
+	my $computer_node_name = $self->data->get_computer_node_name();
+	my $identity           = $self->data->get_image_identity;
+	
 	if ( !$server_allow_user_list ) {
 		my $server_allow_user_list = $self->data->get_server_allow_users();
 	}
 	
-        notify($ERRORS{'OK'}, 0, "server_allow_user_list= $server_allow_user_list");
-        if ( $server_allow_user_list ) {
-
-             my $cmd = "sed -i -e \"/^AllowUsers */d\" /etc/ssh/external_sshd_config; echo \"AllowUsers $server_allow_user_list\" >> /etc/ssh/external_sshd_config";
-             if (run_ssh_command($computer_node_name, $identity, $cmd, "root")) {
-                 notify($ERRORS{'DEBUG'}, 0, "added AllowUsers $server_allow_user_list to external_sshd_config");
-             }
-             else {
-                 notify($ERRORS{'CRITICAL'}, 0, "failed to add AllowUsers $server_allow_user_list to external_sshd_config");
-             }
-				
-				if(!$self->stop_service("ext_sshd")) {
-				
-				}
-				if(!$self->start_service("ext_sshd")) {
-					notify($ERRORS{'WARNING'}, 0, "failed to start ext_sshd");
-					return 0;	
-				}
-			
-				notify($ERRORS{'DEBUG'}, 0, "restarted ext_sshd");
-        }
+	notify($ERRORS{'OK'}, 0, "server_allow_user_list= $server_allow_user_list");
+	if ( $server_allow_user_list ) {
+		my $cmd = "sed -i -e \"/^AllowUsers */d\" /etc/ssh/external_sshd_config; echo \"AllowUsers $server_allow_user_list\" >> /etc/ssh/external_sshd_config";
+		if (run_ssh_command($computer_node_name, $identity, $cmd, "root")) {
+			notify($ERRORS{'DEBUG'}, 0, "added AllowUsers $server_allow_user_list to external_sshd_config");
+		}
+		else {
+			notify($ERRORS{'CRITICAL'}, 0, "failed to add AllowUsers $server_allow_user_list to external_sshd_config");
+		}
+		
+		if(!$self->stop_service("ext_sshd")) {
+		
+		}
+		
+		if(!$self->start_service("ext_sshd")) {
+			notify($ERRORS{'WARNING'}, 0, "failed to start ext_sshd");
+			return 0;	
+		}
+		
+		notify($ERRORS{'DEBUG'}, 0, "restarted ext_sshd");
+	}
 	
 	return 1;
-
 }
 
 #/////////////////////////////////////////////////////////////////////////////
@@ -3094,49 +3095,48 @@ sub service_exists {
 =cut
 
 sub start_service {
-        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();
-
-        my $service_name = shift;
-        if (!$service_name) {
-                notify($ERRORS{'WARNING'}, 0, "service name was not passed as an argument");
-                return;
-        }
-		  my $command;
-
-		  # Check if OS is using systemd or SysVinit
-		  if($self->file_exists("/bin/systemctl")){
-					 $command = "systemctl start $service_name" . ".service";
-		  }
-		  else {
-				  $command = "service $service_name start";
-		  }
-
-		  my ($status, $output) = run_ssh_command($computer_node_name, $management_node_keys, $command, '', '', 1);
-        if (defined($output) && grep(/failed/i, @{$output})) {
-                notify($ERRORS{'DEBUG'}, 0, "service does not exist: $service_name");
-                return 0;
-        }
-        elsif (defined($status) && $status == 0) {
-                notify($ERRORS{'DEBUG'}, 0, "service exists: $service_name");
-        }
-        elsif (defined($status)) {
-                notify($ERRORS{'WARNING'}, 0, "unable to determine if service exists: $service_name, exit status: $status, output:\n@{$output}");
-                return;
-        }
-        else {
-                notify($ERRORS{'WARNING'}, 0, "unable to run ssh command to determine if service exists");
-                return;
-        }
-
-        return 1;
-
+	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();
+	
+	my $service_name = shift;
+	if (!$service_name) {
+		notify($ERRORS{'WARNING'}, 0, "service name was not passed as an argument");
+		return;
+	}
+	my $command;
+	
+	# Check if OS is using systemd or SysVinit
+	if($self->file_exists("/bin/systemctl")){
+		$command = "systemctl start $service_name" . ".service";
+	}
+	else {
+		$command = "service $service_name start";
+	}
+	
+	my ($status, $output) = run_ssh_command($computer_node_name, $management_node_keys, $command, '', '', 1);
+	if (defined($output) && grep(/failed/i, @{$output})) {
+		notify($ERRORS{'DEBUG'}, 0, "service does not exist: $service_name");
+		return 0;
+	}
+	elsif (defined($status) && $status == 0) {
+		notify($ERRORS{'DEBUG'}, 0, "service exists: $service_name");
+	}
+	elsif (defined($status)) {
+		notify($ERRORS{'WARNING'}, 0, "unable to determine if service exists: $service_name, exit status: $status, output:\n@{$output}");
+		return;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "unable to run ssh command to determine if service exists");
+		return;
+	}
+	
+	return 1;
 }
 
 #/////////////////////////////////////////////////////////////////////////////
@@ -3152,49 +3152,48 @@ sub start_service {
 =cut
 
 sub stop_service {
-        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();
-
-        my $service_name = shift;
-        if (!$service_name) {
-                notify($ERRORS{'WARNING'}, 0, "service name was not passed as an argument");
-                return;
-        }
-        my $command;
-
-        # Check if OS is using systemd or SysVinit
-        if($self->file_exists("/bin/systemctl")){
-                $command = "systemctl stop $service_name" . ".service";
-        }
-        else {
-              $command = "service $service_name stop";
-        }
-
-        my ($status, $output) = run_ssh_command($computer_node_name, $management_node_keys, $command, '', '', 1);
-        if (defined($output) && grep(/failed/i, @{$output})) {
-                notify($ERRORS{'DEBUG'}, 0, "service does not exist: $service_name");
-                return 0;
-        }
-        elsif (defined($status) && $status == 0) {
-                notify($ERRORS{'DEBUG'}, 0, "service exists: $service_name");
-        }
-        elsif (defined($status)) {
-                notify($ERRORS{'WARNING'}, 0, "unable to determine if service exists: $service_name, exit status: $status, output:\n@{$output}");
-                return;
-        }
-        else {
-                notify($ERRORS{'WARNING'}, 0, "unable to run ssh command to determine if service exists");
-                return;
-        }
-
-        return 1;
-
+	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();
+	
+	my $service_name = shift;
+	if (!$service_name) {
+		notify($ERRORS{'WARNING'}, 0, "service name was not passed as an argument");
+		return;
+	}
+	my $command;
+	
+	# Check if OS is using systemd or SysVinit
+	if($self->file_exists("/bin/systemctl")){
+		$command = "systemctl stop $service_name" . ".service";
+	}
+	else {
+		$command = "service $service_name stop";
+	}
+	
+	my ($status, $output) = run_ssh_command($computer_node_name, $management_node_keys, $command, '', '', 1);
+	if (defined($output) && grep(/failed/i, @{$output})) {
+		notify($ERRORS{'DEBUG'}, 0, "service does not exist: $service_name");
+		return 0;
+	}
+	elsif (defined($status) && $status == 0) {
+		notify($ERRORS{'DEBUG'}, 0, "service exists: $service_name");
+	}
+	elsif (defined($status)) {
+		notify($ERRORS{'WARNING'}, 0, "unable to determine if service exists: $service_name, exit status: $status, output:\n@{$output}");
+		return;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "unable to run ssh command to determine if service exists");
+		return;
+	}
+	
+	return 1;
 }
 
 #/////////////////////////////////////////////////////////////////////////////
@@ -3209,18 +3208,18 @@ sub stop_service {
 
 sub check_connection_on_port {
 	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;
-   }
-
+	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();
 	my $remote_ip 			= $self->data->get_reservation_remote_ip();
 	my $computer_ip_address   	= $self->data->get_computer_ip_address();
 	my $request_state_name   	= $self->data->get_request_state_name();
 	my $username = $self->data->get_user_login_id();
-
+	
 	my $port = shift;
 	if (!$port) {
 		notify($ERRORS{'WARNING'}, 0, "port variable was not passed as an argument");
@@ -3233,39 +3232,39 @@ sub check_connection_on_port {
 	notify($ERRORS{'DEBUG'}, 0, "checking connections on node $computer_node_name on port $port");
 	foreach my $line (@{$output}) {
 		if ($line =~ /Connection refused|Permission denied/) {
-                    chomp($line);
-                    notify($ERRORS{'WARNING'}, 0, "$line");
-                    if ($request_state_name =~ /reserved/) {
-                        $ret_val = "failed";
-                    }
-                    else {
-                         $ret_val = "timeout";
-                    }
-                    return $ret_val;
-                 } ## end if ($line =~ /Connection refused|Permission denied/)
-                 if ($line =~ /tcp\s+([0-9]*)\s+([0-9]*)\s($computer_ip_address:$port)\s+([.0-9]*):([0-9]*)(.*)(ESTABLISHED)/) {
-                     if ($4 eq $remote_ip) {
-                         $ret_val = "connected";
-                         return $ret_val;
-                     }
-                     else {
-							  my $new_remote_ip = $4;
-                    	  #this isn't the defined remoteIP
-								# Confirm the user is logged in
-								# Is user logged in
-                        if (!$self->user_logged_in()) {
-                           notify($ERRORS{'OK'}, 0, "Detected $new_remote_ip is connected. $username is not logged in yet. Returning no connection");
-                           $ret_val = "no";
-                           return $ret_val;
-                        }
-                        else {	
-										  $self->data->set_reservation_remote_ip($new_remote_ip);	
-										  notify($ERRORS{'OK'}, 0, "Updating reservation remote_ip with $new_remote_ip");
-										  $ret_val = "conn_wrong_ip";
-										  return $ret_val;
-								}
-                     }
-                 }    # tcp check
+			chomp($line);
+			notify($ERRORS{'WARNING'}, 0, "$line");
+			if ($request_state_name =~ /reserved/) {
+				$ret_val = "failed";
+			}
+			else {
+				$ret_val = "timeout";
+			}
+			return $ret_val;
+		} ## end if ($line =~ /Connection refused|Permission denied/)
+		if ($line =~ /tcp\s+([0-9]*)\s+([0-9]*)\s($computer_ip_address:$port)\s+([.0-9]*):([0-9]*)(.*)(ESTABLISHED)/) {
+			if ($4 eq $remote_ip) {
+				$ret_val = "connected";
+				return $ret_val;
+			}
+			else {
+				my $new_remote_ip = $4;
+				#this isn't the defined remoteIP
+				# Confirm the user is logged in
+				# Is user logged in
+				if (!$self->user_logged_in()) {
+					notify($ERRORS{'OK'}, 0, "Detected $new_remote_ip is connected. $username is not logged in yet. Returning no connection");
+					$ret_val = "no";
+					return $ret_val;
+				}
+				else {	
+					$self->data->set_reservation_remote_ip($new_remote_ip);	
+					notify($ERRORS{'OK'}, 0, "Updating reservation remote_ip with $new_remote_ip");
+					$ret_val = "conn_wrong_ip";
+					return $ret_val;
+				}
+			}
+		}    # tcp check
 	}
 	return $ret_val;
 }
@@ -3416,32 +3415,28 @@ sub get_total_memory {
 =cut
 
 sub sanitize_firewall {
-   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 $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 $scope = shift;
 	if(!defined($scope)) {
 		notify($ERRORS{'CRITICAL'}, 0, "scope variable was not passed in as an arguement");
-      return;
+		return;
 	}
 	
 	my $computer_node_name = $self->data->get_computer_node_name();
-   my $mn_private_ip = $self->mn_os->get_private_ip_address();
+	my $mn_private_ip = $self->mn_os->get_private_ip_address();
 	
 	my $firewall_configuration = $self->get_firewall_configuration() || return;
-   my $chain;
-   my $iptables_del_cmd;
+	my $chain;
+	my $iptables_del_cmd;
 	my $INPUT_CHAIN = "INPUT";
-
-   for my $num (sort keys %{$firewall_configuration->{$INPUT_CHAIN}} ) {
-
 	
+	for my $num (sort keys %{$firewall_configuration->{$INPUT_CHAIN}} ) {
 	}
-
-
 }
 
 #/////////////////////////////////////////////////////////////////////////////
@@ -3456,10 +3451,10 @@ sub sanitize_firewall {
 
 sub enable_firewall_port {
 	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;
-   }
+	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;
+	}
 	
 	# Check to see if this distro has iptables
 	# If not return 1 so it does not fail
@@ -3474,17 +3469,17 @@ sub enable_firewall_port {
 		return;
 	}
 	
-   my $computer_node_name = $self->data->get_computer_node_name();
+	my $computer_node_name = $self->data->get_computer_node_name();
 	my $mn_private_ip = $self->mn_os->get_private_ip_address();
 	
 	$protocol = lc($protocol);
 	
 	$scope_argument = '' if (!defined($scope_argument));
 
-   $name = '' if !$name;
-   $description = '' if !$description;
+	$name = '' if !$name;
+	$description = '' if !$description;
 
-   my $scope;
+	my $scope;
 
 	my $INPUT_CHAIN = "INPUT";
 
@@ -3494,73 +3489,72 @@ sub enable_firewall_port {
 	my $iptables_del_cmd;
 
 	for my $num (sort keys %{$firewall_configuration->{$INPUT_CHAIN}} ) {
-   	my $existing_scope = $firewall_configuration->{$INPUT_CHAIN}{$num}{$protocol}{$port}{scope} || '';
-   	my $existing_name = $firewall_configuration->{$INPUT_CHAIN}{$num}{$protocol}{$port}{name} || '';
-   	my $existing_description = $firewall_configuration->{$INPUT_CHAIN}{$num}{$protocol}{$port}{name} || '';
+		my $existing_scope = $firewall_configuration->{$INPUT_CHAIN}{$num}{$protocol}{$port}{scope} || '';
+		my $existing_name = $firewall_configuration->{$INPUT_CHAIN}{$num}{$protocol}{$port}{name} || '';
+		my $existing_description = $firewall_configuration->{$INPUT_CHAIN}{$num}{$protocol}{$port}{name} || '';
 	
-   	if ($existing_scope) {
+		if ($existing_scope) {
 			notify($ERRORS{'DEBUG'}, 0, " num= $num protocol= $protocol port= $port existing_scope= $existing_scope existing_name= $existing_name existing_description= $existing_description ");
 
 			if ($overwrite_existing) {
-         	$scope = $self->parse_firewall_scope($scope_argument);
+				$scope = $self->parse_firewall_scope($scope_argument);
 				$iptables_del_cmd = "iptables -D $INPUT_CHAIN $num";
-         	if (!$scope) {
-            	notify($ERRORS{'WARNING'}, 0, "failed to parse firewall scope argument: '$scope_argument'");
-            	return;
-         	}
+				if (!$scope) {
+					notify($ERRORS{'WARNING'}, 0, "failed to parse firewall scope argument: '$scope_argument'");
+					return;
+				}
 
-         	notify($ERRORS{'DEBUG'}, 0, "existing firewall opening on $computer_node_name will be replaced:\n" .
-            "name: '$existing_name'\n" .
+				notify($ERRORS{'DEBUG'}, 0, "existing firewall opening on $computer_node_name will be replaced:\n" .
+				"name: '$existing_name'\n" .
 				"num: '$num'\n" .
-            "protocol: $protocol\n" .
+				"protocol: $protocol\n" .
 				"port/type: $port\n" .
-            "existing scope: '$existing_scope'\n" .
-            "new scope: $scope\n" .
-            "overwrite existing rule: " . ($overwrite_existing ? 'yes' : 'no')
-         	);
-      	}
+				"existing scope: '$existing_scope'\n" .
+				"new scope: $scope\n" .
+				"overwrite existing rule: " . ($overwrite_existing ? 'yes' : 'no')
+				);
+			}
 			else {
-         	my $parsed_existing_scope = $self->parse_firewall_scope($existing_scope);
-         	if (!$parsed_existing_scope) {
-            	notify($ERRORS{'WARNING'}, 0, "failed to parse existing firewall scope: '$existing_scope'");
-           	 return;
-         	}
-
-         	$scope = $self->parse_firewall_scope("$scope_argument,$existing_scope");
-         	if (!$scope) {
-            	notify($ERRORS{'WARNING'}, 0, "failed to parse firewall scope argument appended with existing scope: '$scope_argument,$existing_scope'");
-            	return;
-         	}
-
-         	if ($scope eq $parsed_existing_scope) {
-            	notify($ERRORS{'DEBUG'}, 0, "firewall is already open on $computer_node_name, existing scope matches scope argument:\n" .
-               "name: '$existing_name'\n" .
-               "protocol: $protocol\n" .
-               "port/type: $port\n" .
-               "scope: $scope\n" .
-               "overwrite existing rule: " . ($overwrite_existing ? 'yes' : 'no')
-            	);
-            	return 1;
-         	}
-      	}
+				my $parsed_existing_scope = $self->parse_firewall_scope($existing_scope);
+				if (!$parsed_existing_scope) {
+					notify($ERRORS{'WARNING'}, 0, "failed to parse existing firewall scope: '$existing_scope'");
+					return;
+				}
+
+				$scope = $self->parse_firewall_scope("$scope_argument,$existing_scope");
+				if (!$scope) {
+					notify($ERRORS{'WARNING'}, 0, "failed to parse firewall scope argument appended with existing scope: '$scope_argument,$existing_scope'");
+					return;
+				}
+
+				if ($scope eq $parsed_existing_scope) {
+					notify($ERRORS{'DEBUG'}, 0, "firewall is already open on $computer_node_name, existing scope matches scope argument:\n" .
+					"name: '$existing_name'\n" .
+					"protocol: $protocol\n" .
+					"port/type: $port\n" .
+					"scope: $scope\n" .
+					"overwrite existing rule: " . ($overwrite_existing ? 'yes' : 'no')
+					);
+					return 1;
+				}
+			}
 		}
 		else {
 			next;
-   	}
+		}
 	}
 
-     	if(!$scope) {
+		if(!$scope) {
 			$scope = $self->parse_firewall_scope($scope_argument);
-     		if (!$scope) {
-        		notify($ERRORS{'WARNING'}, 0, "failed to parse firewall scope argument: '$scope_argument'");
-        		return;
-     		}
+			if (!$scope) {
+				notify($ERRORS{'WARNING'}, 0, "failed to parse firewall scope argument: '$scope_argument'");
+				return;
+			}
 		}
 
-  
-   	$name = "VCL: allow $protocol/$port from $scope" if !$name;
+		$name = "VCL: allow $protocol/$port from $scope" if !$name;
 
-   	$name = substr($name, 0, 60) . "..." if length($name) > 60;
+		$name = substr($name, 0, 60) . "..." if length($name) > 60;
 
 		my $command;
 
@@ -3570,7 +3564,7 @@ sub enable_firewall_port {
 		}
 
 		$command .= "/sbin/iptables -I INPUT 1 -m state --state NEW,RELATED,ESTABLISHED -m $protocol -p $protocol -j ACCEPT";
-	
+		
 		if ($port =~ /\d+/){
 			$command .= " --dport $port";
 		}
@@ -3626,68 +3620,67 @@ sub enable_firewall_port {
 =cut
 
 sub disable_firewall_port {
-   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 $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;
+	}
 
 	# Check to see if this distro has iptables
-   # If not return 1 so it does not fail
-   if (!($self->service_exists("iptables"))) {
-      notify($ERRORS{'WARNING'}, 0, "iptables does not exist on this OS");
-      return 1;
-   }
+	# If not return 1 so it does not fail
+	if (!($self->service_exists("iptables"))) {
+		notify($ERRORS{'WARNING'}, 0, "iptables does not exist on this OS");
+		return 1;
+	}
 	
 	my ($protocol, $port, $scope_argument, $overwrite_existing, $name, $description) = @_;
 	if (!defined($protocol) || !defined($port)) {
-     notify($ERRORS{'WARNING'}, 0, "protocol and port arguments were not supplied");
-     return;
+		notify($ERRORS{'WARNING'}, 0, "protocol and port arguments were not supplied");
+		return;
 	}
 
-   my $computer_node_name = $self->data->get_computer_node_name();
+	my $computer_node_name = $self->data->get_computer_node_name();
 	my $mn_private_ip = $self->mn_os->get_private_ip_address();
 
-   $protocol = lc($protocol);
+	$protocol = lc($protocol);
 
-   $scope_argument = '' if (!defined($scope_argument));
+	$scope_argument = '' if (!defined($scope_argument));
 
-   $name = '' if !$name;
-   $description = '' if !$description;
+	$name = '' if !$name;
+	$description = '' if !$description;
 
-   my $scope;
+	my $scope;
 
-   my $INPUT_CHAIN = "INPUT";
+	my $INPUT_CHAIN = "INPUT";
 
-   my $firewall_configuration = $self->get_firewall_configuration() || return;
-   my $chain;
-   my $command;
+	my $firewall_configuration = $self->get_firewall_configuration() || return;
+	my $chain;
+	my $command;
 
-   for my $num (sort keys %{$firewall_configuration->{$INPUT_CHAIN}} ) {
+	for my $num (sort keys %{$firewall_configuration->{$INPUT_CHAIN}} ) {
 		my $existing_scope = $firewall_configuration->{$INPUT_CHAIN}{$num}{$protocol}{$port}{scope} || '';
 		my $existing_name = $firewall_configuration->{$INPUT_CHAIN}{$num}{$protocol}{$port}{name} || '';
 		if($existing_scope) {
 			$command = "iptables -D $INPUT_CHAIN $num";
 
 			notify($ERRORS{'DEBUG'}, 0, "attempting to execute command on $computer_node_name: '$command'");
-   		my ($status, $output) = $self->execute($command);
-   		if (defined $status && $status == 0) {
-       		notify($ERRORS{'DEBUG'}, 0, "executed command on $computer_node_name: '$command'");
-   		}
-   		else {
-       		notify($ERRORS{'WARNING'}, 0, "output from iptables:\n" . join("\n", @$output));
-   		}
+			my ($status, $output) = $self->execute($command);
+			if (defined $status && $status == 0) {
+				notify($ERRORS{'DEBUG'}, 0, "executed command on $computer_node_name: '$command'");
+			}
+			else {
+				notify($ERRORS{'WARNING'}, 0, "output from iptables:\n" . join("\n", @$output));
+			}
 
-   		# Save rules to sysconfig/iptables -- incase of reboot
-   		my $iptables_save_cmd = "/sbin/iptables-save > /etc/sysconfig/iptables";
-   		my ($status_save, $output_save) = $self->execute($iptables_save_cmd);
-   		if (defined $status_save && $status_save == 0) {
-       		notify($ERRORS{'DEBUG'}, 0, "executed command $iptables_save_cmd on $computer_node_name");
-   		}
+			# Save rules to sysconfig/iptables -- incase of reboot
+			my $iptables_save_cmd = "/sbin/iptables-save > /etc/sysconfig/iptables";
+			my ($status_save, $output_save) = $self->execute($iptables_save_cmd);
+			if (defined $status_save && $status_save == 0) {
+				notify($ERRORS{'DEBUG'}, 0, "executed command $iptables_save_cmd on $computer_node_name");
+			}
 		}
 	}
-   return 1;
-
+	return 1;
 }
 
 #/////////////////////////////////////////////////////////////////////////////

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm?rev=1351461&r1=1351460&r2=1351461&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm Mon Jun 18 19:09:26 2012
@@ -190,7 +190,7 @@ sub _run_vim_cmd {
 		# Keep a count of the number of times vim-cmd is executed for the entire vcld state process
 		# This will be used to improve performance by reducing the number of calls necessary
 		$self->{vim_cmd_calls}++;
-		notify($ERRORS{'DEBUG'}, 0, "vim-cmd call count: $self->{vim_cmd_calls} ($vim_arguments)");
+		#notify($ERRORS{'DEBUG'}, 0, "vim-cmd call count: $self->{vim_cmd_calls} ($vim_arguments)");
 		
 		my ($exit_status, $output) = $self->vmhost_os->execute($command);
 		if (!defined($output)) {
@@ -1000,6 +1000,13 @@ sub vm_power_off {
 		return;
 	}
 	
+	# Check if the VM is already powered off
+	my $vm_power_state = $self->get_vm_power_state($vmx_file_path);
+	if ($vm_power_state && $vm_power_state =~ /off/i) {
+		notify($ERRORS{'DEBUG'}, 0, "VM is already powered off: $vmx_file_path");
+		return 1;
+	}
+	
 	# Get the VM ID
 	my $vm_id = $self->_get_vm_id($vmx_file_path);
 	if (!defined($vm_id)) {

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm?rev=1351461&r1=1351460&r2=1351461&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/libvirt.pm Mon Jun 18 19:09:26 2012
@@ -236,17 +236,8 @@ Define the domain on the node by calling
 
 =cut
 
-	my $command = "virsh define \"$domain_xml_file_path\"";
-	my ($exit_status, $output) = $self->vmhost_os->execute($command);
-	if (!defined($output)) {
-		notify($ERRORS{'WARNING'}, 0, "failed to execute virsh command to define '$domain_name' domain on $node_name");
-		return;
-	}
-	elsif ($exit_status eq '0') {
-		notify($ERRORS{'OK'}, 0, "defined '$domain_name' domain on $node_name");
-	}
-	else {
-		notify($ERRORS{'WARNING'}, 0, "failed to define '$domain_name' domain on $node_name\ncommand: $command\nexit status: $exit_status\noutput:\n" . join("\n", @$output));
+	if (!$self->define_domain($domain_xml_file_path, 1)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to load '$image_name' image on '$computer_name', unable to define domain");
 		return;
 	}
 
@@ -308,7 +299,6 @@ sub capture {
 	my $imagerevision_id = $self->data->get_imagerevision_id();
 	my $image_name = $self->data->get_image_name();
 	my $image_type = $self->data->get_imagetype_name();
-	my $domain_name = $self->get_domain_name();
 	my $node_name = $self->data->get_vmhost_short_name();
 	my $old_image_name = $self->data->get_image_name();
 	my $master_image_directory_path = $self->get_master_image_directory_path();
@@ -321,6 +311,24 @@ sub capture {
 	# Set the imagemeta Sysprep value to 0 to prevent Sysprep from being used
 	$self->data->set_imagemeta_sysprep(0);
 	
+	# Get the domain name
+	my $domain_name = $self->get_domain_name();
+	if (!$domain_name) {
+		notify($ERRORS{'WARNING'}, 0, "unable to capture image on $node_name, domain name could not be determined");
+		return;
+	}
+	
+	# Check the power status before proceeding
+	my $power_status = $self->power_status();
+	if (!$power_status) {
+		notify($ERRORS{'WARNING'}, 0, "unable to capture image on $node_name, power status of '$domain_name' domain could not be determined");
+		return;
+	}
+	elsif ($power_status !~ /on/i) {
+		notify($ERRORS{'WARNING'}, 0, "unable to capture image on $node_name, power status of '$domain_name' domain is $power_status");
+		return;
+	}
+	
 	# Construct the new image name
 	my $new_image_name = $self->get_new_image_name();
 	$self->data->set_image_name($new_image_name);
@@ -337,6 +345,26 @@ sub capture {
 		return;
 	}
 	
+	# Get the domain XML definition
+	my $domain_xml_string = $self->get_domain_xml_string($domain_name);
+	if (!$domain_xml_string) {
+		notify($ERRORS{'WARNING'}, 0, "failed to capture image on $node_name, unable to retrieve domain XML definition: $domain_name");
+		return;
+	}
+	
+	# Delete existing XML definition files
+	$self->os->delete_file("~/*-v*.xml");
+	
+	# Save the domain XML definition to a file in the image
+	my $image_xml_file_path = "~/$new_image_name.xml";
+	if ($self->os->create_text_file($image_xml_file_path, $domain_xml_string)) {
+		notify($ERRORS{'OK'}, 0, "saved domain XML definition text file in image: $image_xml_file_path");
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to capture image on $node_name, unable to save domain XML definition text file in image: $image_xml_file_path, contents:\n$domain_xml_string");
+		return;
+	}
+	
 	# Call the OS module's pre_capture() subroutine
 	if ($self->os->can("pre_capture") && !$self->os->pre_capture({end_state => 'off'})) {
 		notify($ERRORS{'WARNING'}, 0, "failed to complete OS module's pre_capture tasks");
@@ -396,22 +424,15 @@ sub capture {
 			return;
 		}
 		
-		# Get the domain XML definition
-		my $domain_xml = $self->get_domain_xml($domain_name);
-		if (!$domain_xml) {
-			notify($ERRORS{'WARNING'}, 0, "failed to capture image on $node_name, unable to retrieve domain XML definition: $domain_name");
-			return;
-		}
-		
-		# Save the domain XML definition to a file in the master image directory
-		my $master_xml_file_path = $self->get_master_xml_file_path();
-		if ($self->vmhost_os->create_text_file($master_xml_file_path, $domain_xml)) {
-			notify($ERRORS{'OK'}, 0, "saved domain XML definition text file to master image directory: $master_xml_file_path");
-		}
-		else {
-			notify($ERRORS{'WARNING'}, 0, "failed to capture image on $node_name, unable to save domain XML definition text file: $master_xml_file_path");
-			return;
-		}
+		## Save the domain XML definition to a file in the master image directory
+		#my $master_xml_file_path = $self->get_master_xml_file_path();
+		#if ($self->vmhost_os->create_text_file($master_xml_file_path, $domain_xml)) {
+		#	notify($ERRORS{'OK'}, 0, "saved domain XML definition text file to master image directory: $master_xml_file_path");
+		#}
+		#else {
+		#	notify($ERRORS{'WARNING'}, 0, "failed to capture image on $node_name, unable to save domain XML definition text file: $master_xml_file_path");
+		#	return;
+		#}
 		
 		# Copy the master image to the repository if the repository path is configured in the VM host profile
 		if ($repository_image_file_path) {
@@ -429,15 +450,15 @@ sub capture {
 				return;
 			}
 			
-			# Save the domain XML definition to a file in the repository image directory
-			my $repository_xml_file_path = $self->get_repository_xml_file_path();
-			if ($self->vmhost_os->create_text_file($repository_xml_file_path, $domain_xml)) {
-				notify($ERRORS{'OK'}, 0, "saved domain XML definition text file to repository image directory: $master_xml_file_path");
-			}
-			else {
-				notify($ERRORS{'WARNING'}, 0, "failed to capture image on $node_name, unable to save domain XML definition text file to repository image directory: $master_xml_file_path");
-				return;
-			}
+			## Save the domain XML definition to a file in the repository image directory
+			#my $repository_xml_file_path = $self->get_repository_xml_file_path();
+			#if ($self->vmhost_os->create_text_file($repository_xml_file_path, $domain_xml)) {
+			#	notify($ERRORS{'OK'}, 0, "saved domain XML definition text file to repository image directory: $master_xml_file_path");
+			#}
+			#else {
+			#	notify($ERRORS{'WARNING'}, 0, "failed to capture image on $node_name, unable to save domain XML definition text file to repository image directory: $master_xml_file_path");
+			#	return;
+			#}
 		}
 	}
 	
@@ -827,27 +848,13 @@ sub get_domain_name {
 	# If request state is image the domain name will be that of the image used as the base image, not the image being created
 	# Must find existing loaded domain on node in order to determine name
 	if ($request_state_name eq 'image') {
-		# Must ensure that only 1 matching domain was found
-		my @matching_domain_names;
-		my $domain_info = $self->get_domain_info();
-		for my $domain_name (keys %$domain_info) {
-			if ($domain_name =~ /^$computer_short_name:/) {
-				push @matching_domain_names, $domain_name;
-			}
-		}
-		
-		# Make sure only 1 domain was found
-		if (scalar @matching_domain_names == 1) {
-			$self->{domain_name} = $matching_domain_names[0];
-			notify($ERRORS{'DEBUG'}, 0, "retrieved name of domain being captured from $node_name: '$self->{domain_name}'");
-			return $self->{domain_name};
-		}
-		elsif (@matching_domain_names) {
-			notify($ERRORS{'WARNING'}, 0, "unable to determine name of domain to be captured, found multiple domain names beginning with '$computer_short_name:' on $node_name:\n" . join("\n", @matching_domain_names));
-			return;
+		if (my $active_domain_name = $self->get_active_domain_name()) {
+			notify($ERRORS{'DEBUG'}, 0, "retrieved name of domain being captured: '$active_domain_name'");
+			$self->{domain_name} = $active_domain_name;
+			return $active_domain_name;
 		}
 		else {
-			notify($ERRORS{'WARNING'}, 0, "unable to determine name of domain to be captured, did not find a domain name beginning with '$computer_short_name:' on $node_name");
+			notify($ERRORS{'WARNING'}, 0, "unable to determine name of domain to be captured");
 			return;
 		}
 	}
@@ -862,6 +869,106 @@ sub get_domain_name {
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 get_active_domain_name
+
+ Parameters  : none
+ Returns     : string
+ Description : Determines the name of the domain assigned to the reservation.
+               This subroutine is mainly used when capturing base images. The
+               name of the domain is chosen by the person capturing it and may
+               not contain the name of the VCL computer.
+
+=cut
+
+sub get_active_domain_name {
+	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 $os_type = $self->data->get_image_os_type();
+	my $computer_name = $self->data->get_computer_short_name();
+	
+	my $active_os;
+	my $active_os_type = $self->os->get_os_type();
+	if (!$active_os_type) {
+		notify($ERRORS{'WARNING'}, 0, "unable to determine active domain, OS type currently installed on $computer_name could not be determined");
+		return;
+	}
+	elsif ($active_os_type ne $os_type) {
+		notify($ERRORS{'DEBUG'}, 0, "OS type currently installed on $computer_name does not match the OS type of the reservation image:\nOS type installed on $computer_name: $active_os_type\nreservation image OS type: $os_type");
+		
+		my $active_os_perl_package;
+		if ($active_os_type =~ /linux/i) {
+			$active_os_perl_package = 'VCL::Module::OS::Linux';
+		}
+		else {
+			$active_os_perl_package = 'VCL::Module::OS::Windows';
+		}
+		
+		if ($active_os = $self->create_os_object($active_os_perl_package)) {
+			notify($ERRORS{'DEBUG'}, 0, "created a '$active_os_perl_package' OS object for the '$active_os_type' OS type currently installed on $computer_name");
+		}
+		else {
+			notify($ERRORS{'WARNING'}, 0, "unable to determine active domain name, failed to create a '$active_os_perl_package' OS object for the '$active_os_type' OS type currently installed on $computer_name");
+			return;
+		}
+	}
+	else {
+		notify($ERRORS{'DEBUG'}, 0, "'$active_os_type' OS type currently installed on $computer_name matches the OS type of the image assigned to this reservation");
+		$active_os = $self->os;
+	}
+	
+	# Make sure the active OS object implements the required subroutines called below
+	if (!$active_os->can('get_private_mac_address') || !$active_os->can('get_public_mac_address')) {
+		notify($ERRORS{'WARNING'}, 0, "unable to determine active domain name, " . ref($active_os) . " OS object does not implement 'get_private_mac_address' and 'get_public_mac_address' subroutines");
+		return;
+	}
+	
+	# Get the MAC addresses being used by the running VM for this reservation
+	my @domain_mac_addresses = ($active_os->get_private_mac_address(), $active_os->get_public_mac_address());
+	if (!@domain_mac_addresses) {
+		notify($ERRORS{'WARNING'}, 0, "unable to retrieve the private and public MAC address being used by $computer_name");
+		return;
+	}
+	
+	# Remove the colons from the MAC addresses and convert to lower case so they can be compared
+	map { s/[^\w]//g; $_ = lc($_) } (@domain_mac_addresses);
+	
+	my @matching_domain_names;
+	my $domain_info = $self->get_domain_info();
+	for my $domain_name (keys %$domain_info) {
+		my @check_mac_addresses = $self->get_domain_mac_addresses($domain_name);
+		map { s/[^\w]//g; $_ = lc($_) } (@check_mac_addresses);
+		
+		my @matching_mac_addresses = map { my $domain_mac_address = $_; grep(/$domain_mac_address/i, @check_mac_addresses) } @domain_mac_addresses;
+		if (!@matching_mac_addresses) {
+			notify($ERRORS{'DEBUG'}, 0, "ignoring domain '$domain_name' because MAC address does not match any being used by $computer_name");
+			next;
+		}
+		
+		notify($ERRORS{'DEBUG'}, 0, "found matching MAC address between $computer_name and domain '$domain_name':\n" . join("\n", sort(@matching_mac_addresses)));
+		push @matching_domain_names, $domain_name;
+	}
+	
+	if (!@matching_domain_names) {
+		notify($ERRORS{'WARNING'}, 0, "failed to determine active domain name, did not find any domains configured to use MAC address currently being used by $computer_name:\n" . join("\n", sort(@domain_mac_addresses)));
+		return;
+	}
+	elsif (scalar(@matching_domain_names) == 1) {
+		my $active_domain_name = $matching_domain_names[0];
+		notify($ERRORS{'DEBUG'}, 0, "determined active domain name: $active_domain_name");
+		return $active_domain_name;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to determine active domain name, multiple domains (" . join(', ', @matching_domain_names) . ") are configured to use MAC address currently being used by $computer_name:\n" . join("\n", sort(@domain_mac_addresses)));
+		return;
+	}
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 get_domain_file_base_name
 
  Parameters  : none
@@ -1199,6 +1306,75 @@ sub get_new_image_name {
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 define_domain
+
+ Parameters  : $domain_xml_file_path, $autostart (optional)
+ Returns     : boolean
+ Description : Defines a domain on the node.
+
+=cut
+
+sub define_domain {
+	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 $domain_xml_file_path = shift;
+	if (!defined($domain_xml_file_path)) {
+		notify($ERRORS{'WARNING'}, 0, "domain XML file path argument was not specified");
+		return;
+	}
+	
+	my $autostart = shift;
+	
+	my $node_name = $self->data->get_vmhost_short_name();
+	
+	my $define_command = "virsh define \"$domain_xml_file_path\"";
+	my ($define_exit_status, $define_output) = $self->vmhost_os->execute($define_command);
+	if (!defined($define_output)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to execute virsh command to define domain on $node_name: $domain_xml_file_path");
+		return;
+	}
+	elsif ($define_exit_status eq '0') {
+		notify($ERRORS{'OK'}, 0, "defined domain on $node_name, output:\n" . join("\n", @$define_output));
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to define domain on $node_name\ncommand: $define_command\nexit status: $define_exit_status\noutput:\n" . join("\n", @$define_output));
+		return;
+	}
+	
+	if ($autostart) {
+		# Parse the domain name from the 'virsh define' output, should look like this:
+		# Domain vclv11:linux-kvmimage-2935-v0 defined from /tmp/vcl/vcl11_2935-v0.xml
+		my ($domain_name) = join("\n", @$define_output) =~ /Domain\s+(.+)\s+defined/;
+		if ($domain_name) {
+			notify($ERRORS{'DEBUG'}, 0, "parsed domain name from 'virsh define' output: '$domain_name'");
+		}
+		else {
+			notify($ERRORS{'WARNING'}, 0, "failed to parse domain name from 'virsh define' output:\n" . join("\n", @$define_output));
+			return 1;
+		}
+		
+		my $autostart_command = "virsh autostart \"$domain_name\"";
+		my ($autostart_exit_status, $autostart_output) = $self->vmhost_os->execute($autostart_command);
+		if (!defined($autostart_output)) {
+			notify($ERRORS{'WARNING'}, 0, "failed to execute virsh command to configure '$domain_name' domain to autostart on $node_name");
+		}
+		elsif ($autostart_exit_status eq '0') {
+			notify($ERRORS{'OK'}, 0, "configured '$domain_name' domain to autostart on $node_name, output:\n" . join("\n", @$autostart_output));
+		}
+		else {
+			notify($ERRORS{'WARNING'}, 0, "failed to configure '$domain_name' domain to autostart on $node_name\ncommand: $autostart_command\nexit status: $autostart_exit_status\noutput:\n" . join("\n", @$autostart_output));
+		}
+	}
+	
+	return 1;
+}
+	
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 delete_existing_domains
 
  Parameters  : none
@@ -1261,6 +1437,7 @@ sub delete_domain {
 	}
 	
 	my $node_name = $self->data->get_vmhost_short_name();
+	my $request_state_name = $self->data->get_request_state_name();
 	
 	# Make sure domain is defined
 	if (!$self->domain_exists($domain_name)) {
@@ -1286,18 +1463,18 @@ sub delete_domain {
 	}
 	
 	my ($computer_name) = $domain_name =~ /^([^:]+):/;
-	if ($computer_name) {
+	if ($request_state_name eq 'image' || $computer_name) {
 		# Delete disks assigned to to domain
 		my @disk_file_paths = $self->get_domain_disk_file_paths($domain_name);
 		for my $disk_file_path (@disk_file_paths) {
 			# For safety, make sure the disk being deleted begins with the domain's computer name
 			my $disk_file_name = fileparse($disk_file_path, qr/\.[^\/]+$/i);
-			if ($disk_file_name !~ /^$computer_name\_/) {
+			if ($request_state_name ne 'image' && $disk_file_name !~ /^$computer_name\_/) {
 				notify($ERRORS{'WARNING'}, 0, "disk assigned to domain NOT deleted because the file name does not begin with '$computer_name\_':\nfile name: $disk_file_name\nfile path: $disk_file_path");
 				next;
 			}
 			else {
-				notify($ERRORS{'DEBUG'}, 0, "deleting disk assigned to domain, file name begins with '$computer_name\_': $disk_file_path");
+				notify($ERRORS{'DEBUG'}, 0, "deleting disk assigned to domain: $disk_file_path");
 				if (!$self->vmhost_os->delete_file($disk_file_path)) {
 					notify($ERRORS{'WARNING'}, 0, "failed to delete '$domain_name' domain on $node_name, '$disk_file_path' disk could not be deleted");
 					return;
@@ -1575,16 +1752,16 @@ sub get_domain_info {
 
 #/////////////////////////////////////////////////////////////////////////////
 
-=head2 get_domain_xml
+=head2 get_domain_xml_string
 
  Parameters  : $domain_name
- Returns     : hash reference
+ Returns     : string
  Description : Retrieves the XML definition of a domain already defined on the
-               node. Generates a hash.
+               node.
 
 =cut
 
-sub get_domain_xml {
+sub get_domain_xml_string {
 	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");
@@ -1610,13 +1787,43 @@ sub get_domain_xml {
 		return;
 	}
 	
-	if (my $xml = xml_string_to_hash($output)) {
+	return join("\n", @$output);
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_domain_xml
+
+ Parameters  : $domain_name
+ Returns     : hash reference
+ Description : Retrieves the XML definition of a domain already defined on the
+               node. Generates a hash.
+
+=cut
+
+sub get_domain_xml {
+	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 $domain_name = shift;
+	if (!defined($domain_name)) {
+		notify($ERRORS{'WARNING'}, 0, "domain name argument was not specified");
+		return;
+	}
+	
+	my $node_name = $self->data->get_vmhost_short_name();
+	
+	my $domain_xml_string = $self->get_domain_xml_string($domain_name) || return;
+	if (my $xml_hash = xml_string_to_hash($domain_xml_string)) {
 		notify($ERRORS{'DEBUG'}, 0, "retrieved XML definition for '$domain_name' domain on $node_name");
-		#notify($ERRORS{'DEBUG'}, 0, "retrieved XML definition for '$domain_name' domain on $node_name:\n" . format_data($xml));
-		return $xml;
+		#notify($ERRORS{'DEBUG'}, 0, "retrieved XML definition for '$domain_name' domain on $node_name:\n" . format_data($xml_hash));
+		return $xml_hash;
 	}
 	else {
-		notify($ERRORS{'WARNING'}, 0, "failed to convert XML definition for '$domain_name' domain to hash:\n" . join("\n", @$output));
+		notify($ERRORS{'WARNING'}, 0, "failed to convert XML definition for '$domain_name' domain to hash:\n$domain_xml_string");
 		return;
 	}
 }
@@ -1653,6 +1860,22 @@ sub get_domain_disk_file_paths {
 	
 	my @disk_file_paths = ();
 	for my $disk (@$disks) {
+		# Make sure device type is 'disk'
+		if (!$disk->{device}) {
+			notify($ERRORS{'DEBUG'}, 0, "ignoring disk definition, 'device' key is not present:\n" . format_data($disk));
+			next;
+		}
+		elsif ($disk->{device} !~ /^disk$/i) {
+			notify($ERRORS{'DEBUG'}, 0, "ignoring disk definition, 'device' key value is not 'disk', value: '$disk->{device}'\n" . format_data($disk));
+			next;
+		}
+		
+		# Make sure $disk->{source}->[0]->{file}
+		if (!defined($disk->{source}->[0]->{file})) {
+			notify($ERRORS{'DEBUG'}, 0, "ignoring disk definition, '{source}->[0]->{file}' key is not present\n" . format_data($disk));
+			next;
+		}
+		
 		push @disk_file_paths, $disk->{source}->[0]->{file};
 	}
 	
@@ -1661,6 +1884,46 @@ sub get_domain_disk_file_paths {
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 get_domain_mac_addresses
+
+ Parameters  : $domain_name
+ Returns     : array
+ Description : Retrieves the XML definition for the domain and extracts the MAC
+               addresses. An array containing the addresses is returned.
+
+=cut
+
+sub get_domain_mac_addresses {
+	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 $domain_name = shift;
+	if (!defined($domain_name)) {
+		notify($ERRORS{'WARNING'}, 0, "domain name argument was not specified");
+		return;
+	}
+	
+	# Get the domain XML definition
+	my $domain_xml = $self->get_domain_xml($domain_name);
+	
+	# Get the interface array ref section from the XML
+	my $interfaces = $domain_xml->{devices}->[0]->{interface};
+	
+	my @mac_addresses = ();
+	for my $interface (@$interfaces) {
+		#notify($ERRORS{'DEBUG'}, 0, "interface configured for domain '$domain_name':\n" . format_data($interface));
+		push @mac_addresses, $interface->{mac}->[0]->{address};
+	}
+	
+	notify($ERRORS{'DEBUG'}, 0, "retrieved MAC addresses assigned to domain '$domain_name':\n" . join("\n", @mac_addresses));
+	return @mac_addresses;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 domain_exists
 
  Parameters  : $domain_name

Modified: incubator/vcl/trunk/managementnode/lib/VCL/image.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/image.pm?rev=1351461&r1=1351460&r2=1351461&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/image.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/image.pm Mon Jun 18 19:09:26 2012
@@ -584,11 +584,11 @@ sub setup_capture_base_image {
 	my $computer_provisioning_module_name = $computer_info{$computer_id}{provisioning}{module}{name};
 	
 	my $install_type;
-	if ($computer_provisioning_module_name =~ /vm/i) {
-		$install_type = 'vmware';
+	if ($computer_provisioning_module_name =~ /xcat/i) {
+		$install_type = 'partimage';
 	}
 	else {
-		$install_type = 'partimage';
+		$install_type = 'vmware';
 	}
 	
 	print "\nComputer to be captured: $computer_hostname (ID: $computer_id)\n";

Modified: incubator/vcl/trunk/managementnode/lib/VCL/utils.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/utils.pm?rev=1351461&r1=1351460&r2=1351461&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/utils.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/utils.pm Mon Jun 18 19:09:26 2012
@@ -4297,7 +4297,7 @@ sub get_management_node_requests {
 
 =head2  get_image_info
 
- Parameters  : $image_identifier, $no_cache (optional)
+ Parameters  : $image_identifier, $no_cache (optional), $ignore_error (optional)
  Returns     : hash reference
  Description : Retrieves info for the image specified by the argument. The
                argument can either be the image ID or image name.
@@ -4306,7 +4306,7 @@ sub get_management_node_requests {
 
 
 sub get_image_info {
-	my ($image_identifier, $no_cache) = @_;
+	my ($image_identifier, $no_cache, $ignore_error) = @_;
 	if (!defined($image_identifier)) {
 		notify($ERRORS{'WARNING'}, 0, "image identifier argument was not specified");
 		return;
@@ -4372,7 +4372,12 @@ EOF
 
 	# Check to make sure 1 row was returned
 	if (scalar @selected_rows == 0) {
-		notify($ERRORS{'WARNING'}, 0, "zero rows were returned from database select statement:\n$select_statement");
+		if ($ignore_error) {
+			notify($ERRORS{'DEBUG'}, 0, "image does NOT exist in the database: $image_identifier");
+		}
+		else {
+			notify($ERRORS{'WARNING'}, 0, "zero rows were returned from database select statement:\n$select_statement");
+		}
 		return;
 	}
 	elsif (scalar @selected_rows > 1) {
@@ -4819,7 +4824,7 @@ sub run_ssh_command {
 		$port = $arguments->{port} || '22';
 		$output_level = $arguments->{output_level};
 		$max_attempts = $arguments->{max_attempts} || 3;
-		$timeout_seconds = $arguments->{timeout_seconds};
+		$timeout_seconds = $arguments->{timeout};
 	}
 	
 	# Determine the output level if it was specified
@@ -9749,8 +9754,8 @@ sub escape_file_path {
 	# Call quotemeta to escape all special character
 	$path = quotemeta $path;
 	
-	# Unescape wildcard * characters or else subroutines will fail which accept a wildcard file path
-	$path =~ s/\\+([\*\+])/$1/g;
+	# Unescape wildcard *, +, characters or else subroutines will fail which accept a wildcard file path
+	$path =~ s/\\+([\*\+\/\~])/$1/g;
 	
 	return $path;
 }