#!/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; use strict; 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(); my $data; # allows our plugins to get the stdin of the cmd that invoked the plugin if ((($^O =~ /^linux/i) && ($ENV{'SHELL'} =~ /\/ksh$/)) || !defined($ENV{'TERM'})) { my $rin = ""; my $rout; vec($rin, fileno(STDIN), 1) = 1; my $nfound = select($rout = $rin, "", "", 1); if ($nfound) { while () { $data .= $_; } $cmdref->{stdin}->[0] = $data; } } else { if (-p STDIN) { while () { $data .= $_; } $cmdref->{stdin}->[0] = $data; } } Getopt::Long::Configure("posix_default"); Getopt::Long::Configure("no_gnu_compat"); Getopt::Long::Configure("bundling"); my $tmp = " " . join(' ', @ARGV); if (!($tmp =~ / (--help|-h|-v|--version)/)) { my $arg = shift(@ARGV); # Set the noderange if ($arg and $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 { &updatenode_usage(); print "The noderange should be the first argument.\n"; exit 1; } } push(@{ $cmdref->{arg} }, @ARGV); # check the syntax my ($ALLSW, $CMDLINE, $ALTSRC, $HELP, $VERSION, $VERBOSE, $FILESYNC, $GENMYPOST, $USER, $SNFILESYNC, $SWMAINTENANCE, $SETSERVER, $RERUNPS, $SECURITY, $OS, $fanout, $timeout, $NOVERIFY,$RCP); if ( !GetOptions( 'A|updateallsw' => \$ALLSW, 'c|cmdlineonly' => \$CMDLINE, 'd=s' => \$ALTSRC, 'h|help' => \$HELP, 'v|version' => \$VERSION, 'V|verbose' => \$VERBOSE, 'F|sync' => \$FILESYNC, 'g|genmypost' => \$GENMYPOST, 'f|snsync' => \$SNFILESYNC, 'l|user=s' => \$USER, 'S|sw' => \$SWMAINTENANCE, 's|sn' => \$SETSERVER, 'P|scripts:s' => \$RERUNPS, 'k|security' => \$SECURITY, 'o|os=s' => \$OS, 'fanout=i' => \$fanout, 't|timetout=i' => \$timeout, 'n|noverify' => \$NOVERIFY, 'r|node-rcp' => \$RCP, ) ) { &updatenode_usage(); exit 1; } if ($HELP) { &updatenode_usage(); exit 0; } if (($USER) && ($SECURITY)) { my $msg = "-l option is not allowed with -k option."; xCAT::MsgUtils->message("E", $msg); exit 1; } if (($USER) && ($SNFILESYNC)) { my $msg = "-l option is not allowed with -f options."; xCAT::MsgUtils->message("E", $msg); exit 1; } # display the version statement if -v or --verison is specified if ($VERSION) { my $version = xCAT::Utils->Version(); print "$version\n"; exit 0; } if (($FILESYNC) && ($SNFILESYNC)) { # only one my $msg = "Choose either -f to sync the service nodes, or -F to sync the nodes not both."; xCAT::MsgUtils->message("E", $msg); exit 1; } if (($SECURITY) && (($SWMAINTENANCE) || defined($RERUNPS) || ($FILESYNC) || ($SNFILESYNC))) { my $msg = "If you use the -k flag, you cannot specify the -S,-P,-f or -F flags."; xCAT::MsgUtils->message("E", $msg); exit 1; } if ($SNFILESYNC && ($SWMAINTENANCE || defined($RERUNPS) || $SECURITY || $FILESYNC)) { my $msg = "If you specify the -f flag you must not specify either the -S or -k or -P or -F flags"; xCAT::MsgUtils->message("E", $msg); exit 1; } # determine who is running the command on the client and who we will run as # on the node my $current_userid = getpwuid($>); $ENV{DSH_FROM_USERID} = $current_userid; my $to_userid; if ($USER) # entered -l { $to_userid = $USER; } else { $to_userid = $current_userid; } $ENV{DSH_TO_USERID} = $to_userid; # if -k then we have to get the password 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 = "The ssh keys will be updated for '$to_userid' on the node(s).\nPassword:"; xCAT::MsgUtils->message("I", $msg); system("stty -echo"); # turn off keyboard chop($userpw = ); 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) { if (/^DSH_/ || /^XCAT/) { push @{ $cmdref->{environment} }, "$_=$ENV{$_}"; } } # Allow to print server information when -V/--verbose foreach (reverse(@ARGV)) { if ($_ eq '-V' || $_ eq '--verbose') { $ENV{'XCATSHOWSVR'} = 1; last; } } xCAT::Client::submit_request($cmdref, \&xCAT::Client::handle_response); exit $xCAT::Client::EXITCODE;