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 2010/08/04 16:11:02 UTC

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

Author: arkurth
Date: Wed Aug  4 14:11:02 2010
New Revision: 982258

URL: http://svn.apache.org/viewvc?rev=982258&view=rev
Log:
VCL-363
Removed the code from Linux.pm::changepasswd so that it does not recreate /etc/shadow. Removed utils.pm::changelinuxpassword because it is no longer being called.

VCL-49
Removed the commented-out section from utils.pm::reservation_being_processed that called pgrep to check if a process was already running for the reservation. Replaced this with a call to utils.pm::is_management_node_process_running. Updated is_management_node_process_running. It was not parsing the pgrep arguments correctly.

VCL-298
Added code to VMware.pm to check the image.project value and add additional network interfaces if the project is not 'vcl'. It gets a list of all the networks available on the VM host and adds an adapter for any that match up with the image project name. Added Linux.pm::activate_interfaces which finds and activates network interfaces which don't have a corresponding ifcfg-eth* file. The file is created and the interface is brought up allowing interfaces to be added dynamically during load. This is called by Linux.pm::post_load.

Fixed a bug in VMware.pm::get_active_vmx_file_path. It wasn't working correcly when run during an image capture when a new image was created with a different ID.

VCL-100
Added get_network_configuration, get_private_mac_address, get_public_mac_address, and get_public_ip_address to Linux.pm. Added get_private_interface_name and get_public_interface_name to OS.pm. These subroutines make the Linux code more inline with the Windows code and will allow the utils.pm::getdynamicaddress to be removed.

Fixed a bug in Linux.pm::execute. It was using the computer host name rather than the node name. This caused SSH commands to fail because it was attempting to connect to a full DNS host name configured in the computer table which didn't resolve.

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/VMware.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=982258&r1=982257&r2=982258&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm Wed Aug  4 14:11:02 2010
@@ -782,6 +782,153 @@ sub set_vcld_post_load_status {
 	return 1;
 }
 
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_private_interface_name
+
+ Parameters  : none
+ Returns     : string
+ Description : Determines the private interface name based on the information in
+               the network configuration hash returned by
+               get_network_configuration. The interface which is assigned the
+               private IP address for the reservation computer is returned.
+
+=cut
+
+sub get_private_interface_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;
+	}
+	
+	# Get the network configuration hash reference
+	my $network_configuration = $self->get_network_configuration();
+	if (!$network_configuration) {
+		notify($ERRORS{'WARNING'}, 0, "unable to determine private interface name, failed to retrieve network configuration");
+		return;
+	}
+	
+	# Get the computer private IP address
+	my $computer_private_ip_address = $self->data->get_computer_private_ip_address();
+	if (!$computer_private_ip_address) {
+		notify($ERRORS{'DEBUG'}, 0, "unable to retrieve computer private IP address from reservation data");
+		return;
+	}
+	
+	# Loop through all of the network interfaces found
+	foreach my $interface_name (sort keys %$network_configuration) {
+		# Get the interface IP addresses and make sure an IP address was found
+		my @ip_addresses  = keys %{$network_configuration->{$interface_name}{ip_address}};
+		if (!@ip_addresses) {
+			notify($ERRORS{'DEBUG'}, 0, "interface is not assigned an IP address: $interface_name");
+			next;
+		}
+		
+		# Check if interface has the private IP address assigned to it
+		if (grep { $_ eq $computer_private_ip_address } @ip_addresses) {
+			notify($ERRORS{'DEBUG'}, 0, "determined private interface name: $interface_name (" . join (", ", @ip_addresses) . ")");
+			return $interface_name;
+		}
+	}
+
+	notify($ERRORS{'WARNING'}, 0, "failed to determined private interface name, no interface is assigned the private IP address for the reservation: $computer_private_ip_address\n" . format_data($network_configuration));
+	return;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_public_interface_name
+
+ Parameters  : none
+ Returns     : string
+ Description : Determines the public interface name based on the information in
+               the network configuration hash returned by
+               get_network_configuration.
+
+=cut
+
+sub get_public_interface_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;
+	}
+	
+	# Get the network configuration hash reference
+	my $network_configuration = $self->get_network_configuration();
+	if (!$network_configuration) {
+		notify($ERRORS{'WARNING'}, 0, "unable to determine public interface name, failed to retrieve network configuration");
+		return;
+	}
+	
+	# Get the computer private IP address
+	my $computer_private_ip_address = $self->data->get_computer_private_ip_address();
+	if (!$computer_private_ip_address) {
+		notify($ERRORS{'DEBUG'}, 0, "unable to retrieve computer private IP address from reservation data");
+		return;
+	}
+	
+	my $public_interface_name;
+	
+	# Loop through all of the network interfaces found
+	foreach my $interface_name (sort keys %$network_configuration) {
+		# Get the interface IP addresses and make sure an IP address was found
+		my @ip_addresses  = keys %{$network_configuration->{$interface_name}{ip_address}};
+		if (!@ip_addresses) {
+			notify($ERRORS{'DEBUG'}, 0, "interface is not assigned an IP address: $interface_name");
+			next;
+		}
+		
+		# Check if interface has private IP address assigned to it
+		if (grep { $_ eq $computer_private_ip_address } @ip_addresses) {
+			notify($ERRORS{'DEBUG'}, 0, "ignoring private interface: $interface_name (" . join (", ", @ip_addresses) . ")");
+			next;
+		}
+		
+		my $description = $network_configuration->{$interface_name}{description} || '';
+		
+		# Check if the interface should be ignored based on the name or description
+		if ($interface_name =~ /(^lo|loopback|vmnet|afs|tunnel|6to4|isatap|teredo)/i) {
+			notify($ERRORS{'DEBUG'}, 0, "interface ignored because of name: $interface_name (" . join (", ", @ip_addresses) . ")");
+			next;
+		}
+		elsif ($description =~ /loopback|virtual|afs|tunnel|pseudo|6to4|isatap/i) {
+			notify($ERRORS{'DEBUG'}, 0, "interface ignored because of description: $interface_name, description: $description (" . join (", ", @ip_addresses) . ")");
+			next;
+		}
+		
+		# Loop through the IP addresses for the interface
+		# Try to find a public address
+		for my $ip_address (@ip_addresses) {
+			
+			if (is_public_ip_address($ip_address)) {
+				notify($ERRORS{'DEBUG'}, 0, "determined public interface name: $interface_name (" . join (", ", @ip_addresses) . ")");
+				return $interface_name;
+			}
+			else {
+				notify($ERRORS{'DEBUG'}, 0, "found interface assigned a private address not matching private address for reservation: $interface_name (" . join(", ", @ip_addresses) . ")");
+				
+				if ($public_interface_name) {
+					notify($ERRORS{'DEBUG'}, 0, "already found another interface with a private address not matching private address for reservation: $public_interface_name, the first one found will be used if an interface with a public address isn't found");
+				}
+				else {
+					$public_interface_name = $interface_name;
+					notify($ERRORS{'DEBUG'}, 0, "assuming interface is public if another interface with a public address isn't found: $public_interface_name");
+				}
+			}
+		}
+	}
+
+	if ($public_interface_name) {
+		notify($ERRORS{'DEBUG'}, 0, "did not find any interfaces assigned a public IP address, returning interface assigned a private IP address not matching the private IP address assigned to the reservation computer: $public_interface_name");
+		return $public_interface_name;
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to determine the public interface from the network configuration:\n" . format_data($network_configuration));
+		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=982258&r1=982257&r2=982258&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm Wed Aug  4 14:11:02 2010
@@ -284,6 +284,9 @@ sub post_load {
 	else {
 		notify($ERRORS{'DEBUG'}, 0, "ran $script_path");
 	}
+	
+	# Attempt to generate ifcfg-eth* files and ifup any interfaces which the file does not exist
+	$self->activate_interfaces();
 
 	return 1;
 
@@ -339,54 +342,52 @@ sub post_reserve {
 
  Parameters  :
  Returns     : 1,0 success or failure
- Description : To be used for nodes that have both private and public addresses. 
-                                        Set hostname to that of the public address.
+ Description : To be used for nodes that have both private and public addresses.
+               Set hostname to that of the public address.
 
 =cut
 
 sub update_public_hostname {
-     my $self = shift;
-     unless (ref($self) && $self->isa('VCL::Module')) {
-        notify($ERRORS{'CRITICAL'}, 0, "subroutine can only be called as a VCL::Module module object method");
-        return; 
-     }
-         
-     my $management_node_keys = $self->data->get_management_node_keys();
-     my $computer_node_name   = $self->data->get_computer_node_name();
-     my $image_os_type        = $self->data->get_image_os_type();
-     my $image_os_name        = $self->data->get_image_os_name();
-     my $computer_short_name             = $self->data->get_computer_short_name();
-     my $public_hostname;
-
-        #Get the IP address of the public adapter
-
- my $public_IP_address = getdynamicaddress($computer_short_name, $image_os_name, $image_os_type);
-        if (!($public_IP_address)) {
-                notify($ERRORS{'WARNING'}, 0, "Unable to get public IP address");
-                return 0;
-        }
-
-        #Get the hostname for the public IP address
-        my $get_public_hostname = "/bin/ipcalc --hostname $public_IP_address";
-        my ($ipcalc_status, $ipcalc_output) = run_ssh_command($computer_short_name, $management_node_keys,$get_public_hostname);
-        if (!defined($ipcalc_status)) {
-                notify($ERRORS{'WARNING'}, 0, "unable to run ssh cmd $get_public_hostname on $computer_short_name");
-                return 0;
-        }
-        elsif ("@$ipcalc_output" =~ /HOSTNAME=(.*)/i) {
-                $public_hostname = $1;
-                notify($ERRORS{'DEBUG'}, 0, "collected public hostname= $public_hostname");
-        }
-
-        #Set the node's hostname to public hostname
-        my ($set_hostname_status, $set_hostname_output) = run_ssh_command($computer_short_name, $management_node_keys,"hostname -v $public_hostname"); 
-        unless (defined($set_hostname_status) && $set_hostname_status == 0) {
-			notify($ERRORS{'OK'}, 0, "failed to set public_hostname on $computer_short_name output: @${set_hostname_output}");
-        }
-
-        notify($ERRORS{'OK'}, 0, "successfully set public_hostname on $computer_short_name output: @${set_hostname_output}");
-        return 1;
-
+	my $self = shift;
+	unless (ref($self) && $self->isa('VCL::Module')) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine can only be called as a VCL::Module module object method");
+		return; 
+	}
+	
+	my $management_node_keys = $self->data->get_management_node_keys();
+	my $computer_node_name   = $self->data->get_computer_node_name();
+	my $image_os_type        = $self->data->get_image_os_type();
+	my $image_os_name        = $self->data->get_image_os_name();
+	my $computer_short_name  = $self->data->get_computer_short_name();
+	my $public_hostname;
+	
+	# Get the IP address of the public adapter
+	my $public_IP_address = getdynamicaddress($computer_short_name, $image_os_name, $image_os_type);
+	if (!($public_IP_address)) {
+		notify($ERRORS{'WARNING'}, 0, "Unable to get public IP address");
+		return 0;
+	}
+	
+	# Get the hostname for the public IP address
+	my $get_public_hostname = "/bin/ipcalc --hostname $public_IP_address";
+	my ($ipcalc_status, $ipcalc_output) = run_ssh_command($computer_short_name, $management_node_keys,$get_public_hostname);
+	if (!defined($ipcalc_status)) {
+		notify($ERRORS{'WARNING'}, 0, "unable to run ssh cmd $get_public_hostname on $computer_short_name");
+		return 0;
+	}
+	elsif ("@$ipcalc_output" =~ /HOSTNAME=(.*)/i) {
+		$public_hostname = $1;
+		notify($ERRORS{'DEBUG'}, 0, "collected public hostname= $public_hostname");
+	}
+	
+	#Set the node's hostname to public hostname
+	my ($set_hostname_status, $set_hostname_output) = run_ssh_command($computer_short_name, $management_node_keys,"hostname -v $public_hostname"); 
+	unless (defined($set_hostname_status) && $set_hostname_status == 0) {
+		notify($ERRORS{'OK'}, 0, "failed to set public_hostname on $computer_short_name output: @${set_hostname_output}");
+	}
+	
+	notify($ERRORS{'OK'}, 0, "successfully set public_hostname on $computer_short_name output: @${set_hostname_output}");
+	return 1;
 }
 #/////////////////////////////////////////////////////////////////////////////
 
@@ -420,7 +421,6 @@ sub clear_private_keys {
 		notify($ERRORS{'CRITICAL'}, 0, "failed to clear any id_rsa keys from /root/.ssh");
 		return 0;
 	}
-
 }
 
 #/////////////////////////////////////////////////////////////////////////////
@@ -619,23 +619,6 @@ sub set_static_public_address {
 
 #/////////////////////////////////////////////////////////////////////////////
 
-=head2 get_public_interface_name
-
- Parameters  :
- Returns     :
- Description :
-
-=cut
-
-sub get_public_interface_name {
-
-	#global varible pulled from vcld.conf
-	return $ETHDEVICE;
-
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
 =head2 get_public_default_gateway
 
  Parameters  :
@@ -959,73 +942,17 @@ sub changepasswd {
 
 	notify($ERRORS{'WARNING'}, 0, "node is not defined")    if (!(defined($node)));
 	notify($ERRORS{'WARNING'}, 0, "account is not defined") if (!(defined($account)));
-
-	my @ssh;
-	my $l;
-	if ($account eq "root") {
-
-		#if not a predefined password, get one!
-		$passwd = getpw(15) if (!(defined($passwd)));
-		notify($ERRORS{'OK'}, 0, "password for $node is $passwd");
-
-		if (open(OPENSSL, "openssl passwd -1 $passwd 2>&1 |")) {
-			$passwd = <OPENSSL>;
-			chomp $passwd;
-			close(OPENSSL);
-			if ($passwd =~ /command not found/) {
-				notify($ERRORS{'CRITICAL'}, 0, "failed $passwd ");
-				return 0;
-			}
-			my $tmpfile = "/tmp/shadow.$node";
-			if (open(TMP, ">$tmpfile")) {
-				print TMP "$account:$passwd:13061:0:99999:7:::\n";
-				close(TMP);
-				if (run_ssh_command($node, $management_node_keys, "cat /etc/shadow \|grep -v $account >> $tmpfile", "root")) {
-					notify($ERRORS{'DEBUG'}, 0, "collected /etc/shadow file from $node");
-					if (run_scp_command($tmpfile, "$node:/etc/shadow", $management_node_keys)) {
-						notify($ERRORS{'DEBUG'}, 0, "copied updated /etc/shadow file to $node");
-						if (run_ssh_command($node, $management_node_keys, "chmod 600 /etc/shadow", "root")) {
-							notify($ERRORS{'DEBUG'}, 0, "updated permissions to 600 on /etc/shadow file on $node");
-							unlink $tmpfile;
-							return 1;
-						}
-						else {
-							notify($ERRORS{'WARNING'}, 0, "failed to change file permissions on $node /etc/shadow");
-							unlink $tmpfile;
-							return 0;
-						}
-					} ## end if (run_scp_command($tmpfile, "$node:/etc/shadow"...
-					else {
-						notify($ERRORS{'WARNING'}, 0, "failed to copy contents of shadow file on $node ");
-					}
-				} ## end if (run_ssh_command($node, $identity_key, ...
-				else {
-					notify($ERRORS{'WARNING'}, 0, "failed to copy contents of shadow file on $node ");
-					unlink $tmpfile;
-					return 0;
-				}
-			} ## end if (open(TMP, ">$tmpfile"))
-			else {
-				notify($ERRORS{'OK'}, 0, "failed could open $tmpfile $!");
-			}
-		} ## end if (open(OPENSSL, "openssl passwd -1 $passwd 2>&1 |"...
-		return 0;
-	} ## end if ($account eq "root")
-	else {
-		#actual user
-		#push it through passwd cmd stdin
-		# not all distros' passwd command support stdin
-		my @sshcmd = run_ssh_command($node, $management_node_keys, "echo $passwd \| /usr/bin/passwd -f $account --stdin", "root");
-		foreach my $l (@{$sshcmd[1]}) {
-			if ($l =~ /authentication tokens updated successfully/) {
-				notify($ERRORS{'OK'}, 0, "successfully changed local password account $account");
-				return 1;
-			}
-		}
-
-	} ## end else [ if ($account eq "root")
-
-} ## end sub changepasswd
+	
+	$passwd = getpw(15) if (!(defined($passwd)));
+	
+	my ($exit_status, $output) = run_ssh_command($node, $management_node_keys, "echo $passwd \| /usr/bin/passwd -f $account --stdin", "root");
+	if (!defined($output)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to set password for account: $account");
+		return;
+	}
+	notify($ERRORS{'OK'}, 0, "changed password for account: $account, output:\n" . join("\n", @$output));
+	return 1;
+}
 
 #/////////////////////////////////////////////////////////////////////////////
 
@@ -1299,14 +1226,14 @@ sub execute {
 	# Get 2nd display output argument if supplied, or set default value
 	my $display_output = shift || '0';
 	
-	# Get the computer hostname
-	my $computer_hostname = $self->data->get_computer_hostname() || return;
+	# Get the computer node name
+	my $computer_name = $self->data->get_computer_node_name() || return;
 	
 	# Get the identity keys used by the management node
 	my $management_node_keys = $self->data->get_management_node_keys() || '';
 	
 	# Run the command via SSH
-	my ($exit_status, $output) = run_ssh_command($computer_hostname, $management_node_keys, $command, '', '', $display_output);
+	my ($exit_status, $output) = run_ssh_command($computer_name, $management_node_keys, $command, '', '', $display_output);
 	if (defined($exit_status) && defined($output)) {
 		if ($display_output) {
 			notify($ERRORS{'OK'}, 0, "executed command: '$command', exit status: $exit_status, output:\n" . join("\n", @$output));
@@ -1314,7 +1241,7 @@ sub execute {
 		return ($exit_status, $output);
 	}
 	else {
-		notify($ERRORS{'WARNING'}, 0, "failed to run command on $computer_hostname: $command");
+		notify($ERRORS{'WARNING'}, 0, "failed to run command on $computer_name: $command");
 		return;
 	}
 }
@@ -2322,6 +2249,315 @@ sub generate_ext_sshd_init {
         return 1;
 
 }
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 activate_interfaces
+
+ Parameters  : none
+ Returns     : true
+ Description : Finds all networking interfaces with an active link. Checks if an
+               ifcfg-eth* file exists for the interface. An ifcfg-eth* file is
+               generated if it does not exist using DHCP and the interface is
+               brought up via ifup. This is useful if additional interfaces are
+               added by the provisioning module when an image is loaded. 
+
+=cut
+
+sub activate_interfaces {
+	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 0;
+	}
+	
+	# Run 'ip link' to find all interfaces with links
+	my $command = "ip link";
+	notify($ERRORS{'DEBUG'}, 0, "attempting to find network interfaces with an active link");
+	my ($exit_status, $output) = $self->execute($command, 1);
+	if (!defined($output)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to run command to find network interfaces with an active link:\n$command");
+		return;
+	}
+	
+	# Extract the interface names from the 'ip link' output
+	my @interface_names = grep { /^\d+:\s+(eth\d+)/ ; $_ = $1 } @$output;
+	notify($ERRORS{'DEBUG'}, 0, "found interface names:\n" . join("\n", @interface_names));
+	
+	# Find existing ifcfg-eth* files
+	my $ifcfg_directory = '/etc/sysconfig/network-scripts';
+	my @ifcfg_paths = $self->find_files($ifcfg_directory, 'ifcfg-eth*');
+	notify($ERRORS{'DEBUG'}, 0, "found existing ifcfg-eth* files:\n" . join("\n", @ifcfg_paths));
+	
+	# Loop through the linked interfaces
+	for my $interface_name (@interface_names) {
+		my $ifcfg_path = "$ifcfg_directory/ifcfg-$interface_name";
+		
+		# Check if an ifcfg-eth* file already exists for the interface
+		if (grep(/$ifcfg_path/, @ifcfg_paths)) {
+			notify($ERRORS{'DEBUG'}, 0, "ifcfg file already exists for $interface_name");
+			next;
+		}
+		
+		notify($ERRORS{'DEBUG'}, 0, "ifcfg file does not exist for $interface_name");
+		
+		# Assemble the contents of the ifcfg-eth* file for the interface
+		my $ifcfg_contents = <<EOF;
+DEVICE=$interface_name
+BOOTPROTO=dhcp
+STARTMODE=onboot
+ONBOOT=yes
+EOF
+		
+		# Create the ifcfg-eth* file and attempt to call ifup on the interface
+		my $echo_command = "echo \E \"$ifcfg_contents\" > $ifcfg_path && ifup $interface_name";
+		notify($ERRORS{'DEBUG'}, 0, "attempting to echo contents to $ifcfg_path:\n$ifcfg_contents");
+		my ($echo_exit_status, $echo_output) = $self->execute($echo_command, 1);
+		if (!defined($echo_output)) {
+			notify($ERRORS{'WARNING'}, 0, "failed to run command to echo contents to $ifcfg_path");
+			return;
+		}
+		elsif (grep(/done\./, @$echo_output)) {
+			notify($ERRORS{'OK'}, 0, "created $ifcfg_path and enabled interface: $interface_name, output:\n" . join("\n", @$echo_output));
+		}
+		else {
+			notify($ERRORS{'WARNING'}, 0, "failed to create $ifcfg_path and enable interface: $interface_name, output:\n" . join("\n", @$echo_output));
+		}
+	}
+	
+	return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_network_configuration
+
+ Parameters  : $network_type (optional)
+ Returns     : hash reference
+ Description : Retrieves the network configuration on the Linux computer and
+					constructs a hash. A $network_type argument can be supplied
+					containing either 'private' or 'public'. If the $network_type
+					argument is not supplied, the hash keys are the network interface
+					names and the hash reference returned is formatted as follows:
+					|--%{eth0}
+					   |--%{eth0}{ip_address}
+					      |--{eth0}{ip_address}{10.10.4.35} = '255.255.240.0'
+					   |--{eth0}{name} = 'eth0'
+					   |--{eth0}{physical_address} = '00:50:56:08:00:f8'
+					|--%{eth1}
+					   |--%{eth1}{ip_address}
+					      |--{eth1}{ip_address}{152.1.14.200} = '255.255.255.0'
+					   |--{eth1}{name} = 'eth1'
+					   |--{eth1}{physical_address} = '00:50:56:08:00:f9'
+					|--%{eth2}
+					   |--%{eth2}{ip_address}
+					      |--{eth2}{ip_address}{10.1.2.33} = '255.255.240.0'
+					   |--{eth2}{name} = 'eth2'
+					   |--{eth2}{physical_address} = '00:0c:29:ba:c1:77'
+					|--%{lo}
+					   |--%{lo}{ip_address}
+					      |--{lo}{ip_address}{127.0.0.1} = '255.0.0.0'
+					   |--{lo}{name} = 'lo'
+						
+					If the $network_type argument is supplied, a hash reference is
+					returned containing only the configuration for the specified
+					interface:
+					|--%{ip_address}
+						|--{ip_address}{10.1.2.33} = '255.255.240.0'
+					|--{name} = 'eth2'
+					|--{physical_address} = '00:0c:29:ba:c1:77'
+
+=cut
+
+sub get_network_configuration {
+	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 if a 'public' or 'private' network type argument was specified
+	my $network_type = lc(shift());
+	if ($network_type && $network_type !~ /(public|private)/i) {
+		notify($ERRORS{'WARNING'}, 0, "network type argument can only be 'public' or 'private'");
+		return;
+	}
+	
+	my %network_configuration;
+	
+	# Check if the network configuration has already been retrieved and saved in this object
+	if (!$self->{network_configuration}) {
+		# Run ipconfig
+		my $command = "ifconfig -a";
+		my ($exit_status, $output) = $self->execute($command);
+		if (!defined($output)) {
+			notify($ERRORS{'WARNING'}, 0, "failed to run command to retrieve network configuration: $command");
+			return;
+		}
+		
+		# Loop through the ifconfig output lines
+		my $interface_name;
+		for my $line (@$output) {
+			# Extract the interface name from the Link line:
+			# eth2      Link encap:Ethernet  HWaddr 00:0C:29:78:77:AB
+			if ($line =~ /^([^\s]+).*Link/) {
+				$interface_name = $1;
+				$network_configuration{$interface_name}{name} = $interface_name;
+			}
+			
+			# Skip to the next line if the interface name has not been determined yet
+			next if !$interface_name;
+			
+			# Parse the HWaddr line:
+			# eth2      Link encap:Ethernet  HWaddr 00:0C:29:78:77:AB
+			if ($line =~ /HWaddr\s+([\w:]+)/) {
+				$network_configuration{$interface_name}{physical_address} = lc($1);
+			}
+			
+			# Parse the IP address line:
+			# inet addr:10.10.4.35  Bcast:10.10.15.255  Mask:255.255.240.0
+			if ($line =~ /inet addr:([\d\.]+).*Mask:([\d\.]+)/) {
+				$network_configuration{$interface_name}{ip_address}{$1} = $2;
+			}
+		}
+		
+		$self->{network_configuration} = \%network_configuration;
+		notify($ERRORS{'DEBUG'}, 0, "retrieved network configuration:\n" . format_data(\%network_configuration));
+	}
+	else {
+		notify($ERRORS{'DEBUG'}, 0, "network configuration has already been retrieved");
+		%network_configuration = %{$self->{network_configuration}};
+	}
+	
+	# 'public' or 'private' wasn't specified, return all network interface information
+	if (!$network_type) {
+		return \%network_configuration;
+	}
+	
+	# Determine either the private or public interface name based on the $network_type argument
+	my $interface_name;
+	if ($network_type =~ /private/i) {
+		$interface_name = $self->get_private_interface_name();
+	}
+	else {
+		$interface_name = $self->get_public_interface_name();
+	}
+	if (!$interface_name) {
+		notify($ERRORS{'WARNING'}, 0, "failed to determine the $network_type interface name");
+		return;
+	}
+	
+	# Extract the network configuration specific to the public or private interface
+	my $return_network_configuration = $network_configuration{$interface_name};
+	if (!$return_network_configuration) {
+		notify($ERRORS{'WARNING'}, 0, "network configuration does not exist for interface: $interface_name, network configuration:\n" . format_data(\%network_configuration));
+		return;
+	}
+	notify($ERRORS{'DEBUG'}, 0, "returning $network_type network configuration");
+	return $return_network_configuration;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_private_mac_address
+
+ Parameters  : none
+ Returns     : string
+ Description : Returns the MAC address of the interface assigned the private IP
+               address.
+
+=cut
+
+sub get_private_mac_address {
+	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 $private_network_configuration = $self->get_network_configuration('private');
+	if (!$private_network_configuration) {
+		notify($ERRORS{'WARNING'}, 0, "failed to retrieve private network configuration");
+		return;
+	}
+
+	my $private_mac_address = $private_network_configuration->{physical_address};
+	if (!$private_mac_address) {
+		notify($ERRORS{'WARNING'}, 0, "'physical_address' key is not set in the private network configuration hash:\n" . format_data($private_network_configuration));
+		return;
+	}
+	
+	notify($ERRORS{'DEBUG'}, 0, "retrieved private MAC address: $private_mac_address");
+	return $private_mac_address;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_public_mac_address
+
+ Parameters  : none
+ Returns     : string
+ Description : Returns the MAC address of the interface assigned the public IP
+               address.
+
+=cut
+
+sub get_public_mac_address {
+	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 $public_network_configuration = $self->get_network_configuration('public');
+	if (!$public_network_configuration) {
+		notify($ERRORS{'WARNING'}, 0, "failed to retrieve public network configuration");
+		return;
+	}
+
+	my $public_mac_address = $public_network_configuration->{physical_address};
+	if (!$public_mac_address) {
+		notify($ERRORS{'WARNING'}, 0, "'physical_address' key is not set in the public network configuration hash:\n" . format_data($public_network_configuration));
+		return;
+	}
+	
+	notify($ERRORS{'DEBUG'}, 0, "retrieved public MAC address: $public_mac_address");
+	return $public_mac_address;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_public_ip_address
+
+ Parameters  : none
+ Returns     : string
+ Description : Returns the public IP address assigned to the computer.
+
+=cut
+
+sub get_public_ip_address {
+	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 $public_network_configuration = $self->get_network_configuration('public');
+	if (!$public_network_configuration) {
+		notify($ERRORS{'WARNING'}, 0, "failed to retrieve public network configuration");
+		return;
+	}
+	
+	my $public_ip_address = (keys %{$public_network_configuration->{ip_address}})[0];
+	if (!$public_ip_address) {
+		notify($ERRORS{'WARNING'}, 0, "'ip_address' key is not set in the public network configuration hash:\n" . format_data($public_network_configuration));
+		return;
+	}
+	
+	notify($ERRORS{'DEBUG'}, 0, "retrieved public IP address: $public_ip_address");
+	return $public_ip_address;
+}
+
 #/////////////////////////////////////////////////////////////////////////////
 
 1;

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm?rev=982258&r1=982257&r2=982258&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/Provisioning/VMware/VMware.pm Wed Aug  4 14:11:02 2010
@@ -545,13 +545,6 @@ sub get_active_vmx_file_path {
 	
 	my $computer_name = $self->data->get_computer_short_name();
 	
-	# Get the normal, expected vmx file path for this reservation
-	my $vmx_file_path = $self->get_vmx_file_path();
-	if (!$vmx_file_path) {
-		notify($ERRORS{'WARNING'}, 0, "unable to determine normal vmx file path");
-		return;
-	}
-	
 	# Get the MAC addresses being used by the running VM for this reservation
 	my @vm_mac_addresses = ($self->os->get_private_mac_address(), $self->os->get_public_mac_address());
 	if (!@vm_mac_addresses) {
@@ -564,18 +557,22 @@ sub get_active_vmx_file_path {
 
 	# Get an array containing the existing vmx file paths on the VM host
 	my @host_vmx_file_paths = $self->get_vmx_file_paths();
-
-	# Remove the normal vmx file from the array and add it to the beginning
-	# This causes it to be checked first
-	@host_vmx_file_paths = grep($_ ne $vmx_file_path, @host_vmx_file_paths);
-	unshift @host_vmx_file_paths, $vmx_file_path;
-
 	notify($ERRORS{'DEBUG'}, 0, "retrieved vmx file paths currently residing on the VM host:\n" . join("\n", @host_vmx_file_paths));
-
+	
+	# Sort the vmx file path list so that paths containing the computer name are checked first
+	my @ordered_host_vmx_file_paths;
+	push @ordered_host_vmx_file_paths, grep(/$computer_name\_/, @host_vmx_file_paths);
+	push @ordered_host_vmx_file_paths, grep(!/$computer_name\_/, @host_vmx_file_paths);
+	@host_vmx_file_paths = @ordered_host_vmx_file_paths;
+	notify($ERRORS{'DEBUG'}, 0, "sorted vmx file paths so that directories containing $computer_name are checked first:\n" . join("\n", @host_vmx_file_paths));
+	
 	# Loop through the vmx files found on the VM host
 	# Check if the MAC addresses in the vmx file match the MAC addresses currently in use on the VM to be captured
 	my @matching_host_vmx_paths;
 	for my $host_vmx_path (@host_vmx_file_paths) {
+		# Quit checking if a match has already been found and the vmx path being checked doesn't contain the computer name
+		last if (@matching_host_vmx_paths && $host_vmx_path !~ /$computer_name/);
+		
 		# Get the info from the existing vmx file on the VM host
 		my $host_vmx_info = $self->get_vmx_info($host_vmx_path);
 		if (!$host_vmx_info) {
@@ -600,12 +597,7 @@ sub get_active_vmx_file_path {
 		notify($ERRORS{'DEBUG'}, 0, "comparing MAC addresses\nused by $computer_name:\n" . join("\n", sort(@vm_mac_addresses)) . "\nconfigured in $vmx_file_name:\n" . join("\n", sort(@vmx_mac_addresses)));
 		my @matching_mac_addresses = map { my $vm_mac_address = $_; grep(/$vm_mac_address/i, @vmx_mac_addresses) } @vm_mac_addresses;
 		
-		if (@matching_mac_addresses) {
-			push @matching_host_vmx_paths, $host_vmx_path;
-			notify($ERRORS{'DEBUG'}, 0, "found matching MAC addresses: $computer_name <==> $vmx_file_name (" . join(", ", @matching_mac_addresses) . ")");
-			last if ($vmx_file_path eq $host_vmx_path && scalar(@matching_host_vmx_paths) == 1);
-		}
-		else {
+		if (!@matching_mac_addresses) {
 			notify($ERRORS{'DEBUG'}, 0, "ignoring $vmx_file_name because MAC addresses do not match the ones being used by $computer_name");
 			next;
 		}
@@ -964,6 +956,7 @@ sub prepare_vmx {
 	# Get the required data to configure the .vmx file
 	my $image_id                 = $self->data->get_image_id() || return;
 	my $imagerevision_id         = $self->data->get_imagerevision_id() || return;
+	my $image_project            = $self->data->get_image_project() || return;
 	my $computer_id              = $self->data->get_computer_id() || return;
 	my $vmx_file_name            = $self->get_vmx_file_name() || return;
 	my $vmx_file_path            = $self->get_vmx_file_path() || return;
@@ -1194,6 +1187,45 @@ sub prepare_vmx {
 		));
 	}
 	
+	# Add additional Ethernet interfaces if the image project name is not vcl
+	if ($image_project !~ /^vcl$/i) {
+		notify($ERRORS{'DEBUG'}, 0, "image project is: $image_project, checking if additional network adapters should be configured");
+		
+		# Get a list of all the network names configured on the VMware host
+		my @network_names = $self->api->get_network_names();
+		notify($ERRORS{'DEBUG'}, 0, "retrieved network names configured on the VM host: " . join(", ", @network_names));
+		
+		# Check each network name
+		# Begin the index at 2 for additional interfaces added because ethernet0 and ethernet1 have already been added
+		my $interface_index = 2;
+		for my $network_name (@network_names) {
+			# Ignore network names which have already been added
+			if ($network_name =~ /^($virtual_switch_0|$virtual_switch_1)$/) {
+				notify($ERRORS{'DEBUG'}, 0, "ignoring network name because it is already being used for the private or public interface: $network_name");
+				next;
+			}
+			elsif ($network_name =~ /$image_project/i || $image_project =~ /$network_name/i) {
+				notify($ERRORS{'DEBUG'}, 0, "network name ($network_name) and image project name ($image_project) intersect, adding network interface to VM for network $network_name");
+				
+				$vmx_parameters{"ethernet$interface_index.addressType"} = "generated";
+				$vmx_parameters{"ethernet$interface_index.present"} = "TRUE";
+				$vmx_parameters{"ethernet$interface_index.virtualDev"} = "$vm_ethernet_adapter_type";
+				$vmx_parameters{"ethernet$interface_index.networkName"} = "$network_name";
+				
+				$interface_index++;
+			}
+			else {
+				notify($ERRORS{'DEBUG'}, 0, "network name ($network_name) and image project name ($image_project) do not intersect, network interface will not be added to VM for network $network_name");
+			}
+		}
+		
+	}
+	else {
+		notify($ERRORS{'DEBUG'}, 0, "image project is: $image_project, additional network adapters will not be configured");
+	}
+	
+	notify($ERRORS{'DEBUG'}, 0, "vmx parameters:\n" . format_data(\%vmx_parameters));
+	
 	# Create a string from the hash
 	my $vmx_contents = "#!/usr/bin/vmware\n";
 	map { $vmx_contents .= "$_ = \"$vmx_parameters{$_}\"\n" } sort keys %vmx_parameters;

Modified: incubator/vcl/trunk/managementnode/lib/VCL/utils.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/utils.pm?rev=982258&r1=982257&r2=982258&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/utils.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/utils.pm Wed Aug  4 14:11:02 2010
@@ -3227,90 +3227,6 @@ sub known_hosts {
 
 #/////////////////////////////////////////////////////////////////////////////
 
-=head2 changelinuxpassword
-
- Parameters  : $node, $account, $passwd
- Returns     : 0 or 1
- Description : changes linux root password on stock blade installs
-
-=cut
-
-sub changelinuxpassword {
-# change the privileged account passwords on the blade images
-	my ($node, $account, $passwd) = @_;
-	my ($package, $filename, $line, $sub) = caller(0);
-	notify($ERRORS{'WARNING'}, 0, "node is not defined")    if (!(defined($node)));
-	notify($ERRORS{'WARNING'}, 0, "account is not defined") if (!(defined($account)));
-
-	my @ssh;
-	my $l;
-	my $identity_keys = $ENV{management_node_info}{keys};
-	if ($account eq "root") {
-
-
-		#if not a predefined password, get one!
-		$passwd = getpw(15) if (!(defined($passwd)));
-		notify($ERRORS{'OK'}, 0, "password for $node is $passwd");
-
-		if (open(OPENSSL, "openssl passwd -1 $passwd 2>&1 |")) {
-			$passwd = <OPENSSL>;
-			chomp $passwd;
-			close(OPENSSL);
-			if ($passwd =~ /command not found/) {
-				notify($ERRORS{'CRITICAL'}, 0, "failed $passwd ");
-				return 0;
-			}
-			my $tmpfile = "/tmp/shadow.$node";
-			if (open(TMP, ">$tmpfile")) {
-				print TMP "$account:$passwd:13061:0:99999:7:::\n";
-				close(TMP);
-				if (run_ssh_command($node, $identity_keys, "cat /etc/shadow \|grep -v $account >> $tmpfile", "root")) {
-					notify($ERRORS{'DEBUG'}, 0, "collected /etc/shadow file from $node");
-					if (run_scp_command($tmpfile, "$node:/etc/shadow", $identity_keys)) {
-						notify($ERRORS{'DEBUG'}, 0, "copied updated /etc/shadow file to $node");
-						if (run_ssh_command($node, $identity_keys, "chmod 600 /etc/shadow", "root")) {
-							notify($ERRORS{'DEBUG'}, 0, "updated permissions to 600 on /etc/shadow file on $node");
-							unlink $tmpfile;
-							return 1;
-						}
-						else {
-							notify($ERRORS{'WARNING'}, 0, "failed to change file permissions on $node /etc/shadow");
-							unlink $tmpfile;
-							return 0;
-						}
-					} ## end if (run_scp_command($tmpfile, "$node:/etc/shadow"...
-					else {
-						notify($ERRORS{'WARNING'}, 0, "failed to copy contents of shadow file on $node ");
-					}
-				} ## end if (run_ssh_command($node, $identity_keys...
-				else {
-					notify($ERRORS{'WARNING'}, 0, "failed to copy contents of shadow file on $node ");
-					unlink $tmpfile;
-					return 0;
-				}
-			} ## end if (open(TMP, ">$tmpfile"))
-			else {
-				notify($ERRORS{'OK'}, 0, "failed could open $tmpfile $!");
-			}
-		} ## end if (open(OPENSSL, "openssl passwd -1 $passwd 2>&1 |"...
-		return 0;
-	} ## end if ($account eq "root")
-	else {
-		#actual user
-		#push it through passwd cmd stdin
-		my @sshcmd = run_ssh_command($node, $identity_keys, "echo $passwd \| /usr/bin/passwd -f $account --stdin", "root");
-		foreach my $l (@{$sshcmd[1]}) {
-			if ($l =~ /authentication tokens updated successfully/) {
-				notify($ERRORS{'OK'}, 0, "successfully changed local password account $account");
-				return 1;
-			}
-		}
-
-	} ## end else [ if ($account eq "root")
-} ## end sub changelinuxpassword
-
-#/////////////////////////////////////////////////////////////////////////////
-
 =head2 getusergroupmembers
 
  Parameters  : usergroupid
@@ -8885,51 +8801,20 @@ sub reservation_being_processed {
 		$computerloadlog_exists = 0;
 	}
 	
-	# Check for any running processes
-	#my $ps_command = "ps -ef";
-	#notify($ERRORS{'DEBUG'}, 0, "executing ps -ef command: $ps_command");
-	#my ($ps_exit_status, $ps_output) = run_command($ps_command);
-	#if (defined $ps_exit_status && $ps_exit_status == 0) {
-	#	notify($ERRORS{'DEBUG'}, 0, "ps exit status=$ps_exit_status, output:\n@{$ps_output}");
-	#	
-	#	my @matching_processes = grep {/VCL::.*:$reservation_id/} @{$ps_output};
-	#	notify($ERRORS{'DEBUG'}, 0, "matching processes: @matching_processes, count: " . scalar @matching_processes);
-	#}
-	#else {
-	#	notify($ERRORS{'WARNING'}, 0, "failed to execute ps command");
-	#}
-	
-	my $process_running = 0;
-
-	#my $process_running;
-	#if (defined($pgrep_exit_status) && @{$pgrep_output} > 0) {
-	#	notify($ERRORS{'DEBUG'}, 0, "reservation is being processed by:\n@{$pgrep_output}");
-	#	$process_running = 1;
-	#}
-	#elsif (defined($pgrep_exit_status) && @{$pgrep_output} == 0) {
-	#	notify($ERRORS{'DEBUG'}, 0, "did not find any running processes for reservation");
-	#	$process_running = 0;
-	#}
-	#elsif (defined($pgrep_exit_status))  {
-	#	notify($ERRORS{'WARNING'}, 0, "error occurred running command: $pgrep_command, exit status: $pgrep_exit_status, output:\n@{$pgrep_output}");
-	#	$process_running = 0;
-	#}
-	#else {
-	#	notify($ERRORS{'WARNING'}, 0, "command could not be executed: $pgrep_command");
-	#	$process_running = 0;
-	#}
+	# Check if a vcld process is running matching for this reservation
+	my @processes_running = is_management_node_process_running("$PROCESSNAME [0-9]+:$reservation_id ");
 	
 	# Check the results and return
-	if ($computerloadlog_exists && $process_running) {
-		notify($ERRORS{'DEBUG'}, 0, "reservation is currently being processed");
+	if ($computerloadlog_exists && @processes_running) {
+		notify($ERRORS{'DEBUG'}, 0, "reservation is currently being processed, computerloadlog 'begin' entry exists and running process was found: @processes_running");
 		return 1;
 	}
-	elsif (!$computerloadlog_exists && $process_running) {
-		notify($ERRORS{'WARNING'}, 0, "computerloadlog 'begin' entry does NOT exist but running process was found, returning 1");
+	elsif (!$computerloadlog_exists && @processes_running) {
+		notify($ERRORS{'WARNING'}, 0, "computerloadlog 'begin' entry does NOT exist but running process was found: @processes_running, assuming reservation is currently being processed");
 		return 1;
 	}
-	elsif ($computerloadlog_exists && !$process_running) {
-		notify($ERRORS{'WARNING'}, 0, "computerloadlog 'begin' entry exists but running process was NOT found, returning 0");
+	elsif ($computerloadlog_exists && !@processes_running) {
+		notify($ERRORS{'WARNING'}, 0, "computerloadlog 'begin' entry exists but running process was NOT found, assuming reservation is NOT currently being processed");
 		return 0;
 	}
 	else {
@@ -9115,28 +9000,46 @@ sub is_management_node_process_running {
 		return;
 	}
 	
-	my @pids;
-	my $command = "pgrep -fl \"$process_identifier\"";
-	my ($exit_status, $output) = run_command($command, 1);
-	my @filtered_output;
-	@filtered_output = grep(!/sh -c/, @$output) if @$output;
-	if (@filtered_output) {
-		notify($ERRORS{'DEBUG'}, 0, "process is running, identifier: $process_identifier, pgrep output:\n" . join("\n", @filtered_output));
+	my $command = "pgrep -fl '$process_identifier'";
+	my ($exit_status, $output) = run_command($command, 0);
+	if (!defined($output)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to run command to determine if process is running: $command");
+		return;
+	}
+	
+	my @processes_running;
+	for my $line (@$output) {
+		my ($pid) = $line =~ /^(\d+)/;
 		
-		for my $pgrep_line (@filtered_output) {
-			my ($pid) = $pgrep_line =~ /^(\d+)/;
-			push @pids, $pid;
+		if (!defined($pid)) {
+			notify($ERRORS{'DEBUG'}, 0, "ignoring pgrep output line, it does not begin with a number: $line");
+			next;
+		}
+		elsif ($pid eq $PID) {
+			notify($ERRORS{'DEBUG'}, 0, "ignoring pgrep output line for the currently running process: $line");
+			next;
+		}
+		elsif ($line =~ /pgrep -fl/) {
+			notify($ERRORS{'DEBUG'}, 0, "ignoring pgrep output line containing for pgrep command: $line");
+			next;
+		}
+		elsif ($line =~ /sh -c/) {
+			# Ignore lines containing 'sh -c', probably indicating a duplicate process of a command run remotely
+			notify($ERRORS{'DEBUG'}, 0, "ignoring pgrep output line containing 'sh -c': $line");
+			next;
+		}
+		else {
+			notify($ERRORS{'DEBUG'}, 0, "found matching process: $line");
+			push @processes_running, $pid;
 		}
-		
-		notify($ERRORS{'DEBUG'}, 0, "returning pid array: @pids");
-		return @pids;
 	}
-	elsif (defined($exit_status)) {
-		notify($ERRORS{'DEBUG'}, 0, "process is NOT running, identifier: $process_identifier, pgrep output:\n" . join("\n", @$output));
-		return ();
+	
+	if (@processes_running) {
+		notify($ERRORS{'DEBUG'}, 0, "process is running, identifier: '$process_identifier', returning array containing PIDs: @processes_running");
+		return @processes_running;
 	}
 	else {
-		notify($ERRORS{'WARNING'}, 0, "failed to run command to determine if process is running");
+		notify($ERRORS{'DEBUG'}, 0, "process is NOT running, identifier: '$process_identifier'");
 		return;
 	}
 }