Add support to update ssh keys
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@199 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
parent
9523f2a4f6
commit
a7b74a09be
@ -7,6 +7,7 @@ use Data::Dumper;
|
||||
use xCAT::NodeRange;
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head1 xCAT::Utils
|
||||
|
||||
=head2 Package Description
|
||||
@ -14,7 +15,9 @@ use xCAT::NodeRange;
|
||||
This program module file, is a set of utilities used by xCAT commands.
|
||||
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 quote
|
||||
|
||||
Quote a string, taking into account embedded quotes. This function is most
|
||||
@ -35,6 +38,7 @@ This program module file, is a set of utilities used by xCAT commands.
|
||||
Comments:
|
||||
none
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub quote
|
||||
{
|
||||
@ -65,6 +69,7 @@ sub quote
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 isAIX
|
||||
returns 1 if localHost is AIX
|
||||
Arguments:
|
||||
@ -90,6 +95,7 @@ sub isAIX
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 isLinux
|
||||
returns 1 if localHost is Linux
|
||||
Arguments:
|
||||
@ -106,6 +112,7 @@ sub isAIX
|
||||
Comments:
|
||||
none
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
sub isLinux
|
||||
{
|
||||
@ -390,10 +397,8 @@ sub get_site_attribute
|
||||
return $values;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
=head3
|
||||
add_cron_job
|
||||
This function adds a new cron job.
|
||||
@ -411,37 +416,47 @@ sub get_site_attribute
|
||||
none
|
||||
|
||||
=cut
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
sub add_cron_job {
|
||||
$newentry = shift;
|
||||
if ($newentry =~ /xCAT::Utils/) {
|
||||
$newentry=shift;
|
||||
}
|
||||
#read the cron tab entries
|
||||
my @tabs=`/usr/bin/crontab -l 2>/dev/null`;
|
||||
my @newtabs=();
|
||||
foreach(@tabs) {
|
||||
chomp($_);
|
||||
# stop adding if it's already there
|
||||
if ($_ eq $newentry) { return (0, "started"); }
|
||||
#skip headers for Linux
|
||||
next if $_ =~ m/^\#.+(DO NOT EDIT THIS FILE|\(.+ installed on |Cron version )/;
|
||||
push(@newtabs, $_);
|
||||
}
|
||||
sub add_cron_job
|
||||
{
|
||||
$newentry = shift;
|
||||
if ($newentry =~ /xCAT::Utils/)
|
||||
{
|
||||
$newentry = shift;
|
||||
}
|
||||
|
||||
#add new entries to the cron tab
|
||||
push(@newtabs, $newentry);
|
||||
my $tabname="";
|
||||
if (xCAT::Utils::isLinux) { $tabname="-";}
|
||||
open(CRONTAB, "|/usr/bin/crontab $tabname") or return (1, "cannot open crontab.");
|
||||
foreach (@newtabs) { print CRONTAB $_."\n"; }
|
||||
close(CRONTAB);
|
||||
#read the cron tab entries
|
||||
my @tabs = `/usr/bin/crontab -l 2>/dev/null`;
|
||||
my @newtabs = ();
|
||||
foreach (@tabs)
|
||||
{
|
||||
chomp($_);
|
||||
|
||||
return (0, "");
|
||||
# stop adding if it's already there
|
||||
if ($_ eq $newentry) { return (0, "started"); }
|
||||
|
||||
#skip headers for Linux
|
||||
next
|
||||
if $_ =~
|
||||
m/^\#.+(DO NOT EDIT THIS FILE|\(.+ installed on |Cron version )/;
|
||||
push(@newtabs, $_);
|
||||
}
|
||||
|
||||
#add new entries to the cron tab
|
||||
push(@newtabs, $newentry);
|
||||
my $tabname = "";
|
||||
if (xCAT::Utils::isLinux) { $tabname = "-"; }
|
||||
open(CRONTAB, "|/usr/bin/crontab $tabname")
|
||||
or return (1, "cannot open crontab.");
|
||||
foreach (@newtabs) { print CRONTAB $_ . "\n"; }
|
||||
close(CRONTAB);
|
||||
|
||||
return (0, "");
|
||||
}
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
=head3
|
||||
remove_cron_job
|
||||
This function removes a new cron job.
|
||||
@ -461,36 +476,44 @@ sub add_cron_job {
|
||||
none
|
||||
|
||||
=cut
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
sub remove_cron_job {
|
||||
$job = shift;
|
||||
if ($job =~ /xCAT::Utils/) {
|
||||
$job=shift;
|
||||
}
|
||||
sub remove_cron_job
|
||||
{
|
||||
$job = shift;
|
||||
if ($job =~ /xCAT::Utils/)
|
||||
{
|
||||
$job = shift;
|
||||
}
|
||||
|
||||
#read the cron tab entries and remove the one that contains $job
|
||||
my @tabs=`/usr/bin/crontab -l 2>/dev/null`;
|
||||
my @newtabs=();
|
||||
foreach(@tabs) {
|
||||
chomp($_);
|
||||
# stop adding if it's already there
|
||||
next if index($_, $job, 0) >= 0;
|
||||
#skip headers for Linux
|
||||
next if $_ =~ m/^\#.+(DO NOT EDIT THIS FILE|\(.+ installed on |Cron version )/;
|
||||
push(@newtabs, $_);
|
||||
}
|
||||
|
||||
#refresh the cron
|
||||
my $tabname="";
|
||||
if (xCAT::Utils::isLinux) { $tabname="-";}
|
||||
open(CRONTAB, "|/usr/bin/crontab $tabname") or return (1, "cannot open crontab.");
|
||||
foreach (@newtabs) { print CRONTAB $_."\n"; }
|
||||
close(CRONTAB);
|
||||
#read the cron tab entries and remove the one that contains $job
|
||||
my @tabs = `/usr/bin/crontab -l 2>/dev/null`;
|
||||
my @newtabs = ();
|
||||
foreach (@tabs)
|
||||
{
|
||||
chomp($_);
|
||||
|
||||
return (0, "");
|
||||
# stop adding if it's already there
|
||||
next if index($_, $job, 0) >= 0;
|
||||
|
||||
#skip headers for Linux
|
||||
next
|
||||
if $_ =~
|
||||
m/^\#.+(DO NOT EDIT THIS FILE|\(.+ installed on |Cron version )/;
|
||||
push(@newtabs, $_);
|
||||
}
|
||||
|
||||
#refresh the cron
|
||||
my $tabname = "";
|
||||
if (xCAT::Utils::isLinux) { $tabname = "-"; }
|
||||
open(CRONTAB, "|/usr/bin/crontab $tabname")
|
||||
or return (1, "cannot open crontab.");
|
||||
foreach (@newtabs) { print CRONTAB $_ . "\n"; }
|
||||
close(CRONTAB);
|
||||
|
||||
return (0, "");
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
=head3 runcmd
|
||||
@ -503,7 +526,7 @@ sub remove_cron_job {
|
||||
Returns:
|
||||
see below
|
||||
Globals:
|
||||
$::RUNCMD_RC
|
||||
$::RUNCMD_RC , $::CALLBACK
|
||||
Error:
|
||||
Normally, if there is an error running the cmd,it will display the
|
||||
error and exit with the cmds exit code, unless exitcode
|
||||
@ -537,11 +560,9 @@ sub runcmd
|
||||
{
|
||||
if (!($cmd =~ /2>&1$/)) { $cmd .= ' 2>&1'; }
|
||||
|
||||
}
|
||||
if (!$xCAT::Utils::NO_MESSAGES)
|
||||
{
|
||||
xCAT::MsgUtils->message("V", "Running Command: $cmd\n");
|
||||
|
||||
}
|
||||
if ($::VERBOSE) {
|
||||
xCAT::MsgUtils->message("I", "Running Command: $cmd\n");
|
||||
}
|
||||
my $outref = [];
|
||||
@$outref = `$cmd`;
|
||||
@ -579,7 +600,15 @@ sub runcmd
|
||||
chomp $errmsg;
|
||||
|
||||
}
|
||||
if (!$xCAT::Utils::NO_MESSAGES)
|
||||
if ($::CALLBACK)
|
||||
{
|
||||
my %rsp;
|
||||
$rsp->{data}->[0] =
|
||||
"Command failed: $cmd. Error message: $errmsg.\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
xCAT::MsgUtils->message("E",
|
||||
"Command failed: $cmd. Error message: $errmsg.\n");
|
||||
@ -605,14 +634,296 @@ sub runcmd
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 getHomeDir
|
||||
|
||||
Get the path the user home directory from /etc/passwd.
|
||||
|
||||
Arguments:
|
||||
none
|
||||
Returns:
|
||||
path to user home directory.
|
||||
Globals:
|
||||
none
|
||||
Error:
|
||||
none
|
||||
Example:
|
||||
$myHome = xCAT::Utils->getHomeDir();
|
||||
Comments:
|
||||
none
|
||||
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
sub getHomeDir
|
||||
{
|
||||
my ($class, $username) = @_;
|
||||
my @user = split ':', (`/bin/grep ^$username /etc/passwd 2>&1`);
|
||||
my $home = $user[5];
|
||||
return $home;
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 setupSSH
|
||||
|
||||
Transfers the ssh keys to setup ssh to the input nodes.
|
||||
|
||||
Arguments:
|
||||
Array of nodes
|
||||
Returns:
|
||||
|
||||
Globals:
|
||||
$::XCATROOT , $::CALLBACK
|
||||
Error:
|
||||
0=good, 1=error
|
||||
Example:
|
||||
xCAT::Utils->setupSSH(@target_nodes);
|
||||
Comments:
|
||||
Does not setup known_hosts. Assumes automatically
|
||||
setup by SSH ( ssh config option StrictHostKeyChecking no should
|
||||
be set in the ssh config file).
|
||||
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
sub setupSSH
|
||||
{
|
||||
my ($class, $ref_nodes) = @_;
|
||||
my @nodes = $ref_nodes;
|
||||
my @badnodes = ();
|
||||
my $n_str = join ',', @nodes;
|
||||
my $SSHdir = "/install/postscripts/.ssh";
|
||||
if ($::XCATROOT)
|
||||
{
|
||||
$::REMOTESHELL_EXPECT = "$::XCATROOT/sbin/remoteshell.expect";
|
||||
}
|
||||
else
|
||||
{
|
||||
$::REMOTESHELL_EXPECT = "/opt/xcat/sbin/remoteshell.expect";
|
||||
}
|
||||
$::REMOTE_SHELL = "/bin/ssh";
|
||||
|
||||
# make the directory to hold keys to transfer to the nodes
|
||||
if (!-d $SSHdir)
|
||||
{
|
||||
mkdir("/install", 0755);
|
||||
mkdir("/install/postscripts", 0755);
|
||||
mkdir("/install/postscripts/.ssh", 0755);
|
||||
}
|
||||
|
||||
# Generate the keys
|
||||
xCAT::Utils->runcmd("$::REMOTESHELL_EXPECT -k", 0);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{ # error
|
||||
my %rsp;
|
||||
$rsp->{data}->[0] = "remoteshell.expect failed generating keys.\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
|
||||
}
|
||||
|
||||
# Copy the keys to the directory
|
||||
my $rc = xCAT::Utils->cpSSHFiles($SSHdir);
|
||||
if ($rc != 0)
|
||||
{ # error
|
||||
my %rsp;
|
||||
$rsp->{data}->[0] = "Error running cpSSHFiles.\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
open(FILE, ">$SSHdir/copy.perl")
|
||||
or die "cannot open file $SSHdir/copy.perl\n";
|
||||
|
||||
# build the perl copy script in $SSHdir/copy.perl
|
||||
print FILE "#!/usr/bin/perl
|
||||
my (\$name,\$passwd,\$uid,\$gid,\$quota,\$comment,\$gcos,\$dir,\$shell,\$expire) = getpwnam(\"root\");
|
||||
my \$home = \$dir;
|
||||
umask(0077);
|
||||
\$dest_dir = \"\$home/.ssh/\";
|
||||
if (! -d \"\$dest_dir\" ) {
|
||||
# create a local directory
|
||||
\$cmd = \"mkdir -p \$dest_dir\";
|
||||
system(\"\$cmd\");
|
||||
chmod 0700, \$dest_dir;
|
||||
}
|
||||
`cat /tmp/.ssh/authorized_keys >> \$home/.ssh/authorized_keys 2>&1`;
|
||||
`cat /tmp/.ssh/authorized_keys2 >> \$home/.ssh/authorized_keys2 2>&1`;
|
||||
`rm -f /tmp/.ssh/authorized_keys 2>&1`;
|
||||
`rm -f /tmp/.ssh/authorized_keys2 2>&1`;
|
||||
`rm -f /tmp/.ssh/copy.perl 2>&1`;
|
||||
rmdir(\"/tmp/.ssh\");";
|
||||
close FILE;
|
||||
chmod 0744, "$SSHdir/copy.perl";
|
||||
|
||||
# end build Perl code
|
||||
|
||||
#set an ENV var if more than 10 nodes for remoteshell.expect
|
||||
my $num_nodes = scalar(@nodes);
|
||||
if ($num_nodes > 10)
|
||||
{
|
||||
$ENV{'XCAT_UPD_MULTNODES'} = 1;
|
||||
}
|
||||
|
||||
# send the keys to the nodes
|
||||
#
|
||||
my $cmd = "$::REMOTESHELL_EXPECT -s $n_str";
|
||||
my $rc = system("$cmd") >> 8;
|
||||
if ($rc)
|
||||
{
|
||||
my %rsp;
|
||||
$rsp->{data}->[0] = "remoteshell.expect failed sending keys.\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
|
||||
}
|
||||
|
||||
# must always check to see if worked, run test
|
||||
foreach my $n (@nodes)
|
||||
{
|
||||
my $cmd = "$::REMOTESHELL_EXPECT -t $::REMOTE_SHELL $n ";
|
||||
my @cmdout = `$cmd 2>&1`;
|
||||
chomp(@cmdout); # take the newline off
|
||||
my $rc = $? >> 8;
|
||||
if ($rc)
|
||||
{
|
||||
push @badnodes, $n;
|
||||
}
|
||||
}
|
||||
|
||||
xCAT::Utils->runcmd("/bin/stty echo", 0);
|
||||
delete $ENV{'XCAT_UPD_MULTNODES'};
|
||||
|
||||
if (@badnodes)
|
||||
{
|
||||
my $nstring = join ',', @badnodes;
|
||||
my %rsp;
|
||||
$rsp->{data}->[0] =
|
||||
"SSH setup failed for the following nodes: $nstring.\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
return @badnodes;
|
||||
}
|
||||
else
|
||||
{
|
||||
my %rsp;
|
||||
$rsp->{data}->[0] = "$::REMOTE_SHELL setup is complete.\n";
|
||||
xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
=head3 cpSSHFiles
|
||||
|
||||
Copies the ssh keyfiles and the copy perl script into
|
||||
/install/postscripts/.ssh.
|
||||
|
||||
Arguments:
|
||||
directory path
|
||||
Returns:
|
||||
|
||||
Globals:
|
||||
$::CALLBACK
|
||||
Error:
|
||||
|
||||
Example:
|
||||
xCAT::Utils->cpSSHFiles;
|
||||
|
||||
Comments:
|
||||
none
|
||||
|
||||
=cut
|
||||
|
||||
#--------------------------------------------------------------------------------
|
||||
|
||||
sub cpSSHFiles
|
||||
{
|
||||
my ($class, $SSHdir) = @_;
|
||||
my ($cmd, $rc);
|
||||
if ($::VERBOSE)
|
||||
{
|
||||
my %rsp;
|
||||
$rsp->{data}->[0] = "Copying SSH Keys";
|
||||
xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
|
||||
}
|
||||
my $home = xCAT::Utils->getHomeDir("root");
|
||||
|
||||
my $authorized_keys = "$SSHdir/authorized_keys";
|
||||
my $authorized_keys2 = "$SSHdir/authorized_keys2";
|
||||
if ( !(-e "$home/.ssh/identity.pub")
|
||||
|| !(-e "$home/.ssh/id_rsa.pub")
|
||||
|| !(-e "$home/.ssh/id_dsa.pub"))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
$cmd = " cp $home/.ssh/identity.pub $authorized_keys";
|
||||
xCAT::Utils->runcmd($cmd, 0);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
my %rsp;
|
||||
$rsp->{data}->[0] = "$cmd failed.\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
return (1);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($::VERBOSE)
|
||||
{
|
||||
my %rsp;
|
||||
$rsp->{data}->[0] = "$cmd succeeded.\n";
|
||||
xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
|
||||
}
|
||||
}
|
||||
|
||||
$cmd = "cp $home/.ssh/id_rsa.pub $authorized_keys2";
|
||||
xCAT::Utils->runcmd($cmd, 0);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
my %rsp;
|
||||
$rsp->{data}->[0] = "$cmd failed.\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
return (1);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($::VERBOSE)
|
||||
{
|
||||
my %rsp;
|
||||
$rsp->{data}->[0] = "$cmd succeeded.\n";
|
||||
xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
|
||||
}
|
||||
}
|
||||
|
||||
$cmd = "cat $home/.ssh/id_dsa.pub >> $authorized_keys2";
|
||||
xCAT::Utils->runcmd($cmd, 0);
|
||||
if ($::RUNCMD_RC != 0)
|
||||
{
|
||||
my %rsp;
|
||||
$rsp->{data}->[0] = "$cmd failed.\n";
|
||||
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
|
||||
return (1);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($::VERBOSE)
|
||||
{
|
||||
my %rsp;
|
||||
$rsp->{data}->[0] = "$cmd succeeded.\n";
|
||||
xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(-e "$authorized_keys") || !(-e "$authorized_keys2"))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
1;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user