Revision: 2099
http://xcat.svn.sourceforge.net/xcat/?rev=2099&view=rev
Author: linggao
Date: 2008-09-08 18:54:30 +0000 (Mon, 08 Sep 2008)
Log Message:
-----------
added feature to install extra 3rd party rpms during cluster install process or after the fact (usning updatenode command).
Modified Paths:
--------------
xcat-core/trunk/perl-xCAT/xCAT/Postage.pm
xcat-core/trunk/xCAT/postscripts/xcatdsklspost
Added Paths:
-----------
xcat-core/trunk/xCAT/postscripts/otherrpms
xcat-core/trunk/xCAT-server/lib/xcat/plugins/updatenode.pm
Modified: xcat-core/trunk/perl-xCAT/xCAT/Postage.pm
===================================================================
--- xcat-core/trunk/perl-xCAT/xCAT/Postage.pm 2008-09-08 16:47:01 UTC (rev 2098)
+++ xcat-core/trunk/perl-xCAT/xCAT/Postage.pm 2008-09-08 18:54:30 UTC (rev 2099)
@@ -5,6 +5,12 @@
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 @@
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 @@
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 @@
$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;
}
Added: xcat-core/trunk/xCAT/postscripts/otherrpms
===================================================================
--- xcat-core/trunk/xCAT/postscripts/otherrpms (rev 0)
+++ xcat-core/trunk/xCAT/postscripts/otherrpms 2008-09-08 18:54:30 UTC (rev 2099)
@@ -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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Property changes on: xcat-core/trunk/xCAT/postscripts/otherrpms
___________________________________________________________________
Added: svn:executable
+ *
Modified: xcat-core/trunk/xCAT/postscripts/xcatdsklspost
===================================================================
--- xcat-core/trunk/xCAT/postscripts/xcatdsklspost 2008-09-08 16:47:01 UTC (rev 2098)
+++ xcat-core/trunk/xCAT/postscripts/xcatdsklspost 2008-09-08 18:54:30 UTC (rev 2099)
@@ -19,6 +19,7 @@
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 @@
client=yes
foreground=no
output=/dev/null
+#output=/var/log/stunnel.log
verify=0
[xcatd]
accept=400
@@ -44,7 +46,10 @@
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 @@
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 @@
rm -f /tmp/mypostscript
killall stunnel
rm -rf /etc/stunnel
+
+
+
+
+
+
+
+
+
Added: xcat-core/trunk/xCAT-server/lib/xcat/plugins/updatenode.pm
===================================================================
--- xcat-core/trunk/xCAT-server/lib/xcat/plugins/updatenode.pm (rev 0)
+++ xcat-core/trunk/xCAT-server/lib/xcat/plugins/updatenode.pm 2008-09-08 18:54:30 UTC (rev 2099)
@@ -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;
+}
+
+
+
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|