the code drop of updatenode --security

git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@5539 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
daniceexi 2010-03-21 13:11:47 +00:00
parent 9573251682
commit 6b4b8e4ca2
8 changed files with 677 additions and 206 deletions

View File

@ -187,6 +187,35 @@ my %usage = (
renergy noderange [-V] { all | { [savingstatus] [dsavingstatus] [cappingstatus] [cappingmaxmin] [cappingvalue] [cappingsoftmin] [averageAC] [averageDC] [ambienttemp] [exhausttemp] [CPUspeed] [syssbpower] [sysIPLtime] } }
renergy noderange [-V] { {savingstatus}={on | off} | {dsavingstatus}={on-norm | on-maxp | off} | {cappingstatus}={on | off} | {cappingwatt}=watt | {cappingperc}=percentage }",
"updatenode" =>
"Usage:
updatenode [-h|--help|-v|--version]
or
updatenode <noderange> [-V|--verbose] [--security] [-s|--sn]
or
updatenode <noderange> [-V|--verbose] [--security] [--user]
[--devicetype]
or
updatenode <noderange> [-V|--verbose] [-F|--sync] [-S|--sw]
[-P|--scripts [script1,script2,...]] [-s|--sn] [-c|--cmdlineonly]
[attr=val [attr=val...]]
or
updatenode <noderange> [-V|--verbose] [script1,script2,...]
<noderange> is a list of nodes or groups.
[--security] update the security keys and certificates for the target nodes
[--security] [--user] [--devicetype] update the ssh keys for specific device
[-F|--sync] Perform File Syncing.
[-S|--sw] Perform Software Maintenance.
[-P|--scripts] Execute postscripts listed in the postscripts table or
parameters.
[-c|--cmdlineonly] Only use AIX software maintenance information
provided on the command line. (AIX only)
[-s|--sn] Set the server information stored on the nodes.
[script1,script2,...] A comma separated list of postscript names.
If omitted, all the post scripts defined for the nodes will be run.
[attr=val [attr=val...]] Specifies one or more 'attribute equals value'
pairs, separated by spaces. (AIX only)",
);
my $vers = xCAT::Utils->Version();
my %version = (

126
xCAT-client/bin/updatenode Executable file
View File

@ -0,0 +1,126 @@
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
BEGIN { $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr'; }
use Getopt::Long;
use lib "$::XCATROOT/lib/perl";
use Cwd;
use File::Basename;
use xCAT::Client;
use xCAT::MsgUtils;
use xCAT::Usage;
sub updatenode_usage
{
my $usage_string = xCAT::Usage->getUsage("updatenode");
print "$usage_string\n";
}
my $bname = basename($0);
my $cmdref;
$cmdref->{command}->[0] = $bname;
$cmdref->{cwd}->[0] = cwd();
if (-p STDIN) {
my $data;
while ( <STDIN> ) { $data.=$_; }
$cmdref->{stdin}->[0]=$data;
}
my $arg=shift(@ARGV);
# Set the noderange
if ($arg !~ /^-/) {
my @tempnr = ();
foreach my $nr (split(/,/, $arg)) {
if ($nr =~ /^\^(.*)$/) {
my $nrf = $1;
if ($nrf !~ /^\//) { #relative path
$nrf = Cwd::abs_path($nrf);
}
$nrf = "\^" . $nrf;
push @tempnr, $nrf;
} else {
push @tempnr, $nr;
}
}
$arg = join(',',@tempnr);
$cmdref->{noderange}->[0]=$arg;
} else {
push @{$cmdref->{arg}}, $arg;
}
push (@{$cmdref->{arg}}, @ARGV);
# if trying to update security, get the password
# to access the target node firstly
Getopt::Long::Configure("posix_default");
Getopt::Long::Configure("no_gnu_compat");
Getopt::Long::Configure("bundling");
if (
!GetOptions(
'c|cmdlineonly' => \$::CMDLINE,
'h|help' => \$::HELP,
'v|version' => \$::VERSION,
'V|verbose' => \$::VERBOSE,
'F|sync' => \$::FILESYNC,
'S|sw' => \$::SWMAINTENANCE,
's|sn' => \$::SETSERVER,
'P|scripts:s' => \$::RERUNPS,
'security' => \$::SECURITY,
'user=s' => \$::USER,
'devicetype=s' => \$::DEVICETYPE,
)
) {
&updatenode_usage();
exit 1;
}
my $current_userid = getpwuid($>);
$ENV{DSH_FROM_USERID} = $current_userid;
my $to_userid;
if ($::USER)
{
$to_userid = $::USER;
}
else
{
$to_userid = $current_userid;
}
$ENV{DSH_TO_USERID} = $to_userid;
if ($::SECURITY) {
my $msg;
if (!($ENV{'DSH_REMOTE_PASSWORD'}))
{ # if not already set
# prompt for the password for the userid on the node that will be setup
my $userpw;
$msg =
"Enter the password for the userid: $to_userid on the node where the ssh keys \nwill be updated:\n";
xCAT::MsgUtils->message("I", $msg);
system("stty -echo"); # turn off keyboard
chop($userpw = <STDIN>);
system("stty echo"); # turn on keyboard
if ($userpw eq "")
{ # did not enter a password
$msg = "Did not enter a password will abort the security update.";
xCAT::MsgUtils->message("E", $msg);
exit 2;
}
else
{ # password entered pass to the server
$ENV{DSH_REMOTE_PASSWORD} = $userpw;
}
}
}
foreach (keys %ENV) {
push @{$cmdref->{environment}}, "$_=$ENV{$_}";
}
xCAT::Client::submit_request($cmdref,\&xCAT::Client::handle_response);
exit $xCAT::Client::EXITCODE;

View File

@ -1182,7 +1182,7 @@ sub addNodes {
my $nr = join(',', @{$servernodes{$snkey}});
my $cmd;
if (xCAT::Utils->isLinux()) {
$cmd="XCATBYPASS=Y $fanout_string $::XCATROOT/bin/xdsh $nr -s -e /install/postscripts/xcatdsklspost -m $snkey configrmcnode 2>&1";
$cmd="XCATBYPASS=Y $fanout_string $::XCATROOT/bin/xdsh $nr -s -e /install/postscripts/xcatdsklspost 2 -m $snkey configrmcnode 2>&1";
print "$cmd\n";
}
else {

View File

@ -405,6 +405,6 @@ sub remove_nodes_from_knownhosts
return 1;
}
}
xCAT::Utils->runcmd("$::RM -f $file", -1);
xCAT::Utils->runcmd("rm -f $file", -1);
return 0;
}

View File

@ -155,24 +155,9 @@ sub preprocess_updatenode
{
my $cb = shift;
my $rsp = {};
$rsp->{data}->[0] = "Usage:";
$rsp->{data}->[1] = " updatenode [-h|--help|-v|--version]";
$rsp->{data}->[2] = "or";
$rsp->{data}->[3] =
" updatenode <noderange> [-V|--verbose] [-F|--sync] [-S|--sw] [-P|--scripts \n\t\t[-s|--sn] [script1,script2,...]] [-c|--cmdlineonly] \n\t\t[attr=val [attr=val...]]";
$rsp->{data}->[4] = "or";
$rsp->{data}->[5] =
" updatenode <noderange> [-V|--verbose] [script1,script2,...]\n";
$rsp->{data}->[6] = " <noderange> is a list of nodes or groups.";
$rsp->{data}->[7] = " [-F|--sync] Perform File Syncing.";
$rsp->{data}->[8] = " [-S|--sw] Perform Software Maintenance.";
$rsp->{data}->[9] =
" [-P|--scripts] Execute postscripts listed in the postscripts table or \n\tparameters.";
$rsp->{data}->[10] =
" [-c|--cmdlineonly] Only use AIX software maintenance information provided \n\ton the command line. (AIX only)";
$rsp->{data}->[11] = " [-s|--sn] Set the server information stored on the nodes.";
$rsp->{data}->[12] = " [script1,script2,...] A comma separated list of postscript names. \n\tIf omitted, all the postscripts defined for the nodes will be run.";
$rsp->{data}->[13] = " [attr=val [attr=val...]] Specifies one or more 'attribute equals value'\n\tpairs, separated by spaces. (AIX only)";
my $usage_string = xCAT::Usage->getUsage("updatenode");
push @{$rsp->{data}},$usage_string;
$cb->($rsp);
}
@ -187,14 +172,17 @@ sub preprocess_updatenode
Getopt::Long::Configure("no_pass_through");
if (
!GetOptions(
'c|cmdlineonly' => \$::CMDLINE,
'h|help' => \$::HELP,
'v|version' => \$::VERSION,
'V|verbose' => \$::VERBOSE,
'F|sync' => \$::FILESYNC,
'S|sw' => \$::SWMAINTENANCE,
's|sn' => \$::SETSERVER,
'P|scripts:s' => \$::RERUNPS
'c|cmdlineonly' => \$::CMDLINE,
'h|help' => \$::HELP,
'v|version' => \$::VERSION,
'V|verbose' => \$::VERBOSE,
'F|sync' => \$::FILESYNC,
'S|sw' => \$::SWMAINTENANCE,
's|sn' => \$::SETSERVER,
'P|scripts:s' => \$::RERUNPS,
'security' => \$::SECURITY,
'user=s' => \$::USER,
'devicetype=s' => \$::DEVICETYPE,
)
)
{
@ -218,6 +206,30 @@ sub preprocess_updatenode
return \@requests;
}
# -c must work with -S for AIX node
if ($::CMDLINE && !$::SWMAINTENANCE) {
&updatenode_usage($callback);
return \@requests;
}
# -s must work with -P or -S or --security
if ($::SETSERVER && !($::SWMAINTENANCE || $::RERUNPS || $::SECURITY)) {
&updatenode_usage($callback);
return \@requests;
}
# --user and --devicetype must work with --security
if (($::USER || $::DEVICETYPE) && !($::SECURITY && $::USER && $::DEVICETYPE)) {
&updatenode_usage($callback);
return \@requests;
}
# --security cannot work with -S -P -F
if ($::SECURITY && ($::SWMAINTENANCE || $::RERUNPS || defined($::RERUNPS))) {
&updatenode_usage($callback);
return \@requests;
}
# the -P flag is omitted when only postscritps are specified,
# so if there are parameters without any flags, it may mean
# to re-run the postscripts.
@ -226,7 +238,7 @@ sub preprocess_updatenode
# we have one or more operands on the cmd line
if ($#ARGV == 0
&& !($::FILESYNC || $::SWMAINTENANCE || defined($::RERUNPS)))
&& !($::FILESYNC || $::SWMAINTENANCE || defined($::RERUNPS) || $::SECURIT))
{
# there is only one operand
@ -234,6 +246,7 @@ sub preprocess_updatenode
if (!($ARGV[0] =~ /=/))
{
$::RERUNPS = $ARGV[0];
$ARGV[0] = "";
}
}
}
@ -241,7 +254,7 @@ sub preprocess_updatenode
{
# no flags and no operands
if (!($::FILESYNC || $::SWMAINTENANCE || defined($::RERUNPS)))
if (!($::FILESYNC || $::SWMAINTENANCE || defined($::RERUNPS) ||$::SECURITY))
{
$::FILESYNC = 1;
$::SWMAINTENANCE = 1;
@ -249,6 +262,10 @@ sub preprocess_updatenode
}
}
if ($::SECURITY && !($::USER || $::DEVICETYPE)) {
$::RERUNPS = "allkeys44444444security";
}
my $nodes = $request->{node};
if (!$nodes)
{
@ -257,39 +274,38 @@ sub preprocess_updatenode
}
#
# process @ARGV
# process @ARGV for the software maintenance of AIX node, it should
# be the list of attr=val, put attr=val operands in %attrvals hash
#
# the first arg should be a noderange - the other should be attr=val
# - put attr=val operands in %attrvals hash
my %attrvals;
while (my $a = shift(@ARGV))
{
if ($a =~ /=/)
if ($::SWMAINTENANCE) {
while (my $a = shift(@ARGV))
{
# if it has an "=" sign its an attr=val - we hope
my ($attr, $value) = $a =~ /^\s*(\S+?)\s*=\s*(\S*.*)$/;
if (!defined($attr) || !defined($value))
if ($a =~ /=/)
{
my $rsp;
$rsp->{data}->[0] = "Incorrect \'attr=val\' pair - $a\n";
xCAT::MsgUtils->message("E", $rsp, $::callback);
return 3;
# if it has an "=" sign its an attr=val - we hope
my ($attr, $value) = $a =~ /^\s*(\S+?)\s*=\s*(\S*.*)$/;
if (!defined($attr) || !defined($value))
{
my $rsp;
$rsp->{data}->[0] = "Incorrect \'attr=val\' pair - $a\n";
xCAT::MsgUtils->message("E", $rsp, $::callback);
return 3;
}
# put attr=val in hash
$attrvals{$attr} = $value;
}
# put attr=val in hash
$attrvals{$attr} = $value;
}
}
my @nodes = @$nodes;
my $postscripts;
if (@nodes == 0) { return \@requests; }
# handle the re-run postscripts option -P
# handle the validity of postscripts
if (defined($::RERUNPS))
{
if ($::RERUNPS eq "")
@ -299,7 +315,13 @@ sub preprocess_updatenode
else
{
$postscripts = $::RERUNPS;
my @posts = split(',', $postscripts);
my @posts = ();
if ($postscripts eq "allkeys44444444security") {
@posts = ("remoteshell", "aixremoteshell", "servicenode", "xcatserver", "xcatclient");
} else {
@posts = split(',', $postscripts);
}
foreach (@posts)
{
if (!-e "$installdir/postscripts/$_")
@ -315,8 +337,8 @@ sub preprocess_updatenode
}
# If -F option specified, sync files to the noderange.
# Note: This action only happens on MN, since xdcp handles the
# hierarchical scenario
# Note: This action only happens on MN, since xdcp, xdsh handles the
# hierarchical scenario inside
if ($::FILESYNC)
{
my $reqcopy = {%$request};
@ -324,10 +346,10 @@ sub preprocess_updatenode
push @requests, $reqcopy;
}
# when specified -S or -P
# when specified -S or -P or --security
# find service nodes for requested nodes
# build an individual request for each service node
unless (defined($::SWMAINTENANCE) || defined($::RERUNPS))
unless (defined($::SWMAINTENANCE) || defined($::RERUNPS) || $::SECURITY)
{
return \@requests;
}
@ -338,7 +360,6 @@ sub preprocess_updatenode
xCAT::SvrUtils->getNodesetStates($nodes, \%insttype_node);
# figure out the diskless nodes list and non-diskless nodes
foreach my $type (keys %insttype_node) {
if ($type eq "netboot" || $type eq "diskless") {
@ -374,6 +395,7 @@ sub preprocess_updatenode
}
}
my $sn = xCAT::Utils->get_ServiceNode(\@nodes, "xcat", "MN");
if ($::ERROR_RC)
{
@ -385,10 +407,97 @@ sub preprocess_updatenode
# return undef; ???
}
# for security update, we need to handle the service node first
my @good_sns = ();
my @MNip = xCAT::Utils->determinehostname;
my @sns = ();
foreach my $s (keys %$sn) {
if (!grep (/^$s$/, @MNip)) {
push @sns, $s;
}
}
if (scalar(@sns) && $::SECURITY) {
$::CALLBACK = $callback;
$::NODEOUT = ();
# setup the ssh keys
my $req_sshkey = {%$request};
$req_sshkey->{node} = \@sns;
$req_sshkey->{security}->[0] = "yes";
if ($::USER) {
$req_sshkey->{user}->[0] = $::USER;
}
if ($::DEVICETYPE) {
$req_sshkey->{devicetype}->[0] = $::DEVICETYPE;
}
updatenode($req_sshkey, \&updatenode_cb, $subreq);
# run the postscripts: remoteshell, servicenode, xcatserver, xcatclient
if ($postscripts eq "allkeys44444444security") {
my ($rc, $AIXnodes, $Linuxnodes) = xCAT::InstUtils->getOSnodes(\@sns);
my $req_rs = {%$request};
my $ps;
if (scalar(@{$AIXnodes})) {
$ps = "aixremoteshell,servicenode";
$req_rs->{rerunps}->[0] = "yes";
$req_rs->{rerunps4security}->[0] = "yes";
$req_rs->{node} = $AIXnodes;
$req_rs->{postscripts} = [$ps];
updatenode($req_rs, \&updatenode_cb, $subreq);
}
if (scalar(@{$Linuxnodes})) {
$ps = "remoteshell,servicenode,xcatserver,xcatclient";
$req_rs->{rerunps}->[0] = "yes";
$req_rs->{rerunps4security}->[0] = "yes";
$req_rs->{node} = $Linuxnodes;
$req_rs->{postscripts} = [$ps];
updatenode($req_rs, \&updatenode_cb, $subreq);
}
}
# parse the output of update security for sns
foreach my $sn (keys %{$::NODEOUT}) {
if (!grep /^$sn$/, @sns) {
next;
}
if ( (grep /ps ok/, @{$::NODEOUT->{$sn}})
&& (grep /ssh ok/, @{$::NODEOUT->{$sn}}) ) {
push @good_sns, $sn;
}
}
if ($::VERBOSE) {
my $rsp;
push @{$rsp->{data}}, "Update security for following service nodes: @sns.";
push @{$rsp->{data}}, " Following service nodes have been updated successfully: @good_sns";
xCAT::MsgUtils->message("I", $rsp, $callback);
}
}
# build each request for each service node
foreach my $snkey (keys %$sn)
{
if ($::SECURITY
&& !(grep /^$snkey$/, @good_sns)
&& !(grep /^$snkey$/, @MNip)) {
my $rsp;
push @{$rsp->{data}}, "The security update for service node $snkey encountered error, update security for following nodes will be skipped: @{$sn->{$snkey}}";
xCAT::MsgUtils->message("E", $rsp, $callback);
next;
}
# remove the service node which have been handled before
if ($::SECURITY && (grep /^$snkey$/, @MNip)) {
delete @{$sn->{$snkey}}[@sns];
if (scalar(@{$sn->{$snkey}}) == 0) {
next;
}
}
my $reqcopy = {%$request};
$reqcopy->{node} = $sn->{$snkey};
$reqcopy->{'_xcatdest'} = $snkey;
@ -425,6 +534,19 @@ sub preprocess_updatenode
{
$reqcopy->{rerunps}->[0] = "yes";
$reqcopy->{postscripts} = [$postscripts];
if (defined($::SECURITY)) {
$reqcopy->{rerunps4security}->[0] = "yes";
}
}
if (defined($::SECURITY)) {
$reqcopy->{security}->[0] = "yes";
if ($::USER) {
$reqcopy->{user}->[0] = $::USER;
}
if ($::DEVICETYPE) {
$reqcopy->{devicetype}->[0] = $::DEVICETYPE;
}
}
push @requests, $reqcopy;
@ -433,6 +555,40 @@ sub preprocess_updatenode
return \@requests;
}
#--------------------------------------------------------------------------------
=head3 updatenode_cb
A callback function which is used to handle the output of updatenode function
when run updatenode --secruity for service node inside
=cut
#-----------------------------------------------------------------------------
sub updatenode_cb
{
my $resp = shift;
# call the original callback function
$::CALLBACK->($resp);
foreach my $line (@{$resp->{data}}) {
my $node;
my $msg;
if ($line =~ /(.*):(.*)/) {
$node = $1;
$msg = $2;
}
if ($msg =~ /Redeliver certificates has completed/) {
push @{$::NODEOUT->{$node}}, "ps ok";
} elsif ($msg =~ /Setup ssh keys has completed/) {
push @{$::NODEOUT->{$node}}, "ssh ok";
}
}
}
#--------------------------------------------------------------------------------
=head3 updatenode
@ -574,7 +730,7 @@ sub updatenode
{
my $rsp = {};
$rsp->{data}->[0] =
" Internal call command: xdcp -F $synclist";
" $localhostname: Internal call command: xdcp -F $synclist";
$callback->($rsp);
}
my $args = ["-F", "$synclist"];
@ -640,25 +796,25 @@ sub updatenode
my $cmd;
if ($::SETSERVER) {
$cmd =
"XCATBYPASS=Y $::XCATROOT/bin/xdsh $nodestring -s -e $installdir/postscripts/xcatdsklspost -M $snkey otherpkgs 2>&1";
"XCATBYPASS=Y $::XCATROOT/bin/xdsh $nodestring -s -e $installdir/postscripts/xcatdsklspost 2 -M $snkey otherpkgs 2>&1";
} else {
$cmd =
"XCATBYPASS=Y $::XCATROOT/bin/xdsh $nodestring -s -e $installdir/postscripts/xcatdsklspost -m $snkey otherpkgs 2>&1";
"XCATBYPASS=Y $::XCATROOT/bin/xdsh $nodestring -s -e $installdir/postscripts/xcatdsklspost 2 -m $snkey otherpkgs 2>&1";
}
if (defined($::VERBOSE))
{
my $rsp = {};
$rsp->{data}->[0] = " Internal call command: $cmd";
$rsp->{data}->[0] = " $localhostname: Internal call command: $cmd";
$callback->($rsp);
}
if ($cmd && !open(CMD, "$cmd |"))
{
my $rsp = {};
$rsp->{data}->[0] = "Cannot run command $cmd";
$rsp->{data}->[0] = "$localhostname: Cannot run command $cmd";
$callback->($rsp);
}
else
@ -703,6 +859,80 @@ sub updatenode
}
} # end sw maint section
#
# handle of setting up ssh keys
#
if ($request->{security} && $request->{security}->[0] eq "yes") {
# generate the arguments
my @args = ("-K");
if ($request->{user}->[0]) {
push @args, "--user";
push @args, $request->{user}->[0];
}
if ($request->{devicetype}->[0]) {
push @args, "--devicetype";
push @args, $request->{devicetype}->[0];
}
# remove the host key from known_hosts
xCAT::Utils->runxcmd( {
command => ['makeknownhosts'],
node => \@$nodes,
arg => ['-r'],
}, $subreq, 0, 1);
if (defined($::VERBOSE))
{
my $rsp = {};
$rsp->{data}->[0] =
" $localhostname: run makeknownhosts to clean known_hosts file for nodes: @$nodes";
$callback->($rsp);
}
# call the xdsh -K to set up the ssh keys
my @envs = @{$request->{environment}};
my $res = xCAT::Utils->runxcmd( {
command => ['xdsh'],
node => \@$nodes,
arg => \@args,
env => \@envs,
}, $subreq, 0, 1);
if (defined($::VERBOSE))
{
my $rsp = {};
$rsp->{data}->[0] =
" $localhostname: Internal call command: xdsh -K. nodes = @$nodes, arguments = @args, env = @envs";
$rsp->{data}->[1] =
" $localhostname: return messages of last command: @$res";
$callback->($rsp);
}
# parse the output of xdsh -K
my @failednodes = @$nodes;
foreach my $line (@$res) {
chomp($line);
if ($line =~ /SSH setup failed for the following nodes: (.*)\./) {
@failednodes = split(/,/, $1);
} elsif ($line =~ /setup is complete/) {
@failednodes = ();
}
}
my $rsp = {};
foreach my $node (@$nodes) {
if (grep /^$node$/, @failednodes) {
push @{$rsp->{data}}, "$node: Setup ssh keys failed.";
} else {
push @{$rsp->{data}}, "$node: Setup ssh keys has completed.";
}
}
$callback->($rsp);
}
#
# handle the running of cust scripts
#
@ -710,14 +940,22 @@ sub updatenode
if ($request->{rerunps} && $request->{rerunps}->[0] eq "yes")
{
my $postscripts = "";
my $orig_postscripts = "";
if (($request->{postscripts}) && ($request->{postscripts}->[0]))
{
$postscripts = $request->{postscripts}->[0];
$orig_postscripts = $request->{postscripts}->[0];
}
if (scalar(@$Linuxnodes))
{ # we have Linux nodes
my $cmd;
{
if ($orig_postscripts eq "allkeys44444444security") {
$postscripts = "remoteshell,servicenode,xcatserver,xcatclient";
} else {
$postscripts = $orig_postscripts;
}
# we have Linux nodes
my $cmd;
# get server names as known by the nodes
my %servernodes = %{xCAT::InstUtils->get_server_nodes($callback, \@$Linuxnodes)};
# it's possible that the nodes could have diff server names
@ -725,35 +963,43 @@ sub updatenode
foreach my $snkey (keys %servernodes) {
my $nodestring = join(',', @{$servernodes{$snkey}});
my $cmd;
my $mode;
if ($request->{rerunps4security} && $request->{rerunps4security}->[0] eq "yes") {
# for updatenode --security
$mode = "5";
} else {
# for updatenode -P
$mode = "1";
}
if ($::SETSERVER) {
$cmd =
"XCATBYPASS=Y $::XCATROOT/bin/xdsh $nodestring -s -e $installdir/postscripts/xcatdsklspost -M $snkey $postscripts 2>&1";
"XCATBYPASS=Y $::XCATROOT/bin/xdsh $nodestring -s -e $installdir/postscripts/xcatdsklspost $mode -M $snkey $postscripts 2>&1";
} else {
$cmd =
"XCATBYPASS=Y $::XCATROOT/bin/xdsh $nodestring -s -e $installdir/postscripts/xcatdsklspost -m $snkey $postscripts 2>&1";
"XCATBYPASS=Y $::XCATROOT/bin/xdsh $nodestring -s -e $installdir/postscripts/xcatdsklspost $mode -m $snkey $postscripts 2>&1";
}
if (defined($::VERBOSE))
{
my $rsp = {};
$rsp->{data}->[0] = " Internal call command: $cmd";
$rsp->{data}->[0] = " $localhostname: Internal call command: $cmd";
$callback->($rsp);
}
if (!open(CMD, "$cmd |"))
{
my $rsp = {};
$rsp->{data}->[0] = "Cannot run command $cmd";
$rsp->{data}->[0] = "$localhostname: Cannot run command $cmd";
$callback->($rsp);
}
else
{
my $rsp = {};
while (<CMD>)
{
my $rsp = {};
my $output = $_;
chomp($output);
$output =~ s/\\cM//;
@ -762,17 +1008,32 @@ sub updatenode
$output =~
s/returned from postscript/Running of postscripts has completed./;
}
$rsp->{data}->[0] = "$output";
$callback->($rsp);
if ($request->{rerunps4security} && $request->{rerunps4security}->[0] eq "yes") {
if ($output =~ /Running of postscripts has completed/) {
$output =~ s/Running of postscripts has completed/Redeliver certificates has completed/;
push @{$rsp->{data}}, $output;
} elsif ($output !~ /Running postscript|Error loading module/) {
push @{$rsp->{data}}, "$output";
}
} else {
push @{$rsp->{data}}, "$output";
}
}
close(CMD);
$callback->($rsp);
}
}
}
if (scalar(@$AIXnodes))
{ # we have AIX nodes
{
# we have AIX nodes
if ($orig_postscripts eq "allkeys44444444security") {
$postscripts = "aixremoteshell,servicenode";
} else {
$postscripts = $orig_postscripts;
}
# need to pass the name of the server on the xcataixpost cmd line
# get server names as known by the nodes
@ -782,30 +1043,39 @@ sub updatenode
foreach my $snkey (keys %servernodes) {
$nodestring = join(',', @{$servernodes{$snkey}});
my $cmd;
my $mode;
if ($request->{rerunps4security} && $request->{rerunps4security}->[0] eq "yes") {
# for updatenode --security
$mode = "5";
} else {
# for updatenode -P
$mode = "1";
}
if ($::SETSERVER) {
$cmd = "XCATBYPASS=Y $::XCATROOT/bin/xdsh $nodestring -s -e $installdir/postscripts/xcataixpost -M $snkey -c 1 $postscripts 2>&1";
$cmd = "XCATBYPASS=Y $::XCATROOT/bin/xdsh $nodestring -s -e $installdir/postscripts/xcataixpost -M $snkey -c $mode $postscripts 2>&1";
} else {
$cmd = "XCATBYPASS=Y $::XCATROOT/bin/xdsh $nodestring -s -e $installdir/postscripts/xcataixpost -m $snkey -c 1 $postscripts 2>&1";
$cmd = "XCATBYPASS=Y $::XCATROOT/bin/xdsh $nodestring -s -e $installdir/postscripts/xcataixpost -m $snkey -c $mode $postscripts 2>&1";
}
if (defined($::VERBOSE))
{
my $rsp = {};
$rsp->{data}->[0] = " Internal call command: $cmd";
$rsp->{data}->[0] = " $localhostname: Internal call command: $cmd";
$callback->($rsp);
}
if (!open(CMD, "$cmd |"))
{
my $rsp = {};
$rsp->{data}->[0] = "Cannot run command $cmd";
$rsp->{data}->[0] = "$localhostname: Cannot run command $cmd";
$callback->($rsp);
}
else
{
my $rsp = {};
while (<CMD>)
{
my $rsp = {};
my $output = $_;
chomp($output);
$output =~ s/\\cM//;
@ -814,15 +1084,33 @@ sub updatenode
$output =~
s/returned from postscript/Running of postscripts has completed./;
}
$rsp->{data}->[0] = "$output";
$callback->($rsp);
if ($request->{rerunps4security} && $request->{rerunps4security}->[0] eq "yes") {
if ($output =~ /Running of postscripts has completed/) {
$output =~ s/Running of postscripts has completed/Redeliver certificates has completed/;
push @{$rsp->{data}}, $output;
} elsif ($output !~ /Running postscript|Error loading module/) {
push @{$rsp->{data}}, $output;
}
} else {
push @{$rsp->{data}}, "$output";
}
}
close(CMD);
$callback->($rsp);
}
}
}
if ($request->{rerunps4security} && $request->{rerunps4security}->[0] eq "yes") {
# clean the know_hosts
xCAT::Utils->runxcmd( {
command => ['makeknownhosts'],
node => \@$nodes,
arg => ['-r'],
}, $subreq, 0, 1);
}
}
return 0;
}

View File

@ -56,6 +56,38 @@ chomp $::sdate;
$::hname = `hostname`;
chomp $::hname;
# update security certificates keys for service node
if ($ENV{UPDATESECURITY} && $ENV{UPDATESECURITY} eq "1") {
$::servnode = $ENV{'MASTER'};
# only run for service node
if (! -f "/etc/xCATSN") {
exit 0;
}
# copy the postscripts to /install/postscripts
if (&runcmd("mkdir -p /install/postscripts; cp -p -R /xcatpost/* /install/postscripts > /dev/null 2>&1") != 0 ) {
$msg = "$::sdate servicenode: Could not copy postscripts to /install/postscripts.\n";
`logger -t xcat $msg`;
}
# copy the certificates
if (&runcmd("/opt/xcat/sbin/copycerts") != 0) {
$msg = "$::sdate servicenode: Could not run copycerts.\n";
`logger -t xcat $msg`;
}
if ($::osname eq 'AIX') {
# get the xCAT credentials from the server
# the credenticals and certificates copy will be done in xcatclient and xcatserver postscripts
&getcreds;
}
exit 0;
}
if ($::osname eq 'AIX')
{
# AIX service node setup

View File

@ -224,8 +224,13 @@ if (-f $scriptname)
# when called by the updatenode command,
# modify the UPDATENODE flag to 1
if (@ARGV > 0) {
$TMP=`sed -e 's/UPDATENODE=0/UPDATENODE=1/g' $scriptname`;
`echo "$TMP" > $scriptname`;
if ($ARGV[0] == 1 || $ARGV[0] == 2) {
$TMP=`sed -e 's/UPDATENODE=0/UPDATENODE=1/g' $scriptname`;
`echo "$TMP" > $scriptname`;
} elsif ($ARGV[0] == 5) {
$TMP=`sed -e 's/UPDATENODE=0/UPDATENODE=1\\\nUPDATESECURITY=1\\\nexport UPDATESECURITY/g' $scriptname`;
`echo "$TMP" > $scriptname`;
}
}
if (@ARGV>1) {

View File

@ -4,11 +4,12 @@
#
# Generic xCAT post script for diskless nodes
# This script is called in the following different palces:
# updatenode -P ... --> xcatdsklspost 1 ...
# updatenode -S --> xcatdsklspost 2 otherpkgs
# updatenode -P ... --> xcatdsklspost 1 -m/-M ...
# updatenode -S --> xcatdsklspost 2 -m/-M otherpkgs
# moncfg rmcmon --> xcatdsklspost 3 configrmcnodes
# node deployment --> xcatdsklspost
# statelite mode --> xcatdsklspost 4
# update security --> xcatdsklspost 5 -m/-M ...
#
#####################################################
download_postscripts()
@ -40,7 +41,32 @@ download_postscripts()
return $rc
}
MODE=$1
# parse the arguments
ARGNUM=$#;
if [ -z $1 ]; then
NODE_DEPLOYMENT=1
else
case $1 in
1|2|5)
MODE=$1
if [ $ARGNUM -gt 1 ]; then
if [ $2 == "-m" ]; then
P_SIP=$3
else
if [ $2 == "-M" ]; then
P_SIP=$3
new_ms=$P_SIP
fi
fi
fi
if [ $ARGNUM -gt 3 ]; then
POSTSCRIPTS=$4
fi
;;
3|4) MODE=$1;;
esac
fi
if [ ! `uname` == Linux ]; then
MYDIR=`dirname $0`
@ -63,21 +89,8 @@ rm -R -f /tmp/postage/*
#here we get all the postscripts. Please do not change this behaviour because some scripts depend on others
cd /tmp/postage
argnum=$#;
if [ "$MODE" != "4" ]; then # not statelite mode
downloaded=0;
#open the xcatinfo file to look for the master if it is not set
if [ -f /opt/xcat/xcatinfo ]; then
SIP=`grep 'XCATSERVER' /opt/xcat/xcatinfo |cut -d= -f2`
if [ -n "$SIP" ]; then
download_postscripts $SIP
if [ $? -eq 0 ]; then
downloaded=1
fi
fi
fi
else # for statelite mode
if [ "$MODE" == "4" ]; then # for statelite mode
# We have written the xCATSERVER info into the kernel command line!!
for i in `cat /proc/cmdline`; do
KEY=`echo $i | awk -F= '{print $1}'`
@ -96,74 +109,73 @@ else # for statelite mode
logger -t xCAT "xcatdsklspost:xCAT management server IP can't be determined.\nexiting...";
exit;
fi
fi
if [ "$MODE" != "4" ]; then # NOSTATELITE: NOT for statelite MODE
#try the -m if it is specified, -m is passed in the updatenode command
if [ $downloaded -eq 0 ]; then
#get the -m
while [ $# -gt 0 ]
do
case "$1" in
-m) SIP="$2"; break;;
-M) SIP="$2"; new_ms=$SIP; break;;
esac
shift
done
if [ -n "$SIP" ]; then
download_postscripts $SIP
if [ $? -eq 0 ]; then
downloaded=1
fi
else # for common mode
downloaded=0;
#open the xcatinfo file to look for the master if it is not set
if [ -f /opt/xcat/xcatinfo ]; then
SIP=`grep 'XCATSERVER' /opt/xcat/xcatinfo |cut -d= -f2`
if [ -n "$SIP" ]; then
download_postscripts $SIP
if [ $? -eq 0 ]; then
downloaded=1
fi
fi
fi
fi
#try the dhcp server, this is used for initial boot for the node.
if [ $downloaded -eq 0 ]; then
#setup $OSVER ,for SLES11
if [ -e '/etc/SuSE-release' ]; then
OSVER=`grep -h VERSION /etc/SuSE-release |awk '{print $3}'`
fi
SIPS=`grep -h dhcp-server-identifier /var/lib/dhclient/dhclient*.leases 2> /dev/null|awk '{print $3}'|sed -e 's/;//'`
if [ -z "$SIPS" ]; then
SIPS=`grep -h DHCPSID /var/lib/dhcpcd/*.info 2> /dev/null|awk -F= '{print $2}'|sed -e s/\'//g`
fi
SIP=`echo $SIPS|awk '{printf $NF}' | tail -n 1` #Pick one for wget
if [ -n "$SIP" ]; then
download_postscripts $SIP
if [ $? -eq 0 ]; then
downloaded=1
fi
elif [ -x "/sbin/dhcpcd" ]; then
# New dhcpcd doesn't creates *.info files.
for lease in $(ls "/var/lib/dhcpcd/"); do
iface="$(echo "$lease" | sed -n -e 's/^dhcpcd-\(.*\)\.lease$/\1/p')"
if [ -n "$iface" ]; then
SIP="$(dhcpcd -q -T "$iface" | sed -n -e '/new_dhcp_server_identifier/ s/.*=//p')"
if [ -n "$SIP" ]; then
download_postscripts $SIP
if [ $? -eq 0 ]; then
downloaded=1
break
#try the -m if it is specified, -m is passed in the updatenode command
if [ $downloaded -eq 0 ]; then
if [ "XX$P_SIP" != "XX" ]; then
$SIP=$P_SIP
download_postscripts $SIP
if [ $? -eq 0 ]; then
downloaded=1
fi
fi
fi
#try the dhcp server, this is used for initial boot for the node.
if [ $downloaded -eq 0 ]; then
#setup $OSVER ,for SLES11
if [ -e '/etc/SuSE-release' ]; then
OSVER=`grep -h VERSION /etc/SuSE-release |awk '{print $3}'`
fi
SIPS=`grep -h dhcp-server-identifier /var/lib/dhclient/dhclient*.leases 2> /dev/null|awk '{print $3}'|sed -e 's/;//'`
if [ -z "$SIPS" ]; then
SIPS=`grep -h DHCPSID /var/lib/dhcpcd/*.info 2> /dev/null|awk -F= '{print $2}'|sed -e s/\'//g`
fi
SIP=`echo $SIPS|awk '{printf $NF}' | tail -n 1` #Pick one for wget
if [ -n "$SIP" ]; then
download_postscripts $SIP
if [ $? -eq 0 ]; then
downloaded=1
fi
elif [ -x "/sbin/dhcpcd" ]; then
# New dhcpcd doesn't creates *.info files.
for lease in $(ls "/var/lib/dhcpcd/"); do
iface="$(echo "$lease" | sed -n -e 's/^dhcpcd-\(.*\)\.lease$/\1/p')"
if [ -n "$iface" ]; then
SIP="$(dhcpcd -q -T "$iface" | sed -n -e '/new_dhcp_server_identifier/ s/.*=//p')"
if [ -n "$SIP" ]; then
download_postscripts $SIP
if [ $? -eq 0 ]; then
downloaded=1
break
fi
fi
fi
fi
done
done
fi
fi
#no hope, now let's get out of here.
if [ $downloaded -eq 0 ]; then
hn=`hostname`
echo "Cannot download the postscripts from the xCAT server for node $hn"
logger -t xCAT "xcatdsklspost:Cannot download the postscripts from the xCAT server for node $hn"
exit
fi
fi
#no hope, now let's get out of here.
if [ $downloaded -eq 0 ]; then
hn=`hostname`
echo "Cannot download the postscripts from the xCAT server for node $hn"
logger -t xCAT "xcatdsklspost:Cannot download the postscripts from the xCAT server for node $hn"
exit
fi
fi #END NOSTATELITE
fi # finish the postscripts download
if grep 'rw /rw tmpfs ' /proc/mounts >& /dev/null; then
touch /var/lock/subsys/xcatmounts
@ -174,15 +186,7 @@ if grep 'rw /rw tmpfs ' /proc/mounts >& /dev/null; then
ln -sf /etc/rc6.d/K10xcatmounts /etc/rc0.d/K10xcatmounts
fi
if [ "$MODE" != "4" ]; then
#wget -l inf -N -r --waitretry=10 --random-wait --retry-connrefused -t 0 -T 60 ftp://$SIP/postscripts 2> /tmp/wget.log
#mv $SIP/install/postscripts/* /xcatpost;
mv $SIP/postscripts/* /xcatpost;
rm -rf $SIP
else # for statelite mode
if [ "$MODE" == "4" ]; then
MAX=10
TRIES=1
while ! mount $SIP:/install/postscripts /xcatpost -r -n -o nolock
@ -199,17 +203,18 @@ else # for statelite mode
logger -t xCAT "xcatdsklspost:Can't mount $SIP:/install/postscripts... Sleeping $S seconds then trying again"
sleep $S
done
else # for statelite mode
#wget -l inf -N -r --waitretry=10 --random-wait --retry-connrefused -t 0 -T 60 ftp://$SIP/postscripts 2> /tmp/wget.log
#mv $SIP/install/postscripts/* /xcatpost;
chmod +x /xcatpost/*; # no effect for statelite mode, since the directory are readonly
mv $SIP/postscripts/* /xcatpost;
rm -rf $SIP
fi
cd /xcatpost;
PATH=/xcatpost:$PATH
export PATH
if [ "$MODE" != "4" ]; then
chmod +x /xcatpost/*; # no effect for statelite mode, since the directory are readonly
fi
#echo "PATH=$PATH"
if [ -x /usr/bin/openssl ]; then
XCATSERVER="$SIP:3001"
@ -218,7 +223,6 @@ if [ -x /usr/bin/openssl ]; then
export USEOPENSSLFORXCAT
fi
/xcatpost/getpostscript.awk | sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /tmp/mypostscript;
MYCONT=`grep MASTER /tmp/mypostscript`
#echo "MYCONT=$MYCONT"
@ -236,33 +240,17 @@ while [ -z "$MYCONT" ]; do
let SLI=$RANDOM%10
let SLI=10+$SLI
sleep $SLI
if [ "$MODE" != "4" ]; then
for SIP in $SIPS; do #Attempt against several candidates
if [ -x /usr/bin/openssl ]; then
XCATSERVER="$SIP:3001"
export XCATSERVER
USEOPENSSLFORXCAT=1 #Though this is the only method going forward, flag to allow backward compatibility with 2.2 generated netboot images
export USEOPENSSLFORXCAT
fi
/xcatpost/getpostscript.awk | sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /tmp/mypostscript;
MYCONT=`grep MASTER /tmp/mypostscript`
if [ ! -z "$MYCONT" ]; then
break;
fi
done
else # for statelite mode
/xcatpost/getpostscript.awk | sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /tmp/mypostscript;
MYCONT=`grep MASTER /tmp/mypostscript`
if [ ! -z "$MYCONT" ]; then
break;
fi
/xcatpost/getpostscript.awk | sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /tmp/mypostscript;
MYCONT=`grep MASTER /tmp/mypostscript`
if [ ! -z "$MYCONT" ]; then
break;
fi
# echo "MYCONT=$MYCONT"
done
#save the MASTER into the xcatinfo file for node deployment case,
#for updatenode case, only save it when -M is specified
if [ $argnum -eq 0 ] || [ "$MODE" == "4" ]; then
if [ $NODE_DEPLOYMENT -eq 1 ] || [ "$MODE" == "4" ]; then
new_ms=`grep '^MASTER' /tmp/mypostscript |cut -d= -f2`
fi
if [ -n "$new_ms" ]; then
@ -281,14 +269,17 @@ fi
# when called by the updatenode command
#modify the UPDATENODE flag to 1
if [ $argnum -gt 0 ] && [ "$MODE" != "4" ]; then
if [ "$MODE" == "1" ] || [ "$MODE" == "2" ]; then
TMP=`sed -e 's/UPDATENODE=0/UPDATENODE=1/g' /tmp/mypostscript`;
echo "$TMP" > /tmp/mypostscript;
fi
if [ "$MODE" == "5" ]; then
TMP=`sed -e 's/UPDATENODE=0/UPDATENODE=1\nUPDATESECURITY=1\nexport UPDATESECURITY/g' /tmp/mypostscript`;
echo "$TMP" > /tmp/mypostscript;
fi
# postscript name is specified with the updatenode
if [ $argnum -gt 2 ]; then
POSTS=$3
if [ "XX$POSTSCRIPTS" != "XX" ]; then
#remove all the postbootscripts
TMP=`sed "/postbootscripts-start-here/,/postbootscripts-end-here/ d" /tmp/mypostscript`
echo "$TMP" > /tmp/mypostscript
@ -297,7 +288,7 @@ if [ $argnum -gt 2 ]; then
echo "$TMP" > /tmp/mypostscript
echo "# postscripts-start-here\n" >> /tmp/mypostscript
#add requested postscripts in
echo "$POSTS" | tr "," "\n" >> /tmp/mypostscript
echo "$POSTSCRIPTS" | tr "," "\n" >> /tmp/mypostscript
echo "# postscripts-end-here\n" >> /tmp/mypostscript
fi
@ -332,7 +323,7 @@ echo "$TMP" >> /tmp/mypostscript
TMP=`sed "/postbootscripts-start-here/,/postbootscripts-end-here/ s/\(.*\)/run_ps \1/;s/run_ps\s*#/#/;s/run_ps\s*$//" /tmp/mypostscript`
echo "$TMP" > /tmp/mypostscript
if [ $argnum -eq 0 ] || [ "$MODE" == "4" ]; then
if [ $NODE_DEPLOYMENT -eq 1 ] || [ "$MODE" == "4" ]; then
#notify the server that we are done with netbooting
CNS=`grep NODESTATUS= /tmp/mypostscript |awk -F = '{print $2}'`
if [ -z "$CNS" ] || [ "$CNS" != "'0'" -a "$CNS" != "'N'" -a "$CNS" != "'n'" ]; then
@ -355,7 +346,7 @@ if [ "$MODE" == "4" ]; then
fi
#tell user it is done when this is called by updatenode command
if [ $argnum -gt 0 ] && [ "$MODE" != "4" ]; then
if [ "$MODE" == "1" ] || [ "$MODE" == "2" ] || [ "$MODE" == "5" ]; then
echo "returned from postscript"
fi