added feature to install extra 3rd party rpms during cluster install process or after the fact (usning updatenode command).

git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@2099 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
linggao 2008-09-08 18:54:30 +00:00
parent 7a658e6816
commit 6ff1602d8e
4 changed files with 489 additions and 3 deletions

View File

@ -5,6 +5,12 @@ use xCAT::MsgUtils;
use xCAT::NodeRange;
use Data::Dumper;
use strict;
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr';
}
use lib "$::XCATROOT/lib/perl";
#-------------------------------------------------------------------------------
=head1 Postage
@ -158,15 +164,22 @@ sub makescript {
return undef;
}
}
my $os;
my $profile;
my $arch;
if ($et->{'os'}) {
$os=$et->{'os'};
push @scriptd, "OSVER=".$et->{'os'}."\n";
push @scriptd, "export OSVER\n";
}
if ($et->{'arch'}) {
$arch=$et->{'arch'};
push @scriptd, "ARCH=".$et->{'arch'}."\n";
push @scriptd, "export ARCH\n";
}
if ($et->{'profile'}) {
$profile=$et->{'profile'};
push @scriptd, "PROFILE=".$et->{'profile'}."\n";
push @scriptd, "export PROFILE\n";
}
@ -198,12 +211,58 @@ sub makescript {
push @scriptd, "export $_\n";
}
#get packge names for extra rpms
if ($profile) {
my $platform="rh";
if ($os) {
if ($os =~ /rh.*/) { $platform = "rh"; }
elsif ($os =~ /centos.*/) { $platform = "centos"; }
elsif ($os =~ /fedora.*/) { $platform = "fedora"; }
elsif ($os =~ /sles.*/) { $platform = "sles"; }
elsif ($os =~ /aix.*/) { $platform = "aix"; }
}
my $stat="install";
if (($nodesetstate) && ($nodesetstate eq "netboot")) { $stat="netboot";}
my $pathtofiles="$::XCATROOT/share/xcat/$stat/$platform";
my $pkglist;
if (-r "$pathtofiles/$profile.$os.$arch.otherrpms.pkglist") {
$pkglist = "$pathtofiles/$profile.$os.$arch.otherrpms.pkglist";
} elsif (-r "$pathtofiles/$profile.$arch.otherrpms.pkglist") {
$pkglist = "$pathtofiles/$profile.$arch.otherrpms.pkglist";
} elsif (-r "$pathtofiles/$profile.$os.otherrpms.pkglist") {
$pkglist = "$pathtofiles/$profile.$os.otherrpms.pkglist";
} elsif (-r "$pathtofiles/$profile.otherrpms.pkglist") {
$pkglist = "$pathtofiles/$profile.otherrpms.pkglist";
}
if ($pkglist) {
my @otherrpms=();
if (open(FILE1, "<$pkglist")) {
while (readline(FILE1)) {
chomp($_);
push(@otherrpms,$_);
}
close(FILE1);
}
if ( @otherrpms > 0) {
push @scriptd, "OTHERRPMS=". join(',',@otherrpms) . " \n";
push @scriptd, "export OTHERRPMS\n";
}
}
}
###Please do not remove or modify this line of code!!! xcatdsklspost depends on it
push @scriptd, "# postscripts-start-here\n";
my $hasotherrpms=0;
# get the xcatdefaults entry in the postscripts table
my $et = $posttab->getAttribs({node=>"xcatdefaults"},'postscripts');
my $defscripts = $et->{'postscripts'};
if ($defscripts) {
foreach my $n (split(/,/, $defscripts)) {
push @scriptd, $n."\n";
if ((!$hasotherrpms) && ($n eq "otherrpms")) { $hasotherrpms =1;}
push @scriptd, $n."\n";
}
}
@ -212,10 +271,16 @@ sub makescript {
$ps = $et->{'postscripts'};
if ($ps) {
foreach my $n (split(/,/, $ps)) {
if ((!$hasotherrpms) && ($n eq "otherrpms")) { $hasotherrpms =1;}
push @scriptd, $n."\n";
}
}
if (!$hasotherrpms) { push @scriptd, "otherrpms\n";}
###Please do not remove or modify this line of code!!! xcatdsklspost depends on it
push @scriptd, "# postscripts-end-here\n";
return @scriptd;
}

View File

@ -0,0 +1,323 @@
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
package xCAT_plugin::updatenode;
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
use strict;
use warnings;
use xCAT::Table;
use xCAT::Schema;
use Data::Dumper;
use xCAT::NodeRange;
use xCAT::Utils;
use Getopt::Long;
use xCAT::GlobalDef;
use Sys::Hostname;
1;
#-------------------------------------------------------------------------------
=head1 xCAT_plugin:updatenode
=head2 Package Description
xCAT plug-in module. It handles the updatenode command.
=cut
#------------------------------------------------------------------------------
#--------------------------------------------------------------------------------
=head3 handled_commands
It returns a list of commands handled by this plugin.
Arguments:
none
Returns:
a list of commands.
=cut
#--------------------------------------------------------------------------------
sub handled_commands
{
return {
updatenode => "updatenode"};
}
#-------------------------------------------------------
=head3 preprocess_request
Check and setup for hierarchy
=cut
#-------------------------------------------------------
sub preprocess_request
{
my $request = shift;
my $callback = shift;
my $command = $request->{command}->[0];
if ($request->{_xcatdest}) { return [$request]; } #exit if preprocessed
my @requests=();
if ($command eq "updatenode")
{
return preprocess_updatenode($request, $callback);
}
else {
my $rsp={};
$rsp->{data}->[0]= "unsupported command: $command.";
$callback->($rsp);
return \@requests;
}
}
#--------------------------------------------------------------------------------
=head3 process_request
It processes the monitoring control commands.
Arguments:
request -- a hash table which contains the command name and the arguments.
callback -- a callback pointer to return the response to.
Returns:
0 for success. The output is returned through the callback pointer.
1. for unsuccess. The error messages are returns through the callback pointer.
=cut
#--------------------------------------------------------------------------------
sub process_request
{
my $request = shift;
my $callback = shift;
my $command = $request->{command}->[0];
my $localhostname=hostname();
if ($command eq "updatenode")
{
return updatenode($request, $callback);
}
else {
my $rsp={};
$rsp->{data}->[0]= "$localhostname: unsupported command: $command.";
$callback->($rsp);
return 1;
}
}
#--------------------------------------------------------------------------------
=head3 preprocess_updatenode
This function checks for the syntax of the updatenode command
and distribute the command to the right server.
Arguments:
request - the request. The request->{arg} is of the format:
[-h|--help|-v|--version] or
[noderange [postscripts]]
callback - the pointer to the callback function.
Returns:
A pointer to an array of requests.
=cut
#--------------------------------------------------------------------------------
sub preprocess_updatenode {
my $request = shift;
my $callback = shift;
my $args=$request->{arg};
my @requests=();
# subroutine to display the usage
sub updatenode_usage
{
my $cb=shift;
my $rsp={};
$rsp->{data}->[0]= "Usage:";
$rsp->{data}->[1]= " updaenode [noderange [posts]]";
$rsp->{data}->[2]= " updaenode [-h|--help|-v|--version]";
$rsp->{data}->[3]= " noderange is a list of nodes or groups. '\\\*' for all.";
$rsp->{data}->[4]= " posts is a groups of postscript names separated by comma.";
$rsp->{data}->[5]= " if omitted, all the postscripts will be run.";
$cb->($rsp);
}
@ARGV=();
if ($args) {
@ARGV=@{$args};
}
# parse the options
Getopt::Long::Configure("bundling");
Getopt::Long::Configure("no_pass_through");
if(!GetOptions(
'h|help' => \$::HELP,
'v|version' => \$::VERSION))
{
&updatenode_usage($callback);
return \@requests;;
}
# display the usage if -h or --help is specified
if ($::HELP) {
&updatenode_usage($callback);
return \@requests;;
}
# display the version statement if -v or --verison is specified
if ($::VERSION)
{
my $rsp={};
$rsp->{data}->[0]= xCAT::Utils->Version();
$callback->($rsp);
return \@requests;
}
my @nodes;
my $postscripts;
my $bGetAll=0;
if (@ARGV > 0) {
my $noderange=$ARGV[0];
if ($noderange eq '*') { $bGetAll=1;}
else {
@nodes = noderange($noderange);
if (nodesmissed) {
my $rsp={};
$rsp->{data}->[0]= "Invalid nodes in noderange:".join(',',nodesmissed);
$callback->($rsp);
return \@requests;
}
}
} else { #get all nodes
$bGetAll=1;
}
if ($bGetAll) {
@nodes=getAllNodes($callback);
}
if (@nodes == 0) { return \@requests; }
if (@ARGV > 1) {
$postscripts=$ARGV[1];
my @posts=split(',',$postscripts);
foreach (@posts) {
if ( ! -e "/install/postscripts/$_") {
my $rsp={};
$rsp->{data}->[0]= "The postcript /install/postscripts/$_ does not exist.";
$callback->($rsp);
return \@requests;
}
}
}
if (@nodes>0) {
# find service nodes for requested nodes
# build an individual request for each service node
my $sn = xCAT::Utils->get_ServiceNode(\@nodes, "xcat", "MN");
# build each request for each service node
foreach my $snkey (keys %$sn)
{
my $reqcopy = {%$request};
$reqcopy->{nodes} = $sn->{$snkey};
$reqcopy->{'_xcatdest'} = $snkey;
$reqcopy->{postscripts} = [$postscripts];
push @requests, $reqcopy;
}
return \@requests;
}
return \@requests;
}
#--------------------------------------------------------------------------------
=head3 updatenode
This function implements the updatenode command.
Arguments:
request - the request.
callback - the pointer to the callback function.
Returns:
0 for success. The output is returned through the callback pointer.
1. for unsuccess. The error messages are returns through the callback pointer.
=cut
#--------------------------------------------------------------------------------
sub updatenode {
my $request = shift;
my $callback = shift;
my $postscripts="";
if (($request->{postscripts}) && ($request->{postscripts}->[0])) { $postscripts=$request->{postscripts}->[0];}
my $nodes =$request->{nodes};
my $localhostname=hostname();
my $nodestring=join(',', @$nodes);
#print "postscripts=$postscripts\n";
if ($nodestring) {
my $output=`XCATBYPASS=Y $::XCATROOT/bin/xdsh $nodestring -e /install/postscripts/xcatdsklspost $postscripts`;
my $rsp={};
$rsp->{data}->[0]= "$output\n";
$callback->($rsp);
}
return 0;
}
#--------------------------------------------------------------------------------
=head3 getAllNodes
This function gets all the nodes that has 'OSI' has nodetype.
Arguments:
callback
Returns:
an array of nodes
=cut
#--------------------------------------------------------------------------------
sub getAllNodes
{
my $callback =shift;
my @nodes=();
my $table=xCAT::Table->new("nodelist", -create =>0);
if (!$table) {
my $rsp={};
$rsp->{data}->[0]= "Cannot open the nodelist table.";
$callback->($rsp);
return @nodes;
}
my @tmp1=$table->getAllAttribs(('node'));
my $table3=xCAT::Table->new("nodetype", -create =>0);
if (!$table3) {
my $rsp={};
$rsp->{data}->[0]= "Cannot open the nodetype table.";
$callback->($rsp);
return @nodes;
}
my @tmp3=$table3->getAllNodeAttribs(['node','nodetype']);
my %temp_hash3=();
foreach (@tmp3) {
$temp_hash3{$_->{node}}=$_;
}
if (@tmp1 > 0) {
foreach(@tmp1) {
my $node=$_->{node};
my $row3=$temp_hash3{$node};
my $nodetype=""; #default
if (defined($row3) && ($row3)) {
if ($row3->{nodetype}) { $nodetype=$row3->{nodetype}; }
}
#only handle the OSI nodetype
if (($nodetype) && ($nodetype =~ /$::NODETYPE_OSI/)) {
push(@nodes, $node);
}
}
}
$table->close();
$table3->close();
return @nodes;
}

70
xCAT/postscripts/otherrpms Executable file
View File

@ -0,0 +1,70 @@
#!/bin/sh
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
#-------------------------------------------------------------------------------
#=head1 otherrpms
#=head2 It gets the extra rpms and install/update them.
# The environment variable OTHERRPMS contains the rpms to be installed/updated.
# On MN, You need to:
# 1. put rpms under /install/post/otherrpms/os/arch directory where 'os' and 'arch'
# can be found in the nodetype table.
# 2. put the name of the packages to /opt/xcat/share/xcat/netboot(install)/platform
# directory. The file name is one of the following:
# profile.os.arch.otherrpms.pkglist
# profile.os.otherrpms.pkglist
# profile.arch.otherrpms.pkglist
# profile.otherrpms.pkglist
# The install/deployment process will pick up the rpms and install them on the nodes.
# However, if the nodes have already installed and up and running, you can run the following
# command to have the extra rpms installed:
# updatenode noderange otherrpms
#
#=cut
#-------------------------------------------------------------------------------
#echo "OTHERRPMS=$OTHERRPMS"
if [[ -z "$OTHERRPMS" ]]; then
echo "$0: no extra rpms to install"
exit 0
fi
SIP=`grep -h dhcp-server-identifier /var/lib/dhclient/dhclient-*.leases|tail -n 1|awk '{print $3}'|sed -e 's/;//'`
if [ -z "$SIP" ]; then
SIP=`grep -h DHCPSID /var/lib/dhcpcd/*.info|awk -F= '{print $2}'|tail -n 1`
fi
mkdir -p /xcatpost/post/otherrpms;
mkdir -p /tmp/postage/
rm -f -R /xcatpost/post/otherrpms/*
rm -f -R /tmp/postage/*
cd /tmp/postage
for x in `echo "$OTHERRPMS" | tr "," "\n"`
do
wget -l inf -N -r --waitretry=10 --random-wait --retry-connrefused -t 0 -T 60 ftp://$SIP/post/otherrpms/$OSVER/$ARCH/$x-* 2> /tmp/wget.log
done
mv $SIP/post/otherrpms/* /xcatpost/post/otherrpms;
rm -rf $SIP
cd /xcatpost/post/otherrpms/$OSVER/$ARCH
rpm -Uvh *
exit 0

View File

@ -19,6 +19,7 @@ if [ -z "$SIP" ]; then
SIP=`grep -h DHCPSID /var/lib/dhcpcd/*.info|awk -F= '{print $2}'|tail -n 1`
fi
#echo "SIP=$SIP"
if grep 'rw /rw tmpfs ' /proc/mounts >& /dev/null; then
touch /var/lock/subsys/xcatmounts
@ -36,6 +37,7 @@ cat > /etc/stunnel/stunnel.conf << EOF
client=yes
foreground=no
output=/dev/null
#output=/var/log/stunnel.log
verify=0
[xcatd]
accept=400
@ -44,7 +46,10 @@ echo "connect=$SIP:3001" >> /etc/stunnel/stunnel.conf
stunnel;
sleep 1;
mkdir -p /xcatpost;
mkdir /tmp/postage
mkdir -p /tmp/postage
rm -R -f /xcatpost/*
rm -R -f /tmp/postage/*
cd /tmp/postage
#wget -l inf -N -r --waitretry=10 --random-wait --retry-connrefused -t 0 -T 60 ftp://$SIP/install/postscripts 2> /tmp/wget.log
wget -l inf -N -r --waitretry=10 --random-wait --retry-connrefused -t 0 -T 60 ftp://$SIP/postscripts 2> /tmp/wget.log
@ -54,16 +59,30 @@ rm -rf $SIP
cd /xcatpost;
PATH=/xcatpost:$PATH
export PATH
chmod +x /xcatpost/*;
chmod +x /xcatpost/*;
echo "PATH=$PATH"
/xcatpost/getpostscript.awk | sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /tmp/mypostscript;
MYCONT=`cat /tmp/mypostscript`
#echo "MYCONT=$MYCONT"
while [ -z "$MYCONT" ]; do
let SLI=$RANDOM%10
let SLI=10+$SLI
sleep $SLI
/xcatpost/getpostscript.awk | sed -e 's/<[^>]*>//g'|egrep -v '^ *$'|sed -e 's/^ *//' > /tmp/mypostscript;
MYCONT=`cat /tmp/mypostscript`
# echo "MYCONT=$MYCONT"
done
if [ $# -gt 0 ]; then
POSTS=$1
#remove all the postscripts
TMP=`sed "/postscripts-start-here/,/postscripts-end-here/ d" /tmp/mypostscript`
echo "$TMP" > /tmp/mypostscript
#add requested postscripts in
echo "$POSTS" | tr "," "\n" >> /tmp/mypostscript
fi
#MYCONT=`cat /tmp/mypostscript`
#echo "$MYCONT"
chmod +x /tmp/mypostscript
if [ -x /tmp/mypostscript ];then
/tmp/mypostscript
@ -71,3 +90,12 @@ fi
rm -f /tmp/mypostscript
killall stunnel
rm -rf /etc/stunnel