Author: arkurth
Date: Fri May 31 20:32:43 2013
New Revision: 1488390

URL: http://svn.apache.org/r1488390
Log:
VCL-698
Updated Linux.pm::delete_user to use 'df -T' to determine if a home directory 
is on a network drive.

Fixed problems with OS.pm::remove_lines_from_file. It wasn't handling all 
patterns passed to it.  Simplified the subroutine.

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

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=1488390&r1=1488389&r2=1488390&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS.pm Fri May 31 20:32:43 2013
@@ -2024,39 +2024,28 @@ sub remove_lines_from_file {
        
        my $computer_short_name = $self->data->get_computer_short_name();
        
-       # Assemble the command, grep the pattern to retrieve the number of 
times the pattern exists in the file before and after
-       # This is used to verify that the pattern doesn't exist afterwards
-       my $command = "echo -n \"before:\" ; grep -c \"$pattern\" $file_path 
2>&1 ; sed -i -e \"/$pattern/d\" $file_path 2>&1 ; echo -n \"after:\" ; grep -c 
\"$pattern\" $file_path 2>&1";
-       my ($exit_status, $output) = $self->execute($command, 0);
-       if (!defined($output)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to execute command to 
remove lines containing '$pattern' from '$file_path' on 
$computer_short_name\ncommand: $command");
-               return;
-       }
-       elsif (grep(/No such file/i, @$output)) {
-               notify($ERRORS{'WARNING'}, 0, "file does NOT exist on 
$computer_short_name: $file_path");
-               return;
-       }
+       my @lines_removed;
+       my @lines_retained;
        
-       my $output_string = join("\n", @$output);
-       my ($before_count) = $output_string =~ /before:(\d+)/;
-       my ($after_count) = $output_string =~ /after:(\d+)/;
-
-       if (!defined($before_count) || (!defined($after_count) && $before_count 
!= 0)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to remove lines 
containing '$pattern' from '$file_path' on $computer_short_name\ncommand: 
$command\noutput:\n$output_string");
-               return;
-       }
-       elsif ($before_count == 0) {
-               notify($ERRORS{'DEBUG'}, 0, "'$file_path' does not contain any 
lines matching '$pattern'");
-               return 1;
+       my @lines = $self->get_file_contents($file_path);
+       for my $line (@lines) {
+               if ($line =~ /$pattern/) {
+                       push @lines_removed, $line;
+               }
+               else {
+                       push @lines_retained, $line;
+               }
        }
-       elsif ($after_count != 0) {
-               notify($ERRORS{'WARNING'}, 0, "failed to remove lines 
containing '$pattern' from '$file_path' on $computer_short_name, file still 
appears to have lines containing the pattern, command: '$command', 
output:\n$output_string");
-               return;
+       
+       if (@lines_removed) {
+               my $lines_removed_count = scalar(@lines_removed);
+               notify($ERRORS{'DEBUG'}, 0, "removed $lines_removed_count line" 
. ($lines_removed_count > 1 ? 's' : '') . " from $file_path matching pattern: 
'$pattern'\n" . join("\n", @lines_removed));
+               $self->create_text_file($file_path, join("\n", 
@lines_retained)) || return;     
        }
        else {
-               notify($ERRORS{'OK'}, 0, "removed $before_count line" . 
($before_count > 1 ? 's' : '') . " containing '$pattern' from '$file_path'");
-               return 1;
+               notify($ERRORS{'DEBUG'}, 0, "$file_path does NOT contain any 
lines matching pattern: '$pattern'");
        }
+       return 1;
 }
 
 #/////////////////////////////////////////////////////////////////////////////
@@ -2297,7 +2286,8 @@ sub execute_new {
                                );
                                
                                if ($ssh) {
-                                       notify($ERRORS{'DEBUG'}, 0, "created " 
. ref($ssh) . " object to control $computer_name, options: $ssh_options");
+                                       
+                                       notify($ERRORS{'DEBUG'}, 0, "created " 
. ref($ssh) . " object to control $computer_name, SSH options: $ssh_options");
                                }
                                else {
                                        notify($ERRORS{'WARNING'}, 0, "failed 
to create Net::SSH::Expect object to control $computer_name, $!");
@@ -2310,7 +2300,7 @@ sub execute_new {
                                }
                                
                                #$ssh->exec("stty -echo");
-                               $ssh->exec("stty raw -echo");
+                               #$ssh->exec("stty raw -echo");
                                
                                # Set the timeout counter behaviour:
                                # If true, sets the timeout to "inactivity 
timeout"

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm?rev=1488390&r1=1488389&r2=1488390&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm Fri May 31 20:32:43 2013
@@ -328,13 +328,13 @@ sub post_load {
        my $mn_private_ip         = $self->mn_os->get_private_ip_address();
        
        notify($ERRORS{'OK'}, 0, "initiating Linux post_load: $image_name on 
$computer_short_name");
-       
+
        # Wait for computer to respond to SSH
-       if (!$self->wait_for_response(30, 600, 10)) {
+       if (!$self->wait_for_response(5, 600, 10)) {
                notify($ERRORS{'WARNING'}, 0, "$computer_node_name never 
responded to SSH");
                return 0;
        }
-       
+
        # Configure sshd to only listen on the private interface and add 
ext_sshd service listening on the public interface
        if (!$self->configure_ext_sshd()) {
                notify($ERRORS{'WARNING'}, 0, "failed to configure ext_sshd on 
$computer_node_name");
@@ -901,83 +901,103 @@ sub delete_user {
        $user_login_id = $self->data->get_user_login_id() if (!$user_login_id);
        if (!$user_login_id) {
                notify($ERRORS{'WARNING'}, 0, "user could not be determined");
-               return 0;
+               return;
        }
        
-       # Make sure the user login ID was passed
-       my $computer_node_name = shift;
-       $computer_node_name = $self->data->get_computer_node_name() if 
(!$computer_node_name);
-       if (!$computer_node_name) {
-               notify($ERRORS{'WARNING'}, 0, "computer node name could not be 
determined");
-               return 0;
-       }
+       my $computer_node_name = $self->data->get_computer_node_name();
        
-       # Make sure the identity key was passed
-       my $image_identity = shift;
-       $image_identity = $self->data->get_image_identity() if 
(!$image_identity);
-       if (!$image_identity) {
-               notify($ERRORS{'WARNING'}, 0, "image identity keys could not be 
determined");
-               return 0;
+       # Make sure the user exists
+       if (!$self->user_exists($user_login_id)) {
+               notify($ERRORS{'DEBUG'}, 0, "user NOT deleted from 
$computer_node_name because it does not exist: $user_login_id");
+               return 1;
        }
        
-       
+       # Check if the user is logged in
        if ($self->user_logged_in($user_login_id)) {
-               notify($ERRORS{'OK'}, 0, "user $user_login_id is logged in, 
logging of user");
-               if ($self->logoff_user($user_login_id)) {
-               
+               if (!$self->logoff_user($user_login_id)) {
+                       notify($ERRORS{'WARNING'}, 0, "failed to delete user 
$user_login_id from $computer_node_name, user appears to be logged in but could 
NOT be logged off");
+                       return;
                }
        }
-
-       #Clean out any public ssh identity keys 
-       my $home_network_share_cmd = "df /home/$user_login_id";
-   my ($exit_status, $output) = $self->execute($home_network_share_cmd);
-   if(grep(/dev/, @$output)){
-     # confirm .ssh directory exists
-     # Make directory
-     my $rm_keys_cmd = "/bin/rm /home/$user_login_id/.ssh/authorized_keys";
-     if ($self->execute($rm_keys_cmd)) {
-         notify($ERRORS{'DEBUG'}, 0, "removed 
/home/$user_login_id/.ssh/authorized_keys file");
-     }
+       
+       # Run df to determine if home directory is on a local device or network 
share
+       my $home_directory_path = "/home/$user_login_id";
+       my $df_command = "df -T -P $home_directory_path";
+       my ($df_exit_status, $df_output) = $self->execute($df_command);
+       if (!defined($df_output)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to execute command to 
determine if home directory is mounted on a network share, command: 
'$df_command'");
+               return;
+       }
+       elsif (grep(/(no such file|no file system)/i, @$df_output)) {
+               notify($ERRORS{'DEBUG'}, 0, "home directory does NOT exist on 
$computer_node_name: $home_directory_path");
+       }
+       elsif (grep(/[\t\s]+nfs/, @$df_output)) {
+               notify($ERRORS{'DEBUG'}, 0, "home directory is mounted on a 
network share, command: '$df_command', output:\n" . join("\n", @$df_output));
        }
        else {
-               notify($ERRORS{'DEBUG'}, 0, "Detected network mounted home 
directory, will not remove authorized_keys: @$output");
+               notify($ERRORS{'DEBUG'}, 0, "home directory is NOT mounted on a 
network share, command: '$df_command', output:\n" . join("\n", @$df_output));
+               
+               # Delete the user's authorized keys file
+               my $authorized_keys_path = 
"$home_directory_path/.ssh/authorized_keys";
+               $self->delete_file($authorized_keys_path);
        }
        
-       # Use userdel to delete the user
-       # Do not use userdel -r, it will affect HPC user storage for HPC 
installs
-       my $user_delete_command = "/usr/sbin/userdel $user_login_id";
-       my @user_delete_results = $self->execute($user_delete_command);
-       foreach my $user_delete_line (@{$user_delete_results[1]}) {
-               if ($user_delete_line =~ /currently logged in/) {
-                       notify($ERRORS{'WARNING'}, 0, "user not deleted, 
$user_login_id currently logged in");
-                       return 0;
-               }
+       # Call userdel to delete the user
+       # Do not use userdel -r or -f, it could remove a user's home directory 
on a network share
+       my $userdel_command = "/usr/sbin/userdel $user_login_id";
+       my ($userdel_exit_status, $userdel_output) = 
$self->execute($userdel_command);
+       if (!defined($userdel_output)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to execute command to 
delete user from $computer_node_name: $user_login_id");
+               return;
        }
-       
-       # Delete the group
-       my $user_group_cmd = "/usr/sbin/groupdel $user_login_id";
-       if ($self->execute($user_delete_command)) {
-               notify($ERRORS{'DEBUG'}, 0, "attempted to delete usergroup for 
$user_login_id");
+       elsif (grep(/does not exist/i, @$userdel_output)) {
+               notify($ERRORS{'DEBUG'}, 0, "user '$user_login_id' NOT deleted 
from $computer_node_name because it does not exist");
+       }
+       elsif (grep(/userdel: /i, @$userdel_output)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to delete user 
'$user_login_id' from $computer_node_name, command: '$userdel_command', 
output:\n" . join("\n", @$userdel_output));
+               return;
+       }
+       else {
+               notify($ERRORS{'OK'}, 0, "deleted user '$user_login_id' from 
$computer_node_name");
        }
        
-       my $imagemeta_rootaccess = $self->data->get_imagemeta_rootaccess();
-       
-       # Remove user from  external_sshd_config
-       my $rem_user_sshd_cmd = "sed -i -e \"/AllowUsers/s/$user_login_id//\" 
/etc/ssh/external_sshd_config"; 
-       if ($self->execute($rem_user_sshd_cmd)) {
-               if (!$self->restart_service("ext_sshd")) {
-       notify($ERRORS{'WARNING'}, 0, "failed to restart ext_sshd service on 
$computer_node_name after updating /etc/ssh/external_sshd_config");
-       }       
+       # Call groupdel to delete the user's group
+       my $groupdel_command = "/usr/sbin/groupdel $user_login_id";
+       my ($groupdel_exit_status, $groupdel_output) = 
$self->execute($groupdel_command);
+       if (!defined($groupdel_output)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to execute command to 
delete group from $computer_node_name: $user_login_id");
+               return;
+       }
+       elsif (grep(/does not exist/i, @$groupdel_output)) {
+               notify($ERRORS{'DEBUG'}, 0, "group '$user_login_id' NOT deleted 
from $computer_node_name because it does not exist");
+       }
+       elsif (grep(/groupdel: /i, @$groupdel_output)) {
+               notify($ERRORS{'WARNING'}, 0, "failed to delete group 
'$user_login_id' from $computer_node_name, command: '$groupdel_command', 
output:\n" . join("\n", @$groupdel_output));
        }
        else {
-               notify($ERRORS{'WARNING'}, 0, "Failed to remove user_login_id 
from external_sshd_config");
+               notify($ERRORS{'OK'}, 0, "deleted group '$user_login_id' from 
$computer_node_name");
        }
        
+       # Remove username from AllowUsers lines in ssh/external_sshd_config
+       my $external_sshd_config_file_path = '/etc/ssh/external_sshd_config';
+       my @lines = $self->get_file_contents($external_sshd_config_file_path);
+       my $new_file_contents;
+       for my $line (@lines) {
+               if ($line =~ /AllowUsers/) {
+                       $line =~ s/\s*$user_login_id//g;
+                       # If user was only username listed on line, don't add 
empty AllowUsers line back to file
+                       if ($line !~ /AllowUsers\s+\w/) {
+                               next;
+                       }
+               }
+               $new_file_contents .= "$line\n";
+       }
+       $self->create_text_file("$external_sshd_config_file_path\_new", 
$new_file_contents) || return;
+       
        # Remove lines from sudoers
-       $self->remove_lines_from_file('/etc/sudoers', "^$user_login_id .*") || 
return;
+       $self->remove_lines_from_file('/etc/sudoers', 
"^\\s*$user_login_id\\s+") || return;
        
        return 1;
-
 } ## end sub delete_user
 
 #/////////////////////////////////////////////////////////////////////////////
@@ -3999,26 +4019,26 @@ sub user_exists {
                $username = $self->data->get_user_login_id();
        }
        
-       notify($ERRORS{'DEBUG'}, 0, "checking if user $username exists on 
$computer_node_name");
+       notify($ERRORS{'DEBUG'}, 0, "checking if user exists on 
$computer_node_name: $username");
        
        # Attempt to query the user account
        my $query_user_command = "id $username";
-       my ($query_user_exit_status, $query_user_output) = 
$self->execute($query_user_command, 1);
+       my ($query_user_exit_status, $query_user_output) = 
$self->execute($query_user_command, 0);
        
        if (grep(/uid/, @$query_user_output)) {
-               notify($ERRORS{'DEBUG'}, 0, "user $username exists on 
$computer_node_name");
+               notify($ERRORS{'DEBUG'}, 0, "user exists on 
$computer_node_name: $username");
                return 1;
        }
        elsif (grep(/No such user/i, @$query_user_output)) {
-               notify($ERRORS{'DEBUG'}, 0, "user $username does not exist on 
$computer_node_name");
+               notify($ERRORS{'DEBUG'}, 0, "user does not exist on 
$computer_node_name: $username");
                return 0;
        }
        elsif (defined($query_user_exit_status)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to determine if user 
$username exists on $computer_node_name, exit status: $query_user_exit_status, 
output:\n@{$query_user_output}");
+               notify($ERRORS{'WARNING'}, 0, "failed to determine if user 
exists on $computer_node_name: $username, exit status: $query_user_exit_status, 
output:\n@{$query_user_output}");
                return;
        }
        else {
-               notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to 
determine if user $username exists on $computer_node_name");
+               notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to 
determine if user exists on $computer_node_name: $username");
                return;
        }
 }


Reply via email to