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:\...@{$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:\...@{$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:\...@{$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;
        }
 }


Reply via email to