Merge branch '2.8' of ssh://linggao@git.code.sf.net/p/xcat/xcat-core into 2.8

This commit is contained in:
linggao 2014-02-20 09:22:53 -05:00
commit accf4fe1e3
6 changed files with 154 additions and 25 deletions

View File

@ -495,6 +495,7 @@ sub sendnodeskeys
# in $HOME/.ssh/tmp/authorized_keys
# copy to the node to the temp directory
# scp $HOME/.ssh/tmp/authorized_keys to_userid@<node>:/tmp/$to_userid/.ssh
# scp $HOME/.ssh/id_rsa.pub to_userid@<node>:/tmp/$to_userid/.ssh
# If you are going to enable ssh to ssh between nodes, then
# scp $HOME/.ssh/id_rsa to that temp directory on the node
# copy the script $HOME/.ssh/copy.sh to the node, it will do the
@ -607,11 +608,11 @@ sub sendnodeskeys
my $spawncopyfiles;
if ($ENV{'DSH_ENABLE_SSH'}) { # we will enable node to node ssh
$spawncopyfiles=
"$remotecopy $home/.ssh/id_rsa $home/.ssh/copy.sh $home/.ssh/tmp/authorized_keys $to_userid\@$node:/tmp/$to_userid/.ssh ";
"$remotecopy $home/.ssh/id_rsa $home/.ssh/id_rsa.pub $home/.ssh/copy.sh $home/.ssh/tmp/authorized_keys $to_userid\@$node:/tmp/$to_userid/.ssh ";
} else { # no node to node ssh ( don't send private key)
$spawncopyfiles=
"$remotecopy $home/.ssh/copy.sh $home/.ssh/tmp/authorized_keys $to_userid\@$node:/tmp/$to_userid/.ssh ";
"$remotecopy $home/.ssh/id_rsa.pub $home/.ssh/copy.sh $home/.ssh/tmp/authorized_keys $to_userid\@$node:/tmp/$to_userid/.ssh ";
}
# send copy command
unless ($sendkeys->spawn($spawncopyfiles))

View File

@ -1052,7 +1052,8 @@ site => {
" Set to NOGROUPS,if you do not wish to enabled any group of compute nodes.\n".
" Service Nodes are not affected by this attribute\n".
" they are always setup with\n".
" passwordless root access to nodes and other SN.\n\n".
" passwordless root access to nodes and other SN.\n".
" If using the zone table, this attribute in not used.\n\n".
" -----------------\n".
"SERVICES ATTRIBUTES\n".
" -----------------\n".
@ -1191,12 +1192,13 @@ performance => {
},
},
zone => {
cols => [qw(zonename sshkeydir defaultzone comments disable)],
cols => [qw(zonename sshkeydir sshbetweennodes defaultzone comments disable)],
keys => [qw(zonename)],
table_desc => 'Defines a cluster zone for nodes that share root ssh key access to each other.',
descriptions => {
zonename => 'The name of the zone.',
sshkeydir => 'Directory containing the shared root ssh RSA keys.',
sshbetweennodes => 'Indicates whether passwordless ssh will be setup between the nodes of this zone. Values are yes/1 or no/0. Default is yes. ',
defaultzone => 'If nodes are not assigned to any other zone, they will default to this zone. If value is set to yes or 1.',
comments => 'Any user-provided notes.',
disable => "Set to 'yes' or '1' to comment out this row.",
@ -3083,6 +3085,10 @@ push(@{$defspec{node}->{'attrs'}}, @nodeattrs);
tabentry => 'zone.sshkeydir',
access_tabentry => 'zone.zonename=attr:zonename',
},
{attr_name => 'sshbetweennodes',
tabentry => 'zone.sshbetweennodes',
access_tabentry => 'zone.zonename=attr:zonename',
},
{attr_name => 'defaultzone',
tabentry => 'zone.defaultzone',
access_tabentry => 'zone.zonename=attr:zonename',

View File

@ -19,6 +19,7 @@ if ($^O =~ /^aix/i) {
use lib "$::XCATROOT/lib/perl";
use strict;
require xCAT::Table;
require xCAT::Zone;
use File::Path;
#-----------------------------------------------------------------------
@ -271,7 +272,7 @@ sub bldnonrootSSHFiles
Error:
0=good, 1=error
Example:
xCAT::TableUtils->setupSSH(@target_nodes);
xCAT::TableUtils->setupSSH(@target_nodes,$expecttimeout);
Comments:
Does not setup known_hosts. Assumes automatically
setup by SSH ( ssh config option StrictHostKeyChecking no should
@ -335,21 +336,21 @@ sub setupSSH
$::REMOTE_SHELL = "/usr/bin/ssh";
my $rsp = {};
# Get the home directory
my $home = xCAT::Utils->getHomeDir($from_userid);
$ENV{'DSH_FROM_USERID_HOME'} = $home;
if ($from_userid eq "root")
{
# make the directory to hold keys to transfer to the nodes
if (!-d $SSHdir)
{
mkpath("$SSHdir", { mode => 0755 });
}
# generates new keys for root, if they do not already exist
# generates new keys for root, if they do not already exist ~/.ssh
# nodes not used on this option but in there to preserve the interface
my $rc=
xCAT::RemoteShellExp->remoteshellexp("k",$::CALLBACK,$::REMOTE_SHELL,$n_str,$expecttimeout);
@ -374,7 +375,9 @@ else
fi
mkdir -p \$dest_dir
cat /tmp/$to_userid/.ssh/authorized_keys >> \$home/.ssh/authorized_keys 2>&1
cat /tmp/$to_userid/.ssh/id_rsa.pub >> \$home/.ssh/authorized_keys 2>&1
cp /tmp/$to_userid/.ssh/id_rsa \$home/.ssh/id_rsa 2>&1
cp /tmp/$to_userid/.ssh/id_rsa.pub \$home/.ssh/id_rsa.pub 2>&1
chmod 0600 \$home/.ssh/id_* 2>&1
rm -f /tmp/$to_userid/.ssh/* 2>&1
rmdir \"/tmp/$to_userid/.ssh\"
@ -386,6 +389,7 @@ rmdir \"/tmp/$to_userid\" \n";
my $auth_key2=0;
if ($from_userid eq "root")
{
# this will put the root/.ssh/id_rsa.pub key in the authorized keys file to put on the node
my $rc = xCAT::TableUtils->cpSSHFiles($SSHdir);
if ($rc != 0)
{ # error
@ -418,13 +422,43 @@ rmdir \"/tmp/$to_userid\" \n";
xCAT::TableUtils->bldnonrootSSHFiles($from_userid);
}
# send the keys to the nodes for root or some other id
#
# This environment variable determines whether to setup
# node to node ssh
# The nodes must be checked against the site.sshbetweennodes attribute
# For root user and not to devices only to nodes
if (($from_userid eq "root") && (!($ENV{'DEVICETYPE'}))) {
# Need to check if nodes are in a zone.
# If in a zone, then root ssh keys for the node will be taken from the zones ssh keys not ~/.ssh
# zones are only supported on nodes that are not a service node.
# Also for the call to RemoteShellExp, we must group the nodes that are in the same zone
my $tab = xCAT::Table->new("zone");
if ($tab)
{
# if we have zones, need to send the zone keys to each node in the zone
my @zones = $tab->getAllAttribs('zonename');
$tab->close();
if (@zones) { # we have zones defined
my $rc = xCAT::TableUtils->sendkeystozones($ref_nodes,$expecttimeout);
if ($rc != 0)
{
$rsp->{data}->[0] = "Error sending ssh keys to the zones.\n";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
return 1;
}
return 0;
}
} else {
$rsp->{data}->[0] = "Could not open zone table.\n";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
return 1;
}
# if no zone table defined, do it the old way
# send the keys to the nodes for root or some other id
#
# The nodes must be checked against the site.sshbetweennodes attribute
# This site attribute determines whether to setup
# node to node ssh
my $enablenodes;
my $disablenodes;
my @nodelist= split(",", $n_str);
@ -440,10 +474,10 @@ rmdir \"/tmp/$to_userid\" \n";
}
}
my $cmd;
if ($enablenodes) { # node on list to setup nodetonodessh
chop $enablenodes; # remove last comma
$ENV{'DSH_ENABLE_SSH'} = "YES";
# send the keys to the nodes
my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$enablenodes,$expecttimeout);
if ($rc != 0)
{
@ -452,8 +486,9 @@ rmdir \"/tmp/$to_userid\" \n";
}
}
if ($disablenodes) { # node on list to setup nodetonodessh
if ($disablenodes) { # node on list to disable nodetonodessh
chop $disablenodes; # remove last comma
# send the keys to the nodes
my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$disablenodes,$expecttimeout);
if ($rc != 0)
{
@ -462,6 +497,7 @@ rmdir \"/tmp/$to_userid\" \n";
}
}
} else { # from user is not root or it is a device , always send private key
$ENV{'DSH_ENABLE_SSH'} = "YES";
my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$n_str,$expecttimeout);
@ -503,6 +539,60 @@ rmdir \"/tmp/$to_userid\" \n";
#--------------------------------------------------------------------------------
=head3 sendkeystozones
Transfers the ssh keys
for the root id on the nodes using the zone table.
Arguments:
Array of nodes
Timeout for expect call (optional)
Returns:
Env Variables: $DSH_FROM_USERID, $DSH_TO_USERID, $DSH_REMOTE_PASSWORD
the ssh keys are transferred from the $DSH_FROM_USERID to the $DSH_TO_USERID
on the node(s). The DSH_REMOTE_PASSWORD and the DSH_FROM_USERID
must be obtained by
the calling script or from the xdsh client
Globals:
$::XCATROOT , $::CALLBACK
Error:
0=good, 1=error
Example:
xCAT::TableUtils->setupSSH(@target_nodes,$expecttimeout);
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 sendkeystozones
{
my ($class, $ref_nodes,$expecttimeout) = @_;
my @nodes=$ref_nodes;
my %zonehash =xCAT::Zone->getNodeZones(@nodes);
# for each zone in the zonehash
# if sshbetweennodes is yes
# $ENV{'DSH_ENABLE_SSH'} = "YES";
# else
# unset $ENV{'DSH_ENABLE_SSH'}
# send the keys to the nodes
# my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$nodelist,$expecttimeout);
# if ($rc != 0)
# {
# $rsp->{data}->[0] = "remoteshellexp failed sending keys to $zonename.";
# xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
#
# }
# } # endforeach
return 0;
}
#--------------------------------------------------------------------------------
=head3 cpSSHFiles
Builds authorized_keyfiles for root

View File

@ -199,7 +199,7 @@ sub getdefaultzone
foreach my $zone (@zones) {
# Look for the defaultzone=yes/1 entry
if ((defined($zone->{defaultzone})) &&
(($zone->{defaultzone} =~ "yes") || ($zone->{defaultzone} = "1"))) {
(($zone->{defaultzone} =~ "yes") || ($zone->{defaultzone} eq "1"))) {
$defaultzone = $zone->{zonename};
}
$tab->close();
@ -249,28 +249,29 @@ sub iszonedefined
-> {sshkeydir} -> directory containing ssh RSA keys
-> {defaultzone} -> is it the default zone
Example:
my %zonehash =xCAT::Zone->getNodeZones($nodelist);
my %zonehash =xCAT::Zone->getNodeZones(@nodearray);
Rules:
If the nodes nodelist.zonename attribute is a zonename, it is assigned to that zone
If the nodes nodelist.zonename attribute is undefined:
If there is a defaultzone in the zone table, the node is assigned to that zone
If there is no defaultzone in the zone table, the node is assigned to the ~.ssh keydir
$::GETZONEINFO_RC
0 = good return
1 = error occured
=cut
#--------------------------------------------------------------------------------
sub getzoneinfo
{
my ($class, $callback,$nodes) = @_;
# make the list into an array
# $nodelist=~ s/\s*//g; # remove blanks
# my @nodes = split ',', $nodelist;
$::GETZONEINFO_RC=0;
my $zonehash;
my $defaultzone;
# read all the zone table
my $zonetab = xCAT::Table->new("zone");
my @zones;
if ($zonetab){
my @zones = $zonetab->getAllAttribs('zonename','sshkeydir','defaultzone');
@zones = $zonetab->getAllAttribs('zonename','sshkeydir','sshbetweennodes','defaultzone');
$zonetab->close();
if (@zones) {
foreach my $zone (@zones) {
@ -279,7 +280,7 @@ sub getzoneinfo
$zonehash->{$zonename}->{defaultzone}= $zone->{defaultzone};
# find the defaultzone
if ((defined($zone->{defaultzone})) &&
(($zone->{defaultzone} =~ "yes") || ($zone->{defaultzone} = "1"))) {
(($zone->{defaultzone} =~ "yes") || ($zone->{defaultzone} eq "1"))) {
$defaultzone = $zone->{zonename};
}
}
@ -289,6 +290,7 @@ sub getzoneinfo
$rsp->{error}->[0] =
"Error reading the zone table. ";
xCAT::MsgUtils->message("E", $rsp, $callback);
$::GETZONEINFO_RC =1;
return;
}
@ -314,6 +316,15 @@ sub getzoneinfo
$zonename=$nodehash->{$node}->[0]->{zonename};
}
if (defined($zonename)) { # zonename explicitly defined in nodelist.zonename
# check to see if defined in the zone table
if (!(grep(/^$zonename$/, @zones))) {
my $rsp = {};
$rsp->{error}->[0] =
"$node has a zonenane: $zonename that is not define in the zone table. Remove the zonename from the node, or create the zone using mkzone.";
xCAT::MsgUtils->message("E", $rsp, $callback);
$::GETZONEINFO_RC =1;
return;
}
push @{$zonehash->{$zonename}->{nodes}},$node;
} else { # no explict zonename
if (defined ($defaultzone)) { # there is a default zone in the zone table, use it

View File

@ -8,6 +8,8 @@ B<updatenode> B<noderange> [B<-V>|B<--verbose>] [B<-F>|B<--sync>] [B<-f>|B<--sns
B<updatenode> B<noderange> [B<-k>|B<--security>] [B<-t timeout>]
B<updatenode> B<noderange> [B<-g>|B<--genmypost>]
B<updatenode> B<noderange> [B<-V>|B<--verbose>] [B<-t timeout>] [B<script1,script2...>]
B<updatenode> B<noderange> [B<-V>|B<--verbose>] [B<-f>|B<--snsync>]
@ -327,6 +329,11 @@ For statelite installations to sync files, you should use the
read-only option for files/directories listed in
litefile table with source location specified in the litetree table.
=item B<-g|--genmypost
Will generate a new mypostscript file for the
nodes in the noderange, if site precreatemypostscripts is 1 or YES.
=item B<-h|--help>

View File

@ -108,6 +108,7 @@ sub process_request
'h|help' => \$options{'help'},
'k|sshkeypath=s' => \$options{'sshkeypath'},
'K|genkeys' => \$options{'gensshkeys'},
's|sshbetweennodes=s' => \$options{'sshbetweennodes'},
'v|version' => \$options{'version'},
'V|Verbose' => \$options{'verbose'},
)
@ -244,6 +245,7 @@ sub mkzone
# Create path to generated ssh keys
$keydir .= $request->{zonename};
# update the zone table
$rc=updatezonetable($request, $callback,$options,$keydir);
@ -337,11 +339,11 @@ sub usage
my $usagemsg2="";
if ($command eq "mkzone") {
$usagemsg1 = " mkzone -h \n mkzone -v \n";
$usagemsg2 = " mkzone <zonename> [-V] [--defaultzone] [-k <full path to the ssh RSA private key] \n [-a <noderange>] [-g] [-f]";
$usagemsg2 = " mkzone <zonename> [-V] [--defaultzone] [-k <full path to the ssh RSA private key] \n [-a <noderange>] [-g] [-f] [-s <yes/no>]";
} else {
if ($command eq "chzone") {
$usagemsg1 = " chzone -h \n chzone -v \n";
$usagemsg2 = " chzone <zonename> [-V] [--defaultzone] [-k <full path to the ssh RSA private key] \n [-K] [-a <noderange>] [-r <noderange>] [-g] ";
$usagemsg2 = " chzone <zonename> [-V] [--defaultzone] [-k <full path to the ssh RSA private key] \n [-K] [-a <noderange>] [-r <noderange>] [-g] [-s <yes/no>]";
} else {
if ($command eq "rmzone") {
$usagemsg1 = " rmzone -h \n rmzone -v \n";
@ -424,6 +426,18 @@ sub updatezonetable
my $tab = xCAT::Table->new("zone");
if ($tab)
{
# read a record from the zone table, if it is empty then add
# the xcatdefault entry
my @zones = $tab->getAllAttribs('zonename');
if (!(@zones)) { # table empty
my %xcatdefaultzone;
$xcatdefaultzone{defaultzone} ="yes";
$xcatdefaultzone{sshbetweennodes} ="yes";
$xcatdefaultzone{sshkeydir} ="~/.ssh";
$tab->setAttribs({zonename => "xcatdefault"}, \%xcatdefaultzone);
}
# now add the users zone
my %tb_cols;
$tb_cols{sshkeydir} = $keydir;
my $zonename=$request->{zonename};