2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-07-03 14:32:12 +00:00

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

This commit is contained in:
Jia Zhao
2013-10-10 15:27:41 +08:00
124 changed files with 6103 additions and 1338 deletions
-14
View File
@@ -1,14 +0,0 @@
xCAT - eXtreme Cloud Administration Toolkit
xCAT is a toolkit for the deployment and administration of clusters.
xCAT documentation is available at: http://xcat.sourceforge.net/
xCAT is made available as open source software under the EPL license:
http://www.opensource.org/licenses/eclipse-1.0.php
+12 -7
View File
@@ -43,6 +43,10 @@ printusage()
# Process cmd line variable assignments, assigning each attr=val pair to a variable of same name
for i in $*; do
echo $i | grep '='
if [ $? != 0 ];then
continue
fi
# upper case the variable name
varstring=`echo "$i"|cut -d '=' -f 1|tr '[a-z]' '[A-Z]'`=`echo "$i"|cut -d '=' -f 2`
export $varstring
@@ -167,6 +171,7 @@ then
short_ver=`cat Version|cut -d. -f 1,2`
short_short_ver=`cat Version|cut -d. -f 1`
package_dir_name=debs$REL
#TODO: define the core path and tarball name
tarball_name="core-debs-snap.tar.bz2"
@@ -186,8 +191,8 @@ then
cur_date=`date +%Y%m%d`
pkg_version="${short_ver}-${pkg_type}${cur_date}"
if [ ! -d ../../debs ];then
mkdir -p "../../debs"
if [ ! -d ../../$package_dir_name ];then
mkdir -p "../../$package_dir_name"
fi
packages="xCAT-client xCAT-genesis-scripts perl-xCAT xCAT-server xCAT-UI xCAT xCATsn xCAT-test xCAT-OpenStack"
@@ -195,9 +200,9 @@ then
do
file_low=`echo $file | tr '[A-Z]' '[a-z]'`
if grep -q $file $update_log || [ "$BUILDALL" == 1 -o "$file" = "perl-xCAT" ]; then
rm -f ../../debs/${file_low}_*.deb
rm -f ../../$package_dir_name/${file_low}_*.deb
#only for genesis package
rm -f ../../debs/${file_low}-amd64_*.deb
rm -f ../../$package_dir_name/${file_low}-amd64_*.deb
cd $file
dch -v $pkg_version -b -c debian/changelog $build_string
dpkg-buildpackage -uc -us
@@ -208,11 +213,11 @@ then
cd -
find $file -maxdepth 3 -type d -name "${file_low}*" | grep debian | xargs rm -rf
find $file -maxdepth 3 -type f -name "files" | grep debian | xargs rm -rf
mv ${file_low}* ../../debs/
mv ${file_low}* ../../$package_dir_name/
fi
done
find ../../debs/* ! -name *.deb | xargs rm -f
find ../../$package_dir_name/* ! -name *.deb | xargs rm -f
fi
if [ "$PROMOTE" = 1 ]; then
@@ -256,7 +261,7 @@ __EOF__
#import the deb packages into the repo
for dist in $dists; do
for file in `ls ../debs/*.deb`; do
for file in `ls ../$package_dir_name/*.deb`; do
reprepro -b ./ includedeb $dist $file;
done
done
+29 -21
View File
@@ -85,6 +85,21 @@ if [ "$OSNAME" != "AIX" ]; then
export HOME=/root # This is so rpm and gpg will know home, even in sudo
fi
# for the git case, query the current branch and set REL (changing master to devel if necessary)
function setbranch {
#git checkout $BRANCH
#REL=`git rev-parse --abbrev-ref HEAD`
REL=`git name-rev --name-only HEAD`
if [ "$REL" = "master" ]; then
REL="devel"
fi
}
if [ "$REL" = "xcat-core" ]; then # using git
GIT=1
setbranch # this changes the REL variable
fi
YUMDIR=$FRS
YUMREPOURL="https://sourceforge.net/projects/xcat/files/yum"
@@ -112,7 +127,11 @@ fi
XCATCORE="xcat-core" # core-snap is a sym link to xcat-core
DESTDIR=../..$EMBEDDIR/$XCATCORE
if [ "$GIT" = "1" ]; then # using git - need to include REL in the path where we put the built rpms
DESTDIR=../../$REL$EMBEDDIR/$XCATCORE
else
DESTDIR=../..$EMBEDDIR/$XCATCORE
fi
SRCD=core-snap-srpms
# currently aix builds ppc rpms, but someday it should build noarch
@@ -122,6 +141,12 @@ else
NOARCH=noarch
fi
function setversionvars {
VER=`cat Version`
SHORTVER=`cat Version|cut -d. -f 1,2`
SHORTSHORTVER=`cat Version|cut -d. -f 1`
}
if [ "$PROMOTE" != 1 ]; then # very long if statement to not do builds if we are promoting
# we are doing a snap build
@@ -151,20 +176,9 @@ else
#echo "source=$source"
fi
# for the git case, query the current branch and set REL (changing master to devel if necessary)
function setbranch {
#git checkout $BRANCH
REL=`git rev-parse --abbrev-ref HEAD`
if [ "$REL" = "master" ]; then
REL="devel"
fi
}
# If they have not given us a premade update file, do an svn update or git pull and capture the results
SOMETHINGCHANGED=0
if [ "$REL" = "xcat-core" ]; then # using git
GIT=1
setbranch
if [ "$GIT" = "1" ]; then # using git
if [ -z "$GITUP" ]; then
GITUP=../coregitup
echo "git pull > $GITUP"
@@ -187,12 +201,6 @@ else # using svn
GITUP=$SVNUP
fi
function setversionvars {
VER=`cat Version`
SHORTVER=`cat Version|cut -d. -f 1,2`
SHORTSHORTVER=`cat Version|cut -d. -f 1`
}
setversionvars
# Function for making the noarch rpms
@@ -342,8 +350,8 @@ if [ "$OSNAME" != "AIX" ]; then
echo "Signing RPMs..."
build-utils/rpmsign.exp `find $DESTDIR -type f -name '*.rpm'` | grep -v -E '(was already signed|rpm --quiet --resign|WARNING: standard input reopened)'
build-utils/rpmsign.exp $SRCDIR/*rpm | grep -v -E '(was already signed|rpm --quiet --resign|WARNING: standard input reopened)'
createrepo $DESTDIR
createrepo $SRCDIR
createrepo --checksum sha $DESTDIR # specifying checksum so the repo will work on rhel5
createrepo --checksum sha $SRCDIR
rm -f $SRCDIR/repodata/repomd.xml.asc
rm -f $DESTDIR/repodata/repomd.xml.asc
gpg -a --detach-sign $DESTDIR/repodata/repomd.xml
+2 -2
View File
@@ -103,9 +103,9 @@ if [ "$OSNAME" != "AIX" ]; then
echo "Creating repodata directories..."
for i in `find -mindepth 2 -maxdepth 2 -type d `; do
if [ -n "$VERBOSEMODE" ]; then
createrepo $i
createrepo --checksum sha $i # specifying checksum so the repo will work on rhel5
else
createrepo $i >/dev/null
createrepo --checksum sha $i >/dev/null
fi
rm -f $i/repodata/repomd.xml.asc
gpg -a --detach-sign $i/repodata/repomd.xml
+7 -17
View File
@@ -235,24 +235,13 @@ sub setCFMSynclistFile {
# get the cfmdir and synclists attributes
my $osimage_t = xCAT::Table->new('osimage');
my $records = $osimage_t->getAttribs({imagename=>$img}, 'cfmdir', 'synclists');
if ($records)
if (defined ($records->{'cfmdir'}))
{
if ($records->{'cfmdir'}) {$cfmdir = $records->{'cfmdir'}}
if ($records->{'synclists'}) {$synclists = $records->{'synclists'}}
$cfmdir = $records->{'cfmdir'};
if (defined ($records->{'synclists'})) {$synclists = $records->{'synclists'}}
} else {
if ($::VERBOSE)
{
my $rsp = {};
$rsp->{data}->[0] = "There are no records for cfmdir and synclists attribute in the osimage:$img. There is nothing to process.";
xCAT::MsgUtils->message("I", $rsp, $::CALLBACK);
}
return;
}
# no cfmdir defined, return directly
if (!$cfmdir)
{
return;
# no cfmdir defined, return directly
return 0;
}
my $found = 0;
@@ -374,7 +363,8 @@ sub updateCFMSynclistFile {
# recursively list the files under cfm directory
my @files = ();
find ( sub { push @files, $File::Find::name if (! -d) }, $cfmdir);
find ( { wanted => sub { push @files, $File::Find::name if -f }, follow => 1 }, $cfmdir);
if (!@files) # not files under cfm directory, skip to next loop
{
next;
+10
View File
@@ -231,6 +231,16 @@ if (ref($request) eq 'HASH') { # the request is an array, not pure XML
Timeout => 0,
);
}
unless ($client) {
print "Unable to open socket connection to xcatd daemon on $xcathost.\n";
print "Verify that the xcatd daemon is running and that your SSL setup is correct.\n";
if ($@ =~ /SSL Timeout/) {
die "Connection failure: SSL Timeout or incorrect certificates in ~/.xcat";
} else {
die "Connection failure: $@"
}
}
my $msg;
if (ref($request) eq 'HASH') { # the request is an array, not pure XML
$msg=XMLout($request,RootName=>'xcatrequest',NoAttr=>1,KeyAttr=>[]);
+1 -1
View File
@@ -4185,7 +4185,7 @@ sub parse_and_run_dsh
#
# setup ssh keys on the nodes or ib switch
#
my $rc = xCAT::TableUtils->setupSSH($options{'nodes'});
my $rc = xCAT::TableUtils->setupSSH($options{'nodes'},$options{'timeout'});
my @results = "return code = $rc";
return (@results);
}
+9 -1
View File
@@ -368,11 +368,19 @@ sub fsp_api_action {
} elsif( $parameter !=0 && $action =~ /^(on|reset)$/ ) {
#powerinterval for lpars power on
$cmd = "$fsp_api -a $action -i $parameter -T $tooltype -t $type:$fsp_ip:$id:$node_name:";
} elsif ($action =~ /^part_set_lpar_def_state$/) {
$cmd = "$fsp_api -a $action -T $tooltype -s $parameter -t $type:$fsp_ip:$id:$node_name:";
} elsif (exists($request->{opt}->{vios})) {
$cmd = "$fsp_api -a $action -T $tooltype -s 1 -t $type:$fsp_ip:$id:$node_name:$parameter";
} else {
$cmd = "$fsp_api -a $action -T $tooltype -t $type:$fsp_ip:$id:$node_name:$parameter";
}
} else {
$cmd = "$fsp_api -a $action -T $tooltype -t $type:$fsp_ip:$id:$node_name:";
if (exists($request->{opt}->{vios})) {
$cmd = "$fsp_api -a $action -T $tooltype -s 1 -t $type:$fsp_ip:$id:$node_name:";
} else {
$cmd = "$fsp_api -a $action -T $tooltype -t $type:$fsp_ip:$id:$node_name:";
}
}
}
xCAT::MsgUtils->verbose_message($request, "fsp_api_action cmd:$cmd.");
+30 -3
View File
@@ -13,6 +13,7 @@ use xCAT::GlobalDef;
use xCAT::Usage;
use xCAT::NetworkUtils;
use xCAT::FSPUtils;
require xCAT::data::ibmhwtypes;
#use Data::Dumper;
##############################################
@@ -391,6 +392,7 @@ sub format_stanza {
#################################
# Add each attribute
#################################
my $mtm = undef;
foreach ( @attribs ) {
my $d = $data[$i++];
@@ -401,7 +403,8 @@ sub format_stanza {
} elsif ( /^hwtype$/ ) {
$d = $globalhwtype{$type};
} elsif ( /^groups$/ ) {
$d = "$type,all";
next;
#$d = "$type,all";
} elsif ( /^mgt$/ ) {
$d = $hwtype;
} elsif ( /^cons$/ ) {
@@ -414,7 +417,9 @@ sub format_stanza {
} elsif ( /^(mtm|serial)$/ ) {
if ( $type eq "lpar" ) {
$d = undef;
}
} elsif (/^mtm$/) {
$mtm = $d;
}
} elsif (/^side$/) {
unless ( $type =~ /^fsp|bpa$/ ) {
next;
@@ -422,6 +427,15 @@ sub format_stanza {
}
$result .= "\t$_=$d\n";
}
my $tmp_groups = "$type,all";
if (defined($mtm)) {
my $tmp_pre = xCAT::data::ibmhwtypes::parse_group($mtm);
if (defined($tmp_pre)) {
$tmp_groups .= ",$tmp_pre";
}
}
$result .= "\tgroups=$tmp_groups\n";
}
return( $result );
}
@@ -464,6 +478,7 @@ sub format_xml {
#################################
# Add each attribute
#################################
my $mtm = undef;
foreach ( @attribs ) {
my $d = $data[$i++];
@@ -472,7 +487,8 @@ sub format_xml {
} elsif ( /^hwtype$/ ) {
$d = $globalhwtype{$type};
} elsif ( /^groups$/ ) {
$d = "$type,all";
next;
#$d = "$type,all";
} elsif ( /^mgt$/ ) {
$d = $hwtype;
} elsif ( /^cons$/ ) {
@@ -484,6 +500,8 @@ sub format_xml {
} elsif ( /^(mtm|serial)$/ ) {
if ( $type eq "lpar" ) {
$d = undef;
} elsif (/^mtm$/) {
$mtm = $d;
}
} elsif (/^side$/) {
unless ( $type =~ /^fsp|bpa$/ ) {
@@ -492,6 +510,15 @@ sub format_xml {
}
$href->{Node}->{$_} = $d;
}
my $tmp_groups = "$type,all";
if (defined($mtm)) {
my $tmp_pre = xCAT::data::ibmhwtypes::parse_group($mtm);
if (defined($tmp_pre)) {
$tmp_groups .= ",$tmp_pre";
}
}
$href->{Node}->{groups}=$tmp_groups;
#print Dumper($href);
#################################
# XML encoding
+628 -53
View File
@@ -51,6 +51,8 @@ sub parse_args {
sub chvm_parse_extra_options {
my $args = shift;
my $opt = shift;
# Partition used attributes #
my @support_ops = qw(vmcpus vmmemory vmphyslots vmothersetting);
if (ref($args) ne 'ARRAY') {
return "$args";
}
@@ -71,7 +73,20 @@ sub chvm_parse_extra_options {
# if ($value !~ /^\d+\/\d+\/\d+$/) {
# return "'$value' invalid";
# }
} else {
} elsif (grep(/^$cmd$/, @support_ops)) {
if (exists($opt->{p775})) {
return "'$cmd' doesn't work for Power 775 machines.";
} elsif ($cmd eq "vmothersetting") {
if ($value =~ /hugepage:\s*(\d+)/i) {
$opt->{huge_page} = $1;
}
if ($value =~ /bsr:\s*(\d+)/i) {
$opt->{bsr} = $1;
}
next;
}
} else {
return "'$cmd' not support";
}
$opt->{$cmd} = $value;
@@ -109,7 +124,7 @@ sub chvm_parse_args {
$Getopt::Long::ignorecase = 0;
Getopt::Long::Configure( "bundling" );
if ( !GetOptions( \%opt, qw(V|verbose p=s i=s m=s r=s ) )) {
if ( !GetOptions( \%opt, qw(V|verbose p=s i=s m=s r=s p775) )) {
return( usage() );
}
####################################
@@ -126,8 +141,11 @@ sub chvm_parse_args {
# return(usage( "Configuration file or attributes not specified" ));
# }
#}
if (exists($opt{p775})) {
my @cfgdata ;
if ((exists ($opt{p}) || defined($request->{stdin})) && !exists($opt{p775}) ) {
return(usage("Profile just work for Power 775"));
}
if ( exists( $opt{p})) {
if ( exists( $opt{i} ) || exists( $opt{r}) || exists( $opt{m} ) ) {
@@ -302,6 +320,7 @@ sub chvm_parse_args {
$request->{node} = [$other_p];
$request->{noderange} = $other_p;
}
}
####################################
# Check for an extra argument
####################################
@@ -347,21 +366,23 @@ sub mkvm_parse_args {
#############################################
# Process command-line arguments
#############################################
if ( !defined( $args )) {
return(usage( "No command specified" ));
}
#if ( !defined( $args )) {
# return(usage( "No command specified" ));
#}
#############################################
# Checks case in GetOptions, allows opts
# to be grouped (e.g. -vx), and terminates
# at the first unrecognized option.
#############################################
@ARGV = @$args;
if (defined($args)) {
@ARGV = @$args;
}
$Getopt::Long::ignorecase = 0;
Getopt::Long::Configure( "bundling" );
# if ( !GetOptions( \%opt, qw(V|verbose ibautocfg ibacap=s i=s l=s c=s p=s full) )) {
# if ( !GetOptions( \%opt, qw(V|verbose ibautocfg ibacap=s i=s l=s c=s p=s m=s r=s full) )) {
# return( usage() );
# }
if ( !GetOptions( \%opt, qw(V|verbose i=s m=s r=s ) )) {
if ( !GetOptions( \%opt, qw(V|verbose full vios) )) {
return( usage() );
}
####################################
@@ -370,7 +391,37 @@ sub mkvm_parse_args {
if ( grep(/^-$/, @ARGV )) {
return(usage( "Missing option: -" ));
}
if (!exists($opt{p775})) {
my @unsupport_ops = ();
foreach my $tmpop (keys %opt) {
if ($tmpop !~ /full|vios|V/) {
push @unsupport_ops, $tmpop;
}
}
my @support_ops = qw(vmcpus vmmemory vmphyslots vmothersetting);
if (defined(@ARGV[0]) and defined($opt{full})) {
return(usage("Option 'full' shall be used alone."));
} elsif (defined(@ARGV[0])) {
foreach my $arg (@ARGV) {
my ($cmd,$val) = split (/=/,$arg);
if (!grep(/^$cmd$/, @support_ops)) {
push @unsupport_ops, $cmd;
} elsif (!defined($val)) {
return(usage("The option $cmd need specific parameters."));
} else {
$opt{$cmd} = $val;
}
}
}
if (@unsupport_ops) {
my $tmpops = join(",",@unsupport_ops);
return(usage( "The options $tmpops can only work(s) with Power 775 machines."));
}
} else {
if (exists($opt{full}) or exists($opt{vios})) {
return(usage( "Option 'p775' only works for Power 775 machines."));
}
####################################
# Check for non-zero integer
####################################
@@ -408,13 +459,14 @@ sub mkvm_parse_args {
} else {
return(usage( "Invalid entry: $opt{m}.\n For Power 775, the pending memory interleaving mode only could be interleaved(or 1), or non-interleaved(or 2)." ));
}
} else {
} elsif (exists($opt{p775})){
$opt{m} = 2 ;# non-interleaved, which is the default
}
my @ratio = (1, 2, 3, 4, 5);
my %octant_cfg = ();
if ( exists( $opt{r} ) ) {
my @ratio = (1, 2, 3, 4, 5);
my %octant_cfg = ();
my @elems = split(/\,/,$opt{r});
my $range="";
while (my $elem = shift @elems) {
@@ -461,15 +513,15 @@ sub mkvm_parse_args {
}
} # end of "if .. else.."
} # end of while
$opt{octant_cfg}{octant_cfg_value} = (\%octant_cfg);
$opt{octant_cfg}{memory_interleave} = $opt{m};
} #end of if
$opt{octant_cfg}{octant_cfg_value} = (\%octant_cfg);
$opt{octant_cfg}{memory_interleave} = $opt{m};
if ( !exists( $opt{i} ) || !exists( $opt{r} ) ) {
if ( (!exists( $opt{i} ) || !exists( $opt{r} )) ) {
return(usage());
}
}
$opt{target} = \@{$request->{node}};
my $ppctab = xCAT::Table->new( 'ppc');
unless($ppctab) {
@@ -483,6 +535,10 @@ sub mkvm_parse_args {
if ( !$p) {
return(usage("Not found the parent of $node"));
}
if (exists($opt{full}) and defined($other_p) and $other_p eq $p){
return(usage("Only one full partition can be created in one CEC"));
}
if(! defined( $other_p)) {
$other_p = $p;
}
@@ -490,9 +546,10 @@ sub mkvm_parse_args {
return(usage("For Power 775, please make sure the noderange are in one CEC "));
}
}
$request->{node} = [$other_p];
$request->{noderange} = $other_p;
if (exists($opt{p775})) {
$request->{node} = [$other_p];
$request->{noderange} = $other_p;
}
####################################
# No operands - add command name
####################################
@@ -535,10 +592,14 @@ sub rmvm_parse_args {
$Getopt::Long::ignorecase = 0;
Getopt::Long::Configure( "bundling" );
if ( !GetOptions( \%opt, qw(V|verbose service r) )) {
if ( !GetOptions( \%opt, qw(V|verbose service r p775) )) {
return( usage() );
}
return(usage( "rmvm doesn't support for Power 775." ));
if (exists($opt{p775})) {
return(usage( "rmvm doesn't support for Power 775." ));
}
####################################
# Check for "-" with no option
####################################
@@ -592,9 +653,12 @@ sub lsvm_parse_args {
$Getopt::Long::ignorecase = 0;
Getopt::Long::Configure( "bundling" );
if ( !GetOptions( \%opt, qw(V|verbose l|long) )) {
if ( !GetOptions( \%opt, qw(V|verbose l|long p775) )) {
return( usage() );
}
if (exists($opt{l}) && !exists($opt{p775})) {
return(usage( "option 'l' only works for Power 775"));
}
####################################
# Check for "-" with no option
####################################
@@ -622,8 +686,9 @@ sub modify {
my $request = shift;
my $hash = shift;
my $usage_string = xCAT::Usage->getUsage($request->{command});
return modify_by_prof( $request, $hash) if ( $request->{opt}->{p} || $request->{stdin});
return create( $request, $hash) if ( $request->{opt}->{i});
return modify_by_prof( $request, $hash) if ( exists($request->{opt}->{p775}) and ($request->{opt}->{p} || $request->{stdin}));
return create( $request, $hash) if ( exists($request->{opt}->{p775}) and $request->{opt}->{i});
return op_extra_cmds ($request, $hash) if (!exists($request->{opt}->{p775}));
return op_extra_cmds ($request, $hash) if ($request->{opt}->{lparname} || $request->{opt}->{huge_page});
return ([["Error", "Miss argument\n".$usage_string, 1]]);
}
@@ -631,26 +696,72 @@ sub do_op_extra_cmds {
my $request = shift;
my $hash = shift;
my @values = ();
my $action;
my $param;
if (exists($request->{opt}->{lparname})) {
$action = "set_lpar_name";
$param = $request->{opt}->{lparname};
} elsif (exists($request->{opt}->{huge_page})) {
$action = "set_huge_page";
$param = $request->{opt}->{huge_page};
}
my $lparname_para = $request->{opt}->{lparname};
while (my ($mtms, $h) = each(%$hash)) {
my $memhash;
while (my($name, $d) = each(%$h)) {
my $tmp_value = ($param eq '*') ? $name : $param;
xCAT::MsgUtils->verbose_message($request, "$request->{command} $action for node:$name, parm:$tmp_value.");
my $value = xCAT::FSPUtils::fsp_api_action($request, $name, $d, $action, 0, $tmp_value);
if (@$value[1] && ((@$value[1] =~ /Error/i) && (@$value[2] ne '0'))) {
return ([[$name, @$value[1], '1']]) ;
} else {
push @values, [$name, "Success", '0'];
}
foreach my $op (keys %{$request->{opt}}) {
my $action;
my $param = $request->{opt}->{$op};
if ($op eq "lparname") {
$action = "set_lpar_name";
} elsif ($op eq "huge_page") {
$action = "set_huge_page";
} elsif ($op eq "vmcpus") {
$action = "part_set_lpar_pending_proc";
} elsif ($op eq "vmphyslots") {
$action = "set_io_slot_owner_uber";
} elsif ($op eq "vmmemory") {
my @td = @$d;
@td[0] = 0;
$memhash = &query_cec_info_actions($request, $name, \@td, 1, ["part_get_hyp_process_and_mem"]);
if (!exists($memhash->{run})) {
if ($param =~ /(\d+)([G|M]?)\/(\d+)([G|M]?)\/(\d+)([G|M]?)/i) {
my $memsize = $memhash->{mem_region_size};
my $min = $1;
if ($2 == "G" or $2 == '') {
$min = $min * 1024;
}
$min = $min/$memsize;
my $cur = $3;
if ($4 == "G" or $4 == '') {
$cur = $cur * 1024;
}
$cur = $cur/$memsize;
my $max = $5;
if ($6 == "G" or $6 == '') {
$max = $max * 1024;
}
$max = $max/$memsize;
$request->{opt}->{$op} ="$min/$cur/$max";
$param = $request->{opt}->{$op};
} else {
return([[$name, "The format of param:$param is incorrect.", 1]]);
}
$memhash->{run} = 1;
}
$memhash->{memory} = $param;
$memhash->{lpar_used_regions} = 0;
my $ret = &deal_with_avail_mem($request, $name, $d, $memhash);
if (ref($ret) eq "ARRAY") {
return ([[@$ret]]);
}
$param = $memhash->{memory};
$action = "part_set_lpar_pending_mem";
} elsif ($op eq "bsr") {
$action = "set_lpar_bsr";
} else {
last;
}
my $tmp_value = ($param eq '*') ? $name : $param;
xCAT::MsgUtils->verbose_message($request, "$request->{command} $action for node:$name, parm:$tmp_value.");
my $value = xCAT::FSPUtils::fsp_api_action($request, $name, $d, $action, 0, $tmp_value);
if (@$value[1] && ((@$value[1] =~ /Error/i) && (@$value[2] ne '0'))) {
return ([[$name, @$value[1], '1']]) ;
} else {
push @values, [$name, "Success", '0'];
}
}
}
}
return \@values;
@@ -1423,7 +1534,456 @@ sub xCATdB {
}
return undef;
}
########################
#***** partition related
########################
#my @partition_query_actions = qw(part_get_partition_cap part_get_num_of_lpar_slots part_get_hyp_config_process_and_mem part_get_hyp_avail_process_and_mem part_get_service_authority_lpar_id part_get_shared_processing_resource part_get_all_vio_info lpar_lhea_mac part_get_all_io_bus_info part_get_lpar_processing part_get_lpar_memory get_huge_page get_cec_bsr);
my @partition_query_actions = qw(part_get_partition_cap part_get_hyp_process_and_mem part_get_all_io_bus_info get_huge_page get_cec_bsr);
sub parse_part_get_info {
my $hash = shift;
my $data = shift;
my @array = split /\n/, $data;
foreach my $line (@array) {
chomp($line);
if ($line =~ /Num of lpar slots: (\d+)/i) {
$hash->{num_of_lpars} = $1;
} elsif ($line =~ /HYP Configurable Memory[^\(]*\((\d+)\s*regions\)/i) {
$hash->{hyp_config_mem} = $1;
} elsif ($line =~ /HYP Available Memory[^\(]*\((\d+)\s*regions\)/i) {
$hash->{hyp_avail_mem} = $1;
} elsif ($line =~ /HYP Memory Region Size[^\(]*\((\d+)\s*MB\)/i) {
$hash->{mem_region_size} = $1;
} elsif ($line =~ /HYP Configurable Processors: (\d+),\s*Avail Processors: (\d+)/i) {
$hash->{process_units_config} = $1;
$hash->{process_units_avail} = $2;
} elsif ($line =~ /Authority Lpar id:(\w+)/i) {
$hash->{service_lparid} = $1;
} elsif ($line =~ /(\d+),(\d+),[^,]*,(\w+),\w*\(([\w| |-|_]*)\)/) {
$hash->{bus}->{$3}->{cur_lparid} = $1;
$hash->{bus}->{$3}->{bus_slot} = $2;
$hash->{bus}->{$3}->{des} = $4;
} elsif ($line =~ /Phy drc_index:(\w+), Port group: (\w+), Phy port id: (\w+)/) {
$hash->{phy_drc_group_port}->{$1}->{$2}->{$3} = '1';
} elsif ($line =~ /adapter_id=(\w+),lpar_id=([\d|-]+).*port_group=(\d+),phys_port_id=(\d+).*drc_index=(\w+),.*/) {
if (($2 == -1) && ($4 == 255)) {
$hash->{logic_drc_phydrc}->{$3}->{$5} = $1;
#$hash->{logic_drc_phydrc}->{$5}->{$1} = [$2,$3,$4];
}
#} elsif ($line =~ /lpar 0:: Curr Memory::min: 1,cur: (\d+),max:/i) {
} elsif ($line =~ /HYP Reserved Memory Regions:([-]?)(\d+), Min Required Regions:(\d+)/i) {
if ($1 eq '-') {
$hash->{lpar0_used_dec} = 1;
}
$hash->{lpar0_used_mem} = $2;
$hash->{phy_min_mem_req} = $3;
#print "===>lpar0_used_mem:$hash->{lpar0_used_mem}.\n";
} elsif ($line =~ /Curr Memory Req:[^\(]*\((\d+)\s*regions\)/) {
$hash->{lpar_used_regions} = $1;
} elsif ($line =~ /Available huge page memory\(in pages\):\s*(\d+)/) {
$hash->{huge_page_avail} = $1;
} elsif ($line =~ /Available BSR array:\s*(\d+)/) {
$hash->{cec_bsr_avail} = $1;
}
}
}
sub query_cec_info_actions {
my $request = shift;
my $name = shift;
my $td = shift;
my $usage = shift;
my $action_array = shift;
my $lparid = @$td[0];
my $data;
my @array = ();
my %hash = ();
if (!defined($action_array) or ref($action_array) ne "ARRAY") {
$action_array = \@partition_query_actions;
}
foreach my $action (@$action_array) {
#$data .= "======> ret info for $action:\n";
my $values = xCAT::FSPUtils::fsp_api_action($request, $name, $td, $action);
chomp(@$values[1]);
#if ($action eq "part_get_partition_cap" and (@$values[1] =~ /Error:/i or @$values[2] ne 0)) {
if (@$values[1] =~ /Error:/i or @$values[2] ne 0) {
return ([[@$values]]);
}
if (@$values[1] =~ /^$/) {
next;
}
if ($usage eq 0) {
if ($lparid) {
if ($action eq "lpar_lhea_mac") {
my @output = split /\n/,@$values[1];
foreach my $line (@output) {
if ($line =~ /adapter_id=\w+,lpar_id=$lparid,type=hea/) {
#$data .= "$line\n";
push @array, [$name, $line, 0];
}
}
#$data .= "\n";
next;
}
if ($action eq "part_get_all_io_bus_info") {
my @output = split /\n/, @$values[1];
foreach my $line (@output) {
if ($line =~ /^$lparid,/) {
#$data .= "$line\n";
push @array, [$name, $line, 0];
}
}
#$data .= "\n";
next;
}
}
#$data .= "@$values[1]\n\n";
push @array, [$name, @$values[1], @$values[2]];
} else {
&parse_part_get_info(\%hash, @$values[1]);
}
}
if ($usage eq 0) {
#return $data;
return \@array;
} else {
return \%hash;
}
}
#my @partition_query_actions = qw(part_get_partition_cap part_get_num_of_lpar_slots part_get_hyp_config_process_and_mem part_get_hyp_avail_process_and_mem part_get_service_authority_lpar_id part_get_shared_processing_resource part_get_all_vio_info lpar_lhea_mac part_get_all_io_bus_info part_get_lpar_processing part_get_lpar_memory get_huge_page get_cec_bsr);
sub query_cec_info {
my $request = shift;
my $hash = shift;
my $args = $request->{opt};
my @td = ();
my @result = ();
while (my ($mtms,$h) = each(%$hash) ) {
while (my ($name, $d) = each (%$h)) {
@td = @$d;
if (@$d[0] == 0 && @$d[4] ne "lpar") {
last;
}
#my $rethash = query_cec_info_actions($request, $name, $d, 0, ["part_get_lpar_processing","part_get_lpar_memory","part_get_all_vio_info","lpar_lhea_mac","part_get_all_io_bus_info","get_huge_page","get_cec_bsr"]);
my $rethash = query_cec_info_actions($request, $name, $d, 0, ["part_get_lpar_processing","part_get_lpar_memory","part_get_all_io_bus_info","get_huge_page","get_cec_bsr"]);
#push @result, [$name, $rethash, 0];
push @result, @$rethash;
}
if (@td[0] == 0) {
my $rethash = query_cec_info_actions($request, @td[3],\@td, 0);
#push @result, [@td[3], $rethash, 0];
push @result, @$rethash;
}
}
return \@result;
}
########################
#***** partition related
########################
my @partition_config_actions = qw/part_set_lpar_def_state part_set_lpar_pending_proc part_set_lpar_pending_mem part_set_pending_max_vslots part_set_lpar_shared_pool_util_auth part_set_lpar_group_id part_set_lpar_avail_priority part_set_partition_placement part_set_lhea_assign_info part_set_phea_port_info part_set_lhea_port_info part_set_veth_slot_config part_set_vscsi_slot_config part_set_vfchan_slot_config part_clear_vslot_config set_huge_page set_lpar_name/;
sub set_lpar_undefined {
my $request = shift;
my $name = shift;
my $attr = shift;
my $values = xCAT::FSPUtils::fsp_api_action($request, $name, $attr, "part_set_lpar_def_state", 0, 0x0);
if (!@$values[2]) {
return ([$name,"Done",0]);
}
return $values;
}
sub clear_service_authority_lpar {
my $request = shift;
my $name = shift;
my $attr = shift;
my $values = xCAT::FSPUtils::fsp_api_action($request, $name, $attr, "part_get_service_authority_lpar_id");
my @array = split /\n/, @$values[1];
my $service_lparid = undef;
foreach my $line (@array) {
if ($line =~ /Authority Lpar id:([-|\d]+)./i) {
$service_lparid = $1;
}
}
if (defined($service_lparid) and $service_lparid == @$attr[0]) {
xCAT::FSPUtils::fsp_api_action($request, $name, $attr, "part_set_service_authority_lpar_id");
}
}
sub remove {
my $request = shift;
my $hash = shift;
my @result = ();
while (my ($mtms, $h) = each (%$hash)) {
while (my ($name, $d) = each (%$h)) {
&clear_service_authority_lpar($request, $name, $d);
my $values = &set_lpar_undefined($request, $name, $d);
push @result, $values;
}
}
return \@result;
}
sub deal_with_avail_mem {
my $request = shift;
my $name = shift;
my $d = shift;
my $lparhash = shift;
my $max_required_regions;
if ($lparhash->{memory} =~ /(\d+)\/(\d+)\/(\d+)/) {
my ($min,$cur,$max);
my $used_regions = 0;
my $cur_avail = 0;
$min = $1;
$cur = $2;
$max = $3;
my %tmphash;
my $values;
if (exists($lparhash->{lpar_used_regions})) {
$values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_get_lpar_memory");
&parse_part_get_info(\%tmphash, @$values[1]);
if (exists($tmphash{lpar_used_regions})) {
$used_regions = $tmphash{lpar_used_regions};
}
}
$values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_get_hyp_res_mem_regions", 0, $3);
&parse_part_get_info(\%tmphash, @$values[1]);
if (exists($tmphash{lpar0_used_mem}) && exists($tmphash{phy_min_mem_req})) {
if ($min < $tmphash{phy_min_mem_req}) {
$min = $tmphash{phy_min_mem_req};
}
if (exists($lparhash->{lpar0_used_dec})) {
$cur_avail = $lparhash->{hyp_avail_mem} + $used_regions + $tmphash{lpar0_used_mem};
} else {
$cur_avail = $lparhash->{hyp_avail_mem} + $used_regions - $tmphash{lpar0_used_mem};
}
xCAT::MsgUtils->verbose_message($request, "====****====used:$used_regions,avail:$cur_avail,($min:$cur:$max).");
if ($cur_avail < $min) {
return([$name, "Parse reserverd regions failed, no enough memory, available:$lparhash->{hyp_avail_mem}.", 1]);
}
if ($cur > $cur_avail) {
my $new_cur = $cur_avail;
$lparhash->{memory} = "$min/$new_cur/$max";
}
} else {
return ([$name, "Failed to get hypervisor reserved memory regions.", 1]);
}
}
return 0;
}
sub create_lpar {
my $request = shift;
my $name = shift;
my $d = shift;
my $lparhash = shift;
my $values;
if (exists($request->{opt}->{vios})) {
$values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_def_state", 0, 0x03);
} else {
$values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_def_state", 0, 0x01);
}
if (@$values[2] ne 0) {
return ([[$name, @$values[1], @$values[0]]]);
}
$values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "set_lpar_name", 0, $name);
if (@$values[2] ne 0) {
&set_lpar_undefined($request, $name, $d);
return ([$name, @$values[1], @$values[0]]);
}
xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_shared_pool_util_auth");
xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_group_id");
xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_avail_priority");
#print "======>physlots:$lparhash->{physlots}.\n";
$values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "set_io_slot_owner_uber", 0, $lparhash->{physlots});
#$values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "set_io_slot_owner", 0, join(",",@phy_io_array));
if (@$values[2] ne 0) {
&set_lpar_undefined($request, $name, $d);
return ([$name, @$values[1], @$values[2]]);
}
if (exists($lparhash->{phy_hea})) {
my $phy_hash = $lparhash->{phy_hea};
foreach my $phy_drc (keys %$phy_hash) {
#print "======> set_lhea_assign_info: drc_index:$phy_drc.\n";
xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lhea_assign_info", 0, $phy_drc);
my $group_hash = $phy_hash->{$phy_drc};
foreach my $group_id (keys %$group_hash) {
my @lhea_drc = (keys %{$lparhash->{logic_drc_phydrc}->{$group_id}});
foreach my $phy_port_id (keys %{$group_hash->{$group_id}}) {
my $tmp_param = "$phy_drc,$group_id,$phy_port_id";
#print "======> set_phea_port_info: $tmp_param.\n";
xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_phea_port_info", 0, $tmp_param);
my $tmp_lhea_param = $lhea_drc[$phy_port_id].",$phy_port_id";
#print "======> set_lhea_port_info: $tmp_lhea_param.\n";
xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lhea_port_info", 0, $tmp_lhea_param);
}
delete ($lparhash->{logic_drc_phydrc}->{$group_id}->{$lhea_drc[0]});
delete ($lparhash->{logic_drc_phydrc}->{$group_id}->{$lhea_drc[1]});
}
}
}
#print "======>cpus:$lparhash->{cpus}.\n";
$values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_pending_proc", 0, $lparhash->{cpus});
if (@$values[2] ne 0) {
&set_lpar_undefined($request, $name, $d);
return ([$name, @$values[1], @$values[2]]);
}
$values = &deal_with_avail_mem($request, $name, $d,$lparhash);
if (ref($values) eq "ARRAY") {
&set_lpar_undefined($request, $name, $d);
return ([@$values]);
}
#print "======>memory:$lparhash->{memory}.\n";
$values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_pending_mem", 0, $lparhash->{memory});
if (@$values[2] ne 0) {
&set_lpar_undefined($request, $name, $d);
return ([$name, @$values[1], @$values[2]]);
}
xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_comp_modes");
#print "======>memory:$lparhash->{huge_page}.\n";
xCAT::FSPUtils::fsp_api_action($request, $name, $d, "set_huge_page", 0, $lparhash->{huge_page});
#print "======>bsr:$lparhash->{bsr_num}.\n";
xCAT::FSPUtils::fsp_api_action($request, $name, $d, "set_lpar_bsr", 0, $lparhash->{bsr_num});
xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_partition_placement");
if (exists($request->{opt}->{vios})) {
$values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_def_state", 0, 0x04);
} else {
$values = xCAT::FSPUtils::fsp_api_action($request, $name, $d, "part_set_lpar_def_state", 0, 0x02);
}
if (@$values[2] ne 0) {
return ([$name, @$values[1], @$values[2]]);
}
return ([$name, "Done", 0]);
}
sub mkspeclpar {
my $request = shift;
my $hash = shift;
my $opt = $request->{opt};
my $values;
my @result = ();
my $vmtab = xCAT::Table->new( 'vm');
unless($vmtab) {
return([["Error","Cannot open vm table", 1]]);
}
while (my ($mtms, $h) = each (%$hash)) {
my $memhash;
my @nodes = keys(%$h);
my $ent = $vmtab->getNodesAttribs(\@nodes, ['cpus', 'memory','physlots', 'othersettings']);
while (my ($name, $d) = each (%$h)) {
if (!exists($memhash->{run})) {
my @td = @$d;
@td[0] = 0;
$memhash = &query_cec_info_actions($request, $name, \@td, 1, ["part_get_hyp_process_and_mem","lpar_lhea_mac"]);
$memhash->{run} = 1;
}
my $tmp_ent = $ent->{$name}->[0];
if (exists($opt->{vmcpus})) {
$tmp_ent->{cpus} = $opt->{vmcpus};
}
if (exists($opt->{vmmemory})) {
$tmp_ent->{memory} = $opt->{vmmemory};
}
if (exists($opt->{vmphyslots})) {
$tmp_ent->{physlots} = $opt->{vmphyslots};
}
if (exists($opt->{vmothersetting})) {
$tmp_ent->{othersettings} = $opt->{vmothersetting};
}
if (!defined($tmp_ent) ) {
return ([[$name, "Not find params", 1]]);
} elsif (!exists($tmp_ent->{cpus}) || !exists($tmp_ent->{memory}) || !exists($tmp_ent->{physlots})) {
return ([[$name, "The attribute 'vmcpus', 'vmmemory' and 'vmphyslots' are all needed to be specified.", 1]]);
}
if ($tmp_ent->{memory} =~ /(\d+)([G|M]?)\/(\d+)([G|M]?)\/(\d+)([G|M]?)/i) {
my $memsize = $memhash->{mem_region_size};
my $min = $1;
if ($2 == "G" or $2 == '') {
$min = $min * 1024;
}
$min = $min/$memsize;
my $cur = $3;
if ($4 == "G" or $4 == '') {
$cur = $cur * 1024;
}
$cur = $cur/$memsize;
my $max = $5;
if ($6 == "G" or $6 == '') {
$max = $max * 1024;
}
$max = $max/$memsize;
$tmp_ent->{memory} = "$min/$cur/$max";
}
$tmp_ent->{hyp_config_mem} = $memhash->{hyp_config_mem};
$tmp_ent->{hyp_avail_mem} = $memhash->{hyp_avail_mem};
$tmp_ent->{huge_page} = "0/0/0";
$tmp_ent->{bsr_num} = "0";
if (exists($tmp_ent->{othersettings})) {
my $setting = $tmp_ent->{othersettings};
if ($setting =~ /hugepage:(\d+)/) {
my $tmp = $1;
$tmp_ent->{huge_page} = "1/".$tmp."/".$tmp;
}
if ($setting =~ /bsr:(\d+)/) {
$tmp_ent->{bsr_num} = $1;
}
}
$tmp_ent->{phy_hea} = $memhash->{phy_drc_group_port};
$tmp_ent->{logic_drc_phydrc} = $memhash->{logic_drc_phydrc};
$values = &create_lpar($request, $name, $d, $tmp_ent);
push @result, $values;
$name = undef;
$d = undef;
}
}
return \@result;
}
sub mkfulllpar {
my $request = shift;
my $hash = shift;
my $values;
my @result = ();
while (my ($mtms, $h) = each (%$hash)) {
my $rethash;
while (my ($name, $d) = each (%$h)) {
if (!exists($rethash->{run})) {
my @td = @$d;
@td[0] = 0;
$rethash = query_cec_info_actions($request, $name, \@td, 1);
if (ref($rethash) ne 'HASH') {
return ([[$mtms, "Cann't get hypervisor info hash", 1]]);
}
$rethash->{run} = 1;
#print Dumper($rethash);
}
my %lpar_param = ();
$lpar_param{cpus} = "1/".$rethash->{process_units_avail}."/".$rethash->{process_units_config};
$lpar_param{memory} = "1/".$rethash->{hyp_avail_mem}."/".$rethash->{hyp_config_mem};
$lpar_param{hyp_config_mem} = $rethash->{hyp_config_mem};
$lpar_param{hyp_avail_mem} = $rethash->{hyp_avail_mem};
my @phy_io_array = keys(%{$rethash->{bus}});
$lpar_param{physlots} = join(",", @phy_io_array);
$lpar_param{huge_page} = "1/".$rethash->{huge_page_avail}."/".$rethash->{huge_page_avail};
$lpar_param{bsr_num} = $rethash->{cec_bsr_avail};
$lpar_param{phy_hea} = $rethash->{phy_drc_group_port};
$lpar_param{logic_drc_phydrc} = $rethash->{logic_drc_phydrc};
$values = &create_lpar($request, $name, $d, \%lpar_param);
$rethash->{logic_drc_phydrc} = $lpar_param{logic_drc_phydrc};
push @result, $values;
$name = undef;
$d = undef;
}
}
return \@result;
}
##########################################################################
# Creates logical partitions
@@ -1435,13 +1995,14 @@ sub mkvm {
# decide if issuing mkvm with the option '-f'.
# if yes, mklpar will be invoked to
# create a full system partition for each CECs managed by the HMC.
if ( exists($opt->{full})) {
return( mkfulllpar(@_) );
}
else {
# if no, it will execute the original function.
return( create(@_) );
}
if (exists($opt->{p775})) {
return (create(@_));
}
if (exists($opt->{full})) {
return (mkfulllpar(@_));
} else {
return (mkspeclpar(@_));
}
}
##########################################################################
@@ -1455,15 +2016,29 @@ sub chvm {
##########################################################################
# No rmvm for Power 775
##########################################################################
#sub rmvm {
sub rmvm {
my $request = $_[0];
my $opt = $request->{opt};
if (exists($opt->{p775})) {
return ([["lpar","rmvm only support Power Partitioning.", 1]]);
} else {
return( remove(@_) );
}
# return( remove(@_) );
#}
}
##########################################################################
# Lists logical partition profile
##########################################################################
sub lsvm {
return( list(@_) );
my $request = shift;
my $hash = shift;
my $args = $request->{opt};
if (exists($args->{p775})) {
return( list($request, $hash) );
} else {
return (query_cec_info($request, $hash));
}
}
1;
+4 -7
View File
@@ -10,7 +10,7 @@ if ($^O =~ /^aix/i) {
}
use strict;
use Sys::Syslog qw (:DEFAULT setlogsock);
use Sys::Syslog;
use xCAT::Utils;
#use locale;
use Socket;
@@ -456,8 +456,7 @@ sub message
# If they want this msg to also go to syslog, do that now
eval {
openlog("xCAT", '', 'local4');
setlogsock(["tcp", "unix", "stream"]);
openlog("xCAT", "nofatal,pid", "local4");
if ($sev eq 'SE') {
syslog("err", $rsp);
} else {
@@ -503,8 +502,7 @@ sub message
{
print $stdouterrf "Unable to open auditlog\n";
eval {
openlog("xCAT", '', 'local4');
setlogsock(["tcp", "unix", "stream"]);
openlog("xCAT", "nofatal,pid", "local4");
syslog("err", "Unable to write to auditlog");
closelog();
};
@@ -521,8 +519,7 @@ sub message
{ # error
print $stdouterrf "Unable to open auditlog\n";
eval {
openlog("xCAT", '', 'local4');
setlogsock(["tcp", "unix", "stream"]);
openlog("xCAT", "nofatal,pid", "local4");
syslog("err", "Unable to open auditlog");
closelog();
};
+47 -1
View File
@@ -1,5 +1,6 @@
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
package xCAT::NodeRange;
use Text::Balanced qw/extract_bracketed/;
require xCAT::Table;
require Exporter;
use strict;
@@ -549,6 +550,26 @@ sub abbreviate_noderange {
return (join ',',keys %targetelems,keys %nodesleft);
}
sub set_arith {
my $operand = shift;
my $op = shift;
my $newset = shift;
if ($op =~ /@/) { # compute the intersection of the current atom and the node list we have received before this
foreach (keys %$operand) {
unless ($newset->{$_}) {
delete $operand->{$_};
}
}
} elsif ($op =~ /,-/) { # add the nodes from this atom to the exclude list
foreach (keys %$newset) {
delete $operand->{$_}
}
} else { # add the nodes from this atom to the total node list
foreach (keys %$newset) {
$operand->{$_}=1;
}
}
}
# Expand the given noderange
# Input args:
# - noderange to expand
@@ -573,20 +594,45 @@ sub noderange {
}
my %nodes = ();
my %delnodes = ();
if ($range =~ /\(/) {
my ($middle, $end, $start) =
extract_bracketed($range, '()', qr/[^()]*/);
unless ($middle) { die "Unbalanced parentheses in noderange" }
$middle = substr($middle,1,-1);
my $op = ",";
if ($start =~ m/-$/) { #subtract the parenthetical
$op .= "-"
} elsif ($start =~ m/\@$/) {
$op = "@"
}
$start =~ s/,-$//;
$start =~ s/,$//;
$start =~ s/\@$//;
%nodes = map { $_ => 1 } noderange($start,$verify,$exsitenode,%options);
my %innernodes = map { $_ => 1 } noderange($middle,$verify,$exsitenode,%options);
set_arith(\%nodes,$op,\%innernodes);
$range = $end;
}
my $op = ",";
my @elems = split(/(,(?![^[]*?])(?![^\(]*?\)))/,$range); # commas outside of [] or ()
if (scalar(@elems)==1) {
@elems = split(/(@(?![^\(]*?\)))/,$range); # only split on @ when no , are present (inner recursion)
}
while (my $atom = shift @elems) {
while (defined(my $atom = shift @elems)) {
if ($atom eq '') { next; }
if ($atom eq ',') {
next;
}
if ($atom =~ /^-/) { # if this is an exclusion, strip off the minus, but remember it
$atom = substr($atom,1);
$op = $op."-";
} elsif ($atom =~ /^\@/) { # if this is an exclusion, strip off the minus, but remember it
$atom = substr($atom,1);
$op = "@";
}
if ($atom eq '') { next; }
if ($atom =~ /^\^(.*)$/) { # get a list of nodes from a file
open(NRF,$1);
+9
View File
@@ -7,6 +7,7 @@ use xCAT::GlobalDef;
use xCAT::Utils;
use xCAT::TableUtils;
use xCAT::NetworkUtils;
require xCAT::data::ibmhwtypes;
###########################################
# Factory defaults
@@ -168,6 +169,10 @@ sub add_ppc {
# Update nodelist table
###########################
updategroups( $name, $db{nodelist}, $type );
my $tmp_group = xCAT::data::ibmhwtypes::parse_group($model);
if (defined($tmp_group)) {
updategroups($name, $db{nodelist}, $tmp_group);
}
if ( $type =~ /^(fsp|bpa)$/ ) {
$db{nodelist}->setNodeAttribs( $name, {hidden => '1'});
} else {
@@ -525,6 +530,10 @@ sub update_node_attribs
if ( $namediff)
{
updategroups( $name, $db->{nodelist}, $type );
my $tmp_group = xCAT::data::ibmhwtypes::parse_group($model);
if (defined($tmp_group)) {
updategroups($name, $db->{nodelist}, $tmp_group);
}
$db->{nodelist}->setNodeAttribs( $name, {status=>$nodelisthash->{status},
appstatus=>$nodelisthash->{appstatus},
primarysn=>$nodelisthash->{primarysn},
+12 -1
View File
@@ -5,6 +5,8 @@ use strict;
use Getopt::Long;
use xCAT::PPCcli qw(SUCCESS EXPECT_ERROR RC_ERROR NR_ERROR);
use xCAT::Usage;
use xCAT::TableUtils;
require xCAT::data::ibmhwtypes;
##########################################
@@ -59,7 +61,7 @@ sub parse_args {
$Getopt::Long::ignorecase = 0;
Getopt::Long::Configure( "bundling" );
if ( !GetOptions( \%opt, qw(V|verbose) )) {
if ( !GetOptions( \%opt, qw(V|verbose t) )) {
return( usage() );
}
####################################
@@ -75,6 +77,9 @@ sub parse_args {
if ( !defined( $cmd )) {
return(usage( "Invalid command: $ARGV[0]" ));
}
if (exists($opt{t}) and $cmd ne "model") {
return(["Option 't' can only work with 'model'."]);
}
####################################
# Check for an extra argument
####################################
@@ -411,6 +416,12 @@ sub vpd {
#############################
# Output value
#############################
if ($_ eq 'model' and exists($request->{opt}->{t})) {
my $tmp_pre = xCAT::data::ibmhwtypes::parse_args($data->{$_});
if (defined($tmp_pre)) {
xCAT::TableUtils->updatenodegroups($name, $tmp_pre);
}
}
my $value = "@{$prefix{$_}}[0]: $data->{$_}";
push @result, [$name,$value,$Rc];
}
+28 -4
View File
@@ -11,7 +11,7 @@ use xCAT::PPCdb;
use xCAT::GlobalDef;
use xCAT::Usage;
use xCAT::NetworkUtils;
require xCAT::data::ibmhwtypes;
##############################################
# Globals
@@ -545,6 +545,7 @@ sub format_stanza {
#################################
# Add each attribute
#################################
my $mtm = undef;
foreach ( @attribs ) {
my $d = $data[$i++];
@@ -555,7 +556,8 @@ sub format_stanza {
} elsif ( /^hwtype$/ ) {
$d = $globalhwtype{$type};
} elsif ( /^groups$/ ) {
$d = "$type,all";
next;
#$d = "$type,all";
} elsif ( /^mgt$/ ) {
$d = $hwtype;
} elsif ( /^cons$/ ) {
@@ -568,7 +570,9 @@ sub format_stanza {
} elsif ( /^(mtm|serial)$/ ) {
if ( $type eq "lpar" ) {
$d = undef;
}
} elsif (/^mtm$/) {
$mtm = $d;
}
} elsif (/^side$/) {
unless ( $type =~ /^fsp|bpa$/ ) {
next;
@@ -576,6 +580,14 @@ sub format_stanza {
}
$result .= "\t$_=$d\n";
}
my $tmp_groups = "$type,all";
if (defined($mtm)) {
my $tmp_pre = xCAT::data::ibmhwtypes::parse_group($mtm);
if (defined($tmp_pre)) {
$tmp_groups .= ",$tmp_pre";
}
}
$result .= "\tgroups=$tmp_groups\n";
}
return( $result );
}
@@ -623,6 +635,7 @@ sub format_xml {
#################################
# Add each attribute
#################################
my $mtm = undef;
foreach ( @attribs ) {
my $d = $data[$i++];
@@ -631,7 +644,8 @@ sub format_xml {
} elsif ( /^hwtype$/ ) {
$d = $globalhwtype{$type};
} elsif ( /^groups$/ ) {
$d = "$type,all";
next;
#$d = "$type,all";
} elsif ( /^mgt$/ ) {
$d = $hwtype;
} elsif ( /^cons$/ ) {
@@ -643,6 +657,8 @@ sub format_xml {
} elsif ( /^(mtm|serial)$/ ) {
if ( $type eq "lpar" ) {
$d = undef;
} elsif (/^mtm$/){
$mtm = $d;
}
} elsif (/^side$/) {
unless ( $type =~ /^fsp|bpa$/ ) {
@@ -651,6 +667,14 @@ sub format_xml {
}
$href->{Node}->{$_} = $d;
}
my $tmp_groups = "$type,all";
if (defined($mtm)) {
my $tmp_pre = xCAT::data::ibmhwtypes::parse_group($mtm);
if (defined($tmp_pre)) {
$tmp_groups .= ",$tmp_pre";
}
}
$href->{Node}->{groups}=$tmp_groups;
#################################
# XML encoding
#################################
+81 -6
View File
@@ -550,6 +550,32 @@ sub get_allnode_singleattrib_hash
#-------------------------------------------------------------------------------
=head3 get_db_swtiches
Description : Get all records of switch config from a table, then return a string list.
Arguments : $tabname - the table name.
Returns : Reference of the records hash.
=cut
#-------------------------------------------------------------------------------
sub get_db_switches
{
my $class = shift;
my $table = xCAT::Table->new("switches");
my @attribs = ("switch");
my @entries = $table->getAllAttribs(@attribs);
$table->close();
my %allrecords;
foreach (@entries)
{
if ($_->{'switch'}){
$allrecords{$_->{'switch'}} = 0;
}
}
return \%allrecords;
}
#-------------------------------------------------------------------------------
=head3 get_db_swtichports
Description : Get all records of switch config from a table, then return a string list.
Arguments : $tabname - the table name.
@@ -563,6 +589,7 @@ sub get_db_switchports
my $table = xCAT::Table->new("switch");
my @attribs = ("switch", "port");
my @entries = $table->getAllAttribs(@attribs);
$table->close();
my %allrecords;
foreach (@entries)
{
@@ -573,6 +600,46 @@ sub get_db_switchports
#-------------------------------------------------------------------------------
=head3 get_all_cecs
Description : Get all CEC objects name in system.
Arguments : hashref: if not set, return a array ref.
if set, return a hash ref.
Returns : ref for CECs list.
Example :
my $arrayref = xCAT::ProfiledNodeUtils->get_all_cecs();
my $hashref = xCAT::ProfiledNodeUtils->get_all_cecs(1);
=cut
#-------------------------------------------------------------------------------
sub get_all_cecs
{
my $hashref = shift;
my %cecshash;
my @cecslist;
my $ppctab = xCAT::Table->new('ppc');
my @cecs = $ppctab->getAllAttribsWhere("nodetype = 'cec'", 'node');
foreach (@cecs) {
if($_->{'node'}) {
if ($hashref) {
$cecshash{$_->{'node'}} = 1;
} else {
push @cecslist, $_->{'node'};
}
}
}
$ppctab->close();
# Return the ref accordingly
if ($hashref) {
return \%cecshash;
} else {
return \@cecslist;
}
}
#-------------------------------------------------------------------------------
=head3 is_discover_started
Description : Judge whether profiled nodes discovering is running or not.
Arguments : NA
@@ -731,7 +798,14 @@ sub check_profile_consistent{
my $mgt = undef;
$mgt = $mgtentry->{'mgt'} if ($mgtentry->{'mgt'});
$nodehmtab->close();
#Get hardwareprofile nodetype
my $ppctab = xCAT::Table->new('ppc');
my $ntentry = $ppctab->getNodeAttribs($hardwareprofile, ['nodetype']);
my $nodetype = undef;
$nodetype = $ntentry->{'nodetype'} if ($ntentry->{'nodetype'});
$ppctab->close();
# Check if exists provision network
if (not ($installnic and exists $netprofile_nicshash{$installnic}{"network"})){
return 0, "Provisioning network not defined for network profile."
@@ -750,17 +824,18 @@ sub check_profile_consistent{
return 0, "$nictype networkprofile must use with hardwareprofile.";
}
}
if (not $nictype and $mgt) {
# define hardwareprofile, not define fsp or bmc networkprofile
# For nodetype is lpar node, not need to check the nictype as it is not required for lpar node
if (not $nictype and $mgt and $nodetype ne 'lpar' ) {
# define hardwareprofile, not define fsp or bmc networkprofile, and the node type is not lpar
return 0, "$profile_dict{$mgt} hardwareprofile must use with $profile_dict{$mgt} networkprofile.";
}
if ($profile_dict{$mgt} ne $nictype) {
if ($profile_dict{$mgt} ne $nictype and $nodetype ne 'lpar') {
# Networkprofile's nictype is not consistent with hadrwareprofile's mgt
return 0, "Networkprofile's nictype is not consistent with hardwareprofile's mgt.";
}
return 1, "";
}
+23 -18
View File
@@ -41,15 +41,16 @@ package xCAT::RemoteShellExp;
[-t node list] test ssh connection to the node
[-k] Generates the ssh keys needed , for the user on the MN.
[-s node list] copies the ssh keys to the nodes
optional $timeout = timeout value for the expect. Usually from the xdsh -t flag
default timeout is 10 seconds
exit 0 - good
exit 1 - abort
exit 2 - usage error
Examples:
$rc=xCAT::RemoteShellExp->remoteshellexp("k",$callback,$remoteshellcmd);
$rc=xCAT::RemoteShellExp->remoteshellexp("s",$callback,$remoteshellcmd,$nodes);
$rc=xCAT::RemoteShellExp->remoteshellexp("t",$callback,$remoteshellcmd,$nodes);
$rc=xCAT::RemoteShellExp->remoteshellexp("k",$callback,$remoteshellcmd,$nodes,$timeout);
$rc=xCAT::RemoteShellExp->remoteshellexp("s",$callback,$remoteshellcmd,$nodes,$timeout);
$rc=xCAT::RemoteShellExp->remoteshellexp("t",$callback,$remoteshellcmd,$nodes,$timeout);
=cut
@@ -70,7 +71,7 @@ use strict;
#-----------------------------------------------------------------------------
sub remoteshellexp
{
my ($class, $flag, $callback, $remoteshell, $nodes) = @_;
my ($class, $flag, $callback, $remoteshell, $nodes, $timeout) = @_;
my $rc=0;
$::CALLBACK = $callback;
if (!($flag))
@@ -90,6 +91,10 @@ sub remoteshellexp
return 2;
}
my $expecttimeout=10; # default
if (defined($timeout)) { # value supplied
$expecttimeout=$timeout;
}
# for -s flag must have nodes and a $to_userid password
my $to_user_password;
@@ -180,7 +185,7 @@ sub remoteshellexp
{
# if the file size of the id_rsa key is 0, tell them to remove it
# and run the command again
$rc=xCAT::RemoteShellExp->gensshkeys;
$rc=xCAT::RemoteShellExp->gensshkeys($expecttimeout);
}
# send ssh keys to the nodes/devices, to setup passwordless ssh
if ($flag eq "s")
@@ -193,15 +198,15 @@ sub remoteshellexp
return 1;
}
if ($ssh_setup_cmd) { # setup ssh on devices
$rc=xCAT::RemoteShellExp->senddeviceskeys($remoteshell,$remotecopy,$to_userid,$to_user_password,$home,$ssh_setup_cmd,$nodes);
$rc=xCAT::RemoteShellExp->senddeviceskeys($remoteshell,$remotecopy,$to_userid,$to_user_password,$home,$ssh_setup_cmd,$nodes, $expecttimeout);
} else { #setup ssh on nodes
$rc=xCAT::RemoteShellExp->sendnodeskeys($remoteshell,$remotecopy,$to_userid,$to_user_password,$home,$nodes);
$rc=xCAT::RemoteShellExp->sendnodeskeys($remoteshell,$remotecopy,$to_userid,$to_user_password,$home,$nodes, $expecttimeout);
}
}
# test ssh setup on the node
if ($flag eq "t")
{
$rc=xCAT::RemoteShellExp->testkeys($remoteshell,$to_userid,$nodes);
$rc=xCAT::RemoteShellExp->testkeys($remoteshell,$to_userid,$nodes,$expecttimeout);
}
return $rc;
}
@@ -220,9 +225,9 @@ sub remoteshellexp
sub gensshkeys
{
my ($class) = @_;
my ($class, $expecttimeout) = @_;
my $keygen;
my $timeout = 10; # sets Expect default timeout, 0 accepts immediately
my $timeout = $expecttimeout; # sets Expect default timeout, 0 accepts immediately
my $keygen_sent = 0;
my $prompt1 = 'Generating public/private rsa';
my $prompt2 = 'Enter file.*:';
@@ -347,9 +352,9 @@ sub gensshkeys
sub testkeys
{
my ($class,$remoteshell,$to_userid,$nodes) = @_;
my ($class,$remoteshell,$to_userid,$nodes, $expecttimeout) = @_;
my $testkeys;
my $timeout = 10; # sets Expect default timeout, 0 accepts immediately
my $timeout = $expecttimeout; # sets Expect default timeout
my $testkeys_sent = 0;
my $prompt1 = 'Are you sure you want to continue connecting (yes/no)?';
my $prompt2 = 'ssword:';
@@ -469,9 +474,9 @@ sub testkeys
sub sendnodeskeys
{
my ($class,$remoteshell,$remotecopy,$to_userid,$to_userpassword,$home,$nodes) = @_;
my ($class,$remoteshell,$remotecopy,$to_userid,$to_userpassword,$home,$nodes, $expecttimeout) = @_;
my $sendkeys;
my $timeout = 10; # sets Expect default timeout, 0 accepts immediately
my $timeout = $expecttimeout; # sets Expect default timeout, 0 accepts immediately
my $sendkeys_sent = 0;
my $prompt1 = 'Are you sure you want to continue connecting (yes/no)?';
my $prompt2 = 'ssword:';
@@ -759,7 +764,7 @@ sub sendnodeskeys
=head3 senddeviceskeys
Setup the ssh keys on the nodes
Setup the ssh keys on the switches
=cut
@@ -768,9 +773,9 @@ sub sendnodeskeys
sub senddeviceskeys
{
my ($class,$remoteshell,$remotecopy,$to_userid,$to_userpassword,$home,$ssh_setup_cmd,$nodes) = @_;
my ($class,$remoteshell,$remotecopy,$to_userid,$to_userpassword,$home,$ssh_setup_cmd,$nodes, $expecttimeout) = @_;
my $sendkeys;
my $timeout = 10; # sets Expect default timeout, 0 accepts immediately
my $timeout = $expecttimeout; # sets Expect default timeout, 0 accepts immediately
my $sendkeys_sent = 0;
my $prompt1 = 'Are you sure you want to continue connecting (yes/no)?';
my $prompt2 = 'ssword:';
+32 -14
View File
@@ -202,9 +202,11 @@ sub parse_and_run_sinv
#
my @nodelist = ();
my @cmdparts = ();
my $devicecommand =0;
if ($options{'devicetype'}) {
# must split different because devices have commands with spaces
@cmdparts = split(' ', $cmd,3);
$devicecommand =1;
} else {
@cmdparts = split(' ', $cmd);
}
@@ -503,7 +505,7 @@ sub parse_and_run_sinv
);
# write the results to the tempfile after running through xdshcoll
$rc = &storeresults($callback);
$rc = &storeresults($callback,$devicecommand);
}
$processflg = "node";
@@ -534,7 +536,7 @@ sub parse_and_run_sinv
# write the results to the tempfile after running through xdshcoll
$rc = &storeresults($callback);
$rc = &storeresults($callback,$devicecommand);
# Build report and write to output file
# if file exist and has something in it
@@ -1451,12 +1453,11 @@ sub rinvoutput
sub storeresults
{
my $callback = shift;
my $devicecommand= shift;
# open file to write results of xdsh or rinv command
my $newtempfile = $tempfile;
$newtempfile .= "temp";
open(FILE, ">$newtempfile");
if ($? > 0)
unless (open(NEWTMPFILE, ">$newtempfile"))
{
my $rsp = {};
$rsp->{data}->[0] = "Could not open $newtempfile\n";
@@ -1465,9 +1466,9 @@ sub storeresults
}
foreach my $line (@cmdresult)
{
print FILE $line;
print NEWTMPFILE $line;
}
close FILE;
close NEWTMPFILE;
my $outputfile;
if ($processflg eq "seednode")
{ # cmd to seednode
@@ -1479,8 +1480,7 @@ sub storeresults
}
# open file to put results of xdshcoll
open(FILE, ">$outputfile");
if ($? > 0)
unless (open(NEWOUTFILE, ">$outputfile"))
{
my $rsp = {};
$rsp->{data}->[0] = "Could not open $outputfile\n";
@@ -1489,8 +1489,7 @@ sub storeresults
}
my $cmd = " $::XCATROOT/sbin/xdshcoll <$newtempfile |";
open(XCOLL, "$cmd");
if ($? > 0)
unless (open(XCOLL, "$cmd"))
{
my $rsp = {};
$rsp->{data}->[0] = "Could not call xdshcoll \n";
@@ -1503,18 +1502,37 @@ sub storeresults
while (<XCOLL>)
{
$line = $_;
print FILE $line
print NEWOUTFILE $line
}
close(XCOLL);
close FILE;
close NEWOUTFILE;
system("/bin/rm $newtempfile");
# is device command, we get false errors from the Switch, check for
# blank error output lines and remove them. If there is nothing left
# then there really were no errors
my @newerrresult=();
my $processerrors =1;
if ($devicecommand==1) {
foreach my $line (@errresult)
{
my @newline = (split(/:/, $line));
if ($newline[1] !~ /^\s*$/) { # Not blank, then save it
push @newerrresult,$line;
}
}
my $arraysize=@newerrresult;
if ($arraysize < 1) {
$processerrors =0;
}
}
# capture errors
#
if (@errresult)
if ((@errresult) && ($processerrors ==1))
{ # if errors
my $rsp = {};
my $i = 0;
+16 -2
View File
@@ -667,6 +667,9 @@ sub decode_spd {
1066 => 8500,
1333 => 10600,
1600 => 12800,
1867 => 14900,
2133 => 17000,
2134 => 17000,
);
my %ddr3modcap = (
@@ -707,9 +710,20 @@ sub decode_spd {
}
$rethash->{product}->{name}=$memtypes{$spd[2]};
if ($spd[2] == 11) { #DDR3 spec applies
my $ftbdividend = $spd[9] >> 4;
my $ftbdivisor = $spd[9] & 0xf;
my $ftb = $ftbdividend/$ftbdivisor;
my $fineoffset = $spd[34];
if ($fineoffset & 0b10000000) {
#negative value, twos complement
$fineoffset = 0-(($fineoffset ^ 0xff) + 1);
}
$fineoffset = ($ftb * $fineoffset) * 10**-3;
my $mtb = $spd[10]/$spd[11];
my $speed = $speedfromclock{int(2/($mtb*$spd[12]*10**-3))};
$rethash->{product}->{name}="PC3-".$speed;
my $clock = int(2/(($mtb*$spd[12]+$fineoffset)*10**-3));
my $speed = $speedfromclock{$clock};
unless ($speed) { $speed = "UNKNOWN"; }
$rethash->{product}->{name}="PC3-".$speed." ($clock MT/s)";
if ($spd[8]&0b11000) {
$rethash->{product}->{name} .= " ECC";
}
+26 -3
View File
@@ -191,7 +191,7 @@ vmmaster => {
}
},
vm => {
cols => [qw(node mgr host migrationdest storage storagemodel cfgstore memory cpus nics nicmodel bootorder clockoffset virtflags master vncport textconsole powerstate beacon datacenter cluster guestostype othersettings vidmodel vidproto vidpassword comments disable)],
cols => [qw(node mgr host migrationdest storage storagemodel storagecache storageformat cfgstore memory cpus nics nicmodel bootorder clockoffset virtflags master vncport textconsole powerstate beacon datacenter cluster guestostype othersettings physlots vidmodel vidproto vidpassword comments disable)],
keys => [qw(node)],
tablespace =>'XCATTBS32K',
table_desc => 'Virtualization parameters',
@@ -222,14 +222,17 @@ vm => {
'vncport' => 'Tracks the current VNC display port (currently not meant to be set',
'textconsole' => 'Tracks the Psuedo-TTY that maps to the serial port or console of a VM',
'powerstate' => "This flag is used by xCAT to track the last known power state of the VM.",
'othersettings' => "This allows specifying a semicolon delimited list of key->value pairs to include in a vmx file of VMware.",
'othersettings' => "This allows specifying a semicolon delimited list of key->value pairs to include in a vmx file of VMware. For partitioning on normal power machines, this option is used to specify the hugepage and/or bsr information, the value is like:'hugepage:1,bsr=2'.",
'guestostype' => "This allows administrator to specify an identifier for OS to pass through to virtualization stack. Normally this should be ignored as xCAT will translate from nodetype.os rather than requiring this field be used\n",
'beacon' => "This flag is used by xCAT to track the state of the identify LED with respect to the VM.",
'datacenter' => "Optionally specify a datacenter for the VM to exist in (only applicable to VMWare)",
'cluster' => 'Specify to the underlying virtualization infrastructure a cluster membership for the hypervisor.',
'vidproto' => "Request a specific protocol for remote video access be set up. For example, spice in KVM.",
'physlots' => "Specify the physical slots drc index that will assigned to the partition, the delimiter is ',', and the drc index must started with '0x'. For more details, please reference to manpage of 'lsvm'.",
'vidmodel' => "Model of video adapter to provide to guest. For example, qxl in KVM",
'vidpassword' => "Password to use instead of temporary random tokens for VNC and SPICE access",
'storagecache' => "Select caching scheme to employ. E.g. KVM understands 'none', 'writethrough' and 'writeback'",
'storageformat' => "Select disk format to use by default (e.g. raw versus qcow2)",
}
},
hypervisor => {
@@ -1029,6 +1032,8 @@ site => {
" virtual network bridge up correctly. See\n".
" https://sourceforge.net/apps/mediawiki/xcat/index.php?title=XCAT_Virtualization_with_KVM#Setting_up_a_network_bridge\n\n".
" rsh/rcp will be setup and used on AIX. Default is yes.\n\n".
" useflowcontrol: (yes/1 or no/0). If yes, postscripts will use xcatd flow control. If no,\n".
" postscripts use wait and retry. Default is no.\n\n".
" useNFSv4onAIX: (yes/1 or no/0). If yes, NFSv4 will be used with NIM. If no,\n".
" NFSv3 will be used with NIM. Default is no.\n\n".
" vcenterautojoin: When set to no, the VMWare plugin will not attempt to auto remove\n".
@@ -1046,6 +1051,8 @@ site => {
" xcatmaxconnections: Number of concurrent xCAT protocol requests before requests\n".
" begin queueing. This applies to both client command requests\n".
" and node requests, e.g. to get postscripts. Default is 64.\n\n".
" xcatmaxbatchconnections: Number of concurrent xCAT connections allowed from the nodes.\n".
" Value must be less than xcatmaxconnections. Default is 50.\n".
" xcatdport: The port used by the xcatd daemon for client/server communication.\n\n".
" xcatiport: The port used by xcatd to receive install status updates from nodes.\n\n",
" xcatsslversion: The ssl version by xcatd. Default is SSLv3.\n\n",
@@ -2233,10 +2240,26 @@ my @nodeattrs = (
tabentry => 'vm.storage',
access_tabentry => 'vm.node=attr:node',
},
{attr_name => 'vmphyslots',
tabentry => 'vm.physlots',
access_tabentry => 'vm.node=attr:node',
},
{attr_name => 'vmothersetting',
tabentry => 'vm.othersettings',
access_tabentry => 'vm.node=attr:node',
},
{attr_name => 'vmstoragemodel',
tabentry => 'vm.storagemodel',
access_tabentry => 'vm.node=attr:node',
},
{attr_name => 'vmstoragecache',
tabentry => 'vm.storagecache',
access_tabentry => 'vm.node=attr:node',
},
{attr_name => 'vmstorageformat',
tabentry => 'vm.storageformat',
access_tabentry => 'vm.node=attr:node',
},
{attr_name => 'vmcfgstore',
tabentry => 'vm.cfgstore',
access_tabentry => 'vm.node=attr:node',
@@ -3222,7 +3245,7 @@ push(@{$defspec{group}->{'attrs'}}, @nodeattrs);
access_tabentry => 'firmware.file=attr:cfgfile',
},
{attr_name => 'disable',
tabentry => 'auditlog.disable',
tabentry => 'firmware.disable',
access_tabentry => 'firmware.file=attr:cfgfile',
},
);
+16 -12
View File
@@ -30,7 +30,6 @@ use strict;
Example:
my $retdata = xCAT::ServiceNodeUtils->readSNInfo;
=cut
#-----------------------------------------------------------------------------
sub readSNInfo
{
@@ -102,13 +101,17 @@ sub isServiceReq
require xCAT::Table;
my ($class, $servicenodename, $serviceip) = @_;
# list of all services from service node table
# note this must be updated if more services added
my @services = (
"nameserver", "dhcpserver", "tftpserver", "nfsserver",
"conserver", "monserver", "ldapserver", "ntpserver",
"ftpserver", "ipforward"
);
# get list of all services from service node table ( actually all defined attributes)
# read the schema
my $schema = xCAT::Table->getTableSchema("servicenode");
my @services; # list of only the actual service attributes from the servicenode table
my @servicesattrs; # building second copy for call to getAllNodeAttribs, which modifies the array
foreach my $c (@{$schema->{cols}}) {
if (($c ne "node") && ($c ne "comments") && ($c ne "disable")) {
push @servicesattrs,$c;
push @services,$c;
}
}
my @ips = @$serviceip; # list of service node ip addresses and names
my $rc = 0;
@@ -139,10 +142,11 @@ sub isServiceReq
}
my $servicehash;
# read all the nodes from the table, for each service
foreach my $service (@services)
# read all the nodes from the table, all the service attributes
my @snodelist= $servicenodetab->getAllNodeAttribs(\@servicesattrs);
foreach my $service (@services) # check list of services
{
my @snodelist = $servicenodetab->getAllNodeAttribs([$service]);
foreach $serviceip (@ips) # check the table for this servicenode
{
@@ -351,7 +355,7 @@ sub getSNList
$servicenodetab->close;
foreach my $node (@nodes)
{
if ($service eq "") # want all the service nodes
if (! defined ($service) || ($service eq "")) # want all the service nodes
{
push @servicenodes, $node->{node};
}
+94
View File
@@ -323,6 +323,8 @@ sub handle_dbc_request {
return $opentables{$tablename}->{$autocommit}->getAllNodeAttribs(@args);
} elsif ($functionname eq 'getAllEntries') {
return $opentables{$tablename}->{$autocommit}->getAllEntries(@args);
} elsif ($functionname eq 'getMAXMINEntries') {
return $opentables{$tablename}->{$autocommit}->getMAXMINEntries(@args);
} elsif ($functionname eq 'writeAllEntries') {
return $opentables{$tablename}->{$autocommit}->writeAllEntries(@args);
} elsif ($functionname eq 'getAllAttribsWhere') {
@@ -3988,5 +3990,97 @@ sub output_table {
print $fh "\n";
return 0;
}
#--------------------------------------------------------------------------
=head3 getMAXMINEntries
Description: Select the rows in the Table which has the MAX and the row with the
Min value for the input attribute.
Currently only the auditlog and evenlog are setup to have such an attribute (recid).
Arguments:
Table handle
attribute name ( e.g. recid)
Returns:
HASH
max=> max value
min=> min value
Globals:
Error:
Example:
my $tabh = xCAT::Table->new($table);
my $recs=$tabh->getMAXMINEntries("recid");
Comments:
none
=cut
#--------------------------------------------------------------------------------
sub getMAXMINEntries
{
my $self = shift;
if ($dbworkerpid) {
return dbc_call($self,'getMAXMINEntries',@_);
}
my $attr = shift;
my $rets;
my $query;
my $xcatcfg=get_xcatcfg();
# delimit the disable column based on the DB
my $disable= &delimitcol("disable");
my $qstring;
if ($xcatcfg =~ /^DB2:/) { # for DB2
$qstring = "SELECT MAX (\"$attr\") FROM " . $self->{tabname} . " WHERE " . $disable . " is NULL or " . $disable . " in ('0','no','NO','No','nO')";
} else {
$qstring = "SELECT MAX($attr) FROM " . $self->{tabname} . " WHERE " . $disable . " is NULL or " . $disable . " in ('0','no','NO','No','nO')";
}
$query = $self->{dbh}->prepare($qstring);
$query->execute();
while (my $data = $query->fetchrow_hashref())
{
foreach (keys %$data)
{
if ($data->{$_} =~ /^$/)
{
$rets->{"max"} = undef;
} else {
$rets->{"max"} = $data->{$_};
}
last; # better only be one value for max
}
}
$query->finish();
if ($xcatcfg =~ /^DB2:/) { # for DB2
$qstring = "SELECT MIN (\"$attr\") FROM " . $self->{tabname} . " WHERE " . $disable . " is NULL or " . $disable . " in ('0','no','NO','No','nO')";
} else {
$qstring = "SELECT MIN($attr) FROM " . $self->{tabname} . " WHERE " . $disable . " is NULL or " . $disable . " in ('0','no','NO','No','nO')";
}
$query = $self->{dbh}->prepare($qstring);
$query->execute();
while (my $data = $query->fetchrow_hashref())
{
foreach (keys %$data)
{
if ($data->{$_} =~ /^$/)
{
$rets->{"min"} = undef;
} else {
$rets->{"min"} = $data->{$_};
}
last; # better be only one value for min
}
}
return $rets;
}
1;
+55 -6
View File
@@ -257,6 +257,7 @@ sub bldnonrootSSHFiles
Arguments:
Array of nodes
Timeout for expect call (optional)
Returns:
Env Variables: $DSH_FROM_USERID, $DSH_TO_USERID, $DSH_REMOTE_PASSWORD
@@ -281,7 +282,7 @@ sub bldnonrootSSHFiles
#--------------------------------------------------------------------------------
sub setupSSH
{
my ($class, $ref_nodes) = @_;
my ($class, $ref_nodes,$expecttimeout) = @_;
my @nodes = $ref_nodes;
my @badnodes = ();
my $n_str = $nodes[0];
@@ -349,8 +350,9 @@ sub setupSSH
}
# generates new keys for root, if they do not already exist
# nodes not used on this option but in there to preserve the interface
my $rc=
xCAT::RemoteShellExp->remoteshellexp("k",$::CALLBACK,$::REMOTE_SHELL);
xCAT::RemoteShellExp->remoteshellexp("k",$::CALLBACK,$::REMOTE_SHELL,$n_str,$expecttimeout);
if ($rc != 0) {
$rsp->{data}->[0] = "remoteshellexp failed generating keys.";
xCAT::MsgUtils->message("E", $rsp, $::CALLBACK);
@@ -442,7 +444,7 @@ rmdir \"/tmp/$to_userid\" \n";
if ($enablenodes) { # node on list to setup nodetonodessh
chop $enablenodes; # remove last comma
$ENV{'DSH_ENABLE_SSH'} = "YES";
my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$enablenodes);
my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$enablenodes,$expecttimeout);
if ($rc != 0)
{
$rsp->{data}->[0] = "remoteshellexp failed sending keys to enablenodes.";
@@ -452,7 +454,7 @@ rmdir \"/tmp/$to_userid\" \n";
}
if ($disablenodes) { # node on list to setup nodetonodessh
chop $disablenodes; # remove last comma
my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$disablenodes);
my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$disablenodes,$expecttimeout);
if ($rc != 0)
{
$rsp->{data}->[0] = "remoteshellexp failed sending keys to disablenodes.";
@@ -462,7 +464,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);
my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$n_str,$expecttimeout);
if ($rc != 0)
{
$rsp->{data}->[0] = "remoteshellexp failed sending keys.";
@@ -476,7 +478,7 @@ rmdir \"/tmp/$to_userid\" \n";
foreach my $n (@testnodes)
{
my $rc=
xCAT::RemoteShellExp->remoteshellexp("t",$::CALLBACK,"/usr/bin/ssh",$n);
xCAT::RemoteShellExp->remoteshellexp("t",$::CALLBACK,"/usr/bin/ssh",$n,$expecttimeout);
if ($rc != 0)
{
push @badnodes, $n;
@@ -1735,4 +1737,51 @@ sub getimagenames()
$nodetab->close;
return @imagenames;
}
#-----------------------------------------------------------------------------
=head3 updatenodegroups
Update groups attribute for the specified node
Arguments:
node
tabhd: the handler of 'nodelist' table,
groups: the groups attribute need to be merged.
Can be an array or string.
Globals:
none
Error:
Example:
xCAT::TableUtils->updatenodegroups($node, $tab, $groups);
=cut
#-----------------------------------------------------------------------------
sub updatenodegroups {
my ($class, $node, $tabhd, $groups) = @_;
if (!$groups) {
$groups = $tabhd;
$tabhd = xCAT::Table->new('nodelist');
unless ($tabhd) {
xCAT::MsgUtils->message("E", " Could not read the nodelist table\n");
return;
}
}
my ($ent) = $tabhd->getNodeAttribs($node, ['groups']);
my @list = qw(all);
if (defined($ent) and $ent->{groups}) {
push @list, split(/,/,$ent->{groups});
}
if (ref($groups) eq 'ARRAY') {
push @list, @$groups;
} else {
push @list, split(/,/,$groups);
}
my %saw;
@saw{@list} = ();
@list = keys %saw;
$tabhd->setNodeAttribs($node, {groups=>join(",",@list)});
}
1;
+27 -12
View File
@@ -72,16 +72,16 @@ my %usage = (
rinv <noderange> [all|model|serial] [-V|--verbose]
rinv [-h|--help|-v|--version]
BMC specific:
rinv <noderange> [vpd|mprom|deviceid|uuid|guid]
rinv <noderange> [mprom|deviceid|uuid|guid|vpd [-t]|all [-t]]
MPA specific:
rinv <noderange> [firm|bios|diag|mprom|sprom|mparom|mac|mtm]
rinv <noderange> [firm|bios|diag|mprom|sprom|mparom|mac|mtm [-t]]
PPC specific(with HMC):
rinv <noderange> [bus|config|serial|model|firm|all]
rinv <noderange> [all|bus|config|serial|model|firm [-t]]
PPC specific(using Direct FSP Management):
rinv <noderange> [firm]
rinv <noderange> [deconfig [-x]]
Blade specific:
rinv <noderange> [mtm|serial|mac|bios|diag|mprom|mparom|firm|all]
rinv <noderange> [all|serial|mac|bios|diag|mprom|mparom|firm|mtm [-t]]
IBM Flex System Compute Node specific:
rinv <noderange> [firm]
VMware specific:
@@ -199,10 +199,14 @@ my %usage = (
"Usage:
Common:
mkvm [-h|--help|-v|--version]
For PPC(with HMC):
For PPC(with HMC) specific:
mkvm noderange -i id -l singlenode [-V|--verbose]
mkvm noderange -c destcec -p profile [-V|--verbose]
mkvm noderange --full [-V|--verbose]
PPC (using Direct FSP Management) specific:
mkvm noderange [--full]
mkvm noderange [vmcpus=min/req/max] [vmmemory=min/req/max]
[vmphyslots=drc_index1,drc_index2...] [vmothersetting=hugepage:N,bsr:N]
For KVM
mkvm noderange -m|--master mastername -s|--size disksize -f|--force
For zVM
@@ -216,7 +220,8 @@ my %usage = (
PPC (with HMC) specific:
lsvm <noderange> [-a|--all]
PPC (using Direct FSP Management) specific:
lsvm <noderange> [-l|--long]
lsvm <noderange> [-l|--long] --p775
lsvm <noderange>
zVM specific:
lsvm noderange
lsvm noderange --getnetworknames
@@ -231,9 +236,11 @@ my %usage = (
chvm <noderange> [-p profile][-V|--verbose]
chvm <noderange> <attr>=<val> [<attr>=<val>...]
PPC (using Direct FSP Management) specific:
chvm <noderange> [-p <profile>]
chvm <noderange> --p775 [-p <profile>]
chvm <noderange> --p775 -i <id> [-m <memory_interleaving>] -r <partition_rule>
chvm <noderange> [lparname=<*|name>]
chvm <noderange> -i <id> [-m <memory_interleaving>] -r <partition_rule>
chvm <noderange> [vmcpus=min/req/max] [vmmemory=min/req/max]
[vmphyslots=drc_index1,drc_index2...] [vmothersetting=hugepage:N,bsr:N]
VMware specific:
chvm <noderange> [-a size][-d disk][-p disk][--resize disk=size][--cpus count][--mem memory]
zVM specific:
@@ -264,7 +271,9 @@ my %usage = (
"rmvm" =>
"Usage: rmvm <noderange> [--service][-V|--verbose]
rmvm [-h|--help|-v|--version],
rmvm [-p] [-f]",
rmvm [-p] [-f]
PPC (using Direct FSP Management) specific:
rmvm <noderange>",
"lsslp" =>
"Usage: lsslp [-h|--help|-v|--version]
lsslp [<noderange>][-V|--verbose][-i ip[,ip..]][-w][-r|-x|-z][-n][-I][-s FRAME|CEC|MM|IVM|RSA|HMC|CMM|IMM2|FSP]
@@ -343,11 +352,11 @@ my %usage = (
renergy noderange [-V] { cappingstatus={on | enable | off | disable} | {cappingwatt|cappingvalue}=watt }",
"updatenode" =>
"Usage:
updatenode [-h|--help|-v|--version]
updatenode [-h|--help|-v|--version | -g|--genmypost]
or
updatenode <noderange> [-V|--verbose] [-k|--security] [-s|--sn]
updatenode <noderange> [-V|--verbose] [-k|--security] [-s|--sn] [-t <timeout>]
or
updatenode <noderange> [-V|--verbose] [-F|--sync | -f|--snsync] [-l|--user[username]] [--fanout=[fanout value]] [-S|--sw]
updatenode <noderange> [-V|--verbose] [-F|--sync | -f|--snsync] [-l|--user[username]] [--fanout=[fanout value]] [-S|--sw] [-t <timeout>]
[-P|--scripts [script1,script2,...]] [-s|--sn]
[-A|--updateallsw] [-c|--cmdlineonly] [-d alt_source_dir]
[attr=val [attr=val...]]
@@ -368,6 +377,9 @@ Options:
[-f|--snsync] Performs File Syncing to the service nodes that service
the nodes in the noderange.
[-g|--genmypost] Will generate a new mypostscript file for the
the nodes in the noderange, if site precreatemypostscripts is 1 or YES.
[-l|--user] User name to run the updatenode command. It overrides the
current user which is the default.
@@ -381,6 +393,9 @@ Options:
[-s|--sn] Set the server information stored on the nodes.
[-t|--timeout] Time out in seconds to allow the command to run. Default is no timeout,
except for updatenode -k which has a 10 second default timeout.
[-A|--updateallsw] Install or update all software contained in the source
directory. (AIX only)
+1 -1
View File
@@ -3165,7 +3165,7 @@ sub noderangecontainsMn
}
}
if ($mname) { # if Management Node defined in the database
if (grep(/$mname/, @noderange)) { # if MN in the noderange
if (grep(/^$mname$/, @noderange)) { # if MN in the noderange
return $mname;
} else {
return ;
+1 -1
View File
@@ -26,7 +26,7 @@ sub grab_table_data{ #grab table data relevent to VM guest nodes
if ($vpdtab) {
$cfghash->{vpd} = $vpdtab->getNodesAttribs($noderange,['uuid']);
}
$cfghash->{vm} = $vmtab->getNodesAttribs($noderange,['node','host','migrationdest','cfgstore','storage','vidmodel','vidproto','vidpassword','storagemodel','memory','cpus','nics','nicmodel','bootorder','virtflags','datacenter','guestostype','othersettings','master']);
$cfghash->{vm} = $vmtab->getNodesAttribs($noderange,['node','host','migrationdest','cfgstore','storage','storagecache','storageformat','vidmodel','vidproto','vidpassword','storagemodel','memory','cpus','nics','nicmodel','bootorder','virtflags','datacenter','guestostype','othersettings','master']);
my $mactab = xCAT::Table->new("mac",-create=>1);
my $nrtab= xCAT::Table->new("noderes",-create=>1);
$cfghash->{mac} = $mactab->getAllNodeAttribs(['mac'],1);
Regular → Executable
+3
View File
@@ -64,6 +64,7 @@ require Exporter;
"1305067719.718814" => "rhelhpc6.1",#x86_64
"1321545261.599847" => "rhelhpc6.2",#x86_64
"1339640148.070971" => "rhelhpc6.3",#x86_64
"1359576195.413831" => "rhelhpc6.4",#x86_64, RHEL ComputeNode
"1194015916.783841" => "fedora8",
"1194015385.299901" => "fedora8",
"1210112435.291709" => "fedora9",
@@ -75,6 +76,8 @@ require Exporter;
"1273712675.937554" => "fedora13", #x86_64 DVD ISO
"1287685820.403779" => "fedora14", #x86_64 DVD ISO
"1305315870.828212" => "fedora15", #x86_64 DVD ISO
"1372355769.065812" => "fedora19", #x86_64 DVD ISO
"1372402928.663653" => "fedora19", #ppc64 DVD ISO
"1194512200.047708" => "rhas4.6",
"1194512327.501046" => "rhas4.6",
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
package xCAT::data::ibmhwtypes;
require Exporter;
@EXPORT_OK=qw(parse_group mt2group);
use Data::Dumper;
my %groups2mtm = (
"x3250" => ["2583","4251","4252"],
"x3550" => ["7914","7944","7946"],
"x3650" => ["7915","7945"],
"dx360" => [],
"x220" => ["7906"],
"x240" => ["8737","7863"],
"x440" => ["7917"],
"p260" => ["7895"], #789522X, 789523X
"p460" => [], #789542X
"p470" => ["7954"],
);
%mt2group = ();
foreach my $group (keys %groups2mtm) {
foreach my $mtm (@{$groups2mtm{$group}}) {
$mt2group{$mtm} = $group;
}
}
sub parse_group {
my $mtm = shift;
if ($mtm =~ /xCAT::data/) {
$mtm = shift;
}
if ($mtm =~ /^(\w{4})/) {
$mt = $1;
if ($mt eq "7895" and $mtm =~ /789542X/i) {
return "p460";
}
return $mt2group{$mt};
}
return undef;
}
1;
+150 -104
View File
@@ -21,11 +21,8 @@ BEGIN
}
if ($^O =~ /^aix/i) {
print "ERROR - buildkit is not supported on AIX \n";
print "ERROR - the buildkit command is not supported on AIX \n";
exit 1;
# if AIX - make sure we include perl 5.8.2 in INC path.
# Needed to find perl dependencies shipped in deps tarball.
# unshift(@INC, qw(/usr/opt/perl5/lib/5.8.2/aix-thread-multi /usr/opt/perl5/lib/5.8.2 /usr/opt/perl5/lib/site_perl/5.8.2/aix-thread-multi /usr/opt/perl5/lib/site_perl/5.8.2));
}
use lib "$::XCATROOT/lib/perl";
@@ -37,7 +34,6 @@ use Cwd 'abs_path';
use File::Path;
use File::Basename;
#-----------------------------------------------------------------------------
# Main
@@ -396,7 +392,7 @@ while ($arg) {
$::current_dir = $::workdir;
}
if ( ! $::KIT_CREATE ) {
print "kit basename not specified for buildkit create command \n";
print "The Kit basename was not specified for the buildkit create command.\n";
&usage;
exit 1;
}
@@ -405,7 +401,7 @@ while ($arg) {
} elsif ( $command eq 'buildrepo' ) {
$::KIT_BUILDREPO=shift(@ARGV);
if ( ! $::KIT_BUILDREPO ) {
print "kit package repository name not specified for buildkit buildrepo command \n";
print "The Kit package repository name was not specified for buildkit buildrepo command.\n";
&usage;
exit 1;
}
@@ -427,17 +423,17 @@ while ($arg) {
} elsif ( $command eq 'addpkgs' ) {
$::KIT_ADDPKGS=shift(@ARGV);
if (!($::KIT_ADDPKGS)){
print "Missing parameter: <kit tarfile> must be specified with \'buildkit addpkgs\' \n";
print "Missing parameter: the <kit tarfile> name must be specified when using the \'buildkit addpkgs\' command.\n";
&usage;
exit (1);
}
if (!($::PKGDIR)){
print "Missing option: -p <pkgdir> must be specified with \'buildkit addpkgs\' \n";
print "Missing option: the -p <pkgdir> option must be specified with \'buildkit addpkgs\' command. \n";
&usage;
exit (1);
}
} else {
print "buildkit command $arg not recognized \n";
print "The buildkit command $arg is not recognized.\n";
&usage;
exit (1);
}
@@ -473,8 +469,6 @@ if ( $::KIT_CLEANALL ) {
}
if ( $::KIT_ADDPKGS ) { $rc = &kit_addpkgs; }
exit $rc;
#####################################
@@ -582,6 +576,7 @@ sub kit_create
}
print "Kit template for $kitname created in $kitdir directory \n";
return 0;
}
#-----------------------------------------------------------------------------
@@ -621,20 +616,20 @@ sub kit_chkconfig
#-----------------------------------------------------------------------------
sub kit_buildrepo
{
my $rc = 0;
my $repoid = $::KIT_BUILDREPO;
if ( !$debianflag ){
# Check if createrepo bin exists or not. Fail at the beginning.
if (! (-e "/usr/bin/createrepo") ) {
print "Error: /usr/bin/createrepo does not exist, install createrepo first\n";
# Check if createrepo exists or not. Fail at the beginning.
#- don't use specific path - may not be correct in build env
my $rcmd = "createrepo -h > /dev/null";
if ( system( $rcmd ) ) {
print "Error: the createrepo command does not seem to be installed. Make sure createrepo is installed before running the buildkit command. \n";
return 1;
}
}
$repoid =~ s/\s+//g;
$repoid =~ tr/A-Z/a-z/; # convert to lowercase
if ( $repoid ne 'all' ) {
@@ -644,7 +639,7 @@ sub kit_buildrepo
if ( &kit_buildrepo1($kr->{kitrepoid}) ) { return 1; }
}
}
return $rc;
}
#-----------------------------------------------------------------------------
@@ -656,11 +651,8 @@ sub kit_buildrepo
=cut
#-----------------------------------------------------------------------------
sub kit_buildrepo1
{
my $rc = 0;
my $repoid = shift;
$repoid =~ s/\s+//g;
@@ -808,7 +800,7 @@ sub kit_buildrepo1
# run createrepo
my $cr_opts = '';
if (( $repo->{osbasename} =~ m/rh|RH/ ) &&
if (( $repo->{osbasename} =~ m/rh|RH|centos|CentOS/ ) &&
( $repo->{osmajorversion} eq '5') ) {
$cr_opts = '-s md5';
}
@@ -820,8 +812,6 @@ sub kit_buildrepo1
return 0;
}
#-----------------------------------------------------------------------------
=head3 kit_listrepo
@@ -831,9 +821,7 @@ sub kit_buildrepo1
=cut
#-----------------------------------------------------------------------------
sub kit_listrepo
{
# print "Kit Repository: Status \n";
foreach my $kr (@{$::bldkit_config->{kitrepo}{entries}}) {
@@ -855,9 +843,7 @@ sub kit_listrepo
=cut
#-----------------------------------------------------------------------------
sub kit_cleanrepo
{
my $repoid = $::KIT_CLEANREPO;
my $tmp_repoid = $repoid;
@@ -892,6 +878,7 @@ sub kit_cleanrepo
}
if ( !$got_one ) {
print "Kit repository $repoid does not exist.\n";
return 1;
}
}
if ( -d "$::workdir/rpmbuild" ) {
@@ -916,9 +903,7 @@ sub kit_cleanrepo
=cut
#-----------------------------------------------------------------------------
sub kit_buildtar
{
foreach my $kr (@{$::bldkit_config->{kitrepo}{entries}}) {
if (&validate_repo($kr)) {
@@ -1029,7 +1014,7 @@ sub kit_cleantar
print "Removed $::workdir/debbuild\n";
}
}
return;
return 0;
}
#-----------------------------------------------------------------------------
@@ -1905,7 +1890,7 @@ sub build_kitcomp
}
return 0;
}
# find the kitrepo hash for this component
foreach my $kr (@{$::bldkit_config->{kitrepo}{entries}}) {
if ($comp->{kitrepoid} eq $kr->{kitrepoid}) {
@@ -1914,7 +1899,7 @@ sub build_kitcomp
}
}
my $repodir = $::base_repodir."/".$repo{kitreponame};
# Fix the kitpkgdeps value for this kitcomponent
# For any kitpkgdep that has an rpm file in the repo,
# specifically reference it's version-release
@@ -2057,34 +2042,63 @@ sub update_kitcomp_kitpkgdeps
my $repodir = shift;
if (defined($comp->{kitpkgdeps})) {
my $new_kitpkgdeps = '';
foreach my $d (split(/,/, $comp->{kitpkgdeps})) {
$d =~ s/\s+//g;
my $d_short = $d;
$d_short =~ s/^([\w\.\-]+)[<>=]*.*$/$1/;
if ( $d_short eq $d ) {
# no version-release comparisons specified for this kitpkgdep
# do we have an rpm file in the repo?
my $cmd = "rpm -q --qf \"%{NAME} >= %{VERSION}-%{RELEASE},\" -p $repodir/$d-\[0-9\]\*.rpm 2>/dev/null";
if ($::VERBOSE) {
print "running rpm query to get version-release info: \n $cmd \n";
}
my $new_d = `$cmd`;
chomp($new_d);
if ($::VERBOSE) {
print "output: \n \'$new_d\' \n";
}
if ( $new_d ne '' ) {
$new_kitpkgdeps .= "$new_d,";
# we have some rpms listed -n buildkit.conf file
my $new_kitpkgdeps = '';
foreach my $d (split(/,/, $comp->{kitpkgdeps})) {
$d =~ s/\s+//g;
my $d_short = $d;
# strip off everything after ">="
$d_short =~ s/^([\w\.\-]+)[<>=]*.*$/$1/;
# if they are the same then there was no v/r info provided
if ( $d_short eq $d ) {
# no version-release comparisons specified for this kitpkgdep
# do we have this rpm file?
# get a list of any matches
my $lscmd = "cd $repodir; /bin/ls $d-\[0-9\]\*.rpm 2>/dev/null";
my @rpmlist = `$lscmd`;
if ( scalar(@rpmlist) == 0) {
print "Error: Could not find rpm named $d in $repodir. \n";
next;
}
# get the newest version there is
my $newestrpm = xCAT::BuildKitUtils->get_latest_version($repodir, \@rpmlist);
if (!$newestrpm) {
print "Error: Could not determine the latest version of rpm $d contained in $repodir. \n";
next;
}
# get the Version and release values for this rpm
my $cmd = "rpm -q --qf \"%{NAME} >= %{VERSION}-%{RELEASE}\" -p $repodir/$newestrpm 2>/dev/null";
if ($::VERBOSE) {
print "running rpm query to get version-release info: \n $cmd \n";
}
my $new_d = `$cmd`;
if (!$new_d) {
print "Error: Could not determine the latest version of rpm $d. \n";
next;
}
chomp($new_d);
if ($::VERBOSE) {
print "output: \n \'$new_d\' \n";
}
if ( $new_d ne '' ) {
$new_kitpkgdeps .= "$new_d,";
} else {
$new_kitpkgdeps .= "$d,";
}
} else {
$new_kitpkgdeps .= "$d,";
}
} else {
$new_kitpkgdeps .= "$d,";
}
}
$new_kitpkgdeps =~ s/(\,)*$//;
$comp->{kitpkgdeps} = $new_kitpkgdeps;
$new_kitpkgdeps =~ s/(\,)*$//;
$comp->{kitpkgdeps} = $new_kitpkgdeps;
}
return 0;
}
@@ -2092,7 +2106,7 @@ sub update_kitcomp_kitpkgdeps
#-----------------------------------------------------------------------------
=head3 gen_kitcomp_spec
generate the rpm spec file for the kitcomponent metapkg rpm
input: kitcomponent hash
kitrepo hash
@@ -2505,9 +2519,7 @@ sub gen_kitcomp_debdir{
=cut
#-----------------------------------------------------------------------------
sub load_script
{
my $scriptname = shift;
my $SF;
@@ -2525,8 +2537,6 @@ sub load_script
return $script_contents;
}
#-----------------------------------------------------------------------------
=head3 create_kitconf
@@ -3076,15 +3086,17 @@ sub kit_addpkgs
{
# add RPM pkgs to an existing kit tarfile
my $kittarfile=$::KIT_ADDPKGS;
my $rpmdir = $::PKGDIR;
my $kitbfname = basename($kittarfile);
$kitbfname =~ s/.tar.bz2$//;
$kitbfname =~ s/.NEED_PRODUCT_PKGS$//;
my $tmpdir_base = "/tmp/buildkit_workdir/$kitbfname";
my $tmpdir_base = "/tmp/$kitbfname";
# - could be list of pkgdir s
my @pkgdirlist = split(",", $::PKGDIR);
# Cleanup - should have been removed when last command ran
# - but just in case
system ("rm -Rf /tmp/buildkit_workdir");
system ("rm -Rf $tmpdir_base");
# the tar file may not be in the current dir
$kittarfile = "$::workdir/$kittarfile";
@@ -3095,9 +3107,11 @@ sub kit_addpkgs
}
$kittarfile = abs_path($kittarfile);
if ( !(-d $rpmdir) ) {
print "The package directory $rpmdir could not be read. \n";
return 1;
foreach my $rpmdir (@pkgdirlist) {
if ( !(-d $rpmdir) ) {
print "The package directory $rpmdir could not be read. \n";
return 1;
}
}
# Create work directory
@@ -3109,7 +3123,7 @@ sub kit_addpkgs
if ( system("cd $tmpdir_base; tar -jxf $kittarfile ") ) {
print "Error extracting tarfile $kittarfile \n";
# Cleanup
system ("rm -Rf /tmp/buildkit_workdir");
system ("rm -Rf $tmpdir_base");
return 1;
}
my $tmp_kit_conf = `find $tmpdir_base -name kit.conf`;
@@ -3121,7 +3135,7 @@ sub kit_addpkgs
unless ( open( $CKF, "<", $tmp_kit_conf ) ) {
print "The Kit configuration file $tmp_kit_conf could not be read or was not included in the kit tar file. \n";
# Cleanup
system ("rm -Rf /tmp/buildkit_workdir");
system ("rm -Rf $tmpdir_base");
return 1;
}
my @lines = <$CKF>;
@@ -3159,6 +3173,8 @@ sub kit_addpkgs
exit 1;
}
my $rpmdir=$::PKGDIR;
my $ext_filename = '';
my $ext_reponames = '';
my $non_native_filename = '';
@@ -3231,7 +3247,7 @@ sub kit_addpkgs
if ( system("ls $fromfile > /dev/null") ){
print "The product package file $ext_filename could not be read from the package directory $rpmdir. \n";
# Cleanup
system ("rm -Rf /tmp/buildkit_workdir");
system ("rm -Rf $tmpdir_base");
return 1;
}
foreach my $repo (split(/,/, $ext_reponames)) {
@@ -3239,13 +3255,13 @@ sub kit_addpkgs
if ( ! -d ($repodir) && (! mkpath($repodir)) ) {
print "Error creating repository directory $repodir\n";
# Cleanup
system ("rm -Rf /tmp/buildkit_workdir");
system ("rm -Rf $tmpdir_base");
return 1;
}
if (system("cp -fp $fromfile $repodir")) {
print "Error copying package file $fromfile to $repodir \n";
# Cleanup
system ("rm -Rf /tmp/buildkit_workdir");
system ("rm -Rf $tmpdir_base");
return 1;
}
$create_repodata_list{$repodir}=1;
@@ -3277,7 +3293,7 @@ sub kit_addpkgs
if (!-d "$tdir" or !-d "$source_dir") {
print "Error open kitcomponent rpm build direcotry $tdir or $tdir/$non_native_kitcompname \n";
# Cleanup
system ("rm -Rf /tmp/buildkit_workdir");
system ("rm -Rf $tmpdir_base");
return 1;
}
@@ -3287,13 +3303,13 @@ sub kit_addpkgs
my $fromfile = $rpmdir."/".$tepmfilename;
if ( system("ls $fromfile > /dev/null") ){
print "The product package file $non_native_filename could not be read from the package directory $rpmdir. \n";
system ("rm -Rf /tmp/buildkit_workdir");
system ("rm -Rf $tmpdir_base");
return 1;
}
if (system("cp -fp $fromfile $tdir/$non_native_kitcompname")) {
print "Error copying package file $fromfile to $tdir/$non_native_kitcompname \n";
# Cleanup
system ("rm -Rf /tmp/buildkit_workdir");
system ("rm -Rf $tmpdir_base");
return 1;
}
}
@@ -3318,7 +3334,7 @@ sub kit_addpkgs
if (!-r "$spec") {
print "Error open kitcomponent rpm build spec $tdir/$non_native_kitcompname.spec \n";
# Cleanup
system ("rm -Rf /tmp/buildkit_workdir");
system ("rm -Rf $tmpdir_base");
return 1;
}
my $rpmbuild_dir = $tmpdir."/rpmbuild";
@@ -3401,7 +3417,7 @@ sub kit_addpkgs
if (system( $createrepocmd )) {
print "Error running $createrepocmd. \n";
# Cleanup
system ("rm -Rf /tmp/buildkit_workdir");
system ("rm -Rf $tmpdir_base");
return 1;
}
}
@@ -3411,13 +3427,13 @@ sub kit_addpkgs
if ( system("cd $tmpdir; cd ..; tar -cjhf $new_tarfile $kitname/*") ) {
print "Error building tarfile $new_tarfile \n";
# Cleanup
system ("rm -Rf /tmp/buildkit_workdir");
system ("rm -Rf $tmpdir_base");
return 1;
}
print "Kit tar file $new_tarfile successfully built \n";
# Cleanup
system ("rm -Rf /tmp/buildkit_workdir");
system ("rm -Rf $tmpdir_base");
return 0;
}
@@ -3435,7 +3451,9 @@ sub NEW_kit_addpkgs
# add RPM pkgs to an existing kit tarfile
my $tmpdir_base = shift;
my $tmpdir = shift;
my $rpmdir = $::PKGDIR;
# - could be list of pkgdir dirs
my @pkgdirlist = split(",", $::PKGDIR);
$::NEW_PARTIAL_KIT = 1;
$::workdir = "$tmpdir_base/build_input";
@@ -3447,12 +3465,13 @@ sub NEW_kit_addpkgs
if ($tmp_buildkit_conf ne $::full_buildkit_conf) {
print "$tmp_buildkit_conf should match $::full_buildkit_conf .... error??? \n";
}
my $loadrc = &load_bldkitconf($tmp_buildkit_conf);
if ( $loadrc != 0 ) {
print "Error reading buildkit config file $tmp_buildkit_conf \n";
return 1;
}
if ( defined($::KITVERSION) ) {
$::bldkit_config->{kit}{entries}[0]->{version} = $::KITVERSION;
}
@@ -3465,6 +3484,7 @@ sub NEW_kit_addpkgs
print "Error validating buildkit config file $tmp_buildkit_conf \n";
return 1;
}
if ($tmpdir ne $::deploy_dir) {
if (system ("mv $tmpdir $::deploy_dir ") ) {
print "Error moving $tmpdir to $::deploy_dir \n";
@@ -3475,40 +3495,53 @@ sub NEW_kit_addpkgs
$::base_repodir = "$::deploy_dir/repos";
my $kitname = $::bldkit_config->{kit}{entries}[0]->{kitname};
# Handle external packages
# Handle external packages
if ($::HAVE_EXTERNAL_PKG) {
foreach my $kp (@{$::bldkit_config->{kitpackage}{entries}}) {
if ($kp->{isexternalpkg} eq 'yes') {
my $ext_filename = $kp->{filename};
my $ext_reponames = $kp->{kitreponame};
my $fromfile = $rpmdir."/".$ext_filename;
if ( system("ls $fromfile > /dev/null") ){
print "The product package file $ext_filename could not be read from the package directory $rpmdir. \n";
my $files = xCAT::BuildKitUtils->find_latest_pkg(\@pkgdirlist, $ext_filename);
my @fromfiles=@$files;
if (scalar(@fromfiles) ==0 ) {
print "Error: The product package file $ext_filename was not found in the package directory(s) @pkgdirlist.\n";
# Cleanup
system ("rm -Rf /tmp/buildkit_workdir");
system ("rm -Rf $tmpdir_base");
return 1;
}
foreach my $repo (split(/,/, $ext_reponames)) {
my $repodir = $::base_repodir."/".$repo;
if ( ! -d ($repodir) && (! mkpath($repodir)) ) {
print "Error creating repository directory $repodir\n";
# Cleanup
system ("rm -Rf /tmp/buildkit_workdir");
system ("rm -Rf $tmpdir_base");
return 1;
}
foreach my $fromfile (@fromfiles) {
if (system("cp -fp $fromfile $repodir")) {
print "Error copying package file $fromfile to $repodir \n";
# Cleanup
system ("rm -Rf /tmp/buildkit_workdir");
system ("rm -Rf $tmpdir_base");
return 1;
}
}
if ($::VERBOSE) {
print "Copied @fromfiles\n to $repodir\n";
}
}
}
}
}
# Handle non_native_pkgs
# Comma-separated list of non-native package
# paths that will be included as files in this kit
# component.
# these are not RPMs!
my $to_source_dir = "$::workdir/source_packages";
mkpath("$to_source_dir");
foreach my $kc (@{$::bldkit_config->{kitcomponent}{entries}}) {
@@ -3519,16 +3552,28 @@ sub NEW_kit_addpkgs
if ("$key" =~ /EXTERNALPKGS/) {
#the $non_native_filename may contain several pkgs, can check and copy at the same time
foreach my $nnpkg (split(/,/, $value)){
my $fromfile = $rpmdir."/".$nnpkg;
if ( system("ls $fromfile > /dev/null") ){
print "The product package file $nnpkg could not be read from the package directory $rpmdir. \n";
return 1;
}
if (system("cp -fp $fromfile $to_source_dir")) {
print "Error copying package file $fromfile to $to_source_dir \n";
return 1;
}
my $found=0;
foreach my $pdir (@pkgdirlist) {
my $fromfile = $pdir."/".$nnpkg;
if ( system("ls $fromfile > /dev/null") ){
next;
} else {
$found++;
if (system("cp -fp $fromfile $to_source_dir")) {
print "Error copying package file $fromfile to $to_source_dir \n";
# Cleanup
system ("rm -Rf $tmpdir_base");
next;
} else {
if ($::VERBOSE) {
print "Copied $fromfile to $to_source_dir\n";
}
}
}
}
if (!$found) {
print "Could not find $nnpkg.\n";
}
}
}
}
@@ -3539,6 +3584,7 @@ sub NEW_kit_addpkgs
$::HAVE_EXTERNAL_PKG = '';
$::HAVE_NON_NATIVE_PKGS = '';
$::NON_NATIVE_PKGS = {};
foreach my $kc (@{$::bldkit_config->{kitcomponent}{entries}}) {
my $rc=0;
if ( $debianflag ){
@@ -3552,12 +3598,13 @@ sub NEW_kit_addpkgs
return 1;
}
}
# run createrepo
foreach my $kr (@{$::bldkit_config->{kitrepo}{entries}}) {
my $repodir = "$::base_repodir/$kr->{kitreponame}";
if ( -d $repodir ) {
my $cr_opts = '';
if (( $kr->{osbasename} =~ m/rh|RH/ ) &&
if (( $kr->{osbasename} =~ m/rh|RH|centos|CentOS/ ) &&
( $kr->{osmajorversion} eq '5') ) {
$cr_opts = '-s md5';
}
@@ -3575,12 +3622,11 @@ sub NEW_kit_addpkgs
}
}
# Build the full kit tar file
my $buildtar_rc = &kit_buildtar;
# clean out the tmp dir
system ("rm -Rf /tmp/buildkit_workdir");
system ("rm -Rf $tmpdir_base");
if ($buildtar_rc) {
print "Error building full kit tarfile \n";
+258 -89
View File
@@ -13,12 +13,15 @@ if ($^O =~ /^aix/i) {
unshift(@INC, qw(/usr/opt/perl5/lib/5.8.2/aix-thread-multi /usr/opt/perl5/lib/5.8.2 /usr/opt/perl5/lib/site_perl/5.8.2/aix-thread-multi /usr/opt/perl5/lib/site_perl/5.8.2));
}
use lib "$::XCATROOT/lib/perl";
use POSIX qw(ceil);
use File::Path;
use Socket;
use strict;
use Symbol;
my $sha1support;
if ( -f "/etc/debian_version" ) {
$sha1support = eval {
require Digest::SHA;
@@ -50,6 +53,255 @@ This program module file, is a set of utilities used by xCAT buildkit command
#-------------------------------------------------------------
#--------------------------------------------------------------------------
=head3 get_latest_version
Find the latest version in a list of rpms with the same basename
Arguments:
- the repo location
- a list of rpms with the same basename
Returns:
- name of rpm
- undef
Example:
my $new_d = xCAT::BuildKitUtils->get_latest_version($repodir, \@rpmlist);
Comments:
=cut
#--------------------------------------------------------------------------
sub get_latest_version
{
my ($class, $repodir, $rpms) = @_;
my @rpmlist = @$rpms;
my %localversions_hash = ();
my %file_name_hash = ();
my $i = 0;
foreach my $rpm (@rpmlist)
{
# include path
my $fullrpmpath = "$repodir/$rpm*";
# get the basename, version, and release for this rpm
my $rcmd = "rpm -qp --queryformat '%{N} %{V} %{R}\n' $repodir/$rpm";
my $out = `$rcmd`;
my ($rpkg, $VERSION, $RELEASE) = split(' ', $out);
chomp $VERSION;
chomp $RELEASE;
$localversions_hash{$i}{'VERSION'} = $VERSION;
$localversions_hash{$i}{'RELEASE'} = $RELEASE;
$file_name_hash{$VERSION}{$RELEASE} = $rpm;
$i++;
}
if ($i == 0)
{
print "error\n";
return undef;
}
my $versionout = "";
my $releaseout = "";
$i = 0;
foreach my $k (keys %localversions_hash)
{
if ($i == 0)
{
$versionout = $localversions_hash{$k}{'VERSION'};
$releaseout = $localversions_hash{$k}{'RELEASE'};
}
# if this is a newer version/release then set them
if ( xCAT::BuildKitUtils->testVersion($localversions_hash{$k}{'VERSION'}, ">", $versionout, $localversions_hash{$k}{'RELEASE'}, $releaseout) ) {
$versionout = $localversions_hash{$k}{'VERSION'};
$releaseout = $localversions_hash{$k}{'RELEASE'};
}
$i++;
}
if ($i == 0)
{
print "Error: Could not determine the latest version for the following list of rpms: @rpmlist\n";
return undef;
} else {
return ($file_name_hash{$versionout}{$releaseout});
}
}
#--------------------------------------------------------------------------
=head3 find_latest_pkg
Find the latest rpm package give the rpm name and a list of
possible package locations.
Arguments:
- a list of package directories
- the name of the rpm
Returns:
- \@foundrpmlist
- undef
Example:
my $newrpm = xCAT::BuildKitUtils->find_latest_pkg(\@pkgdirs, $rpmname);
Comments:
=cut
#--------------------------------------------------------------------------
sub find_latest_pkg
{
my ($class, $pkgdirs, $rpmname) = @_;
my @pkgdirlist = @$pkgdirs;
my @rpms;
my %foundrpm;
# need to check each pkgdir for the rpm(s)
# - if more than one match need to pick latest
# find all the matches in all the directories
foreach my $rpmdir (@pkgdirlist) {
my $ffile = $rpmdir."/".$rpmname;
if ( system("/bin/ls $ffile > /dev/null 2>&1") ){
# if not then skip to next dir
next;
} else {
# if so then get the details and add it to the %foundrpm hash
my $cmd = "/bin/ls $ffile 2>/dev/null";
my $output = `$cmd`;
my @rpmlist = split(/\n/, $output);
if ( scalar(@rpmlist) == 0) {
# no rpms to check
next;
}
foreach my $r (@rpmlist) {
my $rcmd = "rpm -qp --queryformat '%{N} %{V} %{R}\n' $r*";
my $out = `$rcmd`;
my ($name, $fromV, $fromR) = split(' ', $out);
chomp $fromV;
chomp $fromR;
# ex. {ppe_rte_man}{/tmp/rpm1/ppe_rte_man-1.3.0.5-s005a.x86_64.rpm}{version}=$fromV;
$foundrpm{$name}{$r}{version}=$fromV;
$foundrpm{$name}{$r}{release}=$fromR;
#print "name=$name, full=$r, verson= $fromV, release=$fromR\n";
}
}
}
# for each unique rpm basename
foreach my $r (keys %foundrpm ) {
# if more than one with same basename then find the latest
my $latestmatch="";
foreach my $frpm (keys %{$foundrpm{$r}} ) {
# if we already found a match in some other dir
if ($latestmatch) {
# then we need to figure out which is the newest
# if the $frpm is newer than use it
if ( xCAT::BuildKitUtils->testVersion($foundrpm{$r}{$frpm}{version}, ">", $foundrpm{$r}{$latestmatch}{version}, $foundrpm{$r}{$frpm}{release}, $foundrpm{$r}{$latestmatch}{release}) ) {
$latestmatch = $frpm;
}
} else {
$latestmatch = $frpm;
}
}
push(@rpms, $latestmatch);
}
if (scalar(@rpms)) {
return \@rpms;
} else {
return undef;
}
}
#------------------------------------------------------------------------------
=head3 testVersion
Compare version1 and version2 according to the operator and
return True or False.
Arguments:
$version1
$operator
$version2
$release1
$release2
Returns:
True or False
Example:
Comments:
The return value is generated with the Require query of the
rpm command.
=cut
#-----------------------------------------------------------------------------
sub testVersion
{
my ($class, $version1, $operator, $version2, $release1, $release2) = @_;
my @a1 = split(/\./, $version1);
my @a2 = split(/\./, $version2);
my $len = (scalar(@a1) > scalar(@a2) ? scalar(@a1) : scalar(@a2));
$#a1 = $len - 1; # make the arrays the same length before appending release
$#a2 = $len - 1;
push @a1, split(/\./, $release1);
push @a2, split(/\./, $release2);
$len = (scalar(@a1) > scalar(@a2) ? scalar(@a1) : scalar(@a2));
my $num1 = '';
my $num2 = '';
for (my $i = 0 ; $i < $len ; $i++)
{
# remove any non-numbers on the end
my ($d1) = $a1[$i] =~ /^(\d*)/;
my ($d2) = $a2[$i] =~ /^(\d*)/;
my $diff = length($d1) - length($d2);
if ($diff > 0) # pad d2
{
$num1 .= $d1;
$num2 .= ('0' x $diff) . $d2;
}
elsif ($diff < 0) # pad d1
{
$num1 .= ('0' x abs($diff)) . $d1;
$num2 .= $d2;
}
else # they are the same length
{
$num1 .= $d1;
$num2 .= $d2;
}
}
# Remove the leading 0s or perl will interpret the numbers as octal
$num1 =~ s/^0+//;
$num2 =~ s/^0+//;
# be sure that $num1 is not a "".
if (length($num1) == 0) { $num1 = 0; }
if (length($num2) == 0) { $num2 = 0; }
if ($operator eq '=') { $operator = '=='; }
my $bool = eval "$num1 $operator $num2";
return $bool;
}
#-------------------------------------------------------------------------------
@@ -111,95 +363,6 @@ sub get_OS_VRMF
return (length($version) ? $version : undef);
}
#----------------------------------------------------------------------------
=head3 testversion
Compare version1 and version2 according to the operator and
return True or False.
Arguments:
$version1
$operator
$version2
$release1
$release2
Returns:
True or False
Example:
if (BuildKitUtils->testversion ( $ins_ver,
"<",
$req_ver,
$ins_rel,
$req_rel)){ blah; }
Comments:
=cut
#-------------------------------------------------------------------------------
sub testversion
{
my ($class, $version1, $operator, $version2, $release1, $release2) = @_;
my @a1 = split(/\./, $version1);
my @a2 = split(/\./, $version2);
my $len = (scalar(@a1) > scalar(@a2) ? scalar(@a1) : scalar(@a2));
$#a1 = $len - 1; # make the arrays the same length before appending release
$#a2 = $len - 1;
push @a1, split(/\./, $release1);
push @a2, split(/\./, $release2);
$len = (scalar(@a1) > scalar(@a2) ? scalar(@a1) : scalar(@a2));
my $num1 = '';
my $num2 = '';
for (my $i = 0 ; $i < $len ; $i++)
{
my ($d1) = $a1[$i] =~ /^(\d*)/; # remove any non-numbers on the end
my ($d2) = $a2[$i] =~ /^(\d*)/;
my $diff = length($d1) - length($d2);
if ($diff > 0) # pad d2
{
$num1 .= $d1;
$num2 .= ('0' x $diff) . $d2;
}
elsif ($diff < 0) # pad d1
{
$num1 .= ('0' x abs($diff)) . $d1;
$num2 .= $d2;
}
else # they are the same length
{
$num1 .= $d1;
$num2 .= $d2;
}
}
# Remove the leading 0s or perl will interpret the numbers as octal
$num1 =~ s/^0+//;
$num2 =~ s/^0+//;
#SLES Changes ??
# if $num1="", the "eval '$num1 $operator $num2'" will fail.
# So MUST BE be sure that $num1 is not a "".
if (length($num1) == 0) { $num1 = 0; }
if (length($num2) == 0) { $num2 = 0; }
#End of SLES Changes
if ($operator eq '=') { $operator = '=='; }
my $bool = eval "$num1 $operator $num2";
if (length($@))
{
# error msg ?
}
return $bool;
}
#-------------------------------------------------------------------------------
=head3 isLinux
@@ -387,6 +550,12 @@ sub osver
$ver = $lines[0];
$ver =~ s/\.//;
$ver =~ s/[^0-9]*([0-9]+).*/$1/;
my $minorver;
if (grep /PATCHLEVEL/, $lines[2]) {
$minorver = $lines[2];
$minorver =~ s/PATCHLEVEL[^0-9]*([0-9]+).*/$1/;
}
$ver = $ver . ".$minorver" if ( $minorver );
}
elsif (-f "/etc/UnitedLinux-release")
{
@@ -171,6 +171,12 @@ sub process_request {
# Do the check
my $imageprofile = parse_str_arg($request->{arg}->[0]);
if (! exists($request->{kitdata}))
{
$rsp->{data}->[0] = "Skipped running \"$command\" plugin command for \"$PLUGIN_KITNAME\" kit.";
xCAT::MsgUtils->message("I", $rsp, $callback);
return;
}
my $kitdata = $request->{kitdata};
if (! defined($kitdata)) {
$kitdata = xCAT::KitPluginUtils->get_kits_used_by_image_profiles([$imageprofile]);
@@ -742,4 +748,4 @@ sub parse_list_arg {
}
1;
1;
+2 -1
View File
@@ -219,6 +219,7 @@ sub asunode {
my $passwd = shift;
my $batchfile = shift;
my $args;
$bmc =~ s/,.*//;
if ($batchfile) {
$args = "batch $batchfile";
} else {
@@ -386,7 +387,7 @@ sub getdefaultcredentials {
last;
}
}
if (!defined($user) || !defined($pw)) { die "Did not find the ipmi username and password in the xCAT passwd table.\n"; }
if (!defined($user) || !defined($pw)) { $user = "USERID"; $pw = "PASSW0RD"; }
return ($user, $pw);
}
-1
View File
@@ -12,7 +12,6 @@ $XML::Simple::PREFERRED_PARSER='XML::Parser';
use IO::Handle;
use IO::Select;
use Thread qw(yield);
use xCAT::Utils;
use Getopt::Long qw(:config pass_through require_order);
use POSIX qw(:signal_h :errno_h :sys_wait_h);
my $interface;
+30 -4
View File
@@ -14,7 +14,6 @@ $XML::Simple::PREFERRED_PARSER='XML::Parser';
#use Data::Dumper;
use IO::Handle;
use IO::Select;
use xCAT::Utils;
use Getopt::Long;
use POSIX qw(:signal_h :errno_h :sys_wait_h);
use Thread qw(yield);
@@ -30,7 +29,7 @@ if (!GetOptions(
"nonodecheck" => \$::NONODECHECK, #does not check the noderange, in this case, noderange need to be a list of nodes.
'h|help' => \$help,
) || $help || scalar(@ARGV)<2 ) {
print "Usage: psh [-i <interface>] [-l <user>] [-f <fanout>] <noderange> <command>\n";
print "Usage: psh [-i <interface>] [-l <user>] [-f <fanout>] [--nonodecheck] <noderange> <command>\n";
exit;
}
my %nodehdl;
@@ -171,9 +170,36 @@ sub sshnode {
if (length($username)) { $username = "-l $username"; }
my $in;
my $args = join(" ",@_);
#print "ssh -o BatchMode=yes $username $node " . xCAT::Utils->quote($args) . " 2>&1 |\n";
my $pid = open($$out,"ssh -o BatchMode=yes $username $node " . xCAT::Utils->quote($args) . " 2>&1 |");
#print "ssh -o BatchMode=yes $username $node " . &quote($args) . " 2>&1 |\n";
my $pid = open($$out,"ssh -o BatchMode=yes $username $node " . &quote($args) . " 2>&1 |");
$pids{$pid} = $node;
}
sub quote
{
my $str = shift;
# if the value has imbedded double quotes, use single quotes. If it also has
# single quotes, escape the double quotes.
if (!($str =~ /\"/)) # no embedded double quotes
{
$str =~ s/\$/\\\$/sg; # escape the dollar signs
$str =~ s/\`/\\\`/sg;
$str = qq("$str");
}
elsif (!($str =~ /\'/))
{
$str = qq('$str');
} # no embedded single quotes
else # has both embedded double and single quotes
{
# Escape the double quotes. (Escaping single quotes does not seem to work
# in the shells.)
$str =~ s/\"/\\\"/sg; #" this comment helps formating
$str =~ s/\$/\\\$/sg; # escape the dollar signs
$str =~ s/\`/\\\`/sg;
$str = qq("$str");
}
}
# vim: set et ts=2 sts=2 sw=2 :
+2
View File
@@ -88,6 +88,7 @@ if (
'v|version' => \$::VERSION,
'V|verbose' => \$::VERBOSE,
'F|sync' => \$::FILESYNC,
'g|genmypost' => \$::GENMYPOST,
'f|snsync' => \$::SNFILESYNC,
'l|user:s' => \$::USER,
'S|sw' => \$::SWMAINTENANCE,
@@ -96,6 +97,7 @@ if (
'k|security' => \$::SECURITY,
'o|os:s' => \$::OS,
'fanout=i' => \$::fanout,
't|timetout=i' => \$::timeout,
)
) {
&updatenode_usage();
+76 -13
View File
@@ -1,6 +1,6 @@
=head1 NAME
B<chvm> - Changes HMC-, IVM-, and zVM-managed partition profiles or virtual machines. For Power 775, chvm could be used to change the octant configuration values for generating LPARs; change the I/O slots assignment to LPARs within the same CEC.
B<chvm> - Changes HMC-, DFM-, IVM-, and zVM-managed partition profiles or virtual machines. For Power 775, chvm could be used to change the octant configuration values for generating LPARs; change the I/O slots assignment to LPARs within the same CEC.
=head1 SYNOPSIS
@@ -16,11 +16,14 @@ B<chvm> [B<-V>| B<--verbose>] I<noderange> I<attr>=I<val> [I<attr>=I<val>...]
=head2 PPC (using Direct FSP Management) specific:
B<chvm> I<noderange> [B<-p> I<profile>]
B<chvm> I<noderange> I<--p775> [B<-p> I<profile>]
B<chvm> I<noderange> I<--p775> B<-i id> [B<-m> I<memory_interleaving>] B<-r> I<partition_rule>
B<chvm> I<noderange> [B<lparname>={B<*>|B<name>}]
B<chvm> I<noderange> B<-i id> [B<-m> I<memory_interleaving>] B<-r> I<partition_rule>
B<chvm> I<noderange> [B<vmcpus=min/req/max>] [B<vmmemory=min/req/max>]
[B<vmphyslots=drc_index1,drc_index2...>] [B<vmothersetting=hugepage:N,bsr:N>]
=head2 VMware/KVM specific:
@@ -98,12 +101,18 @@ This command also supports to change specific partition attributes by specifying
=head2 PPC (using Direct FSP Management) specific:
For Power 755(use option I<--p775> to specify):
chvm could be used to change the octant configuration values for generating LPARs. chvm is designed to set the Octant configure value to split the CPU and memory for partitions, and set Octant Memory interleaving value. The chvm will only set the pending attributes value. After chvm, the CEC needs to be rebooted manually for the pending values to be enabled. Before reboot the cec, the administrator can use chvm to change the partition plan. If the the partition needs I/O slots, the administrator should use chvm to assign the I/O slots.
chvm is also designed to assign the I/O slots to the new LPAR. Both the current IO owning lpar and the new IO owning lpar must be powered off before an IO assignment. Otherwise, if the I/O slot is belonged to an Lpar and the LPAR is power on, the command will return an error when trying to assign that slot to a different lpar.
The administrator should use lsvm to get the profile content, and then edit the content, and add the node name with ":" manually before the I/O which will be assigned to the node. And then the profile can be piped into the chvm command, or changed with the -p flag.
For normal power machine:
chvm could be used to modify the resources assigned to partitions. The admin shall specify the attributes with options I<vmcpus>, I<vmmemory>, I<vmphyslots> and/or I<vmothersetting>. If nothing specified, nothing will be returned.
=head2 VMware/KVM specific:
The chvm command modifes the vm specified in noderange. Calling with deregister or purge options at the same time as the resize option is not recommended.
@@ -150,17 +159,21 @@ Verbose output.
=over 10
=item B<--p775>
Specify the operation is for Power 775 machines.
=item B<-i>
Starting numeric id of the newly created partitions. For Power 775 using Direct FSP Management, the id value only could be B<1>, B<5>, B<9>, B<13>, B<17>, B<21>, B<25> and B<29>.
Starting numeric id of the newly created partitions. For Power 775 using Direct FSP Management, the id value only could be B<1>, B<5>, B<9>, B<13>, B<17>, B<21>, B<25> and B<29>. Shall work with option B<--p775>.
=item B<-m>
memory interleaving. The setting value only could be B<1> or B<2>. B<2> means B<non-interleaved> mode (also 2MC mode), the memory cannot be shared across the processors in an octant. B<1> means B<interleaved> mode (also 8MC mode) , the memory can be shared. The default value is B<1> .
memory interleaving. The setting value only could be B<1> or B<2>. B<2> means B<non-interleaved> mode (also 2MC mode), the memory cannot be shared across the processors in an octant. B<1> means B<interleaved> mode (also 8MC mode) , the memory can be shared. The default value is B<1>. Shall work with option B<--p775>.
=item B<-r>
partition rule.
partition rule. Shall work with option B<--p775>.
If all the octants configuration value are same in one CEC, it will be " B<-r> B<0-7>:I<value>" .
@@ -176,12 +189,16 @@ The octants configuration value for one Octant could be B<1>, B<2>, B<3>, B<4>,
=item B<-p> I<profile>
Name of I/O slots assignment profile.
Name of I/O slots assignment profile. Shall work with option B<--p775>.
=item B<lparname>={B<*>|B<name>}
Set LPAR name for the specified lpars. If '*' specified, it means to get names from xCAT database and then set them for the specified lpars. If a string is specified, it only supports single node and the string will be set for the specified lpar. The user can use lsvm to check the lparnames for lpars.
=item B<vmcpus=value> B<vmmemory=value> B<vmphyslots=value> B<vmothersetting=value>
To specify the parameters that will be modified.
=back
=head2 VMware/KVM specific:
@@ -385,7 +402,7 @@ Output is similar to:
then:
chvm lpar1 -i 1 -m 1 -r 0:1
chvm lpar1 --p775 -i 1 -m 1 -r 0:1
Output is similar to:
@@ -398,7 +415,7 @@ Output is similar to:
then:
chvm lpar1-lpar8 -i 1 -m 1 -r 0-7:1
chvm lpar1-lpar8 --p775 -i 1 -m 1 -r 0-7:1
Output is similar to:
@@ -418,7 +435,7 @@ Output is similar to:
then:
chvm lpar1-lpar9 -i 1 -m 1 -r 0:5,1-7:1
chvm lpar1-lpar9 --p775 -i 1 -m 1 -r 0:5,1-7:1
Output is similar to:
@@ -441,11 +458,11 @@ Output is similar to:
then run the command:
cat /tmp/lparfile | chvm lpar4
cat /tmp/lparfile | chvm lpar4 --p775
5. To change the I/O slot profile for lpar1-lpar8 using the configuration data in the file /tmp/lparfile. Users can use the output of lsvm.and remove the cec information, and modify the lpar id before each I/O, and run the command as following:
chvm lpar1-lpar8 -p /tmp/lparfile
chvm lpar1-lpar8 --p775 -p /tmp/lparfile
6. To change the LPAR name, enter:
@@ -454,6 +471,52 @@ then run the command:
Output is similar to:
lpar1: Success
7. For Normal Power machine, to modify the resource assigned to a partition:
Before modify, the resource assigned to node 'lpar1' can be shown with:
lsvm lpar1
The output is similar to:
lpar1: Lpar Processor Info:
Curr Processor Min: 1.
Curr Processor Req: 4.
Curr Processor Max: 16.
lpar1: Lpar Memory Info:
Curr Memory Min: 1.00 GB(4 regions).
Curr Memory Req: 4.00 GB(16 regions).
Curr Memory Max: 32.00 GB(128 regions).
lpar1: 1,513,U78AA.001.WZSGVU7-P1-T7,0x21010201,0xc03(USB Controller)
lpar1: 1,512,U78AA.001.WZSGVU7-P1-T9,0x21010200,0x104(RAID Controller)
lpar1: 1/2/2
lpar1: 128.
To modify the resource assignment:
chvm lpar1 vmcpus=1/2/16 vmmemory=1G/8G/32G vmphyslots=0x21010202
The output is similar to:
lpar1: Success
The resource information after modification is similar to:
lpar1: Lpar Processor Info:
Curr Processor Min: 1.
Curr Processor Req: 2.
Curr Processor Max: 16.
lpar1: Lpar Memory Info:
Curr Memory Min: 1.00 GB(4 regions).
Curr Memory Req: 8.00 GB(32 regions).
Curr Memory Max: 32.00 GB(128 regions).
lpar1: 1,514,U78AA.001.WZSGVU7-P1-C19,0x21010202,0xffff(Empty Slot)
lpar1: 1,513,U78AA.001.WZSGVU7-P1-T7,0x21010201,0xc03(USB Controller)
lpar1: 1,512,U78AA.001.WZSGVU7-P1-T9,0x21010200,0x104(RAID Controller)
lpar1: 1/2/2
lpar1: 128.
Note: The physical I/O resources specified with I<vmphyslots> will be appended to the specified partition. The physical I/O resources which are not specified but belonged to the partition will not be removed. For more information about I<vmphyslots>, please refer to L<lsvm(1)|lsvm.1>.
=head2 VMware/KVM specific:
@@ -520,7 +583,7 @@ Output is similar to:
Output is similar to:
gpok3: Replacing user entry of LNX3... Done
=head1 FILES
/opt/xcat/bin/chvm
+100
View File
@@ -0,0 +1,100 @@
=head1 NAME
B<genimage> - Generate an initrd (initial ramfs) which to be used for statefull install or stateless netboot.
=head1 SYNOPSIS
B<geninitrd> <imagename>
B<geninitrd> [B<-h> | B<--help>]
=head1 DESCRIPTION
Generate the initrd for the osimage: B<imagename> which is an xCAT object of I<osimage> type.
B<Diskfull Osimage>
=over 2
If the B<imagename> is a statefull one (The provmethod attribute for the osimage is 'install'),
this command is used to rebuild the initrd to inject the new drivers from driver rpms or
'update distro' and copy the rebuilt initrd and new kernel (If there's new kernel in 'update
distro') to the directory I</tftpboot/xcat/<imagename>>.
If the initrd has been rebuilt by geninitrd, when run nodeset, the I<--noupdateinitrd> option
should be used to skip the rebuilding of initrd to improve the performance.
Three attributes of osimage object can be used to specify the Driver RPM location and Driver names
for injecting new drviers to initrd.
B<netdrivers> - comma separated driver names that need to be injected to the initrd.
The postfix '.ko' can be ignored. The netdrivers attribute must be set to specify the new driver list.
If you want to load all the drivers from the driver rpms, using the keyword allupdate.
B<driverupdatesrc> - comma separated driver rpm packages (full path should be specified)
B<osupdatename> - comma separated 'osdistroupdate' object. Each 'osdistroupdate' object specifies a
Linux distro update. When run geninitrd, 'kernel-*.rpm' will be searched from osdistroupdate.dirpath
to get all the rpm packages and then search the drivers from the rpm packages.
Refer to the doc: https://sourceforge.net/apps/mediawiki/xcat/index.php?title=Using_Linux_Driver_Update_Disk
=back
B<Stateless Osimage>
=over 2
If the B<imagename> is a stateless one (The provmethod attribute for the osimage is 'netboot'),
this command is used to generate the initrd from the rootimg which generated by 'genimage' command.
So the 'genimage' must be run once before running the geninitrd command.
Two attributes of osimage object can be used to specify the Driver RPM location and Driver names
for injecting new drviers to initrd.
B<netdrivers> - comma separated driver names that need to be injected to the initrd.
The postfix '.ko' can be ignored. The netdrivers attribute must be set to specify the new driver list.
If you want to load all the drivers from the driver rpms, using the keyword allupdate.
B<driverupdatesrc> - comma separated driver rpm packages (full path should be specified)
=back
=head1 Parameters
I<imagename> specifies the name of an os image definition to be used. The specification for the image is storted in the I<osimage> table and I<linuximage> table.
=head1 RETURN VALUE
0 The command completed successfully.
1 An error has occurred.
=head1 EXAMPLES
=over 3
=item 1
To generate initrd for the osimage B<myimagename>:
geninitrd myimagename
=back
=head1 FILES
/opt/xcat/bin/geninitrd
/opt/xcat/bin/genimage
/opt/xcat/share/xcat/netboot/<OS>/genimage
=head1 SEE ALSO
L<geninitrd(1)|geninitrd.1>, L<genimage(1)|genimage.1>
+71 -11
View File
@@ -1,6 +1,6 @@
=head1 NAME
B<lsvm> - Lists partition profile information for HMC-, IVM-, KVM-, Vmware- and zVM-managed nodes. For Power 775, it lists the LPARs' I/O slots information and CEC configuration.
B<lsvm> - Lists partition profile information for HMC-, DFM-, IVM-, KVM-, Vmware- and zVM-managed nodes. For Power 775, it lists the LPARs' I/O slots information and CEC configuration.
=head1 SYNOPSIS
@@ -14,7 +14,9 @@ B<lsvm> [B<-a>| B<--all>] I<noderange>
=head2 For PPC (using Direct FSP Management):
B<lsvm> [B<-l>| B<--long>] I<noderange>
B<lsvm> [B<-l>| B<--long>] B<--p775> I<noderange>
B<lsvm> I<noderange>
=head2 For zVM:
@@ -26,7 +28,9 @@ The lsvm command lists all partition profiles defined for the partitions specifi
=head2 For PPC (using Direct FSP Management):
For Power 775, lsvm lists all partition I/O slots information for the partitions specified in noderange. If noderange is a CEC, it gets the CEC's pump mode value, octant's memory interleaving value, the all the octants configure value, and all the I/O slots information.
For Power 775(use option I<--p775> to specify), lsvm lists all partition I/O slots information for the partitions specified in noderange. If noderange is a CEC, it gets the CEC's pump mode value, octant's memory interleaving value, the all the octants configure value, and all the I/O slots information.
For DFM-managed (short for Direct FSP Management mode) normal power machine, lsvm lists the processor, memory, physical I/O slots, hugepage and BSR info for the specified partitions or CEC.
The pump mode value has the valid options:
1 - Node Pump Mode
@@ -69,10 +73,13 @@ B<-a>
List all the profiles for one partition
B<--p775>
Specify the operation is for Power 775 machines.
B<-l>
Show lparnames for lpars.
Show lparnames for lpars. It shall work with option B<--p775>.
=head1 RETURN VALUE
@@ -102,7 +109,7 @@ g Output is similar to:
3. For Power 775, to list the I/O slot information of lpar1, enter:
lsvm lpar1
lsvm lpar1 --p775
Output is similar to:
@@ -112,7 +119,7 @@ Output is similar to:
To list the lparname of lpars, enter:
lsvm lpar1 -l
lsvm lpar1 -l --p775
Output is similar to:
lpar1: 1: 514/U78A9.001.0123456-P1-C17/0x21010202/2/1
@@ -121,7 +128,7 @@ Output is similar to:
4. For Power 775, to list the I/O slot information and octant configuration of cec1, enter:
lsvm cec1
lsvm cec1 --p775
Output is similar to:
@@ -154,7 +161,7 @@ Output is similar to:
To list the lparname of lpars, enter:
lsvm cec1 -l
lsvm cec1 -l --p775
Output is similar to:
@@ -190,7 +197,6 @@ Output is similar to:
Page Size(in GB): 16
Maximum huge page memory(in pages): 24
Requested huge page memory(in pages): 15
=======
Number of BSR arrays: 256,Bytes per BSR array: 4096,Available BSR array: 0;
Available huge page memory(in pages): 0
Configurable huge page memory(in pages): 12
@@ -208,6 +214,61 @@ Output is similar to:
gpok3: INCLUDE LNXDFLT
gpok3: COMMAND SET VSWITCH VSW2 GRANT LNX3
6. For DFM-managed normal power machine, list out the detailed resource information:
lsvm cec
Output is similar to:
cec: HYP Configurable Processors: 16, Avail Processors: 16.
HYP Configurable Memory:32.00 GB(128 regions).
HYP Available Memory: 31.25 GB(125 regions).
HYP Memory Region Size: 0.25 GB(256 MB).
cec: All Physical I/O info:
65535,519,U78AA.001.WZSGVU7-P1-C7,0x21010207,0xffff(Empty Slot)
65535,518,U78AA.001.WZSGVU7-P1-C6,0x21010206,0xffff(Empty Slot)
65535,517,U78AA.001.WZSGVU7-P1-C5,0x21010205,0xffff(Empty Slot)
65535,516,U78AA.001.WZSGVU7-P1-C4,0x21010204,0xffff(Empty Slot)
65535,514,U78AA.001.WZSGVU7-P1-C19,0x21010202,0xffff(Empty Slot)
65535,513,U78AA.001.WZSGVU7-P1-T7,0x21010201,0xc03(USB Controller)
65535,512,U78AA.001.WZSGVU7-P1-T9,0x21010200,0x104(RAID Controller)
cec: Huge Page Memory
Available huge page memory(in pages): 2
Configurable huge page memory(in pages): 2
Page Size(in GB): 16
Maximum huge page memory(in pages): 4
Requested huge page memory(in pages): 2
cec: Barrier Synchronization Register(BSR)
Number of BSR arrays: 256
Bytes per BSR array: 4096
Available BSR array: 256
Note: The lines list in "All Physical I/O info" section represent all the physical I/O resource information. The format is like "owner_lparid,slot_id,physical resource name,drc_index,slot_class_code(class discription)". The 'drc index' is short for Dynamic Resource Configuration Index, it uniquely indicate a physical I/O resource in normal power machine.
For DFM-managed partition on normal power machine, list out the detailed information:
lsvm lpar1
Output is similar to:
lpar1: Lpar Processor Info:
Curr Processor Min: 1.
Curr Processor Req: 16.
Curr Processor Max: 16.
lpar1: Lpar Memory Info:
Curr Memory Min: 0.25 GB(1 regions).
Curr Memory Req: 30.75 GB(123 regions).
Curr Memory Max: 32.00 GB(128 regions).
lpar1: 1,519,U78AA.001.WZSGVU7-P1-C7,0x21010207,0xffff(Empty Slot)
lpar1: 1,518,U78AA.001.WZSGVU7-P1-C6,0x21010206,0xffff(Empty Slot)
lpar1: 1,517,U78AA.001.WZSGVU7-P1-C5,0x21010205,0xffff(Empty Slot)
lpar1: 1,516,U78AA.001.WZSGVU7-P1-C4,0x21010204,0xffff(Empty Slot)
lpar1: 1,514,U78AA.001.WZSGVU7-P1-C19,0x21010202,0xffff(Empty Slot)
lpar1: 1,513,U78AA.001.WZSGVU7-P1-T7,0x21010201,0xc03(USB Controller)
lpar1: 1,512,U78AA.001.WZSGVU7-P1-T9,0x21010200,0x104(RAID Controller)
lpar1: 1/2/2
lpar1: 256.
=head1 FILES
/opt/xcat/bin/lsvm
@@ -218,4 +279,3 @@ Output is similar to:
L<mkvm(1)|mkvm.1>, L<chvm(1)|chvm.1>, L<rmvm(1)|rmvm.1>
+107 -9
View File
@@ -1,6 +1,6 @@
=head1 NAME
B<mkvm> - Creates HMC-, IVM-, and zVM-managed partitions or other virtual machines.
B<mkvm> - Creates HMC-, DFM-, IVM-, and zVM-managed partitions or other virtual machines.
=head1 SYNOPSIS
@@ -10,7 +10,7 @@ B<mkvm> [B<-h>| B<--help>]
B<mkvm> [B<-v>| B<--version>]
=head2 For PPC (with HMC):
=head2 For PPC (with HMC) specific:
B<mkvm> [B<-V>| B<--verbose>] I<noderange> B<-i> I<id> B<-l> I<singlenode>
@@ -18,6 +18,13 @@ B<mkvm> [B<-V>| B<--verbose>] I<noderange> B<-c> I<destcec> B<-p> I<profile>
B<mkvm> [B<-V>| B<--verbose>] I<noderange> B<--full>
=head2 For PPC (using Direct FSP Management) specific:
B<mkvm> I<noderange> [B<--full>]
B<mkvm> I<noderange> [B<vmcpus=min/req/max>] [B<vmmemory=min/req/max>]
[B<vmphyslots=drc_index1,drc_index2...>] [B<vmothersetting=hugepage:N,bsr:N>]
=head2 For KVM:
B<mkvm> I<noderange> [B<-m|--master> I<mastername>] [B<-s|--size> I<disksize>] [B<--mem> I<memsize>] [B<--cpus> I<cpucount>] [B<-f|--force>]
@@ -34,9 +41,7 @@ B<mkvm> I<noderange> [I<source_virtual_machine>] [B<pool=> I<disk_pool>]
=head1 DESCRIPTION
=head2 For PPC:
For PPC (with HMC) specific:
=head2 For PPC (with HMC) specific:
The first form of mkvm command creates new partition(s) with the same profile/resources as the partition specified by I<singlenode>. The -i and I<noderange> specify the starting numeric partition number and the I<noderange> for the newly created partitions, respectively. The LHEA port numbers and the HCA index numbers will be automatically increased if they are defined in the source partition.
@@ -46,6 +51,12 @@ Please make sure the nodes in the I<noderange> is defined in the I<nodelist> tab
Please note that the mkvm command currently only supports creating standard LPARs, not virtual LPARs working with VIOS server.
=head2 For PPC (using Direct FSP Management) specific:
With option I<full>, a partition using all the resources on a normal power machine will be created.
If no option is specified, a partition using the parameters specified with attributes such as 'vmcpus', 'vmmory', 'vmphyslots', 'vmothersetting' will be created. Those attributes can either be specified with '*def' commands running before or be specified with this command.
=head2 For KVM and Vmware:
The mkvm command creates new virtual machine(s) with the I<disksize> size of hard disk, I<memsize> size of memory and I<cpucount> number of cpu.
@@ -78,6 +89,10 @@ The cpu count which will be created for the kvm/vmware virtual machine.
Request to create a new full system partition for each CEC.
=item B<vmcpus=value> B<vmmemory=value> B<vmphyslots=value> B<vmothersetting=value>
To specify the parameters which are used to create a partition. The I<vmcpus>, I<vmmemory> and I<vmphyslots> are necessay, and the value specified with this command have a more high priority. If the value of any of the three options is not specified, the corresponding value specified for the node object will be used. If any of the three attributes is neither specified with this command nor specified with the node object, error information will be returned. To reference to L<lsvm(1)|lsvm.1> for more information about 'drc_index' for I<vmphyslots>.
=item B<-f|--force>
If B<-f|--force> is specified, the storage will be destroyed first if it existed.
@@ -120,7 +135,7 @@ Verbose output.
=head1 EXAMPLES
1. To create a new partition lpar5 based on the profile/resources of lpar4, enter:
1. To create a new HMC-managed partition lpar5 based on the profile/resources of lpar4, enter:
mkdef -t node -o lpar5 mgt=hmc groups=all
@@ -133,7 +148,7 @@ Output is similar to:
lpar5: Success
2. To create new partitions lpar5-lpar8 based on the profile/resources of lpar4, enter:
2. To create new HMC-managed partitions lpar5-lpar8 based on the profile/resources of lpar4, enter:
mkdef -t node -o lpar5-lpar8 mgt=hmc groups=all
@@ -149,7 +164,7 @@ Output is similar to:
lpar8: Success
3. To duplicate all the partitions associated with cec01 on cec02, first save the lpars from cec01 to a file:
3. To duplicate all the HMC-managed partitions associated with cec01 on cec02, first save the lpars from cec01 to a file:
lsvm lpar01-lpar04 > /tmp/myprofile
@@ -165,7 +180,7 @@ Output is similar to:
lpar8: Success
4. To duplicate all the partitions associated with cec01 on cec02, one is for cec01, the other is for cec02:
4. To duplicate all the HMC-managed partitions associated with cec01 on cec02, one is for cec01, the other is for cec02:
mkdef -t node -o lpar5,lpar6 mgt=hmc groups=all
chtab node=lpar5 ppc.parent=cec01
@@ -221,6 +236,89 @@ Output is similar to:
mkvm vm1 -s 10G --mem 2048 --cpus 2
8. To create a full partition on normal power machine.
First, define a node object:
mkdef -t node -o lpar1 mgt=fsp cons=fsp nodetype=ppc,osi id=1 hcp=cec parent=cec hwtype=lpar groups=lpar,all
Then, create the partion on the specified cec.
mkvm lpar1 --full
The output is similar to:
lpar1: Done
To query the resources allocated to node 'lpar1'
lsvm lpar1
The output is similar to:
lpar1: Lpar Processor Info:
Curr Processor Min: 1.
Curr Processor Req: 16.
Curr Processor Max: 16.
lpar1: Lpar Memory Info:
Curr Memory Min: 0.25 GB(1 regions).
Curr Memory Req: 30.75 GB(123 regions).
Curr Memory Max: 32.00 GB(128 regions).
lpar1: 1,519,U78AA.001.WZSGVU7-P1-C7,0x21010207,0xffff(Empty Slot)
lpar1: 1,518,U78AA.001.WZSGVU7-P1-C6,0x21010206,0xffff(Empty Slot)
lpar1: 1,517,U78AA.001.WZSGVU7-P1-C5,0x21010205,0xffff(Empty Slot)
lpar1: 1,516,U78AA.001.WZSGVU7-P1-C4,0x21010204,0xffff(Empty Slot)
lpar1: 1,514,U78AA.001.WZSGVU7-P1-C19,0x21010202,0xffff(Empty Slot)
lpar1: 1,513,U78AA.001.WZSGVU7-P1-T7,0x21010201,0xc03(USB Controller)
lpar1: 1,512,U78AA.001.WZSGVU7-P1-T9,0x21010200,0x104(RAID Controller)
lpar1: 1/2/2
lpar1: 256.
Note: The 'parent' attribute for node 'lpar1' is the object name of physical power machine that the full partition will be created on.
9. To create a partition using some of the resources on normal power machine.
Option 1:
After a node object is defined, the resources that will be used for the partition shall be specified like this:
chdef lpar1 vmcpus=1/4/16 vmmemory=1G/4G/32G vmphyslots=0x21010201,0x21010200 vmothersetting=bsr:128,hugepage:2
Then, create the partion on the specified cec.
mkvm lpar1
Option 2:
mkvm lpar1 vmcpus=1/4/16 vmmemory=1G/4G/32G vmphyslots=0x21010201,0x21010200 vmothersetting=bsr:128,hugepage:2
The outout is similar to:
lpar1: Done
Note: The 'vmplyslots' specify the drc index of the physical slot device. Every drc index shall be delimited with ','. The 'vmothersetting' specify two kinds of resource, bsr(Barrier Synchronization Register) specified the num of BSR arrays, hugepage(Huge Page Memory) specified the num of huge pages.
To query the resources allocated to node 'lpar1'
lsvm lpar1
The output is similar to:
lpar1: Lpar Processor Info:
Curr Processor Min: 1.
Curr Processor Req: 4.
Curr Processor Max: 16.
lpar1: Lpar Memory Info:
Curr Memory Min: 1.00 GB(4 regions).
Curr Memory Req: 4.00 GB(16 regions).
Curr Memory Max: 32.00 GB(128 regions).
lpar1: 1,513,U78AA.001.WZSGVU7-P1-T7,0x21010201,0xc03(USB Controller)
lpar1: 1,512,U78AA.001.WZSGVU7-P1-T9,0x21010200,0x104(RAID Controller)
lpar1: 1/2/2
lpar1: 128.
=head1 FILES
/opt/xcat/bin/mkvm
+12
View File
@@ -123,6 +123,14 @@ To import nodes using a profile, follow the following steps:
switch=myswitch
switchport=9
Example of a node information file that specifies a CEC-based rack-mounted Power node that uses direct FSP management:
# Node information file begins
# This entry defines a Power rack-mount node.
__hostname__:
mac=b8:ac:6f:37:59:28
cec=mycec
# Node information file ends.
The node information file includes the following items:
B<__hostname__:> This is a mandatory item.
@@ -145,6 +153,10 @@ B<slotid=<slot-id>> This is a mandatory item while define a PureFlex node.
Description: The node position in the PureFlex Chassis.
B<cec=<cec-name>> This is a mandatory option for defining Power rack-mounted nodes.
Description: Specifies the name of a Power rack-mount central electronic complex (CEC).
B<ip=<ip-address>> This is an optional item.
Description: Specify the IP address used for provisioning a node, where <ip-address> is in the form xxx.xxx.xxx.xxx. If this item is not included, the IP address used to provision the node is generated automatically according to the Network Profile used by the node.
+6
View File
@@ -43,6 +43,12 @@ rently executing remote shell processes.
Log into the nodes as the specified username. The default is to use the same username as you
are running the psh command as.
=item B<-n|--nonodecheck>
Do not send the noderange to xcatd to expand it into a list of nodes. Instead, use the noderange exactly as it is specified.
In this case, the noderange must be a simple list of comma-separated hostnames of the nodes.
This allows you to run B<psh> even when xcatd is not running.
=item B<noderange>
See L<noderange(3)|noderange.3>.
+21 -1
View File
@@ -11,6 +11,10 @@ B<rbootseq> [B<-h>|B<--help>|B<-v>|B<--version>]
B<rbootseq> I<noderange> {B<hd0>|B<hd1>|B<hd2>|B<hd3>|B<net>|B<iscsi>|B<iscsicrit>|B<cdrom>|B<usbflash>|B<floppy>|B<none>|B<list>|B<stat>}B<,>I<...>
=head2 HP Blade specific:
B<rbootseq> I<noderange> {B<hd>|B<net1>|B<net2>|B<net3>|B<net4>|B<cdrom>|B<usbflash>|B<floppy>|B<none>}B<,>I<...>
=head2 PPC (using Direct FSP Management) specific:
B<rbootseq> I<noderange> B<[hfi|net]>
@@ -52,6 +56,22 @@ The fourth hard disk.
Boot over the ethernet network, using a PXE or BOOTP broadcast.
=item B<n>|B<net>|B<network>|B<net1>|B<nic1> (HP Blade Only)
Boot over the first ethernet network, using a PXE or BOOTP broadcast.
=item B<net2>|B<nic2> (HP Blade Only)
Boot over the second ethernet network, using a PXE or BOOTP broadcast.
=item B<net3>|B<nic3> (HP Blade Only)
Boot over the third ethernet network, using a PXE or BOOTP broadcast.
=item B<net3>|B<nic3> (HP Blade Only)
Boot over the fourth ethernet network, using a PXE or BOOTP broadcast.
=item B<hfi>
Boot p775 nodes over the HFI network, using BOOTP broadcast.
@@ -68,7 +88,7 @@ Boot to an iSCSI disk over the network.
The CD or DVD drive.
=item B<usbflas>|B<usb>|B<flash>
=item B<usbflash>|B<usb>|B<flash>
A USB flash drive.
+20 -3
View File
@@ -14,7 +14,8 @@ B<Power 6 server specific :>
B<renergy> I<noderange> [-V] { all | [savingstatus] [cappingstatus]
[cappingmaxmin] [cappingvalue] [cappingsoftmin] [averageAC]
[averageDC] [ambienttemp] [exhausttemp] [CPUspeed] }
[averageDC] [ambienttemp] [exhausttemp] [CPUspeed]
[syssbpower] [sysIPLtime]}
B<renergy> I<noderange> [-V] { savingstatus={on | off}
| cappingstatus={on | off} | cappingwatt=watt
@@ -158,7 +159,7 @@ Supported attributes:
B<Query>: savingstatus,cappingstatus,cappingmin,cappingmax,
cappingvalue,cappingsoftmin,averageAC,averageDC,ambienttemp,
exhausttemp,CPUspeed
exhausttemp,CPUspeed,syssbpower,sysIPLtime
B<Set>: savingstatus,cappingstatus,cappingwatt,cappingperc
@@ -192,7 +193,7 @@ cappingperc
=back
B<9125-F2C>
B<9125-F2C>, B<9119-FHB>
=over 4
@@ -208,6 +209,22 @@ cappingperc,fsavingstatus,ffovalue
=back
B<Non of Above>
=over 4
For the machine type which is not in the above list, the following
attributes can be tried but not guaranteed:
B<Query>: savingstatus,dsavingstatus,cappingstatus,cappingmin,
cappingmax,,cappingvalue,cappingsoftmin,averageAC,averageDC,
ambienttemp,exhausttemp,CPUspeed,syssbpower,sysIPLtime
B<Set>: savingstatus,dsavingstatus,cappingstatus,cappingwatt,
cappingperc
=back
=back
Note:
+22 -6
View File
@@ -1,6 +1,6 @@
=head1 NAME
B<rmvm> - Removes HMC-, IVM-, KVM-, Vmware- and zVM-managed partitions or virtual machines.
B<rmvm> - Removes HMC-, DFM-, IVM-, KVM-, Vmware- and zVM-managed partitions or virtual machines.
=head1 SYNOPSIS
@@ -8,17 +8,22 @@ I<rmvm [-h| --help]>
I<rmvm [-v| --version]>
I<rmvm [-V| --verbose] noderange [-r] [--service]>
=head2 For KVM and Vmware:
I<rmvm [-p] [-f]>
=head2 PPC (using Direct FSP Management) specific:
I<rmvm noderange>
=head1 DESCRIPTION
The rmvm command removes the partitions specified in noderange. If noderange is an CEC, all the partitions associated with that CEC will be removed. Note that removed partitions are automatically removed from the xCAT database. For IVM-managed systems, care must be taken to not remove the VIOS partition, or all the associated partitions will be removed as well.
For DFM-managed (short For Direct FSP Management mode) normal power machines, only partitions can be removed. No options is needed.
=head1 OPTIONS
@@ -34,6 +39,8 @@ B<--service> Remove the service partitions of the specified CECs.
B<-p> Purge the existence of the VM from persistant storage. This will erase all storage related to the VM in addition to removing it from the active virtualization configuration.
B<-p|--part> Remove the specified partiton on normal power machine.
B<-f> Force remove the VM, even if the VM appears to be online. This will bring down a live VM if requested.
=head1 RETURN VALUE
@@ -44,7 +51,7 @@ B<-f> Force remove the VM, even if the VM appears to be online. This w
=head1 EXAMPLES
1. To remove the partition lpar3, enter:
1. To remove the HMC-managed partition lpar3, enter:
I<rmvm lpar3>
@@ -52,7 +59,7 @@ Output is similar to:
lpar3: Success
2. To remove all the partitions associated with CEC cec01, enter:
2. To remove all the HMC-managed partitions associated with CEC cec01, enter:
I<rmvm cec01>
@@ -62,7 +69,7 @@ Output is similar to:
lpar2: Success
lpar3: Success
3. To remove the service partitions of the specified CEC cec01 and cec02, enter:
3. To remove the HMC-managed service partitions of the specified CEC cec01 and cec02, enter:
I<rmvm cec01,cec02 --service>
@@ -71,7 +78,7 @@ Output is similar to:
cec01: Success
cec02: Success
4. To remove the partition lpar1, but retain its definition, enter:
4. To remove the HMC-managed partition lpar1, but retain its definition, enter:
I<rmvm lpar1 -r>
@@ -87,6 +94,15 @@ Output is similar to:
gpok4: Deleting virtual server LNX4... Done
6. To remove a DFM-managed partition on normal power machine:
I<rmvm lpar1>
Output is similar to:
lpar1: Done
=head1 FILES
/opt/xcat/bin/rmvm
+8 -3
View File
@@ -4,11 +4,11 @@ B<updatenode> - Update nodes in an xCAT cluster environment.
=head1 SYNOPSIS
B<updatenode> B<noderange> [B<-V>|B<--verbose>] [B<-F>|B<--sync>] [B<-f>|B<--snsync>] [B<-S>|B<--sw>] [B<-l> I<userID>] [B<-P>|B<--scripts> [B<script1,script2...>]] [B<-s>|B<--sn>] [B<-A>|B<--updateallsw>] [B<-c>|B<--cmdlineonly>] [B<-d alt_source_dir>] [B<--fanout>] [B<attr=val> [B<attr=val...>]]
B<updatenode> B<noderange> [B<-V>|B<--verbose>] [B<-F>|B<--sync>] [B<-f>|B<--snsync>] [B<-S>|B<--sw>] [B<-l> I<userID>] [B<-P>|B<--scripts> [B<script1,script2...>]] [B<-s>|B<--sn>] [B<-A>|B<--updateallsw>] [B<-c>|B<--cmdlineonly>] [B<-d alt_source_dir>] [B<--fanout>] [B<-t timeout>} [B<attr=val> [B<attr=val...>]]
B<updatenode> B<noderange> [B<-k>|B<--security>]
B<updatenode> B<noderange> [B<-k>|B<--security>] [B<-t timeout>]
B<updatenode> B<noderange> [B<-V>|B<--verbose>] [B<script1,script2...>]
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>]
@@ -363,6 +363,11 @@ Specifies that node software should be updated.
Set the server information stored on the nodes.
=item B<-t timeout>
Specifies a timeout in seconds the command will wait for the remote targets to complete. If timeout is not specified
it will wait indefinitely. The exception is the updatenode -k option whose default timeout is 10 seconds.
=item B<-v|--version>
Command Version.
+4 -3
View File
@@ -117,7 +117,7 @@ A timeout value for remote command execution can be specified with the
B<-t> flag or with the B<DSH_TIMEOUT> environment variable. If any remote
target does not provide output to either standard output or standard
error within the timeout value, B<xdsh> displays an error message and
exits.
exits.
If streaming mode is specified with the B<-s> flag, output is returned as
it becomes available from each target, instead of waiting for the
@@ -333,7 +333,8 @@ available from any target in the specified I<timeout>, B<xdsh>
displays an error and terminates execution for the remote
targets that failed to respond. If I<timeout> is not specified,
B<xdsh> waits indefinitely to continue processing output from
all remote targets.
all remote targets. The exception is the -K flag which defaults
to 10 seconds.
=item B<-T>|B<--trace>
@@ -565,7 +566,7 @@ To define a BNT Ethernet switch as a node and run a command to create a new vlan
B<chdef> I<myswitch groups=all>
B<tabch> I<switch=myswitch switches.sshusername=admin switches.sshpassword=passw0rd>
B<tabch> I<switch=myswitch switches.sshusername=admin switches.sshpassword=passw0rd switches.protocol=[ssh|telnet]>
where I<admin> and I<passw0rd> are the SSH user name and password for the switch. If it is for Telnet, add I<tn:> in front of the user name: I<tn:admin>.
<xdsh> I<myswitch --devicetype EthSwitch::BNT 'enable;configure terminal;vlan 3;end;show vlan'>
+7
View File
@@ -6,6 +6,8 @@ B<nodeset> - set the boot state for a noderange
B<nodeset> [I<noderange>] [I<boot>|I<install>|I<stat>|I<iscsiboot>|I<netboot>|I<statelite>|I<offline>|I<runcmd=bmcsetup>|I<osimage[=<imagename>>]]
B<nodeset> I<noderange> [I<osimage=<imagename>> I<--noupdateinitrd>]
B<nodeset> [I<-h>|I<--help>|I<-v>|I<--version>]
=head1 B<Description>
@@ -67,6 +69,11 @@ Cleanup the current pxe/tftp boot configuration files for the nodes requested
Prepare server for installing a node using the specified os image. The os image is defined in the I<osimage> table and I<linuximage> table. If the <imagename> is omitted, the os image name will be obtained from I<nodetype.provmethod> for the node.
=item B<--noupdateinitrd>
Skip the rebuilding of initrd when the 'netdrivers', 'drvierupdatesrc' or 'osupdatename' were set for injecting new drviers to initrd. But, the geninitrd command
should be run to rebuild the initrd for new drivers injecting. This is used to improve the performance of nodeset command.
=item B<runimage>=<task>>
If you would like to run a task after deployment, you can define that task with this attribute.
+23 -6
View File
@@ -1,18 +1,21 @@
=head1 NAME
B<tabrestore> - replaces the contents of an xCAT database table with the contents in a csv file.
B<tabrestore> - replaces with or adds to a xCAT database table the contents in a csv file.
=head1 SYNOPSIS
B<tabrestore> I<table.csv>
B<tabrestore> [-a] I<table.csv>
B<tabrestore> [I<-?> | I<-h> | I<--help>]
B<tabrestore> [I<v> | I<--version>]
=head1 DESCRIPTION
The tabrestore command reads the contents of the specified file and puts its data
in the corresponding table in the xCAT database. Any existing rows in that table
are replaced. The file must be in csv format. It could be created by tabdump.
are replaced unless the (-a) flag is used and then the rows in the file are added to the table.
The file must be in csv format. It could be created by tabdump.
Only one table can be specified.
This command can be used to copy the example table entries in /opt/xcat/share/xcat/templates/e1350
@@ -26,6 +29,14 @@ into the xCAT database.
Display usage message.
=item B<-v|--version>
Display version.
=item B<-a|--addrows>
Add rows from the CSV file to the table instead of replacing the table with the CSV file.
=back
=head1 RETURN VALUE
@@ -48,9 +59,9 @@ An error has occurred.
=item *
To put rows into the mp table:
To replace the rows in the mp table with the rows in the mp.csv file:
B< tabrestore> I<mp.csv>
B< tabrestore> I<mp.csv>
The file mp.csv could contain something like:
@@ -59,9 +70,15 @@ The file mp.csv could contain something like:
=item *
To add the rows in the mp.csv file to the rows in the mp table:
B< tabrestore> -a I<mp.csv>
=item *
To restore database tables that we dumped with dumpxCATdb:
restorexCATdb -p <restore directory:
restorexCATdb -p <restore directory>
=back
+5 -1
View File
@@ -14,7 +14,7 @@ B<xcatconfig> {B<-i>|B<--initinstall>} [B<-V>|B<--verbose>]
B<xcatconfig> {B<-u>|B<--updateinstall>} [B<-V>|B<--verbose>]
B<xcatconfig> [B<-k>|B<--sshkeys>] [B<-s>|B<--sshnodehostkeys>] [B<-c>|B<--credentials>] [B<-d>|B<--database>] [B<-m>|B<--mgtnode>] [B<-V>|B<--verbose>]
B<xcatconfig> [B<-k>|B<--sshkeys>] [B<-s>|B<--sshnodehostkeys>] [B<-c>|B<--credentials>] [B<-d>|B<--database>] [B<-m>|B<--mgtnode>] [B<-t>|B<--tunables>] [B<-V>|B<--verbose>]
B<xcatconfig> {B<-f>|B<--force>} [B<-V>|B<--verbose>]
@@ -74,6 +74,10 @@ Redistribute credentials and ssh keys to the service nodes and ssh keys to the n
This option will add the Management Node to the database with the correct attributes set to be recognized by xCAT. This should be run after the hostname of the Management Node is set to the name that will resolve to the cluster-facing NIC.
=item B<-t|--tunables>
This option will set tunable parameters on the Management and Service nodes recommended for your Linux cluster. It will only set them during initial install, if you run xcatconfig -f or xcatconfig -t.
=back
=head1 EXAMPLES
+30 -3
View File
@@ -7,11 +7,15 @@ BEGIN { $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/o
use lib "$::XCATROOT/lib/perl";
use File::Basename;
use xCAT::Client;
use xCAT::Utils;
use Getopt::Long;
sub usage {
print "Usage: tabrestore <tablename>.csv\n";
print " tabrestore -a <tablename>.csv\n";
print " tabrestore [-?|-h|--help]\n";
print " tabrestore [-v|--version]\n";
exit $_[0];
}
@@ -21,12 +25,35 @@ $cmdref->{command}->[0] = "tabrestore";
# Get the options
my $HELP;
if (!GetOptions('h|?|help' => \$HELP)) { usage(1); }
if (
!GetOptions(
'h|?|help' => \$HELP,
'v|version' => \$VERSION,
'a|addrows' => \$ADDROWS,
)
)
{ usage(1); }
my $arg=shift(@ARGV);
while ($arg =~ /^-/) {
push (@{$cmdref->{arg}}, $arg);
$arg=shift(@ARGV);
}
if ($VERSION)
{
my $version = xCAT::Utils->Version();
print "$version\n";
exit 0;
}
if ($HELP)
{
usage;
}
if ($ADDROWS)
{
$cmdref->{addrows}->[0] = "yes";
}
unless ($arg) { usage(2); } # no filename specified
# Open the specified table file and put its contents in the data key
@@ -40,7 +67,7 @@ while (<$fh>) {
push @{$cmdref->{data}},$_;
}
push (@{$cmdref->{arg}}, @ARGV); # get the rest of the arguments
xCAT::Client::submit_request($cmdref,\&xCAT::Client::handle_response);
exit $xCAT::Client::EXITCODE;
exit $xCAT::Client::EXITCODE;
+1 -1
View File
@@ -623,4 +623,4 @@ dracut_install /lib64/rsyslog/lmnet.so
dracut_install /lib64/rsyslog/lmstrmsrv.so
dracut_install /lib64/rsyslog/imuxsock.so
dracut_install /usr/lib64/libnfsidmap/nsswitch.so
dracut_install killall logger nc nslookup bc chown chroot dd expr kill mkdosfs parted rsync shutdown sort ssh-keygen tr blockdev findfs insmod kexec lvm mdadm mke2fs pivot_root sshd swapon tune2fs # for sysclone
dracut_install killall logger nc nslookup bc chown chroot dd expr kill mkdosfs parted rsync shutdown sort ssh-keygen tr blockdev findfs insmod kexec lvm mdadm mke2fs pivot_root sshd swapon tune2fs mkreiserfs reiserfstune # for sysclone
+1
View File
@@ -4,3 +4,4 @@ instmods e1000 e1000e virtio_net igb ines sfc mlx4_en cxgb3 cxgb4 tg3 bnx2 bnx2x
instmods macvlan macvtap 8021q bridge bonding vmxnet3 cpufreq_ondemand acpi-cpufreq powernow-k8 cdc_ether
instmods mptctl #LSI firmware management requires this
instmods mlx4_ib ib_umad #make the mellanox ib available enough to examine /sys
instmods reiserfs #reiserfs on sysclone
+3
View File
@@ -5,6 +5,9 @@ PUBKEY=`echo $PUBKEY|sed -e 's/ //g'`
export PUBKEY
echo "Beginning node discovery process"
for nic in `ip link|grep mtu|grep -v LOOPBACK|grep -v usb|grep -v ,LOWER_UP|awk -F: '{print $2}'`; do
ip link set $nic up
done
waitforlink=100
while [ ! -z "$NICSTOBRINGUP" -a $waitforlink -gt 0 ]; do
NICSTOBRINGUP=`ip link|grep mtu|grep -v LOOPBACK|grep -v usb|grep -v ,LOWER_UP|awk -F: '{print $2}'`
+1 -1
View File
@@ -82,7 +82,7 @@ dhclient -6 -pf /var/run/dhclient6.$bootnic.pid $bootnic -lf /var/lib/dhclient/d
NICSTOBRINGUP=`ip link|grep mtu|grep -v LOOPBACK|grep -v $bootnic|grep -v usb|grep -v ,UP|awk -F: '{print $2}'`
export NICSTOBRINGUP
for nic in $NICSTOBRINGUP; do
(while ! ethtool $nic | grep Link\ detected|grep yes > /dev/null; do sleep 5; done; cdhclient -cf /etc/dhclient.conf -pf /var/run/dhclient.$nic.pid $nic ) &
(while ! ethtool $nic | grep Link\ detected|grep yes > /dev/null; do sleep 5; done; dhclient -cf /etc/dhclient.conf -pf /var/run/dhclient.$nic.pid $nic ) &
(while ! ethtool $nic | grep Link\ detected|grep yes > /dev/null; do sleep 5; done; dhclient -cf /etc/dhclient.conf -6 -pf /var/run/dhclient6.$nic.pid -lf /var/lib/dhclient/dhclient6.leases $nic ) &
done
openssl genrsa -out /etc/xcat/certkey.pem 4096 > /dev/null 2>&1 &
-1
View File
@@ -31,7 +31,6 @@ case "$1" in
ln -sf /opt/xcat/sbin/xcatd /usr/sbin/xcatd
#SHA1 has been get rid of after Squeeze released. Its functionality is also provided by Digest::SHA (which is in core).
#but ipmi.pm need SHA1.pm, so create this link
cd -
;;
abort-upgrade|abort-remove|abort-deconfigure)
+1
View File
@@ -46,6 +46,7 @@ use Digest::MD5 qw/md5/;
my $pendingpackets=0;
my %tabooseq; #TODO: this is a global which means one taboo in the whole set causes unrelated session objects to consider it taboo unnecessarily
my $maxpending; #determined dynamically based on rcvbuf detection
my $ipmi2support;
if ( -f "/etc/debian_release" ){
$ipmi2support = eval {
require Digest::SHA;
+1
View File
@@ -57,6 +57,7 @@ my %modules = (
cec => "xCAT::FSPvm",
},
rmvm => { hmc => "xCAT::PPCvm",
fsp => "xCAT::FSPvm",
},
lsvm => { hmc => "xCAT::PPCvm",
fsp => "xCAT::FSPvm",
+52 -4
View File
@@ -90,6 +90,7 @@ sub run_remote_shell_api {
my $output;
my $errmsg;
my $ssh_tried=0;
my $nl_tried=0;
if (!$telnet) {
eval {
@@ -209,6 +210,18 @@ sub run_remote_shell_api {
$output.="Password is required.\n";
return [1, $output];
}
} else {
# for some switches like BNT, user has to type an extra new line
# in order to get the prompt.
if ($verbose) {
print " add a newline\n";
}
$nl_tried=1;
if (! $t->put(String => "\n",
Errmode => "return")) {
$output.="Login disconnected\n";
return [1, $output];
}
}
if (!$login_done) {
@@ -228,13 +241,48 @@ sub run_remote_shell_api {
$output.="Login failed: bad login name or password\n";
return [1, $output];
} else {
if ($t->errmsg) {
$output.= $t->errmsg . "\n";
return [1, $output];
if (!$nl_tried) {
# for some switches like BNT, user has to type an extra new line
# in order to get the prompt.
if ($verbose) {
print " add a newline\n";
}
$nl_tried=1;
if (! $t->put(String => "\n",
Errmode => "return")) {
$output.="Login disconnected\n";
return [1, $output];
}
}
else {
if ($t->errmsg) {
$output.= $t->errmsg . "\n";
return [1, $output];
}
}
}
}
#check if the extra newline helps or not
if (!$login_done) {
#Wait for command prompt
($prematch, $match) = $t->waitfor(Match => "/$prompt/",
Errmode => "return");
if ($verbose) {
print "4. prematch=$prematch\n match=$match\n";
}
if ($match =~ /$prompt/) {
$login_done=1;
} else {
if ($t->errmsg) {
$output.= $t->errmsg . "\n";
return [1, $output];
}
}
}
}
}
}
+5 -1
View File
@@ -178,7 +178,7 @@ sub subvars {
my $source_in_pre;
my $c = 0;
foreach my $pkgdir(@pkgdirs) {
if( $platform =~ /^(rh|SL)$/ ) {
if( $platform =~ /^(rh|SL|centos|fedora)$/ ) {
if ( $c == 0 ) {
# After some tests, if we put the repo in pre scripts in the kickstart like for rhels6.x
# the rhels5.9 will not be installed successfully. So put in kickstart directly.
@@ -875,7 +875,11 @@ sub tabdb
}
}
#$tmplerr="Unable to find requested $field from $table, with $key";
my $savekey=$key;
$key = '$NODE'; # make sure we use getNodeAttribs when get_replacement
# calls this routine (tabdb)
my $rep=get_replacement($table,$key,$field);
$key=$savekey; # restore just in case we rely on the node=$node setting
if ($rep) {
return tabdb($rep->[0], $rep->[1], $rep->[2]);
} else {
+5 -2
View File
@@ -69,15 +69,18 @@ sub validate {
$policytable->close;
my $rule;
my $peerstatus="untrusted";
# This sorts the policy table rows based on the level of the priority field in the row.
# note the lower the number in the policy table the higher the priority
my @sortedpolicies = sort { $a->{priority} <=> $b->{priority} } (@$policies);
# check to see if peerhost is trusted
foreach $rule (@$policies) {
foreach $rule (@sortedpolicies) {
if (($rule->{name} and $rule->{name} eq $peername) && ($rule->{rule}=~ /trusted/i)) {
$peerstatus="Trusted";
last;
}
}
RULE: foreach $rule (@$policies) {
RULE: foreach $rule (@sortedpolicies) {
if ($rule->{name} and $rule->{name} ne '*') {
#TODO: more complex matching (lists, wildcards)
next unless ($peername and $peername eq $rule->{name});
+206 -27
View File
@@ -14,11 +14,20 @@ use xCAT::TableUtils;
use xCAT::NodeRange;
use xCAT_monitoring::monitorctrl;
use Sys::Hostname;
use File::Path qw/mkpath/;
#print "xCAT_monitoring::snmpmon loaded\n";
1;
my $confdir;
if(xCAT::Utils->isAIX()){
$::snmpconfdir = "/opt/freeware/etc";
} else {
$::snmpconfdir = "/usr/share/snmp";
}
#-------------------------------------------------------------------------------
=head1 xCAT_monitoring:snmpmon
@@ -63,7 +72,11 @@ sub start {
`/bin/kill -9 $pid`;
}
# start it up again!
system("/usr/sbin/snmptrapd -m ALL");
if(xCAT::Utils->isAIX()){
system("/opt/freeware/sbin/snmptrapd -m ALL");
} else {
system("/usr/sbin/snmptrapd -m ALL");
}
# get the PID of the currently running snmpd if it is running.
# if it's running then we just leave. Otherwise, if we don't get A PID, then we
@@ -266,7 +279,7 @@ sub config {
}
return (1, "net-snmp is not installed")
} else {
my ($ret, $err)=configSNMP();
my ($ret, $err)=configSNMP(2, $noderef, $callback);
if ($ret != 0) { return ($ret, $err);}
}
@@ -324,22 +337,25 @@ sub deconfig {
my $callback=shift;
my $localhostname=hostname();
if (-f "/usr/share/snmp/snmptrapd.conf.orig"){
if (-f "$::snmpconfdir/snmptrapd.conf.orig"){
# copy back the old one
`mv -f /usr/share/snmp/snmptrapd.conf.orig /usr/share/snmp/snmptrapd.conf`;
`mv -f $::snmpconfdir/snmptrapd.conf.orig $::snmpconfdir/snmptrapd.conf`;
} else {
if (-f "/usr/share/snmp/snmptrapd.conf"){
if (-f "$::snmpconfdir/snmptrapd.conf"){
# if the file exists, delete all entries that have xcat_traphandler
my $cmd = "grep -v xcat_traphandler /usr/share/snmp/snmptrapd.conf ";
$cmd .= "> /usr/share/snmp/snmptrapd.conf.unconfig ";
`$cmd`;
my $cmd = "grep -v xcat_traphandler $::snmpconfdir/snmptrapd.conf ";
$cmd .= "> $::snmpconfdir/snmptrapd.conf.unconfig ";
`$cmd`;
# move it back to the snmptrapd.conf file.
`mv -f /usr/share/snmp/snmptrapd.conf.unconfig /usr/share/snmp/snmptrapd.conf`;
`mv -f $::snmpconfdir/snmptrapd.conf.unconfig $::snmpconfdir/snmptrapd.conf`;
}
}
deconfigSNMP(2,$noderef,$callback);
if ($scope) {
if ($callback) {
my $rsp={};
@@ -359,7 +375,21 @@ sub deconfig {
return (0, "");
}
#--------------------------------------------------------------------------------
=head3 deconfigSNMP
This function remove xcat_traphanlder from the snmptrapd.conf file,
remove the node configurations from snmptrapd.conf, and
restarts the snmptrapd with the new configuration.
Arguments:
none.
Returns:
(return code, message)
=cut
=cut
#--------------------------------------------------------------------------------
sub deconfigSNMP {
return (0, "");
}
#--------------------------------------------------------------------------------
=head3 configBMC
@@ -838,45 +868,54 @@ sub configSwitch {
=cut
#--------------------------------------------------------------------------------
sub configSNMP {
my $action=shift;
my $noderef=shift;
my $callback=shift;
my $ret_val=0;
my $ret_text="";
print "configSNMP called \n";
my $isSN=xCAT::Utils->isServiceNode();
my $master=xCAT::TableUtils->get_site_Master();
my $cmd;
# now move /usr/share/snmp/snmptrapd.conf to /usr/share/snmp/snmptrapd.conf.orig
# now move $::snmpconfdir/snmptrapd.conf to $::snmpconfdir/snmptrapd.conf.orig
# if it exists.
if (-f "/usr/share/snmp/snmptrapd.conf"){
mkpath("$::snmpconfdir");
if (-f "$::snmpconfdir/snmptrapd.conf"){
# if the file exists and has references to xcat_traphandler in mn or 'forward' in sn
# then there is nothing that needs to be done.
if ($isSN) {
`/bin/grep "forward default $master" /usr/share/snmp/snmptrapd.conf > /dev/null`;
`/bin/grep "forward default $master" $::snmpconfdir/snmptrapd.conf > /dev/null`;
} else {
`/bin/grep xcat_traphandler /usr/share/snmp/snmptrapd.conf > /dev/null`;
`/bin/grep xcat_traphandler $::snmpconfdir/snmptrapd.conf > /dev/null`;
}
# if the return code is 1, then there is no xcat_traphandler, or 'forward'
# references and we need to put them in.
if($? >> 8){
# back up the original file.
`/bin/cp -f /usr/share/snmp/snmptrapd.conf /usr/share/snmp/snmptrapd.conf.orig`;
`/bin/cp -f $::snmpconfdir/snmptrapd.conf $::snmpconfdir/snmptrapd.conf.orig`;
# if the file exists and does not have "authCommunity execute,net public" then add it.
open(FILE1, "</usr/share/snmp/snmptrapd.conf");
open(FILE, ">/usr/share/snmp/snmptrapd.conf.tmp");
open(FILE1, "<$::snmpconfdir/snmptrapd.conf");
open(FILE, ">$::snmpconfdir/snmptrapd.conf.tmp");
my $found=0;
my $forward_handled=0;
while (readline(FILE1)) {
if (/\s*authCommunity.*public/) {
$found=1;
if (/\s*authCommunity.*public/) {
$found=1;
if (!/\s*authCommunity\s*.*execute.*public/) {
s/authCommunity\s*(.*)\s* public/authCommunity $1,execute public/; #modify it to have 'execute' if found
}
}
if (!/\s*authCommunity\s*.*net.*public/) {
s/authCommunity\s*(.*)\s* public/authCommunity $1,net public/; #modify it to have 'net' if found
}
}
} elsif (/\s*forward\s*default/) {
if (($isSN) && (!/$master/)) {
s/\s*forward/\#forward/; #comment out the old one
if (($isSN) && (!/$master/)) {
s/\s*forward/\#forward/; #comment out the old one
if (!$forward_handled) {
print FILE "forward default $master\n";
$forward_handled=1;
@@ -892,7 +931,7 @@ sub configSNMP {
if (!$found) { #add new one if not found
print FILE "authCommunity log,execute,net public\n";
}
# now add the new traphandle commands:
if (!$isSN) {
print FILE "traphandle default $::XCATROOT/sbin/xcat_traphandler\n";
@@ -900,13 +939,13 @@ sub configSNMP {
close(FILE1);
close(FILE);
`mv -f /usr/share/snmp/snmptrapd.conf.tmp /usr/share/snmp/snmptrapd.conf`;
`mv -f $::snmpconfdir/snmptrapd.conf.tmp $::snmpconfdir/snmptrapd.conf`;
}
}
else { # The snmptrapd.conf file does not exists
# create the file:
my $handle = new IO::File;
open($handle, ">/usr/share/snmp/snmptrapd.conf");
open($handle, ">$::snmpconfdir/snmptrapd.conf");
print $handle "authCommunity log,execute,net public\n";
if ($isSN) {
print $handle "forward default $master\n"; #forward the trap from sn to mn
@@ -916,6 +955,146 @@ sub configSNMP {
close($handle);
}
# Configure SNMPv3 on AIX
# if(xCAT::Utils->isAIX()){
#the identification of this node
my @hostinfo=xCAT::NetworkUtils->determinehostname();
my $isSV=xCAT::Utils->isServiceNode();
my %iphash=();
foreach(@hostinfo) {$iphash{$_}=1;}
if (!$isSV) { $iphash{'noservicenode'}=1;}
my $all=0;
my %nodehash=();
if ((!$noderef) || (@$noderef==0)) {$all=1;}
else {
foreach(@$noderef) { $nodehash{$_}=1;}
}
my %mpa_hash=();
my %masterhash=();
my @node_a=();
my $table=xCAT::Table->new("mp");
if ($table) {
my @tmp1=$table->getAllNodeAttribs(['node','mpa']);
if (@tmp1 > 0) {
foreach(@tmp1) {
my $node=$_->{node};
my $mpa=$_->{mpa};
if ((!$all) && (!exists($nodehash{$node})) && (!exists($nodehash{$mpa}))) {next;}
if ($mpa_hash{$mpa}) { next;} #already handled
$mpa_hash{$mpa}=1;
my $pHash=xCAT_monitoring::monitorctrl->getNodeMonServerPair([$mpa], 0);
if (ref($pHash) eq 'ARRAY') {
if ($callback) {
my $rsp={};
if ($ret_val) {
$rsp->{data}->[0]=$pHash->[1];
}
$callback->($rsp);
} else {
xCAT::MsgUtils->message('S', "[mon]: " . $pHash->[1]);
}
return (0, "");
}
my $pairs=$pHash->{$mpa};
my @a_temp=split(':',$pairs);
my $monserver=$a_temp[0];
my $master=$a_temp[1];
if ($monserver) {
if (!$iphash{$monserver}) { next;} #skip if has sn but not localhost
} else {
if ($isSV) { next; } #skip if does not have sn but localhost is a sn
}
push(@node_a, $mpa);
# find the master node and add the node in the hash
if(exists($masterhash{$master})) {
my $ref=$masterhash{$master};
push(@$ref, $mpa);
} else { $masterhash{$master}=[$mpa]; }
} #foreach
}
$table->close();
}
if (@node_a==0){ return ($ret_val, $ret_text);} #nothing to handle
# Read username, password, and mac from DB.
foreach my $mpa ( @node_a ) {
my $mac;
my $user;
my $password;
my $mpatable=xCAT::Table->new("mpa");
if ($mpatable) {
my $mpa_a = $mpatable->getAttribs({mpa => $mpa}, 'username', 'password');
if ( $mpa_a and $mpa_a->{username} and $mpa_a->{password} ) {
$user = $mpa_a->{username};
$password = $mpa_a->{password};
} else {
xCAT::MsgUtils->message('E', "No username or password found for $mpa");
}
}
my $mactable=xCAT::Table->new("mac");
if ( $mactable ) {
my $mac_a = $mactable->getAttribs({node=> $mpa}, 'mac');
if ( $mac_a and $mac_a->{mac} ) {
$mac = $mac_a->{mac};
} else {
xCAT::MsgUtils->message('E', "No mac found for $mpa");
}
}
my $found1=0;
my $found2=0;
if ( $mac and $user and $password ) {
#write configuration file
open(FILE1, "<$::snmpconfdir/snmptrapd.conf");
open(FILE, ">$::snmpconfdir/snmptrapd.conf.tmp");
while (readline(FILE1)) {
if (/\s*authUser.*$user/) {
$found1=1;
if (!/\s*authUser\s*.*execute.*$user/) {
s/authUser\s*(.*)\s* $user/authUser $1,execute $user/; #modify it to have 'execute' if found
}
}
if (!/\s*authUser\s*.*net.*$user/) {
s/authUser\s*(.*)\s* $user/authUser $1,net $user/; #modify it to have 'net' if found
}
if (/\s*createUser.*$mac.*$user.*$password/) {
$found2=1;
}
print FILE $_;
}
}
if (!$found1) { #add new one if not found
print FILE "authUser log,execute,net $user\n";
}
if (!$found2) {
print FILE "createUser -e 0x8000045001$mac $user SHA $password DES\n";
}
close(FILE1);
close(FILE);
`mv -f $::snmpconfdir/snmptrapd.conf.tmp $::snmpconfdir/snmptrapd.conf`;
}
# }
# TODO: put the mib files to /usr/share/snmp/mibs
return (0, "");
}
+5 -3
View File
@@ -3159,10 +3159,12 @@ sub defls
foreach my $imgattr (keys %imgentry)
{
# Only store the attributes that are not in general node attributes
if(!defined($myhash{$obj}{$imgattr}) && defined($imgentry{$imgattr}))
{
# This is not the right thing to do, list all the osimage attributes instead,
# like the postscripts and postbootscripts attributes,
#if(!defined($myhash{$obj}{$imgattr}) && defined($imgentry{$imgattr}))
#{
$nodeosimagehash{$obj}{$imgattr} = $imgentry{$imgattr};
}
#}
}
}
if (scalar(keys %{$nodeosimagehash{$obj}}) == 0)
+93 -36
View File
@@ -172,6 +172,7 @@ sub mknetboot
my $nodes = @{$req->{node}};
my @args = @{$req->{arg}} if(exists($req->{arg}));
my @nodes = @{$req->{node}};
my $noupdateinitrd = $req->{'noupdateinitrd'};
my $ostab = xCAT::Table->new('nodetype');
#my $sitetab = xCAT::Table->new('site');
my $linuximagetab;
@@ -182,6 +183,8 @@ sub mknetboot
my $xcatdport = "3001";
my $xcatiport = "3002";
my $nodestatus = "y";
my @myself = xCAT::NetworkUtils->determinehostname();
my $myname = $myself[(scalar @myself)-1];
#if ($sitetab)
#{
@@ -446,7 +449,7 @@ sub mknetboot
if ($statelite) {
unless ( -r "$rootimgdir/kernel") {
$callback->({
error=>[qq{Did you run "genimage" before running "liteimg"? kernel cannot be found...}],
error=>[qq{Did you run "genimage" before running "liteimg"? kernel cannot be found at $rootimgdir/kernel on $myname}],
errorcode=>[1]
});
next;
@@ -454,7 +457,7 @@ sub mknetboot
if (!-r "$rootimgdir/initrd-statelite.gz") {
if (! -r "$rootimgdir/initrd.gz") {
$callback->({
error=>[qq{Did you run "genimage" before running "liteimg"? initrd.gz or initrd-statelite.gz cannot be found}],
error=>[qq{Did you run "genimage" before running "liteimg"? initrd.gz or initrd-statelite.gz cannot be found at $rootimgdir/initrd.gz on $myname}],
errorcode=>[1]
});
next;
@@ -473,7 +476,7 @@ sub mknetboot
} else {
unless ( -r "$rootimgdir/kernel") {
$callback->({
error=>[qq{Did you run "genimage" before running "packimage"? kernel cannot be found}],
error=>[qq{Did you run "genimage" before running "packimage"? kernel cannot be found at $rootimgdir/kernel on $myname}],
errorcode=>[1]
});
next;
@@ -481,7 +484,7 @@ sub mknetboot
if (!-r "$rootimgdir/initrd-stateless.gz") {
if (! -r "$rootimgdir/initrd.gz") {
$callback->({
error=>[qq{Did you run "genimage" before running "packimage"? initrd.gz or initrd-stateless.gz cannot be found}],
error=>[qq{Did you run "genimage" before running "packimage"? initrd.gz or initrd-stateless.gz cannot be found at $rootimgdir/initrd.gz on $myname}],
errorcode=>[1]
});
next;
@@ -491,7 +494,7 @@ sub mknetboot
}
unless ( -r "$rootimgdir/rootimg.gz" or -r "$rootimgdir/rootimg.sfs" ) {
$callback->({
error=>["No packed image for platform $osver, architecture $arch, and profile $profile, please run packimage (e.g. packimage -o $osver -p $profile -a $arch"],
error=>["No packed image for platform $osver, architecture $arch, and profile $profile found at $rootimgdir/rootimg.gz or $rootimgdir/rootimg.sfs on $myname, please run packimage (e.g. packimage -o $osver -p $profile -a $arch"],
errorcode => [1]});
next;
}
@@ -520,7 +523,7 @@ sub mknetboot
}
}
if ($docopy) {
if ($docopy && !$noupdateinitrd) {
mkpath("$tftppath");
if (-f "$rootimgdir/hypervisor") {
copy("$rootimgdir/hypervisor", "$tftppath");
@@ -1576,7 +1579,8 @@ sub mksysclone
}
}
# copy postscripts
# copy postscripts, the xCAT scripts may update, but the image is captured long time ago
# should update the scripts at each nodeset
my $script1 = "configefi";
my $script2 = "updatenetwork";
my $pspath = "$installroot/sysclone/scripts/post-install/";
@@ -1859,7 +1863,7 @@ sub mksysclone
$kcmdline .= "n8r";
}
}
$kcmdline .= " xcatd=$xcatmaster:$xcatdport SCRIPTNAME=$imagename";
$kcmdline .= " XCAT=$xcatmaster:$xcatdport xcatd=$xcatmaster:$xcatdport SCRIPTNAME=$imagename";
#$kcmdline .= " noipv6";
# add the addkcmdline attribute to the end
# of the command, if it exists
@@ -2428,6 +2432,7 @@ sub insert_dd {
my @rpm_list;
my @driver_list;
my $Injectalldriver;
my $updatealldriver;
my @rpm_drivers;
@@ -2472,6 +2477,9 @@ sub insert_dd {
if (/^allupdate$/) {
$Injectalldriver = 1;
next;
} elsif (/^updateonly$/) {
$updatealldriver = 1;
next;
}
unless (/\.ko$/) {
s/$/.ko/;
@@ -2482,7 +2490,7 @@ sub insert_dd {
chomp(@dd_list);
chomp(@rpm_list);
unless (@dd_list || (@rpm_list && ($Injectalldriver || @driver_list))) {
unless (@dd_list || (@rpm_list && ($Injectalldriver || $updatealldriver || @driver_list))) {
return ();
}
@@ -2493,7 +2501,7 @@ sub insert_dd {
# dracut + drvier rpm
# !dracut + driver rpm
# !dracut + driver disk
if (!<$install_dir/$os/$arch/Packages/dracut*> || (@rpm_list && ($Injectalldriver || @driver_list))) {
if (!<$install_dir/$os/$arch/Packages/dracut*> || (@rpm_list && ($Injectalldriver || $updatealldriver || @driver_list))) {
mkpath "$dd_dir/initrd_img"; # The dir for the new initrd
# unzip the initrd image
@@ -2556,13 +2564,12 @@ sub insert_dd {
}
my $new_kernel_ver;
if (@rpm_list && ($Injectalldriver || @driver_list)) {
if (@rpm_list && ($Injectalldriver || $updatealldriver || @driver_list)) {
# Extract the files from rpm to the tmp dir
mkpath "$dd_dir/rpm";
foreach my $rpm (@rpm_list) {
if (-r $rpm) {
$cmd = "cd $dd_dir/rpm; rpm2cpio $rpm | cpio -idum";
#$cmd = "rpm -i --quiet --nodeps --force --ignorearch --ignoreos --nosignature --root $dd_dir/rpm $rpm";
xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
my $rsp;
@@ -2579,17 +2586,17 @@ sub insert_dd {
# and copy it to the /tftpboot
my @new_kernels = <$dd_dir/rpm/boot/vmlinuz*>;
foreach my $new_kernel (@new_kernels) {
if (-r $new_kernel && $new_kernel =~ /\/vmlinuz-(.*(x86_64|ppc64))$/) {
$new_kernel_ver = $1;
$cmd = "/bin/mv -f $new_kernel $kernelpath";
xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
my $rsp;
push @{$rsp->{data}}, "Handle the driver update failed. Could not move $new_kernel to $kernelpath.";
xCAT::MsgUtils->message("I", $rsp, $callback);
if (-r $new_kernel && $new_kernel =~ /\/vmlinuz-(.*(x86_64|ppc64|el\d+))$/) {
$new_kernel_ver = $1;
$cmd = "/bin/mv -f $new_kernel $kernelpath";
xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
my $rsp;
push @{$rsp->{data}}, "Handle the driver update failed. Could not move $new_kernel to $kernelpath.";
xCAT::MsgUtils->message("I", $rsp, $callback);
}
}
}
}
# To skip the conflict of files that some rpm uses the xxx.ko.new as the name of the driver
# Change it back to xxx.ko here
@@ -2620,7 +2627,7 @@ sub insert_dd {
# For dracut mode, only copy the drivers from rpm packages to the /lib/modules/<kernel>
# The driver disk will be handled that append the whole disk to the orignial initrd
if (@rpm_list && ($Injectalldriver || @driver_list)) {
if (@rpm_list && ($Injectalldriver || $updatealldriver || @driver_list)) {
# Copy the firmware to the rootimage
if (-d "$dd_dir/rpm/lib/firmware") {
if (! -d "$dd_dir/initrd_img/lib/firmware") {
@@ -2635,14 +2642,15 @@ sub insert_dd {
}
}
# if the new kernel from update distro is not existed in initrd, copy all the modules for the new kernel to initrd
if ((! -r "$dd_dir/initrd_img/lib/modules/$new_kernel_ver") && (-r "$dd_dir/rpm/lib/modules/$new_kernel_ver")) {
$cmd = "/bin/cp -rf $dd_dir/rpm/lib/modules/$new_kernel_ver $dd_dir/initrd_img/lib/modules/";
xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
my $rsp;
push @{$rsp->{data}}, "Handle the driver update failed. Could not copy $dd_dir/rpm/lib/modules/$new_kernel_ver to $dd_dir/initrd_img/lib/modules.";
xCAT::MsgUtils->message("E", $rsp, $callback);
# get the name list for all drivers in the original initrd if 'netdrivers=updateonly'
# then only the drivers in this list will be updated from the drvier rpms
if ($updatealldriver) {
$driver_name = "\*\.ko";
@all_real_path = ();
find(\&get_all_path, <$dd_dir/initrd_img/lib/modules/*>);
foreach my $real_path (@all_real_path) {
my $driver = basename($real_path);
push @driver_list, $driver;
}
}
@@ -2650,9 +2658,19 @@ sub insert_dd {
# Figure out the kernel version
my @kernelpaths = <$dd_dir/initrd_img/lib/modules/*>;
my @kernelvers;
if ($new_kernel_ver) {
push @kernelvers, $new_kernel_ver;
}
# if new kernel is used, remove all the original kernel directories
foreach (@kernelpaths) {
if (basename($_) =~ /^[\d\.]+/) {
push @kernelvers, basename($_);
my $kernelv = basename($_);
if ($kernelv =~ /^[\d\.]+/) {
if ($new_kernel_ver) {
rmtree ("$dd_dir/initrd_img/lib/modules/$kernelv");
} else {
push @kernelvers, $kernelv;
}
}
}
@@ -2662,6 +2680,7 @@ sub insert_dd {
}
if (@driver_list) {
foreach my $driver (@driver_list) {
$driver =~ s/\.gz$//;
$driver_name = $driver;
@all_real_path = ();
find(\&get_all_path, <$dd_dir/rpm/lib/modules/$kernelver/*>);
@@ -2824,7 +2843,7 @@ sub insert_dd {
}
# Merge the drviers from rpm packages to the initrd
if (@rpm_list && ($Injectalldriver || @driver_list)) {
if (@rpm_list && ($Injectalldriver || $updatealldriver || @driver_list)) {
# Copy the firmware to the rootimage
if (-d "$dd_dir/rpm/lib/firmware") {
if (! -d "$dd_dir/initrd_img/lib") {
@@ -2844,18 +2863,44 @@ sub insert_dd {
mkpath ("$dd_dir/modules/$new_kernel_ver/$arch/");
}
# get the name list for all drivers in the original initrd if 'netdrivers=updateonly'
# then only the drivers in this list will be updated from the drvier rpms
if ($updatealldriver) {
$driver_name = "\*\.ko";
@all_real_path = ();
find(\&get_all_path, <$dd_dir/modules/*>);
foreach my $real_path (@all_real_path) {
my $driver = basename($real_path);
push @driver_list, $driver;
}
}
# Copy the drivers to the initrd
# Figure out the kernel version
my @kernelpaths = <$dd_dir/modules/*>;
my @kernelvers;
if ($new_kernel_ver) {
push @kernelvers, $new_kernel_ver;
}
foreach (@kernelpaths) {
push @kernelvers, basename($_);
my $kernelv = basename($_);
if ($kernelv =~ /^[\d\.]+/) {
if ($new_kernel_ver) {
rmtree ("$dd_dir/modules/$kernelv");
} else {
push @kernelvers, $kernelv;
}
}
}
foreach my $kernelver (@kernelvers) {
unless (-d "$dd_dir/rpm/lib/modules/$kernelver") {
next;
}
# create path for the new kernel in the modules package
unless (-d "$dd_dir/modules/$kernelver") {
mkpath ("$dd_dir/modules/$kernelver/$arch/");
}
# find the $kernelver/$arch dir in the $dd_dir/modules
my $arch4modules;
foreach (<$dd_dir/modules/$kernelver/*>) {
@@ -2931,13 +2976,23 @@ sub insert_dd {
if (-d $ma) {
mkpath "$dd_dir/depmod/lib/modules/$mk";
xCAT::Utils->runcmd("/bin/cp -rf $ma/* $dd_dir/depmod/lib/modules/$mk", -1);
$cmd = "depmod -b $dd_dir/depmod/";
$cmd = "depmod -b $dd_dir/depmod/ $mk";
#$cmd = "depmod -b $dd_dir/depmod/";
xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
my $rsp;
push @{$rsp->{data}}, "Handle the driver update failed. Could not generate the depdency for the drivers in the initrd.";
xCAT::MsgUtils->message("I", $rsp, $callback);
}
# remove the .ko postfix from the driver name for rh5
$cmd = "/bin/sed ".'s/\.ko//g'." $dd_dir/depmod/lib/modules/$mk/modules.dep > $dd_dir/depmod/lib/modules/$mk/modules.dep1; mv -f $dd_dir/depmod/lib/modules/$mk/modules.dep1 $dd_dir/depmod/lib/modules/$mk/modules.dep";
xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
my $rsp;
push @{$rsp->{data}}, "Handle the driver update failed. Could not generate the depdency for the drivers in the initrd.";
xCAT::MsgUtils->message("I", $rsp, $callback);
}
if (-f "$dd_dir/depmod/lib/modules/$mk/modules.dep") {
copy ("$dd_dir/depmod/lib/modules/$mk/modules.dep", "$dd_dir/initrd_img/modules/modules.dep");
}
@@ -3089,10 +3144,12 @@ sub insert_dd {
@rpm_drivers = keys %dnhash;
if (@rpm_list) {
if (@driver_list) {
if (@rpm_drivers) {
push @{$rsp->{data}}, "The drivers:".join(',', sort(@rpm_drivers))." from ".join(',', sort(@rpm_list))." have been injected to initrd.";
} elsif ($Injectalldriver) {
push @{$rsp->{data}}, "All the drivers from :".join(',', sort(@rpm_list))." have been injected to initrd.";
} else {
push @{$rsp->{data}}, "No driver was injected to initrd.";
}
}
+87 -38
View File
@@ -28,6 +28,7 @@ use xCAT::GlobalDef;
use xCAT_monitoring::monitorctrl;
use strict;
use LWP;
require xCAT::data::ibmhwtypes;
#use warnings;
my %mm_comm_pids;
@@ -1773,6 +1774,7 @@ sub rscan_xml {
my $href = {
Node => { }
};
my $mtm = undef;
foreach ( @rscan_attribs ) {
my $d = $data[$i++];
@@ -1789,6 +1791,7 @@ sub rscan_xml {
}
} elsif ( /^groups$/ ) {
$d = "$type,all";
$ignore = 1;
} elsif ( /^mgt$/ ) {
if ($origtype eq "ppcblade") {
$d = "fsp";
@@ -1831,13 +1834,23 @@ sub rscan_xml {
} else {
$ignore = 1;
}
} elsif (/^mtm$/) {
$d =~ /^(\w{4})/;
$mtm = $1;
}
if (!$ignore) {
$href->{Node}->{$_} = $d;
}
}
my $tmp_groups = "$type,all";
if (defined($mtm)) {
my $tmp_pre = xCAT::data::ibmhwtypes::parse_group($mtm);
if (defined($tmp_pre)) {
$tmp_groups .= ",$tmp_pre";
}
}
$href->{Node}->{groups} = $tmp_groups;
$xml.= XMLout($href,NoAttr=>1,KeyAttr=>[],RootName=>undef);
}
return( $xml );
@@ -1872,7 +1885,7 @@ sub rscan_stanza {
$objname = $data[1];
}
$result .= "$objname:\n\tobjtype=node\n";
my $mtm = undef;
foreach ( @rscan_attribs ) {
my $d = $data[$i++];
@@ -1889,6 +1902,7 @@ sub rscan_stanza {
}
} elsif ( /^groups$/ ) {
$d = "$type,all";
$ignore = 1;
} elsif ( /^mgt$/ ) {
if ($origtype eq "ppcblade") {
$d = "fsp";
@@ -1931,12 +1945,23 @@ sub rscan_stanza {
} else {
$ignore = 1;
}
} elsif (/^mtm$/) {
$d =~ /^(\w{4})/;
$mtm = $1;
}
if (!$ignore) {
$result .= "\t$_=$d\n";
}
}
my $tmp_groups = "$type,all";
if (defined ($mtm)) {
my $tmp_pre = xCAT::data::ibmhwtypes::parse_group($mtm);
if (defined ($tmp_pre)) {
$tmp_groups .= ",$tmp_pre";
}
}
$result .= "\tgroups=$tmp_groups\n";
}
return( $result );
}
@@ -2246,6 +2271,13 @@ sub inv {
}
}
}
if ($updatetable and $updatehash{mtm}) {
#updatenodegroups
my $tmp_pre = xCAT::data::ibmhwtypes::parse_group($updatehash{mtm}) ;
if (defined($tmp_pre)) {
xCAT::TableUtils->updatenodegroups($currnode, $tmp_pre);
}
}
if ($updatetable and keys %updatehash) {
my $vpdtab = xCAT::Table->new('vpd');
$vpdtab->setNodeAttribs($currnode,\%updatehash);
@@ -4278,11 +4310,11 @@ sub process_request {
return;
}
}
#my $bladeuser = 'USERID';
#my $bladepass = 'PASSW0RD';
my $bladeuser = 'USERID';
my $bladepass = 'PASSW0RD';
my $blademaxp = 64;
#my $sitetab = xCAT::Table->new('site');
#my $mpatab = xCAT::Table->new('mpa');
my $mpatab = xCAT::Table->new('mpa');
my $mptab = xCAT::Table->new('mp');
my $tmp;
my @entries = xCAT::TableUtils->get_site_attribute("blademaxp");
@@ -4294,19 +4326,19 @@ sub process_request {
# ($tmp)=$sitetab->getAttribs({'key'=>'blademaxp'},'value');
# if (defined($tmp)) { $blademaxp=$tmp->{value}; }
#}
#if ($request->{environment}->[0]->{XCAT_BLADEUSER}) {
# $bladeuser=$request->{environment}->[0]->{XCAT_BLADEUSER}->[0];
# $bladepass=$request->{environment}->[0]->{XCAT_BLADEPASS}->[0];
#} else {
#my $passtab = xCAT::Table->new('passwd');
# if ($passtab) {
# ($tmp)=$passtab->getAttribs({'key'=>'blade'},'username','password');
# if (defined($tmp)) {
# $bladeuser = $tmp->{username};
# $bladepass = $tmp->{password};
# }
# }
#}
if ($request->{environment}->[0]->{XCAT_BLADEUSER}) {
$bladeuser=$request->{environment}->[0]->{XCAT_BLADEUSER}->[0];
$bladepass=$request->{environment}->[0]->{XCAT_BLADEPASS}->[0];
} else {
my $passtab = xCAT::Table->new('passwd');
if ($passtab) {
($tmp)=$passtab->getAttribs({'key'=>'blade'},'username','password');
if (defined($tmp)) {
$bladeuser = $tmp->{username};
$bladepass = $tmp->{password};
}
}
}
if ($request->{command}->[0] eq "findme") {
my $mptab = xCAT::Table->new("mp");
unless ($mptab) { return 2; }
@@ -4388,6 +4420,12 @@ sub process_request {
unless ($node) {
return 1; #failure
}
if ($request->{mtm} and $request->{mtm} =~ /^(\w{4})/) {
my $group = xCAT::data::ibmhwtypes::parse_group($request->{mtm});
if (defined($group)) {
xCAT::TableUtils->updatenodegroups($node, $group);
}
}
if ($mac) {
my $mactab = xCAT::Table->new('mac',-create=>1);
$mactab->setNodeAttribs($macmap{$mac},{mac=>$mac});
@@ -4419,25 +4457,24 @@ sub process_request {
my @nodes=split(',', $2);
my @ids=split(',', $3);
my @mptypes=split(',', $4);
#my $user=$bladeuser;
#my $pass=$bladepass;
my $user=$bladeuser;
my $pass=$bladepass;
my $ent;
#if (defined($mpatab)) {
# my @user_array = $mpatab->getNodeAttribs($mpa, qw(username password));
# foreach my $entry (@user_array) {
# if ($entry->{username}) {
# if ($entry->{username} =~ /^USERID$/ or $entry->{username} !~ /^HMC$/) {
# $ent = $entry;
# last;
# }
# }
# }
# if (defined($ent->{password})) { $pass = $ent->{password}; }
# if (defined($ent->{username})) { $user = $ent->{username}; }
#}
my $authdata = xCAT::PasswordUtils::getIPMIAuth(noderange=>[$mpa]);
$mpahash{$mpa}->{username} = $authdata->{$mpa}->{username};
$mpahash{$mpa}->{password} = $authdata->{$mpa}->{password};
if (defined($mpatab)) {
my @user_array = $mpatab->getNodeAttribs($mpa, qw(username password));
foreach my $entry (@user_array) {
if ($entry->{username}) {
if ($entry->{username} =~ /^USERID$/) {
$ent = $entry;
last;
}
}
}
if (defined($ent->{password})) { $pass = $ent->{password}; }
if (defined($ent->{username})) { $user = $ent->{username}; }
}
$mpahash{$mpa}->{username} = $user;
$mpahash{$mpa}->{password} = $pass;
my $nodehmtab = xCAT::Table->new('nodehm');
my $hmdata = $nodehmtab->getNodesAttribs(\@nodes, ['node', 'mgt']);
for (my $i=0; $i<@nodes; $i++) {
@@ -5012,6 +5049,7 @@ sub updateBMC {
my $user = shift;
my $pass = shift;
my @nodes = ();
my $mphash;
my $mptab = xCAT::Table->new('mp');
if ($mptab) {
my @mpents = $mptab->getAllNodeAttribs(['node','mpa','id']);
@@ -5019,15 +5057,26 @@ sub updateBMC {
my $node = $_->{node};
if (defined($_->{mpa}) and ($_->{mpa} eq $mpa) and defined($_->{id}) and ($_->{id} ne '0')) {
push @nodes, $node;
$mphash->{$node} = [$_];
}
}
}
my $ipmitab = xCAT::Table->new('ipmi');
if ($ipmitab) {
my $ipmihash = $ipmitab->getNodesAttribs(\@nodes, ['bmc']);
my $ipmihash = $ipmitab->getNodesAttribs(\@nodes, ['bmc','username','password']);
foreach (@nodes) {
if (defined($ipmihash->{$_}->[0]) && defined ($ipmihash->{$_}->[0]->{'bmc'})) {
xCAT::IMMUtils::setupIMM($_,curraddr=>$ipmihash->{$_}->[0]->{'bmc'},skipbmcidcheck=>1,skipnetconfig=>1,cliusername=>$user,clipassword=>$pass,callback=>$CALLBACK);
my $ipmiuser = $user;
my $ipmipass = $pass;
my $authdata = xCAT::PasswordUtils::getIPMIAuth(noderange=>[$_],ipmihash=>$ipmihash, mphash=>$mphash);
if (exists($authdata->{$_}->{username})) {
$ipmiuser = $authdata->{$_}->{username};
}
if (exists($authdata->{$_}->{password})) {
$ipmipass = $authdata->{$_}->{password};
}
xCAT::IMMUtils::setupIMM($_,curraddr=>$ipmihash->{$_}->[0]->{'bmc'},skipbmcidcheck=>1,skipnetconfig=>1,cliusername=>$ipmiuser,clipassword=>$ipmipass,callback=>$CALLBACK);
}
}
}
+1 -1
View File
@@ -138,7 +138,7 @@ sub process_request
} elsif (/ssh_dsa_hostkey/) {
if (-r "/etc/xcat/hostkeys/$client/ssh_host_dsa_key") {
$tfilename="/etc/xcat/hostkeys/$client/ssh_host_rsa_key";
$tfilename="/etc/xcat/hostkeys/$client/ssh_host_dsa_key";
} elsif (-r "/etc/xcat/hostkeys/ssh_host_dsa_key") {
$tfilename="/etc/xcat/hostkeys/ssh_host_dsa_key";
} else {
+82 -22
View File
@@ -565,16 +565,55 @@ sub process_request {
if ($ctx->{restartneeded}) {
xCAT::SvrUtils::sendmsg("Restarting $service", $callback);
if (xCAT::Utils->isAIX())
{
system("/usr/bin/stopsrc -s $service");
system("/usr/bin/startsrc -s $service");
}
else
{
system("service $service stop");
system("service $service start");
}
if (xCAT::Utils->isAIX())
{
my $cmd = "/usr/bin/stopsrc -s $service";
my @output=xCAT::Utils->runcmd($cmd, 0);
my $outp = join('', @output);
if ($::RUNCMD_RC != 0)
{
my $rsp = {};
$rsp->{data}->[0] = "Command failed: $cmd. Error message: $outp.\n";
xCAT::MsgUtils->message("E", $rsp, $callback);
return;
}
$cmd = "/usr/bin/startsrc -s $service";
@output=xCAT::Utils->runcmd($cmd, 0);
$outp = join('', @output);
if ($::RUNCMD_RC != 0)
{
my $rsp = {};
$rsp->{data}->[0] = "Command failed: $cmd. Error message: $outp.\n";
xCAT::MsgUtils->message("E", $rsp, $callback);
return;
}
}
else
{
my $cmd = "service $service stop";
my @output=xCAT::Utils->runcmd($cmd, 0);
my $outp = join('', @output);
if ($::RUNCMD_RC != 0)
{
my $rsp = {};
$rsp->{data}->[0] = "Command failed: $cmd. Error message: $outp.\n";
xCAT::MsgUtils->message("E", $rsp, $callback);
return;
}
$cmd = "service $service start";
@output=xCAT::Utils->runcmd($cmd, 0);
$outp = join('', @output);
if ($::RUNCMD_RC != 0)
{
my $rsp = {};
$rsp->{data}->[0] = "Command failed: $cmd. Error message: $outp.\n";
xCAT::MsgUtils->message("E", $rsp, $callback);
return;
}
}
xCAT::SvrUtils::sendmsg("Restarting named complete", $callback);
}
} else {
@@ -590,8 +629,16 @@ sub process_request {
my @output=xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0)
{
system("/usr/bin/startsrc -s $service");
xCAT::SvrUtils::sendmsg("Starting named complete", $callback);
$cmd = "/usr/bin/startsrc -s $service";
@output=xCAT::Utils->runcmd($cmd, 0);
my $outp = join('', @output);
if ($::RUNCMD_RC != 0)
{
my $rsp = {};
$rsp->{data}->[0] = "Command failed: $cmd. Error message: $outp.\n";
xCAT::MsgUtils->message("E", $rsp, $callback);
return;
}
}
}
else
@@ -600,11 +647,19 @@ sub process_request {
my @output=xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0)
{
system("service $service start");
xCAT::SvrUtils::sendmsg("Starting named complete", $callback);
$cmd = "service $service start";
@output=xCAT::Utils->runcmd($cmd, 0);
my $outp = join('', @output);
if ($::RUNCMD_RC != 0)
{
my $rsp = {};
$rsp->{data}->[0] = "Command failed: $cmd. Error message: $outp.\n";
xCAT::MsgUtils->message("E", $rsp, $callback);
return;
}
}
}
}
#now we stick to Net::DNS style updates, with TSIG if possible. TODO: kerberized (i.e. Windows) DNS server support, maybe needing to use nsupdate -g....
if ($external)
{
@@ -617,9 +672,11 @@ sub process_request {
$ctx->{resolver} = Net::DNS::Resolver->new(nameservers=>['127.0.0.1']);
}
add_or_delete_records($ctx);
my $ret = add_or_delete_records($ctx);
unless($ret) {
xCAT::SvrUtils::sendmsg("DNS setup is completed", $callback);
}
xCAT::SvrUtils::sendmsg("DNS setup is completed", $callback);
umask($oldmask);
}
@@ -1073,8 +1130,11 @@ sub add_or_delete_records {
}
my $zone;
foreach $zone (keys %{$ctx->{updatesbyzone}}) {
my $ip = xCAT::NetworkUtils->getipaddr($ctx->{nsmap}->{$zone});
my $ip = xCAT::NetworkUtils->getipaddr($ctx->{nsmap}->{$zone});
if( !defined $ip) {
xCAT::SvrUtils::sendmsg([1,"Please make sure $ctx->{nsmap}->{$zone} exist in /etc/hosts or DNS."], $callback);
return 1;
}
my $resolver = Net::DNS::Resolver->new(nameservers=>[$ip]);
my $entry;
my $numreqs = 300; # limit to 300 updates in a payload, something broke at 644 on a certain sample, choosing 300 for now
@@ -1094,7 +1154,7 @@ sub add_or_delete_records {
{
if ($reply->header->rcode ne 'NOERROR')
{
xCAT::SvrUtils::sendmsg([1,"Failure encountered updating $zone, error was ".$reply->header->rcode], $callback);
xCAT::SvrUtils::sendmsg([1,"Failure encountered updating $zone, error was ".$reply->header->rcode.". See more details in system log."], $callback);
}
}
else
@@ -1112,7 +1172,7 @@ sub add_or_delete_records {
{
if ($reply->header->rcode ne 'NOERROR')
{
xCAT::SvrUtils::sendmsg([1,"Failure encountered updating $zone, error was ".$reply->header->rcode], $callback);
xCAT::SvrUtils::sendmsg([1,"Failure encountered updating $zone, error was ".$reply->header->rcode.". See more details in system log."], $callback);
}
}
else
+7 -2
View File
@@ -831,7 +831,7 @@ sub mkinstall
#}
# need to add these in, otherwise aptitude will ask questions
$kcmdline .= " locale=en_US console-setup/layoutcode=us";
$kcmdline .= " locale=en_US";
#$kcmdline .= " netcfg/wireless_wep= netcfg/get_hostname= netcfg/get_domain=";
# default answers as much as possible, we don't want any interactiveness :)
@@ -849,11 +849,16 @@ sub mkinstall
#$kcmdline .= " DEBCONF_DEBUG=5";
# I don't need the timeout for ubuntu, but for debian there is a problem with getting dhcp in a timely manner
$kcmdline .= " netcfg/dhcp_timeout=120";
# safer way to set hostname, avoid problems with nameservers
$kcmdline .= " hostname=".$node;
#from 12.10, the live install changed, so add the live-installer
if ( -r "$pkgdir/install/filesystem.squashfs")
{
$kcmdline .= " live-installer/net-image=http://${instserver}${pkgdir}/install/filesystem.squashfs";
}
$bptab->setNodeAttribs(
$node,
{
+8
View File
@@ -97,6 +97,7 @@ my %guestidmap = (
"rhel.6.*" => "rhel6_",
"rhel.5.*" => "rhel5_",
"rhel4.*" => "rhel4_",
"centos6.*" => "rhel6_",
"centos5.*" => "rhel5_",
"centos4.*" => "rhel4_",
"sles11.*" => "sles11_",
@@ -4218,6 +4219,13 @@ sub copycd {
$found=1;
last;
}
if (/VMware ESXi 5\.5/) {
$darch="x86_64";
$arch="x86_64";
unless ($distname) { $distname='esxi5.5'; }
$found=1;
last;
}
}
}
+1
View File
@@ -28,6 +28,7 @@ sub handled_commands {
mkvm => 'nodehm:mgt',
lsvm => 'nodehm:mgt',
chvm => 'nodehm:mgt',
rmvm => 'nodehm:mgt',
rscan => 'nodehm:mgt',
getfspcon => 'nodehm:cons',
getmulcon => 'fsp',
+27
View File
@@ -10,6 +10,7 @@ use xCAT::SvrUtils;
use xCAT::Table;
#use Data::Dumper;
use File::Path;
use File::Copy;
use Getopt::Long;
Getopt::Long::Configure("bundling");
Getopt::Long::Configure("pass_through");
@@ -169,6 +170,7 @@ sub process_request {
$otherpkglist = $ref_linuximage_tab->{'otherpkglist'};
$postinstall_filename = $ref_linuximage_tab->{'postinstall'};
$destdir = $ref_linuximage_tab->{'rootimgdir'};
$rootimg_dir = $ref_linuximage_tab->{'rootimgdir'};
$driverupdatesrc = $ref_linuximage_tab->{'driverupdatesrc'};
# TODO: how can we do if the user specifies one wrong value to the following attributes?
@@ -363,6 +365,31 @@ sub process_request {
# print FILE "\n";
#}
#close FILE;
# update the generated initrd to /tftpboot/xcat so that don't need to rerun nodeset to update them
if (($::RUNCMD_RC == 0) && $imagename) {
my $tftpdir = "/tftpboot";
my @siteents = xCAT::TableUtils->get_site_attribute("tftpdir");
if ($#siteents >= 0)
{
$tftpdir = $siteents[0];
}
my $tftppath = "$tftpdir/xcat/osimage/$imagename";
my $installdir = "/install";
@siteents = xCAT::TableUtils->get_site_attribute("installdir");
if ($#siteents >= 0)
{
$installdir = $siteents[0];
}
unless (-d $tftppath) {
mkpath $tftppath;
}
copy("$rootimg_dir/initrd-stateless.gz", "$tftppath");
copy("$rootimg_dir/initrd-statelite.gz", "$tftppath");
copy("$rootimg_dir/kernel", "$tftppath");
}
#parse the output and save the image data to osimage and linuximage table
save_image_data($callback, $doreq, $tempfile);
+48 -5
View File
@@ -26,8 +26,28 @@ sub preprocess_request
my $req = shift;
my $callback = shift;
unless (defined ($req->{arg}) && $req->{arg}->[0]) {
xCAT::MsgUtils->message("E", {error=>["An osimage name needs to be specified."], errorcode=>["1"]}, $callback);
my $usage = sub {
my $callback = shift;
xCAT::MsgUtils->message("I", {data=>["Usage: geninitrd <imagename> [-h | --help]"]}, $callback);
};
my $osimage;
if (defined ($req->{arg})) {
foreach (@{$req->{arg}}) {
if (/^-/) {
$usage->($callback);
return;
}else {
$osimage = $_;
}
}
} else {
$usage->($callback);
return;
}
unless ($osimage) {
$usage->($callback);
return;
}
@@ -46,10 +66,11 @@ sub process_request
{
my $req = shift;
my $callback = shift;
my $doreq = shift;
if ($req->{command}->[0] eq 'geninitrd')
{
return geninitrd($req, $callback);
return geninitrd($req, $callback, $doreq);
}
}
@@ -57,6 +78,7 @@ sub process_request
sub geninitrd {
my $req = shift;
my $callback = shift;
my $doreq = shift;
my $osimage = $req->{arg}->[0];
@@ -69,7 +91,7 @@ sub geninitrd {
return;
}
my $oient = $osimagetab->getAttribs({imagename => $osimage}, 'osvers', 'osarch', 'osupdatename');
my $oient = $osimagetab->getAttribs({imagename => $osimage}, 'provmethod', 'osvers', 'osarch', 'osupdatename');
unless ($oient && $oient->{'osvers'} && $oient->{'osarch'} ) {
xCAT::MsgUtils->message("E", {error=>["The osimage [$osimage] was not defined or [osvers, osarch] attributes were not set."], errorcode=>["1"]}, $callback);
return;
@@ -84,7 +106,7 @@ sub geninitrd {
return;
}
my $lient = $linuximagetab->getAttribs({imagename => $osimage}, 'pkgdir', 'driverupdatesrc', 'netdrivers');
my $lient = $linuximagetab->getAttribs({imagename => $osimage}, 'rootimgdir', 'pkgdir', 'driverupdatesrc', 'netdrivers');
unless ($lient && $lient->{'pkgdir'}) {
xCAT::MsgUtils->message("E", {error=>["The osimage [$osimage] was not defined or [pkgdir] attribute was not set."], errorcode=>["1"]}, $callback);
return;
@@ -93,6 +115,27 @@ sub geninitrd {
$driverupdatesrc = $lient->{'driverupdatesrc'};
$netdrivers = $lient->{'netdrivers'};
# if the provmethod equals 'netboot', call the genimage --onlyinitrd directly
if ($oient->{'provmethod'} && ($oient->{'provmethod'} eq "netboot" || $oient->{'provmethod'} eq "statelite")) {
if ($lient->{'rootimgdir'}) {
unless (-d $lient->{'rootimgdir'}."/rootimg/lib/modules") {
xCAT::MsgUtils->message("E", {error=>["The genimage should be run before running geninitrd."], errorcode=>["1"]}, $callback);
return;
}
} else {
xCAT::MsgUtils->message("E", {error=>["The rootimgdir attribute for the osimage should be set."], errorcode=>["1"]}, $callback);
return;
}
my @output = `genimage $osimage --onlyinitrd`;
xCAT::MsgUtils->message("I", {data=>\@output}, $callback);
#$doreq->({ command => ['genimage'],
# arg => [$osimage, '--onlyinitrd'] }, $callback);
return;
} elsif (!$oient->{'provmethod'} || $oient->{'provmethod'} ne "install") {
xCAT::MsgUtils->message("E", {error=>["The attribute [provmethod] for osimage [$osimage] must be set to install, netboot or statelite."], errorcode=>["1"]}, $callback);
return;
}
# get the path list of the osdistroupdate
if ($oient->{'osupdatename'}) {
my @osupdatenames = split (/,/, $oient->{'osupdatename'});
+39 -1
View File
@@ -205,6 +205,32 @@ sub addotherinterfaces
}
}
sub delotherinterfaces
{
my $node = shift;
my $otherinterfaces = shift;
my $domain = shift;
my @itf_pairs = split(/,/, $otherinterfaces);
foreach (@itf_pairs)
{
my ($itf, $ip);
if ($_ =~ /!/) {
($itf, $ip) = split(/!/, $_);
} else {
($itf, $ip) = split(/:/, $_);
}
if ($ip && xCAT::NetworkUtils->isIpaddr($ip))
{
if ($itf =~ /^-/)
{
$itf = $node . $itf;
}
delnode $itf, $ip, '', $domain;
}
}
}
sub add_hosts_content {
my %args = @_;
my $nodelist = $args{nodelist};
@@ -247,6 +273,10 @@ sub add_hosts_content {
if ($DELNODE)
{
delnode $nodename, $ip, $ref->{hostnames}, $domain;
if (defined($ref->{otherinterfaces}))
{
delotherinterfaces $nodename, $ref->{otherinterfaces}, $domain;
}
}
else
{
@@ -257,9 +287,10 @@ sub add_hosts_content {
else
{
my $rsp;
push @{$rsp->{data}}, "Invalid IP Addr \'$_->{ip}\' for node \'$_->{node}\'.";
push @{$rsp->{data}}, "Invalid IP Addr \'$ref->{ip}\' for node \'$ref->{node}\'.";
xCAT::MsgUtils->message("E", $rsp, $callback);
}
if (defined($ref->{otherinterfaces}))
{
addotherinterfaces $callback, $nodename, $ref->{otherinterfaces}, $domain;
@@ -451,6 +482,13 @@ sub process_request
{
addnode $callback, $_->{node}, $_->{ip}, $_->{hostnames}, $domain;
}
else
{
my $rsp;
push @{$rsp->{data}}, "Invalid IP Addr \'$_->{ip}\' for node \'$_->{node}\'.";
xCAT::MsgUtils->message("E", $rsp, $callback);
}
if (defined($_->{otherinterfaces}))
{
addotherinterfaces $callback, $_->{node}, $_->{otherinterfaces}, $domain;
+9
View File
@@ -90,21 +90,30 @@ my %bootnumbers = (
'f' => 2,
'floppy' => 2,
'usb' => 3,
'usbflash' => 3,
'flash' => 3,
'h' => 4,
'hd' => 4,
'hdd' => 4,
'hd0' => 4,
'harddisk' => 4,
'eth0' => 5,
'nic1' => 5,
'net1' => 5,
'net' => 5,
'n' => 5,
'pxe_nic1' => 5,
'eth1' => 6,
'nic2' => 6,
'net2' => 6,
'pxe_nic2' => 6,
'eth2' => 7,
'nic3' => 7,
'net3' => 7,
'pxe_nic3' => 7,
'eth3' => 8,
'nic4' => 8,
'net4' => 8,
'pxe_nic4' => 8
);
+75 -50
View File
@@ -438,7 +438,7 @@ sub get_files{
my @files;
my $dir = "$installroot/netboot/$osvers/s390x/$profile";
opendir(DIR, $dir) or $callback->({error=>["Could not open image files in directory $dir"], errorcode=>[1]});
while (my $file = readdir(DIR)) {
# We only want files in the directory that end with .img
next unless (-f "$dir/$file");
@@ -449,7 +449,7 @@ sub get_files{
if (@files) {
$attrs->{rawimagefiles}->{files} = [@files];
}
closedir(DIR);
}
else {
@@ -465,37 +465,51 @@ sub get_files{
$attrs->{linuximage}->{pkglist} = $temp;
}
}
@arr = ("$installroot/netboot");
# look for ramdisk
my $ramdisk = look_for_file('initrd-stateless.gz', $callback, $attrs, @arr);
unless($ramdisk){
$callback->({error=>["Couldn't find ramdisk (initrd-stateless.gz) for $imagename"],errorcode=>[1]});
$errors++;
}else{
$attrs->{ramdisk} = $ramdisk;
}
# look for kernel
my $kernel = look_for_file('kernel', $callback, $attrs, @arr);
unless($kernel){
$callback->({error=>["Couldn't find kernel (kernel) for $imagename"],errorcode=>[1]});
$errors++;
}else{
$attrs->{kernel} = $kernel;
}
# look for rootimg.gz
my $rootimg = look_for_file('rootimg.gz', $callback, $attrs, @arr);
unless($rootimg){
$callback->({error=>["Couldn't find rootimg (rootimg.gz) for $imagename"],errorcode=>[1]});
$errors++;
}else{
$attrs->{rootimg} = $rootimg;
}
}
} elsif ($provmethod =~ /statelite/) {
my $rootimgdir=$attrs->{linuximage}->{rootimgdir};
my $ramdisk;
my $kernel;
my $rootimg;
# look for ramdisk, kernel and rootimg.gz
if($rootimgdir) {
if (-f "$rootimgdir/initrd-stateless.gz") {
$ramdisk="$rootimgdir/initrd-stateless.gz";
}
if (-f "$rootimgdir/kernel") {
$kernel="$rootimgdir/kernel";
}
if (-f "$rootimgdir/rootimg.gz") {
$rootimg="$rootimgdir/rootimg.gz";
}
} else {
$ramdisk = look_for_file('initrd-stateless.gz', $callback, $attrs, @arr);
$kernel = look_for_file('kernel', $callback, $attrs, @arr);
$rootimg = look_for_file('rootimg.gz', $callback, $attrs, @arr);
}
unless($ramdisk){
$callback->({error=>["Couldn't find ramdisk (initrd-stateless.gz) for $imagename"],errorcode=>[1]});
$errors++;
}else{
$attrs->{ramdisk} = $ramdisk;
}
unless($kernel){
$callback->({error=>["Couldn't find kernel (kernel) for $imagename"],errorcode=>[1]});
$errors++;
}else{
$attrs->{kernel} = $kernel;
}
unless($rootimg){
$callback->({error=>["Couldn't find rootimg (rootimg.gz) for $imagename"],errorcode=>[1]});
$errors++;
}else{
$attrs->{rootimg} = $rootimg;
}
}
} elsif ($provmethod =~ /statelite/) {
@arr = ("$installroot/custom/netboot", "$xcatroot/share/xcat/netboot");
#get .pkglist file
if (! $attrs->{linuximage}->{pkglist}) {
@@ -510,25 +524,36 @@ sub get_files{
}
@arr = ("$installroot/netboot");
# look for kernel
my $kernel = look_for_file('kernel', $callback, $attrs, @arr);
unless($kernel){
$callback->({error=>["Couldn't find kernel (kernel) for $imagename"],errorcode=>[1]});
$errors++;
}else{
$attrs->{kernel} = $kernel;
}
my $rootimgdir=$attrs->{linuximage}->{rootimgdir};
my $kernel;
my $ramdisk;
#look for kernel and ramdisk
if($rootimgdir) {
if (-f "$rootimgdir/kernel") {
$kernel="$rootimgdir/kernel";
}
if (-f "$rootimgdir/initrd-statelite.gz") {
$ramdisk="$rootimgdir/initrd-statelite.gz";
}
} else {
$kernel = look_for_file('kernel', $callback, $attrs, @arr);
$ramdisk = look_for_file('initrd-statelite.gz', $callback, $attrs, @arr);
}
unless($kernel){
$callback->({error=>["Couldn't find kernel (kernel) for $imagename"],errorcode=>[1]});
$errors++;
}else{
$attrs->{kernel} = $kernel;
}
# look for ramdisk
my $ramdisk = look_for_file('initrd-statelite.gz', $callback, $attrs, @arr);
unless($ramdisk){
$callback->({error=>["Couldn't find ramdisk (initrd-statelite.gz) for $imagename"],errorcode=>[1]});
$errors++;
}else{
$attrs->{ramdisk} = $ramdisk;
}
}
unless($ramdisk){
$callback->({error=>["Couldn't find ramdisk (initrd-statelite.gz) for $imagename"],errorcode=>[1]});
$errors++;
}else{
$attrs->{ramdisk} = $ramdisk;
}
}
}
if (( $provmethod =~ /raw/ ) and ( $arch =~ /s390x/ )) {
+322 -13
View File
@@ -34,6 +34,7 @@ my $iem_support;
my $vpdhash;
my %allerrornodes=();
my $global_sessdata;
require xCAT::data::ibmhwtypes;
eval {
require IBM::EnergyManager;
@@ -55,6 +56,7 @@ sub handled_commands {
rspreset => 'nodehm:mgt', #done
rvitals => 'nodehm:mgt', #done
rinv => 'nodehm:mgt', #done
rflash => 'nodehm:mgt', #done
rsetboot => 'nodehm:mgt', #done
rbeacon => 'nodehm:mgt', #done
reventlog => 'nodehm:mgt',
@@ -465,12 +467,16 @@ sub on_bmc_connect {
}
#ok, detect some common prereqs here, notably:
#getdevid
if ($command eq "getrvidparms") {
if ($command eq "getrvidparms" or $command eq "rflash") {
unless (defined $sessdata->{device_id}) {
$sessdata->{ipmisession}->subcmd(netfn=>6,command=>1,data=>[],callback=>\&gotdevid,callback_args=>$sessdata);
return;
}
getrvidparms($sessdata);
if ($command eq "getrvidparms") {
getrvidparms($sessdata);
} else {
rflash($sessdata);
}
}
#initsdr
if ($command eq "rinv" or $command eq "reventlog" or $command eq "rvitals") {
@@ -1208,6 +1214,174 @@ sub ripmi_callback {
xCAT::SvrUtils::sendmsg($output,$callback,$sessdata->{node},%allerrornodes);
}
sub isfpc {
my $sessdata = shift;
return 1
}
sub rflash {
my $sessdata = shift;
if (isfpc($sessdata)) {
#first, start a fpc firmware transaction
$sessdata->{firmpath} = $sessdata->{subcommand};
$sessdata->{firmctx} = "init";
$sessdata->{ipmisession}->subcmd(netfn=>0x8, command=>0x17,
data=>[0,0,1,0,0,0,0],
callback=>\&fpc_firmup_config,
callback_args=>$sessdata);
} else {
die "Unimplemented";
}
}
sub fpc_firmup_config {
if (check_rsp_errors(@_)) {
abort_fpc_update($_[1]);
return;
}
my $rsp = shift;
my $sessdata = shift;
unless ($sessdata->{firmupxid}) {
$sessdata->{firmupxid} = $rsp->{data}->[0];
}
my $data;
if ($sessdata->{firmctx} eq 'init') {
$data =[0, $sessdata->{firmupxid}, 1, 0, 1, 0, 0, 0,
length($sessdata->{firmpath}),
unpack("C*",$sessdata->{firmpath})];
$sessdata->{firmctx} = 'p1';
} elsif ($sessdata->{firmctx} eq 'p1') {
$data = [0, $sessdata->{firmupxid}, 3, 0, 5];
$sessdata->{firmctx} = 'p2';
} elsif ($sessdata->{firmctx} eq 'p2') {
$data = [0, $sessdata->{firmupxid}, 4, 0, 0xa];
$sessdata->{firmctx} = 'p3';
} elsif ($sessdata->{firmctx} eq 'p3') {
$data = [0, $sessdata->{firmupxid}, 5, 0, 3];
$sessdata->{firmctx} = 'p4';
} elsif ($sessdata->{firmctx} eq 'p4') {
$data = [0, $sessdata->{firmupxid}, 6, 0, 1];
$sessdata->{firmctx} = 'xfer';
xCAT::SvrUtils::sendmsg("Transferring firmware",$callback,$sessdata->{node},%allerrornodes);
$sessdata->{ipmisession}->subcmd(netfn=>0x8, command=>0x19,
data=>[0, $sessdata->{firmupxid}],
callback=>\&fpc_firmxfer_watch,
callback_args=>$sessdata);
return;
}
$sessdata->{ipmisession}->subcmd(netfn=>0x8, command=>0x18,
data=>$data,
callback=>\&fpc_firmup_config,
callback_args=>$sessdata);
}
sub abort_fpc_update {
my $sessdata = shift;
$sessdata->{ipmisession}->subcmd(netfn=>0x8, command=>0x15, data=>[], callback=>\&fpc_update_aborted, callback_args=>$sessdata);
}
sub fpc_update_aborted {
check_rsp_errors(@_);
return;
}
sub fpc_firmxfer_watch {
if ($_[0]->{code} == 0x89) {
xCAT::SvrUtils::sendmsg([1,"Transfer failed (wrong url?)"],$callback,$_[1]->{node},%allerrornodes);
abort_fpc_update($_[1]);
return;
}
if (check_rsp_errors(@_)) {
abort_fpc_update($_[1]);
return;
}
my $rsp = shift;
my $sessdata = shift;
my $delay=1;
my $watch=2;
if ($sessdata->{firmctx} eq 'apply') { $delay = 15; $watch = 1;}
if (check_rsp_errors(@_)) {
return;
}
my $percent = 0;
if ($rsp->{data} and (length(@{$rsp->{data}}) > 0)) {
$percent = $rsp->{data}->[0];
}
#$callback->({sinfo=>"$percent%"});
if ($percent == 100) {
if ($sessdata->{firmctx} eq 'xfer') {
xCAT::SvrUtils::sendmsg("Applying firmware",$callback,$sessdata->{node},%allerrornodes);
$sessdata->{firmctx} = "apply";
$sessdata->{ipmisession}->subcmd(netfn=>0x8, command=>0x20,
data=>[0, $sessdata->{firmupxid}],
callback=>\&fpc_firmxfer_watch,
callback_args=>$sessdata);
return;
} else {
xCAT::SvrUtils::sendmsg("Resetting FPC",$callback,$sessdata->{node},%allerrornodes);
resetbmc($sessdata);
}
} else {
$sessdata->{ipmisession}->subcmd(netfn=>0x8, command=>0x12,
data=>[$watch],
delayxmit=>$delay,
callback=>\&fpc_firmxfer_watch,
callback_args=>$sessdata);
}
}
sub reseat_node {
my $sessdata = shift;
if (1) { # TODO: FPC path checked for
my $mptab = xCAT::Table->new('mp', -create=>0);
unless ($mptab) {
xCAT::SvrUtils::sendmsg([1,"mp table must be configured for reseat"],$callback,$sessdata->{node},%allerrornodes);
return;
}
my $mpent = $mptab->getNodeAttribs($sessdata->{node},[qw/mpa id/]);
unless ($mpent and $mpent->{mpa} and $mpent->{id}) {
xCAT::SvrUtils::sendmsg([1,"mp table must be configured for reseat"],$callback,$sessdata->{node},%allerrornodes);
return;
}
my $fpc = $mpent->{mpa};
my $ipmitab = xCAT::Table->new("ipmi");
my $ipmihash = $ipmitab->getNodesAttribs([$fpc],['bmc','username','password']) ;
my $authdata = xCAT::PasswordUtils::getIPMIAuth(noderange=>[$fpc],ipmihash=>$ipmihash);
my $nodeuser=$authdata->{$fpc}->{username};
my $nodepass=$authdata->{$fpc}->{password};
$sessdata->{slotnumber} = $mpent->{id};
$sessdata->{fpcipmisession} = xCAT::IPMI->new(bmc=>$mpent->{mpa},userid=>$nodeuser,password=>$nodepass);
$sessdata->{fpcipmisession}->login(callback=>\&fpc_node_reseat,callback_args=>$sessdata);
}
}
sub fpc_node_reseat {
my $status = shift;
my $sessdata = shift;
if ($status =~ /ERROR:/) {
xCAT::SvrUtils::sendmsg([1,$status],$callback,$sessdata->{node},%allerrornodes);
return;
}
$sessdata->{fpcipmisession}->subcmd(netfn=>0x32, command=>0xa4,
data=>[$sessdata->{slotnumber}, 2],
callback=>\&fpc_node_reseat_complete, callback_args=>$sessdata);
}
sub fpc_node_reseat_complete {
my $rsp = shift;
my $sessdata = shift;
if ($rsp->{error}) {
xCAT::SvrUtils::sendmsg([1,$rsp->{error}],$callback,$sessdata->{node},%allerrornodes);
return;
}
if ($rsp->{code} == 0) {
xCAT::SvrUtils::sendmsg("reseat",$callback,$sessdata->{node},%allerrornodes);
} elsif ($rsp->{code} == 0xd5) {
xCAT::SvrUtils::sendmsg([1,"No node in slot"],$callback,$sessdata->{node},%allerrornodes);
} else {
xCAT::SvrUtils::sendmsg([1,"Unknown error code ".$rsp->{code}],$callback,$sessdata->{node},%allerrornodes);
}
}
sub power {
my $sessdata = shift;
@@ -1218,7 +1392,9 @@ sub power {
my $rc = 0;
my $text;
my $code;
if (not $sessdata->{acpistate} and $sessdata->{mfg_id} == 20301) { #Only implemented for IBM servers
if ($sessdata->{subcommand} eq "reseat") {
reseat_node($sessdata);
} elsif (not $sessdata->{acpistate} and $sessdata->{mfg_id} == 20301) { #Only implemented for IBM servers
$sessdata->{ipmisession}->subcmd(netfn=>0x3a,command=>0x1d,data=>[1],callback=>\&power_with_acpi,callback_args=>$sessdata);
} else {
$sessdata->{ipmisession}->subcmd(netfn=>0,command=>1,data=>[],callback=>\&power_with_context,callback_args=>$sessdata);
@@ -1568,6 +1744,11 @@ sub inv {
sub fru_initted {
my $sessdata = shift;
my $key;
my @args = @{$sessdata->{extraargs}};
my $up_group = undef;
if (grep /-t/, @args) {
$up_group = '1';
}
my @types = @{$sessdata->{invtypes}};
my $format = "%-20s %s";
@@ -1576,11 +1757,17 @@ sub fru_initted {
my $type;
foreach $type (split /,/,$fru->rec_type) {
if(grep {$_ eq $type} @types) {
my $bmcifo="";
if ($sessdata->{bmcnum} != 1) {
$bmcifo=" on BMC ".$sessdata->{bmcnum};
}
xCAT::SvrUtils::sendmsg(sprintf($format.$bmcifo,$sessdata->{fru_hash}->{$key}->desc . ":",$sessdata->{fru_hash}->{$key}->value),$callback,$sessdata->{node},%allerrornodes);
my $bmcifo="";
if ($sessdata->{bmcnum} != 1) {
$bmcifo=" on BMC ".$sessdata->{bmcnum};
}
xCAT::SvrUtils::sendmsg(sprintf($format.$bmcifo,$sessdata->{fru_hash}->{$key}->desc . ":",$sessdata->{fru_hash}->{$key}->value),$callback,$sessdata->{node},%allerrornodes);
if ($up_group and $type eq "model" and $fru->desc =~ /MTM/) {
my $tmp_pre = xCAT::data::ibmhwtypes::parse_group($fru->value);
if (defined($tmp_pre)) {
xCAT::TableUtils->updatenodegroups($sessdata->{node}, $tmp_pre);
}
}
last;
}
}
@@ -1773,9 +1960,69 @@ sub got_fpga_buildid {
$sessdata->{fpgabuildid} = $res{data};
get_imm_property(property=>"/v2/fpga/build_version",callback=>\&got_fpga_version,sessdata=>$sessdata);
} else {
initfru_with_mprom($sessdata);
get_imm_property(property=>"/v2/ibmc/dm/fw/bios/backup_build_id",callback=>\&got_backup_bios_buildid,sessdata=>$sessdata);
}
}
sub got_backup_bios_buildid {
my %res = @_;
my $sessdata = $res{sessdata};
if ($res{data}) {
$sessdata->{backupbiosbuild} = $res{data};
get_imm_property(property=>"/v2/ibmc/dm/fw/bios/backup_build_version",callback=>\&got_backup_bios_version,sessdata=>$sessdata);
} else {
initfru_with_mprom($sessdata);
}
}
sub got_backup_bios_version {
my %res = @_;
my $sessdata = $res{sessdata};
if ($res{data}) {
$sessdata->{backupbiosversion} = $res{data};
my $fru = FRU->new();
$fru->rec_type("bios,uefi,firmware");
$fru->desc("Backup UEFI Version");
$fru->value($sessdata->{backupbiosversion}." (".$sessdata->{backupbiosbuild}.")");
$sessdata->{fru_hash}->{backupuefi} = $fru;
get_imm_property(property=>"/v2/ibmc/dm/fw/imm2/backup_build_id",callback=>\&got_backup_imm_buildid,sessdata=>$sessdata);
} else {
initfru_with_mprom($sessdata);
}
}
sub got_backup_imm_buildid {
my %res = @_;
my $sessdata = $res{sessdata};
if ($res{data}) {
$sessdata->{backupimmbuild} = $res{data};
get_imm_property(property=>"/v2/ibmc/dm/fw/imm2/backup_build_version",callback=>\&got_backup_imm_version,sessdata=>$sessdata);
} else {
initfru_with_mprom($sessdata);
}
}
sub got_backup_imm_version {
my %res = @_;
my $sessdata = $res{sessdata};
if ($res{data}) {
$sessdata->{backupimmversion} = $res{data};
get_imm_property(property=>"/v2/ibmc/dm/fw/imm2/backup_build_date",callback=>\&got_backup_imm_builddate,sessdata=>$sessdata);
} else {
initfru_with_mprom($sessdata);
}
}
sub got_backup_imm_builddate {
my %res = @_;
my $sessdata = $res{sessdata};
if ($res{data}) {
$sessdata->{backupimmdate} = $res{data};
my $fru = FRU->new();
$fru->rec_type("bios,uefi,firmware");
$fru->desc("Backup IMM Version");
$fru->value($sessdata->{backupimmversion}." (".$sessdata->{backupimmbuild}." ".$sessdata->{backupimmdate}.")");
$sessdata->{fru_hash}->{backupimm} = $fru;
}
initfru_with_mprom($sessdata);
}
sub got_fpga_version {
my %res = @_;
my $sessdata = $res{sessdata};
@@ -2772,6 +3019,7 @@ sub parseprod {
}
$idx+=$currsize;
($currsize,$currdata,$encode)=extractfield(\@area,$idx);
if ($currsize < 0) { last }
}
return \%info;
@@ -2844,6 +3092,7 @@ sub parseboard {
}
$idx+=$currsize;
($currsize,$currdata,$encode)=extractfield(\@area,$idx);
if ($currsize < 0) { last }
}
if ($global_sessdata->{isanimm}) { #we can understand more specifically some of the extra fields...
$boardinf{frunum}=$boardinf{extra}->[0]->{value};
@@ -2908,6 +3157,7 @@ sub parsechassis {
}
$idx+=$currsize;
($currsize,$currdata,$encode)=extractfield(\@chassarea,$idx);
if ($currsize < 0) { last }
}
return \%chassisinf;
}
@@ -2919,7 +3169,7 @@ sub extractfield { #idx is location of the type/length byte, returns something a
my $data;
if ($idx >= scalar @$area) {
xCAT::SvrUtils::sendmsg([1,"Error parsing FRU data from BMC"],$callback);
return 1,undef,undef;
return -1,undef,undef;
}
my $size = $area->[$idx] & 0b00111111;
my $encoding = ($area->[$idx] & 0b11000000)>>6;
@@ -3905,8 +4155,8 @@ sub getaddsensorevent {
0x0f => "Enabling docking station",
0x10 => "Docking staion ejection",
0x11 => "Disable docking station",
0x12 => "Calling operation system wake-up vector",
0x13 => "Starting operation system boot process, call init 19h",
0x12 => "Calling operating system wake-up vector",
0x13 => "Starting operating system boot process, call init 19h",
0x14 => "Baseboard or motherboard initialization",
0x16 => "Floppy initialization",
0x17 => "Keyboard test",
@@ -5176,6 +5426,57 @@ sub sensor_was_read {
if (@exparts) {
$extext = join(",",@exparts);
}
} elsif ($sdr->sensor_type == 0x28) {
if ($exdata1 & 1) {
push @exparts,"Degraded or unavailable";
}
if ($exdata1 & 1<<1) {
push @exparts,"Degraded or unavailable";
}
if ($exdata1 & 1<<2) {
push @exparts,"Offline";
}
if ($exdata1 & 1<<3) {
push @exparts,"Unavailable";
}
if ($exdata1 & 1<<4) {
push @exparts,"Failure";
}
if ($exdata1 & 1<<5) {
push @exparts,"FRU Failure";
}
} elsif ($sdr->sensor_type == 0x2b) {
if ($exdata1 & 1) {
push @exparts,"Change detected";
}
if ($exdata1 & 1<<1) {
push @exparts,"Firmware change detected";
}
if ($exdata1 & 1<<2) {
push @exparts,"Hardware incompatibility detected";
}
if ($exdata1 & 1<<3) {
push @exparts,"Firmware incompatibility detected";
}
if ($exdata1 & 1<<4) {
push @exparts,"Unsupported hardware version";
}
if ($exdata1 & 1<<5) {
push @exparts,"Unsupported firmware verion";
}
if ($exdata1 & 1<<6) {
push @exparts,"Hardware change successful";
}
if ($exdata1 & 1<<7) {
push @exparts,"Firmware change successful";
}
} elsif ($sdr->sensor_type == 0x1b) {
if ($exdata1 & 1) {
push @exparts,"Cable connected";
}
if ($exdata1 & 1<<1) {
push @exparts,"Incorrect cable connection";
}
} else {
$extext = "xCAT needs to add support for ".$sdr->sensor_type;
}
@@ -5974,7 +6275,7 @@ sub preprocess_request {
return 0;
}
if ( ($subcmd ne 'stat') && ($subcmd ne 'state') && ($subcmd ne 'status') && ($subcmd ne 'on') && ($subcmd ne 'off') && ($subcmd ne 'softoff') && ($subcmd ne 'nmi')&& ($subcmd ne 'cycle') && ($subcmd ne 'reset') && ($subcmd ne 'boot') && ($subcmd ne 'wake') && ($subcmd ne 'suspend')) {
if ( ($subcmd ne 'reseat') && ($subcmd ne 'stat') && ($subcmd ne 'state') && ($subcmd ne 'status') && ($subcmd ne 'on') && ($subcmd ne 'off') && ($subcmd ne 'softoff') && ($subcmd ne 'nmi')&& ($subcmd ne 'cycle') && ($subcmd ne 'reset') && ($subcmd ne 'boot') && ($subcmd ne 'wake') && ($subcmd ne 'suspend')) {
$callback->({data=>["Unsupported command: $command $subcmd", $usage_string]});
$request = {};
return;
@@ -5998,6 +6299,14 @@ sub preprocess_request {
my (@bmcnodes, @nohandle);
xCAT::Utils->filter_nodes($request, undef, undef, \@bmcnodes, \@nohandle);
$realnoderange = \@bmcnodes;
} elsif ($command eq "rinv") {
if ($exargs[0] eq "-t" and $#exargs == 0) {
unshift @{$request->{arg}}, 'all';
} elsif ((grep /-t/, @exargs) and !(grep /(all|vpd)/, @exargs) ) {
$callback->({errorcode=>[1],error=>["option '-t' can only work with 'all' or 'vpd'"]});
$request = {};
return 0;
}
}
if (!$realnoderange) {
+71 -7
View File
@@ -303,6 +303,47 @@ sub comp_word
}
#-------------------------------------------------------
=head3 check_newinstall
Check if the given kitcomp list are in NEW_INSTALL_LIST
or not. If so, set $::noupgrade all other kitcomp
depending on this list will be put into NEW_INSTALL_LIST
also
=cut
#-------------------------------------------------------
sub check_newinstall
{
my $kitcomponents = shift;
my @lines = @_;
my @kitcomps = split /,/, $kitcomponents;
foreach my $kitcomp ( @kitcomps ) {
last if ( $::noupgrade );
my $match_newinstall = 0;
foreach my $line ( @lines ) {
chomp($line);
if ( $line =~ /^#NEW_INSTALL_LIST#$/ ) {
$match_newinstall = 1;
}
if ( $line =~ /\/$kitcomp$/ ) {
if ( $match_newinstall ) {
$::noupgrade = 1;
}
last;
}
}
}
}
#-------------------------------------------------------
=head3 assign_to_osimage
@@ -319,7 +360,7 @@ sub assign_to_osimage
my $callback = shift;
my $tabs = shift;
(my $kitcomptable) = $tabs->{kitcomponent}->getAttribs({kitcompname=> $kitcomp}, 'kitname', 'kitreponame', 'basename', 'kitpkgdeps', 'prerequisite', 'exlist', 'genimage_postinstall','postbootscripts', 'driverpacks');
(my $kitcomptable) = $tabs->{kitcomponent}->getAttribs({kitcompname=> $kitcomp}, 'kitname', 'kitreponame', 'basename', 'kitcompdeps', 'kitpkgdeps', 'prerequisite', 'exlist', 'genimage_postinstall','postbootscripts', 'driverpacks');
(my $osimagetable) = $tabs->{osimage}->getAttribs({imagename=> $osimage}, 'provmethod', 'osarch', 'postbootscripts', 'kitcomponents');
(my $linuximagetable) = $tabs->{linuximage}->getAttribs({imagename=> $osimage}, 'rootimgdir', 'exlist', 'postinstall', 'otherpkglist', 'otherpkgdir', 'driverupdatesrc');
@@ -688,6 +729,13 @@ sub assign_to_osimage
push @lines, "$kitreponame/$kitcomptable->{prerequisite}\n";
$::noupgrade = 1;
}
# Check if this kitcomponent's kitcompdeps are in NEW_INSTALL_LIST or not.
# If so, set $::noupgrade to put this kitcomp in a new NEW_INSTALL_LIST
if ( $kitcomptable and $kitcomptable->{kitcompdeps} ) {
check_newinstall($kitcomptable->{kitcompdeps}, @lines);
}
if ( $::noupgrade ) {
push @lines, "#NEW_INSTALL_LIST#\n";
foreach my $kitdeployparam ( @kitdeployparams ) {
@@ -2141,7 +2189,7 @@ sub addkitcomp
if ( $kitcomp eq $oskitcomp ) {
my %rsp;
push@{ $rsp{data} }, "$kitcomp kit component is already in osimage $osimage";
xCAT::MsgUtils->message( "E", \%rsp, $callback );
xCAT::MsgUtils->message( "I", \%rsp, $callback );
$catched = 1;
}
}
@@ -2174,7 +2222,7 @@ sub addkitcomp
my %rsp;
push@{ $rsp{data} }, "Upgrading kit component $oskitcomp to $kitcomp";
xCAT::MsgUtils->message( "I", \%rsp, $callback );
my $ret = xCAT::Utils->runxcmd({ command => ['rmkitcomp'], arg => ['-f','-u','-i',$osimage, $oskitcomp] }, $request_command, -2, 1);
my $ret = xCAT::Utils->runxcmd({ command => ['rmkitcomp'], arg => ['-f','-i',$osimage, $oskitcomp] }, $request_command, -2, 1);
if ( !$ret ) {
my %rsp;
push@{ $rsp{data} }, "Failed to remove kit component $kitcomp from $osimage";
@@ -2379,7 +2427,6 @@ sub rmkitcomp
my %rsp;
push@{ $rsp{data} }, "kitcomponent $kitcompdep basename does not exist";
xCAT::MsgUtils->message( "E", \%rsp, $callback );
return 1;
}
my $kitcompdepname = get_highest_version('kitcompname', 'version', 'release', @entries);
@@ -2438,7 +2485,7 @@ sub rmkitcomp
foreach my $kitcomponent (keys %kitcomps) {
my @kitcompscripts = split( ',', $kitcomps{$kitcomponent}{postbootscripts} );
foreach my $kitcompscript ( @kitcompscripts ) {
if ( $osimagescript =~ /^$kitcompscript$/ ) {
if ( $osimagescript =~ /^$kitcompscript/ ) {
$match = 1;
last;
}
@@ -2491,19 +2538,36 @@ sub rmkitcomp
# Remove symlink from osimage.otherpkgdir.
# Read all the kitcomponents assigned to all the osimage to make sure the repo used by other osimage
# will not be deleted.
my @allosikitcomps = $tabs{osimage}->getAllAttribs( 'imagename', 'kitcomponents' );
(my $linuximagetable) = $tabs{linuximage}->getAttribs({imagename=> $osimage}, 'postinstall', 'exlist', 'otherpkglist', 'otherpkgdir', 'driverupdatesrc');
if ( $linuximagetable and $linuximagetable->{otherpkgdir} ) {
my $otherpkgdir = $linuximagetable->{otherpkgdir};
foreach my $kitcomponent (keys %kitcomps) {
my %newosikitcomponents;
foreach my $allosikitcomp (@allosikitcomps) {
if ( $allosikitcomp->{kitcomponents} and $allosikitcomp->{imagename} ) {
my @allkitcomps = split /,/, $allosikitcomp->{kitcomponents};
foreach my $allkitcomp ( @allkitcomps ) {
if ( $allosikitcomp->{imagename} ne $osimage or $allkitcomp ne $kitcomponent ) {
$newosikitcomponents{$allkitcomp} = 1;
}
}
}
}
if ( $kitcomps{$kitcomponent}{kitreponame} ) {
if ( -d "$otherpkgdir/$kitcomps{$kitcomponent}{kitreponame}" ) {
# Check if this repo is used by other kitcomponent before removing the link
my $match = 0;
foreach my $osikitcomp ( @osikitcomps ) {
next if ( $osikitcomp =~ /$kitcomponent/ );
foreach my $osikitcomp ( keys %newosikitcomponents ) {
my $depkitrepodir;
(my $kitcomptable) = $tabs{kitcomponent}->getAttribs({kitcompname => $osikitcomp}, 'kitreponame');
if ( $kitcomptable and $kitcomptable->{kitreponame} ) {
+26 -7
View File
@@ -278,7 +278,9 @@ sub get_filepath_by_url { #at the end of the day, the libvirt storage api gives
my $create = $args{create};
my $force = $args{force};
my $format = $args{format};
my $sparse = 1;
if ($url =~ /^lvm:/) {
$sparse = 0;
$format = 'raw';
}
unless ($format) {
@@ -327,7 +329,7 @@ sub get_filepath_by_url { #at the end of the day, the libvirt storage api gives
# additionally, when mastering a powered down node, we should rebase the node to be a cow clone of the master it just spawned
} else {
my $vol;
if ($format eq 'raw') { #skip allocation specification for now
unless ($sparse) { #skip allocation specification for now
#currently, LV can have reduced allocation, but *cannot* grow.....
$vol = $poolobj->create_volume("<volume><name>".$desiredname."</name><target><format type='$format'/></target><capacity>".getUnits($create,"G",1)."</capacity></volume>");
} else {
@@ -488,6 +490,10 @@ sub build_diskstruct {
$cdhash->{target}->{dev}='hdc';
push @returns,$cdhash;
}
my $cachemethod = "none";
if ( $confdata->{vm}->{$node}->[0]->{storagecache}) {
$cachemethod = $confdata->{vm}->{$node}->[0]->{storagecache};
}
if (defined $confdata->{vm}->{$node}->[0]->{storage}) {
@@ -530,8 +536,7 @@ sub build_diskstruct {
$tdiskhash->{device}='disk';
$tdiskhash->{driver}->{name}='qemu';
$tdiskhash->{driver}->{type}=$disks{$_}->{format};
$tdiskhash->{driver}->{cache}="none"; #in this scenario, making a brand new vm, there is not much the hypervisor cache can do for us that the
#guest cannot do for itself
$tdiskhash->{driver}->{cache}=$cachemethod;
$tdiskhash->{source}->{file}=$_;
$tdiskhash->{target}->{dev} = $disks{$_}->{device};
if ($disks{$_} =~ /^vd/) {
@@ -1209,13 +1214,17 @@ sub createstorage {
#my $diskstruct = shift;
my $node = $cfginfo->{node};
my @flags = split /,/,$cfginfo->{virtflags};
my $format;
foreach (@flags) {
if (/^imageformat=(.*)\z/) {
$imgfmt=$1;
$format=$1;
} elsif (/^clonemethod=(.*)\z/) {
$clonemethod=$1;
}
}
if ($cfginfo->{storageformat}) {
$format = $cfginfo->{storageformat};
}
my $mountpath;
my $pathappend;
@@ -1242,7 +1251,7 @@ sub createstorage {
if ($filename =~ /^nfs:/ or $filename =~ /^dir:/ or $filename =~ /^lvm:/) { #libvirt storage pool to be used for this
my @sizes = split /,/,$size;
foreach (@sizes) {
get_filepath_by_url(url=>$filename,dev=>$prefix.shift(@suffixes),create=>$_, force=>$force);
get_filepath_by_url(url=>$filename,dev=>$prefix.shift(@suffixes),create=>$_, force=>$force, format=>$format);
}
}else{
oldCreateStorage($filename, $mastername, $size, $cfginfo, $force);
@@ -1653,6 +1662,15 @@ sub chvm {
$suffix=$1;
$format='raw';
}
if ($confdata->{vm}->{$node}->[0]->{storageformat}) {
$format = $confdata->{vm}->{$node}->[0]->{storageformat};
}
#when creating a new disk not cloned from anything, disable cache as copy on write content similarity is a lost cause...
my $cachemode = 'none';
#unless user knows better
if ($confdata->{vm}->{$node}->[0]->{storagecache}) {
$cachemode = $confdata->{vm}->{$node}->[0]->{storagecache};
}
my $bus;
if ($suffix =~ /^sd/) {
$bus='scsi';
@@ -1661,8 +1679,7 @@ sub chvm {
} elsif ($suffix =~ /vd/) {
$bus='virtio';
}
#when creating a new disk not cloned from anything, disable cache as copy on write content similarity is a lost cause...
my $xml = "<disk type='file' device='disk'><driver name='qemu' type='$format' cache='none'/><source file='$_'/><target dev='$suffix' bus='$bus'/></disk>";
my $xml = "<disk type='file' device='disk'><driver name='qemu' type='$format' cache='$cachemode'/><source file='$_'/><target dev='$suffix' bus='$bus'/></disk>";
if ($currstate eq 'on') { #attempt live attach
eval {
$dom->attach_device($xml);
@@ -2796,6 +2813,8 @@ sub process_request {
}
}
}
#donot update node provision status (installing or netbooting) here
xCAT::Utils->filter_nostatusupdate(\%newnodestatus);
#print "newstatus" . Dumper(\%newnodestatus);
xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%newnodestatus, 1);
}
+19 -4
View File
@@ -20,6 +20,7 @@ use xCAT::MacMap;
use xCAT::IMMUtils;
use xCAT_plugin::blade;
use xCAT::SLP;
require xCAT::data::ibmhwtypes;
my $mpahash;
@@ -1401,11 +1402,18 @@ sub xCATdB {
my $id = ($type =~ /bpa|frame/) ? $frameid:$cageid;
my $hidden = ($type =~ /bpa|fsp/)? 1:0;
my $groups = lc($type).",all";
my $tmp_pre = xCAT::data::ibmhwtypes::parse_group($model);
if (defined($tmp_pre)) {
$groups .= ",$tmp_pre";
}
########################################
# Write result to every tables,
########################################
if ( $type =~ /^bpa|fsp|cec|frame$/ ) {
$nodelisthash{$hostname} = {groups=>"$type,all", hidden=>$hidden};
#$nodelisthash{$hostname} = {groups=>"$type,all", hidden=>$hidden};
$nodelisthash{$hostname} = {groups=>$groups, hidden=>$hidden};
$ppchash{$hostname} = {id=>$id, parent=>$parent, hcp=>$hostname, nodetype=>$globalhwtype{$type}};
$vpdhash{$hostname} = {mtm=>$model, serial=>$serial, side=>$side};
$nodehmhash{$hostname} = {mgt=>$globalmgt{$type}};
@@ -1416,7 +1424,7 @@ sub xCATdB {
my @data = ($type, $model, $serial, $side, $ip, $frameid, $cageid, $parent, $mac);
xCAT::PPCdb::add_systemX( $type, $hostname, \@data );
} elsif ( $type =~ /^(hmc|ivm)$/ ) {
$nodelisthash{$hostname} = {groups=>"$type,all", hidden=>$hidden};
$nodelisthash{$hostname} = {groups=>$groups, hidden=>$hidden};
$ppchash{$hostname} = {nodetype=>$globalhwtype{$type}};
$vpdhash{$hostname} = {mtm=>$model, serial=>$serial};
$nodetypehash{$hostname} = {nodetype=>$globalnodetype{$type}};
@@ -1424,7 +1432,7 @@ sub xCATdB {
$hostshash{$hostname} = {ip=>$ip};
$machash{$hostname} = {mac=>$mac};
}elsif ($type =~ /^cmm$/){
$nodelisthash{$hostname} = {groups=>"cmm,all", hidden=>$hidden};
$nodelisthash{$hostname} = {groups=>$groups, hidden=>$hidden};
$vpdhash{$hostname} = {mtm=>$model, serial=>$serial};
$nodetypehash{$hostname} = {nodetype=>$globalnodetype{$type}};
$nodehmhash{$hostname} = {mgt=>"blade"};
@@ -1474,6 +1482,12 @@ sub format_stanza {
$ip = $2;
}
my $type = ${$outhash->{$name}}{type};
my $groups = "$type,all";
my $tmp_pre = xCAT::data::ibmhwtypes::parse_group(${$outhash->{$name}}{mtm});
if (defined($tmp_pre)) {
$groups .= ",$tmp_pre";
}
#################################
# Node attributes
@@ -1490,7 +1504,8 @@ sub format_stanza {
if ($type =~ /^fsp|bpa|cmm$/) {
$result .= "\tside=${$outhash->{$name}}{side}\n";
}
$result .= "\tgroups=$type,all\n";
#$result .= "\tgroups=$type,all\n";
$result .= "\tgroups=$groups\n";
$result .= "\tmgt=$globalmgt{$type}\n";
if ($type =~ /^fsp|bpa|frame|cec$/) {
$result .= "\tid=${$outhash->{$name}}{$globalid{$type}}\n";
+4 -6
View File
@@ -596,7 +596,7 @@ sub nodeset {
my $subreq = shift;
my $host2mic = shift;
my $usage_string = "nodeset noderange [osimage=imagename]";
my $usage_string = "nodeset noderange osimage[=imagename]";
my $nodes = $request->{'node'};
my $args = $request->{arg};
@@ -604,9 +604,6 @@ sub nodeset {
foreach (@$args) {
if (/osimage=(.*)/) {
$setosimg = $1;
} else {
xCAT::MsgUtils->message("E", {error=>[$usage_string], errorcode=>["1"]}, $callback);
return;
}
}
@@ -625,11 +622,12 @@ sub nodeset {
}
$nttab->setNodesAttribs(\%setpmethod);
}
# get the provision method from nodetype table
my $nthash = $nttab->getNodesAttribs($nodes,['provmethod']);
foreach my $node (@$nodes) {
unless (defined ($nthash->{$node}->[0]->{'provmethod'})) {
xCAT::MsgUtils->message("E", {error=>["The provmethod for the node $node must be set before the nodeset."], errorcode=>["1"]}, $callback);
xCAT::MsgUtils->message("E", {error=>["The provmethod for the node $node must be set by [nodeset <node> osimage=<image name>] or set in the provmethod attribute of the node."], errorcode=>["1"]}, $callback);
return;
}
}
+67 -43
View File
@@ -31,6 +31,7 @@ require xCAT::ProfiledNodeUtils;
my %allhostnames;
my %allbmcips;
my %allmacs;
my %allcecs;
my %allmacsupper;
my %allips;
my %allinstallips;
@@ -370,7 +371,7 @@ Usage:
my %allfspips = %$recordsref;
# Get all switches name
$recordsref = xCAT::ProfiledNodeUtils->get_allnode_singleattrib_hash('switches', 'switch');
$recordsref = xCAT::ProfiledNodeUtils->get_db_switches();
%allswitches = %$recordsref;
# Get all switches_switchport
@@ -398,6 +399,10 @@ Usage:
# Merge all BMC IPs and install IPs into allips.
%allips = (%allips, %allbmcips, %allinstallips, %allfspips);
# Get all CEC names
$recordsref = xCAT::ProfiledNodeUtils->get_all_cecs(1);
%allcecs = %$recordsref;
#TODO: can not use getallnode to get rack infos.
$recordsref = xCAT::ProfiledNodeUtils->get_all_rack(1);
%allracks = %$recordsref;
@@ -460,32 +465,26 @@ Usage:
}
}
# Create the real hostinfo string in stanza file format.
# Create the full hostinfo dict.
xCAT::MsgUtils->message('S', "Generating new hostinfo string.");
my ($retcode_gen, $retstr_gen) = gen_new_hostinfo_string(\%hostinfo_dict);
my ($retcode_gen, $retstr_gen) = gen_new_hostinfo_dict(\%hostinfo_dict);
unless ($retcode_gen){
setrsp_progress("Failed to validate node information file.");
setrsp_errormsg($retstr_gen);
return;
}
# call mkdef to create hosts and then call nodemgmt for node management plugins.
# create hosts and then call nodemgmt for node management plugins.
setrsp_progress("Importing nodes...");
setrsp_progress("Creating nodes...");
my $warnstr = "";
my $retref = xCAT::Utils->runxcmd({command=>["mkdef"], stdin=>[$retstr_gen], arg=>['-z']}, $request_command, 0, 2);
my $retstrref = parse_runxcmd_ret($retref);
# runxcmd failed.
if ($::RUNCMD_RC != 0){
if (xCAT::DBobjUtils->setobjdefs(\%hostinfo_dict) != 0){
$warnstr = "Warning: failed to import some nodes.";
setrsp_progress($warnstr);
if ($retstrref->[1]) {
$warnstr .= "Details: $retstrref->[1]";
}
setrsp_progress($warnstr);
}
setrsp_progress("Configuring nodes...");
$retref = xCAT::Utils->runxcmd({command=>["kitnodeadd"], node=>\@nodelist, sequential=>[1], macflag=>[$mac_addr_mode]}, $request_command, 0, 2);
$retstrref = parse_runxcmd_ret($retref);
my $retref = xCAT::Utils->runxcmd({command=>["kitnodeadd"], node=>\@nodelist, sequential=>[1], macflag=>[$mac_addr_mode]}, $request_command, 0, 2);
my $retstrref = parse_runxcmd_ret($retref);
if ($::RUNCMD_RC != 0){
$warnstr .= "Warning: failed to run command kitnodeadd.";
if ($retstrref->[1]) {
@@ -542,12 +541,15 @@ Usage:
}
setrsp_progress("Updating DNS entries");
$retref = "";
$retref = xCAT::Utils->runxcmd({command=>["makedns"], node=>$nodes, arg=>['-d']}, $request_command, 0, 2);
setrsp_progress("Updating hosts entries");
$retref = "";
$retref = xCAT::Utils->runxcmd({command=>["makehosts"], node=>$nodes, arg=>['-d']}, $request_command, 0, 2);
setrsp_progress("Removing nodes...");
$retref = "";
$retref = xCAT::Utils->runxcmd({command=>["noderm"], node=>$nodes}, $request_command, 0, 2);
$retstrref = parse_runxcmd_ret($retref);
if ($::RUNCMD_RC != 0){
@@ -739,6 +741,7 @@ Usage:
# Call update plugins first.
if(exists $args_dict{'hardwareprofile'} || exists $args_dict{'imageprofile'}){
setrsp_progress("Configuring nodes...");
$retref = "";
$retref = xCAT::Utils->runxcmd({command=>["kitnodeupdate"], node=>$nodes, sequential=>[1]}, $request_command, 0, 2);
$retstrref = parse_runxcmd_ret($retref);
if ($::RUNCMD_RC != 0){
@@ -749,6 +752,7 @@ Usage:
# If network profile specified. Need re-generate IPs for all nodess again.
if(exists $args_dict{'networkprofile'}){
setrsp_progress("Regenerate IP addresses for nodes...");
$retref = "";
$retref = xCAT::Utils->runxcmd({command=>["noderegenips"], node=>$nodes, sequential=>[1]}, $request_command, 0, 2);
$retstrref = parse_runxcmd_ret($retref);
if ($::RUNCMD_RC != 0){
@@ -980,9 +984,11 @@ Usage:
#$retref = xCAT::Utils->runxcmd({command=>["makedns"], node=>$nodes, arg=>['-d']}, $request_command, 0, 2);
#setrsp_progress("Updating hosts entries");
$retref = "";
$retref = xCAT::Utils->runxcmd({command=>["makehosts"], node=>$nodes, arg=>['-d']}, $request_command, 0, 2);
next;
}
$retref = "";
$retref = xCAT::Utils->runxcmd({command=>[$command], node=>$nodes, sequential=>[1]}, $request_command, 0, 2);
my $retstrref = parse_runxcmd_ret($retref);
if ($::RUNCMD_RC != 0){
@@ -1070,6 +1076,7 @@ Usage:
setrsp_progress("Warning: failed to update /etc/hosts for unmanaged node.");
}
$retref = "";
$retref = xCAT::Utils->runxcmd({command=>["makedns"], node=>[$args_dict{"hostname"}]}, $request_command, 0, 2);
$retstrref = parse_runxcmd_ret($retref);
if ($::RUNCMD_RC != 0){
@@ -1601,22 +1608,20 @@ sub findme{
my ($hostinfo_dict_ref, $invalid_records_ref) = validate_node_entries();
my %hostinfo_dict = %$hostinfo_dict_ref;
# Create the real hostinfo string in stanza file format.
# Create the full hostinfo dict
xCAT::MsgUtils->message('S', "Profiled nodes discover: Generating new hostinfo string.\n");
my ($retcode_gen, $retstr_gen) = gen_new_hostinfo_string($hostinfo_dict_ref);
my ($retcode_gen, $retstr_gen) = gen_new_hostinfo_dict($hostinfo_dict_ref);
unless ($retcode_gen){
setrsp_errormsg($retstr_gen);
return;
}
# call mkdef to create hosts and then call nodemgmt for node management plugins.
xCAT::MsgUtils->message('S', "Call mkdef to create nodes.\n");
my $retref = xCAT::Utils->runxcmd({command=>["mkdef"], stdin=>[$retstr_gen], arg=>['-z']}, $request_command, 0, 2);
my $retstrref = parse_runxcmd_ret($retref);
# runxcmd failed.
if ($::RUNCMD_RC != 0){
setrsp_errormsg($retstr_gen);
return;
# Create hosts and then call nodemgmt for node management plugins.
xCAT::MsgUtils->message('S', "Creating nodes...\n");
my $warnstr;
if (xCAT::DBobjUtils->setobjdefs(\%hostinfo_dict) != 0){
$warnstr = "Warning: failed to import node.";
setrsp_progress($warnstr);
}
my @nodelist = keys %hostinfo_dict;
@@ -1626,10 +1631,11 @@ sub findme{
$request->{"command"} = ["discovered"];
$request->{"node"} = \@nodelist;
$request->{discoverymethod} = ['profile'];
$retref = xCAT::Utils->runxcmd($request, $request_command, 0, 2);
$retstrref = parse_runxcmd_ret($retref);
my $retref = xCAT::Utils->runxcmd($request, $request_command, 0, 2);
my $retstrref = parse_runxcmd_ret($retref);
xCAT::MsgUtils->message('S', "Call nodemgmt plugins.\n");
$retref = "";
$retref = xCAT::Utils->runxcmd({command=>["kitnodeadd"], node=>\@nodelist, sequential=>[1]}, $request_command, 0, 2);
$retstrref = parse_runxcmd_ret($retref);
@@ -1642,19 +1648,19 @@ sub findme{
#-------------------------------------------------------
=head3 gen_new_hostinfo_string
=head3 gen_new_hostinfo_dict
Description : Generate a stanza file format string used for 'mkdef' to create nodes.
Description : Generate full hostinfo dict
Arguments : hostinfo_dict_ref - The reference of hostinfo dict.
Returns : (returnvalue, returnmsg)
returnvalue - 0, stands for generate new hostinfo string failed.
1, stands for generate new hostinfo string OK.
returnvalue - 0, stands for generate new hostinfo dict failed.
1, stands for generate new hostinfo dict OK.
returnnmsg - error messages if generate failed.
- the new hostinfo string if generate OK.
- OK for success cases.
=cut
#-------------------------------------------------------
sub gen_new_hostinfo_string{
sub gen_new_hostinfo_dict{
my $hostinfo_dict_ref = shift;
my %hostinfo_dict = %$hostinfo_dict_ref;
@@ -1683,9 +1689,9 @@ sub gen_new_hostinfo_string{
# Check whether this is Power env.
my $is_fsp = xCAT::ProfiledNodeUtils->is_fsp_node($args_dict{'networkprofile'});
# compose the stanza string for hostinfo file.
my $hostsinfostr = "";
foreach my $item (sort(keys %hostinfo_dict)){
# Set Nodes's type:
$hostinfo_dict{$item}{"objtype"} = 'node';
# Generate IPs for other interfaces defined in MAC file.
my %ipshash;
foreach (keys %netprofileattr){
@@ -1760,6 +1766,22 @@ sub gen_new_hostinfo_string{
$hostinfo_dict{$item}{"mpa"} = $chassisname;
}
}
# generate CEC-based rack-mount Power nodes' attributes
# lparid is optional, if not set, set it to 1
if ((exists $hostinfo_dict{$item}{"cec"}) && (! $is_fsp) ){
$hostinfo_dict{$item}{"hcp"} = $hostinfo_dict{$item}{"cec"};
$hostinfo_dict{$item}{"parent"} = $hostinfo_dict{$item}{"cec"};
delete($hostinfo_dict{$item}{"cec"});
if (exists $hostinfo_dict{$item}{"lparid"}) {
$hostinfo_dict{$item}{"id"} = $hostinfo_dict{$item}{"lparid"};
delete($hostinfo_dict{$item}{"lparid"});
} else {
$hostinfo_dict{$item}{"id"} = 1;
}
$hostinfo_dict{$item}{"mgt"} = "fsp";
}
# get the chain attribute from hardwareprofile and insert it to node.
my $chaintab = xCAT::Table->new('chain');
@@ -1800,15 +1822,8 @@ sub gen_new_hostinfo_string{
}
}
# Generate the hostinfo string.
$hostsinfostr = "$hostsinfostr$item:\n";
my $itemdictref = $hostinfo_dict{$item};
my %itemdict = %$itemdictref;
foreach (keys %itemdict){
$hostsinfostr = "$hostsinfostr $_=\"$itemdict{$_}\"\n";
}
}
return 1, $hostsinfostr;
return 1, "OK";
}
#-------------------------------------------------------
@@ -2150,6 +2165,15 @@ sub validate_node_entry{
if (!($node_entry{$_} =~ /^[1-9]\d*$/)){
$errmsg .= "Specified slotid $node_entry{$_} is invalid";
}
}elsif ($_ eq "lparid"){
if (not exists $node_entry{"cec"}){
$errmsg .= "The lparid option must be used with the cec option.\n";
}
}elsif ($_ eq "cec"){
# Check the specified CEC is existing
if (! exists $allcecs{$node_entry{$_}}){
$errmsg .= "The CEC name $node_entry{$_} that is specified in the node information file is not defined in the system.\n";
}
}elsif ($_ eq "nicips"){
# Check Multi-Nic's ip
my $othernics = $node_entry{$_};
+21 -55
View File
@@ -10,6 +10,7 @@ use File::Path;
use Getopt::Long;
require xCAT::Utils;
require xCAT::TableUtils;
use xCAT::ServiceNodeUtils;
my $addkcmdlinehandled;
my $request;
my $callback;
@@ -128,7 +129,7 @@ sub setstate {
$kcmdlinehack =~ s/#TABLE:([^:#]+):([^:#]+):([^:#]+)#/$naval/;
} else {
my $msg = "Table key of $2 not yet supported by boottarget mini-template";
$callback->({
$::callback->({
error => ["$msg"],
errorcode => [1]
});
@@ -147,7 +148,7 @@ sub setstate {
unless ($ipfn) {
my @myself = xCAT::NetworkUtils->determinehostname();
my $myname = $myself[(scalar @myself)-1];
$callback->(
$::callback->(
{
error => [
"$myname: Unable to determine or reasonably guess the image server for $node"
@@ -279,6 +280,7 @@ sub preprocess_request {
my $callback1 = shift;
my $command = $req->{command}->[0];
my $sub_req = shift;
my $nodes = $req->{node};
my @args=();
if (ref($req->{arg})) {
@args=@{$req->{arg}};
@@ -327,71 +329,35 @@ sub preprocess_request {
my @entries = xCAT::TableUtils->get_site_attribute("sharedtftp");
my $t_entry = $entries[0];
if ( defined($t_entry) and ($t_entry == 0 or $t_entry =~ /no/i)) {
# check for computenodes and servicenodes from the noderange, if so error out
my @SN;
my @CN;
xCAT::ServiceNodeUtils->getSNandCPnodes(\@$nodes, \@SN, \@CN);
if ((@SN > 0) && (@CN >0 )) { # there are both SN and CN
my $rsp;
$rsp->{data}->[0] =
"Nodeset was run with a noderange containing both service nodes and compute nodes. This is not valid. You must submit with either compute nodes in the noderange or service nodes. \n";
xCAT::MsgUtils->message("E", $rsp, $callback1);
return;
}
$req->{'_disparatetftp'}=[1];
if ($req->{inittime}->[0]) {
return [$req];
}
return xCAT::Scope->get_broadcast_scope($req,@_);
if (@CN >0 ) { # if compute nodes broadcast to all servicenodes
return xCAT::Scope->get_broadcast_scope($req,@_);
}
}
return [$req];
}
#sub preprocess_request {
# my $req = shift;
# $callback = shift;
# if ($req->{_xcatdest}) { return [$req]; } #Exit if the packet has been preprocessed in its history
# my @requests = ({%$req}); #Start with a straight copy to reflect local instance
# my $sitetab = xCAT::Table->new('site');
# (my $ent) = $sitetab->getAttribs({key=>'xcatservers'},'value');
# $sitetab->close;
# if ($ent and $ent->{value}) {
# foreach (split /,/,$ent->{value}) {
# if (xCAT::NetworkUtils->thishostisnot($_)) {
# my $reqcopy = {%$req};
# $reqcopy->{'_xcatdest'} = $_;
# push @requests,$reqcopy;
# }
# }
# }
# return \@requests;
#}
#sub preprocess_request {
# my $req = shift;
# my $callback = shift;
# my %localnodehash;
# my %dispatchhash;
# my $nrtab = xCAT::Table->new('noderes');
# foreach my $node (@{$req->{node}}) {
# my $nodeserver;
# my $tent = $nrtab->getNodeAttribs($node,['tftpserver']);
# if ($tent) { $nodeserver = $tent->{tftpserver} }
# unless ($tent and $tent->{tftpserver}) {
# $tent = $nrtab->getNodeAttribs($node,['servicenode']);
# if ($tent) { $nodeserver = $tent->{servicenode} }
# }
# if ($nodeserver) {
# $dispatchhash{$nodeserver}->{$node} = 1;
# } else {
# $localnodehash{$node} = 1;
# }
# }
# my @requests;
# my $reqc = {%$req};
# $reqc->{node} = [ keys %localnodehash ];
# if (scalar(@{$reqc->{node}})) { push @requests,$reqc }
#
# foreach my $dtarg (keys %dispatchhash) { #iterate dispatch targets
# my $reqcopy = {%$req}; #deep copy
# $reqcopy->{'_xcatdest'} = $dtarg;
# $reqcopy->{node} = [ keys %{$dispatchhash{$dtarg}}];
# push @requests,$reqcopy;
# }
# return \@requests;
#}
sub process_request {
$request = shift;
$callback = shift;
my $sub_req = shift;
$::callback=$callback;
my @args;
my @nodes;
my @rnodes;
+9 -1
View File
@@ -27,6 +27,7 @@ use xCAT::NetworkUtils;
use xCAT::MsgUtils;
use xCAT::DiscoveryUtils;
use xCAT::NodeRange qw/noderange/;
require xCAT::data::ibmhwtypes;
use Time::HiRes qw(gettimeofday sleep);
@@ -272,7 +273,14 @@ sub findme {
$nltab->setNodeAttribs($node, {groups=>"all"});
}
}
# update node groups with pre-defined groups
if (defined($param{'mtm'})){
my @list = ();
my $tmp_group = xCAT::data::ibmhwtypes::parse_group($param{'mtm'});
if (defined($tmp_group)) {
xCAT::TableUtils->updatenodegroups($node, $nltab, $tmp_group);
}
}
# set the mgt for the node
my $hmtab = xCAT::Table->new('nodehm');
unless ($hmtab) {
+313 -21
View File
@@ -37,7 +37,8 @@ sub handled_commands
copycd => "sles",
mknetboot => "nodetype:os=(sles.*)|(suse.*)",
mkinstall => "nodetype:os=(sles.*)|(suse.*)",
mkstatelite => "nodetype:os=(sles.*)"
mkstatelite => "nodetype:os=(sles.*)",
mksysclone => "nodetype:os=(sles.*)|(suse.*)"
};
}
@@ -55,6 +56,7 @@ sub mknetboot
my $globaltftpdir = "/tftpboot";
my $nodes = @{$req->{node}};
my @nodes = @{$req->{node}};
my $noupdateinitrd = $req->{'noupdateinitrd'};
my $ostab = xCAT::Table->new('nodetype');
#my $sitetab = xCAT::Table->new('site');
my $linuximagetab;
@@ -404,7 +406,7 @@ sub mknetboot
}
}
if ($docopy) {
if ($docopy && !$noupdateinitrd) {
mkpath("$tftppath");
copy("$rootimgdir/kernel", "$tftppath");
if ($statelite) {
@@ -690,6 +692,10 @@ sub process_request
{
return mknetboot($request, $callback, $doreq);
}
elsif ($request->{command}->[0] eq 'mksysclone')
{
return mksysclone($request, $callback, $doreq);
}
}
sub mkinstall
@@ -1204,6 +1210,259 @@ sub mkinstall
#}
}
sub mksysclone
{
my $request = shift;
my $callback = shift;
my $doreq = shift;
my @nodes = @{$request->{node}};
my $osimagetab;
my %img_hash=();
my $installroot;
my $globaltftpdir;
$installroot = "/install";
$globaltftpdir = "/tftpboot";
my @ents = xCAT::TableUtils->get_site_attribute("installdir");
my $site_ent = $ents[0];
if( defined($site_ent) )
{
$installroot = $site_ent;
}
@ents = xCAT::TableUtils->get_site_attribute("tftpdir");
$site_ent = $ents[0];
if( defined($site_ent) )
{
$globaltftpdir = $site_ent;
}
my $node;
my $ostab = xCAT::Table->new('nodetype');
my $restab = xCAT::Table->new('noderes');
my $bptab = xCAT::Table->new('bootparams',-create=>1);
my $hmtab = xCAT::Table->new('nodehm');
my %osents = %{$ostab->getNodesAttribs(\@nodes, ['os', 'arch', 'provmethod'])};
my %rents =
%{$restab->getNodesAttribs(\@nodes,
['xcatmaster', 'nfsserver', 'tftpdir', 'primarynic', 'installnic'])};
my %hents =
%{$hmtab->getNodesAttribs(\@nodes,
['serialport', 'serialspeed', 'serialflow'])};
my $xcatdport="3001";
my @entries = xCAT::TableUtils->get_site_attribute("xcatdport");
if ( defined($entries[0])) {
$xcatdport = $entries[0];
}
my @entries = xCAT::TableUtils->get_site_attribute("master");
my $master_entry = $entries[0];
require xCAT::Template;
my $flag_return = 0;
# Warning message for nodeset <noderange> install/netboot/statelite
foreach my $knode (keys %osents)
{
my $ent = $osents{$knode}->[0];
if ($ent && $ent->{provmethod} && ($ent->{provmethod} eq 'sysclone')){
$callback->( { error => ["$knode: The provmethod \"sysclone\" have been deprecated. use \"nodeset <noderange> osimage=<osimage_name>\" instead."],
errorcode => [1]});
# Do not print this warning message multiple times
$flag_return = 1;
}
}
if ( $flag_return == 1 ){
return;
}
# copy postscripts
my $pspath = "$installroot/sysclone/scripts/post-install/";
my $clusterfile = "$installroot/sysclone/scripts/cluster.txt";
mkpath("$pspath");
copy("$installroot/postscripts/configefi","$pspath/15all.configefi");
copy("$installroot/postscripts/updatenetwork","$pspath/16all.updatenetwork");
copy("$installroot/postscripts/runxcatpost","$pspath/17all.runxcatpost");
copy("$installroot/postscripts/killsyslog","$pspath/99all.killsyslog");
unless (-r "$pspath/10all.fix_swap_uuids")
{
mkpath("$pspath");
copy("/var/lib/systemimager/scripts/post-install/10all.fix_swap_uuids","$pspath");
}
unless (-r "$pspath/11all.replace_byid_device")
{
mkpath("$pspath");
copy("/var/lib/systemimager/scripts/post-install/11all.replace_byid_device","$pspath");
}
unless (-r "$pspath/95all.monitord_rebooted")
{
mkpath("$pspath");
copy("/var/lib/systemimager/scripts/post-install/95all.monitord_rebooted","$pspath");
}
# copy hosts
copy("/etc/hosts","$installroot/sysclone/scripts/");
foreach $node (@nodes)
{
my $os;
my $tftpdir;
my $arch;
my $imagename; # set it if running of 'nodeset osimage=xxx'
my $xcatmaster;
my $instserver;
my $ient = $rents{$node}->[0];
if ($ient and $ient->{xcatmaster})
{
$xcatmaster = $ient->{xcatmaster};
} else {
$xcatmaster = $master_entry;
}
my $osinst;
if ($rents{$node}->[0] and $rents{$node}->[0]->{tftpdir}) {
$tftpdir = $rents{$node}->[0]->{tftpdir};
} else {
$tftpdir = $globaltftpdir;
}
my $ent = $osents{$node}->[0];
if ($ent and $ent->{provmethod} and ($ent->{provmethod} ne 'install') and ($ent->{provmethod} ne 'netboot') and ($ent->{provmethod} ne 'statelite') and ($ent->{provmethod} ne 'sysclone')) {
$imagename=$ent->{provmethod};
#print "imagename=$imagename\n";
if (!exists($img_hash{$imagename})) {
if (!$osimagetab) {
$osimagetab=xCAT::Table->new('osimage', -create=>1);
}
(my $ref) = $osimagetab->getAttribs({imagename => $imagename}, 'osvers', 'osarch', 'profile', 'provmethod');
if ($ref) {
$img_hash{$imagename}->{osarch}=$ref->{'osarch'};
} else {
$callback->(
{error => ["The os image $imagename does not exists on the osimage table for $node"],
errorcode => [1]});
next;
}
}
my $ph=$img_hash{$imagename};
$arch = $ph->{osarch};
}
# copy kernel and initrd from image dir to /tftpboot
my $ramdisk_size = 200000;
if ( -r "$tftpdir/xcat/genesis.kernel.$arch"
and ( -r "$tftpdir/xcat/genesis.fs.$arch.gz"
or -r "$tftpdir/xcat/genesis.fs.$arch.lzma" ))
{
#We have a shot...
my $ent = $rents{$node}->[0];
my $sent = $hents{$node}->[0];
my $kcmdline = "ramdisk_size=$ramdisk_size";
my $ksdev = "";
if ($ent->{installnic})
{
$ksdev = $ent->{installnic};
}
elsif ($ent->{primarynic})
{
$ksdev = $ent->{primarynic};
}
else
{
$ksdev = "bootif"; #if not specified, fall back to bootif
}
if ($ksdev eq "mac")
{
my $mactab = xCAT::Table->new("mac");
my $macref = $mactab->getNodeAttribs($node, ['mac']);
$ksdev = $macref->{mac};
}
unless ( $ksdev eq "bootif" ) {
$kcmdline .= " netdevice=" . $ksdev;
}
if ($arch =~ /ppc/) {
$kcmdline .= " dhcptimeout=150";
}
if (defined($sent->{serialport}))
{
unless ($sent->{serialspeed})
{
$callback->( { error => [ "serialport defined, but no serialspeed for $node in nodehm table" ],
errorcode => [1] } );
}
else {
#go cmdline if serial console is requested, the shiny ansi is just impractical
$kcmdline .= " cmdline console=tty0 console=ttyS"
. $sent->{serialport} . ","
. $sent->{serialspeed};
if ($sent->{serialflow} =~ /(hard|cts|ctsrts)/) {
$kcmdline .= "n8r";
}
}
}
$kcmdline .= " XCAT=$xcatmaster:$xcatdport xcatd=$xcatmaster:$xcatdport SCRIPTNAME=$imagename";
my $i = "xcat/genesis.fs.$arch.gz";
if ( -r "$tftpdir/xcat/genesis.fs.$arch.lzma" ){
$i = "xcat/genesis.fs.$arch.lzma";
}
$bptab->setNodeAttribs(
$node,
{
kernel => "xcat/genesis.kernel.$arch",
initrd => $i,
kcmdline => $kcmdline
}
);
}
else
{
$callback->( { error => ["Kernel and initrd not found in $tftpdir/xcat"],
errorcode => [1] } );
}
# assign nodes to an image
if (-r "$clusterfile")
{
my $cmd = qq{cat $clusterfile | grep "$node"};
my $out = xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC == 0)
{
my $out = `sed -i /$node./d $clusterfile`;
}
}
my $cmd =qq{echo "$node:compute:$imagename:" >> $clusterfile};
my $out = xCAT::Utils->runcmd($cmd, -1);
unless (-r "$installroot/sysclone/images/$imagename/opt/xcat/xcatdsklspost")
{
mkpath("$installroot/sysclone/images/$imagename/opt/xcat/");
copy("$installroot/postscripts/xcatdsklspost","$installroot/sysclone/images/$imagename/opt/xcat/");
}
}
# check systemimager-server-rsyncd to make sure it's running.
my $out = xCAT::Utils->runcmd("service systemimager-server-rsyncd status", -1);
if ($::RUNCMD_RC != 0) { # not running
my $rc = xCAT::Utils->startService("systemimager-server-rsyncd");
if ($rc != 0) {
return 1;
}
}
}
sub copycd
{
my $request = shift;
@@ -1689,6 +1948,7 @@ sub insert_dd () {
my @rpm_list;
my @driver_list;
my $Injectalldriver;
my $updatealldriver;
my @rpm_drivers;
@@ -1734,6 +1994,9 @@ sub insert_dd () {
if (/^allupdate$/) {
$Injectalldriver = 1;
next;
} elsif (/^updateonly$/) {
$updatealldriver = 1;
next;
}
unless (/\.ko$/) {
s/$/.ko/;
@@ -1744,7 +2007,7 @@ sub insert_dd () {
chomp(@dd_list);
chomp(@rpm_list);
unless (@dd_list || (@rpm_list && ($Injectalldriver || @driver_list))) {
unless (@dd_list || (@rpm_list && ($Injectalldriver || $updatealldriver || @driver_list))) {
return ();
}
@@ -1757,7 +2020,7 @@ sub insert_dd () {
# Unzip the original initrd
# This only needs to be done for ppc or handling the driver rpm
# For the driver disk against x86, append the driver disk to initrd directly
if ($arch =~/ppc/ || (@rpm_list && ($Injectalldriver || @driver_list))) {
if ($arch =~/ppc/ || (@rpm_list && ($Injectalldriver || $updatealldriver || @driver_list))) {
if ($arch =~ /ppc/) {
$cmd = "gunzip --quiet -c $pkgdir/1/suseboot/initrd64 > $dd_dir/initrd";
} elsif ($arch =~ /x86/) {
@@ -1782,7 +2045,7 @@ sub insert_dd () {
}
# Start to load the drivers from rpm packages
if (@rpm_list && ($Injectalldriver || @driver_list)) {
if (@rpm_list && ($Injectalldriver || $updatealldriver || @driver_list)) {
# Extract the files from rpm to the tmp dir
mkpath "$dd_dir/rpm";
my $new_kernel_ver;
@@ -1804,17 +2067,17 @@ sub insert_dd () {
# get the new kernel if it exists in the update distro
my @new_kernels = <$dd_dir/rpm/boot/vmlinu*>;
foreach my $new_kernel (@new_kernels) {
if (-r $new_kernel && $new_kernel =~ /\/vmlinu[zx]-(.*(x86_64|ppc64|default))$/) {
$new_kernel_ver = $1;
$cmd = "/bin/mv -f $new_kernel $dd_dir/rpm/newkernel";
xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
my $rsp;
push @{$rsp->{data}}, "Handle the driver update failed. Could not move $new_kernel to $dd_dir/rpm/newkernel.";
xCAT::MsgUtils->message("I", $rsp, $callback);
if (-r $new_kernel && $new_kernel =~ /\/vmlinu[zx]-(.*(x86_64|ppc64|default))$/) {
$new_kernel_ver = $1;
$cmd = "/bin/mv -f $new_kernel $dd_dir/rpm/newkernel";
xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
my $rsp;
push @{$rsp->{data}}, "Handle the driver update failed. Could not move $new_kernel to $dd_dir/rpm/newkernel.";
xCAT::MsgUtils->message("I", $rsp, $callback);
}
}
}
}
# To skip the conflict of files that some rpm uses the xxx.ko.new as the name of the driver
# Change it back to xxx.ko here
@@ -1851,14 +2114,45 @@ sub insert_dd () {
# if the new kernel from update distro is not existed in initrd, create the path for it
if (! -r "$dd_dir/initrd_img/lib/modules/$new_kernel_ver/") {
mkpath ("$dd_dir/initrd_img/lib/modules/$new_kernel_ver/");
# link the /modules to this new kernel dir
unlink "$dd_dir/initrd_img/modules";
$cmd = "/bin/ln -sf lib/modules/$new_kernel_ver/initrd $dd_dir/initrd_img/modules";
xCAT::Utils->runcmd($cmd, -1);
if ($::RUNCMD_RC != 0) {
my $rsp;
push @{$rsp->{data}}, "Handle the driver update failed. Could not create link to the new kernel dir.";
xCAT::MsgUtils->message("I", $rsp, $callback);
}
}
# get the name list for all drivers in the original initrd if 'netdrivers=updateonly'
# then only the drivers in this list will be updated from the drvier rpms
if ($updatealldriver) {
$driver_name = "\*\.ko";
@all_real_path = ();
find(\&get_all_path, <$dd_dir/initrd_img/lib/modules/*>);
foreach my $real_path (@all_real_path) {
my $driver = basename($real_path);
push @driver_list, $driver;
}
}
# Copy the drivers to the rootimage
# Figure out the kernel version
my @kernelpaths = <$dd_dir/initrd_img/lib/modules/*>;
my @kernelvers;
if ($new_kernel_ver) {
push @kernelvers, $new_kernel_ver;
}
foreach (@kernelpaths) {
push @kernelvers, basename($_);
my $kernelv = basename($_);
if ($kernelv =~ /^[\d\.]+/) {
if ($new_kernel_ver) {
rmtree ("$dd_dir/initrd_img/lib/modules/$kernelv");
} else {
push @kernelvers, $kernelv;
}
}
}
foreach my $kernelver (@kernelvers) {
@@ -1871,7 +2165,6 @@ sub insert_dd () {
$driver_name = $driver;
@all_real_path = ();
find(\&get_all_path, <$dd_dir/rpm/lib/modules/$kernelver/*>);
#if ($real_path && $real_path =~ m!$dd_dir/rpm(/lib/modules/$kernelver/.*?)[^\/]*$!) {
# NOTE: for the initrd of sles that the drivers are put in the /lib/modules/$kernelver/initrd/
foreach my $real_path (@all_real_path) {
if ($real_path && $real_path =~ m!$dd_dir/rpm/lib/modules/$kernelver/!) {
@@ -1895,8 +2188,7 @@ sub insert_dd () {
$driver_name = "\*\.ko";
@all_real_path = ();
find(\&get_all_path, <$dd_dir/rpm/lib/modules/$kernelver/*>);
foreach $real_path (@all_real_path) {
#if ($real_path && $real_path =~ m!$dd_dir/rpm(/lib/modules/$kernelver/.*?)[^\/]*$!) {
foreach my $real_path (@all_real_path) {
# NOTE: for the initrd of sles that the drivers are put in the /lib/modules/$kernelver/initrd/
if ($real_path && $real_path =~ m!$dd_dir/rpm/lib/modules/$kernelver/!) {
if (! -d "$dd_dir/initrd_img/lib/modules/$kernelver/initrd") {
@@ -2007,10 +2299,10 @@ sub insert_dd () {
@rpm_drivers = keys %dnhash;
if (@rpm_list) {
if (@driver_list) {
if (@rpm_drivers) {
push @{$rsp->{data}}, "The drivers:".join(',', sort(@rpm_drivers))." from ".join(',', sort(@rpm_list))." have been injected to initrd.";
} elsif ($Injectalldriver) {
push @{$rsp->{data}}, "All the drivers from :".join(',', sort(@rpm_list))." have been injected to initrd.";
} else {
push @{$rsp->{data}}, "No driver was injected to initrd.";
}
}
xCAT::MsgUtils->message("I", $rsp, $callback);
+66 -77
View File
@@ -358,7 +358,11 @@ sub noderm
nodech($nodes, \@tablist, $cb, 0);
}
#
# restores the table from the input CSV file. Default deletes the table rows and
# replaces with the rows in the file
# If -a flag is input then it adds the rows from the CSV file to the table.
#
sub tabrestore
{
# the usage for tabrestore is in the tabrestore client cmd
@@ -367,6 +371,7 @@ sub tabrestore
my $request = shift;
my $cb = shift;
my $table = $request->{table}->[0];
my $addrows = $request->{addrows}->[0];
# do not allow teal tables
if ( $table =~ /^x_teal/ ) {
$cb->({error => "$table is not supported in tabrestore. Use Teal maintenance commands. ",errorcode=>1});
@@ -377,7 +382,9 @@ sub tabrestore
$cb->({error => "Unable to open $table",errorcode=>4});
return;
}
$tab->delEntries(); #Yes, delete *all* entries
if (!defined($addrows)) { # this is a replace not add rows
$tab->delEntries(); #Yes, delete *all* entries
}
my $header = shift @{$request->{data}};
unless ($header =~ /^#/) {
$cb->({error => "Data missing header line starting with #",errorcode=>1});
@@ -525,7 +532,7 @@ sub tabrestore
next LINE;
}
#TODO: check for error from DB and rollback
#check for error from DB and rollback
my @rc = $tab->setAttribs(\%record, \%record);
if (not defined($rc[0]))
{
@@ -580,9 +587,10 @@ sub tabdump
if ($args) {
@ARGV = @{$args};
}
Getopt::Long::Configure("posix_default");
Getopt::Long::Configure("no_gnu_compat");
Getopt::Long::Configure("bundling");
Getopt::Long::Configure("posix_default");
Getopt::Long::Configure("no_gnu_compat");
Getopt::Long::Configure("bundling");
if (!GetOptions(
'h|?|help' => \$HELP,
@@ -604,14 +612,15 @@ sub tabdump
return;
}
if ($FILENAME and $FILENAME !~ /^\//) { $FILENAME =~ s/^/$request->{cwd}->[0]\//; }
if ($HELP) { $tabdump_usage->(0); return; }
if (($NUMBERENTRIES) && ($DESC)) {
$cb->({error => "You cannot use the -n and -d flag together. ",errorcode=>1});
return 1;
}
if (($NUMBERENTRIES) && ($OPTW)) {
$cb->({error => "You cannot use the -n and -w flag together. ",errorcode=>1});
return 1;
@@ -620,10 +629,8 @@ sub tabdump
$cb->({error => "You cannot use the -n and -f flag together. ",errorcode=>1});
return 1;
}
if (scalar(@ARGV)>1) { $tabdump_usage->(1); return; }
my %rsp;
# If no arguments given, we display a list of the tables
if (!scalar(@ARGV)) {
@@ -647,15 +654,15 @@ sub tabdump
}
# get the table name
$table = $ARGV[0];
# if -n can only be the auditlog or eventlog
if ($NUMBERENTRIES) {
if (!( $table =~ /^auditlog/ ) && (!($table =~ /^eventlog/))){
$cb->({error => "$table table is not supported in tabdump -n. You may only use this option on the auditlog or the eventlog.",errorcode=>1});
return 1;
}
}
}
}
# do not allow teal tables
if ( $table =~ /^x_teal/ ) {
$cb->({error => "$table table is not supported in tabdump. Use Teal maintenance commands. ",errorcode=>1});
@@ -703,7 +710,6 @@ sub tabdump
return $rc;
}
my $recs;
my @ents;
my @attrarray;
@@ -758,12 +764,12 @@ sub tabdump
}
#
# display input number of records for the table requested tabdump -n
# note currently only supports auditlog and eventlog
#
sub tabdump_numberentries {
my $table = shift;
my $cb = shift;
my $numberentries = shift; # either number of records to display
my $attrrecid="recid";
my $VERBOSE = shift;
my $rc=0;
@@ -772,38 +778,21 @@ sub tabdump_numberentries {
$cb->({error => "Unable to open $table",errorcode=>4});
return 1;
}
my $DBname = xCAT::Utils->get_DBName;
my @attribs = ($attrrecid);
my @ents=$tab->getAllAttribs(@attribs);
if (@ents) { # anything to process
# find smallest and largest recid, note table is not ordered by recid after
# a while
my $smallrid;
my $largerid;
foreach my $rid (@ents) {
if (!(defined $smallrid)) {
$smallrid=$rid;
}
if (!(defined $largerid)) {
$largerid=$rid;
}
if ($rid->{$attrrecid} < $smallrid->{$attrrecid}) {
$smallrid=$rid;
}
if ($rid->{$attrrecid} > $largerid->{$attrrecid}) {
$largerid=$rid;
}
}
my $RECID;
#determine recid to show all records after
$RECID= $largerid->{$attrrecid} - $numberentries ;
$rc=tabdump_recid($table,$cb,$RECID, $attrrecid);
} else {
#determine recid to show all records after
my $RECID;
my $attrrecid="recid";
my $values = $tab->getMAXMINEntries($attrrecid);
my $max=$values->{"max"};
if (defined($values->{"max"})){
$RECID= $values->{"max"} - $numberentries ;
$rc=tabdump_recid($table,$cb,$RECID, $attrrecid);
} else {
my %rsp;
push @{$rsp{data}}, "Nothing to display from $table.";
$rsp{errorcode} = $rc;
$cb->(\%rsp);
}
}
return $rc;
}
# Display requested recored
@@ -831,6 +820,7 @@ sub tabdump_recid {
output_table($table,$cb,$tab,\@recs);
return $rc;
}
# Display information from the daemon.
#
sub lsxcatd
@@ -1066,7 +1056,7 @@ sub tabprune
if (($table eq "eventlog") || ($table eq "auditlog")) {
$attrrecid="recid";
} else {
if ($table eq "isnm_perf") { # if ISNM These tables are really not supported in 2.8 or later
if ($table eq "isnm_perf") { # if ISNM These tables are really not supported in 2.8 or later
$attrrecid="perfid";
} else {
$attrrecid="period"; # isnm_perf_sum table
@@ -1134,51 +1124,34 @@ sub tabprune_numberentries {
$cb->({error => "Unable to open $table",errorcode=>4});
return 1;
}
my $DBname = xCAT::Utils->get_DBName;
my @attribs = ("$attrrecid");
my @ents=$tab->getAllAttribs(@attribs);
if (@ents) { # anything to process
# find smallest and largest recid, note table is not ordered by recid after
# a while
my $smallrid;
my $largerid;
foreach my $rid (@ents) {
if (!(defined $smallrid)) {
$smallrid=$rid;
}
if (!(defined $largerid)) {
$largerid=$rid;
}
if ($rid->{$attrrecid} < $smallrid->{$attrrecid}) {
$smallrid=$rid;
}
if ($rid->{$attrrecid} > $largerid->{$attrrecid}) {
$largerid=$rid;
}
}
my $RECID;
my $RECID;
my $values = $tab->getMAXMINEntries($attrrecid);
if ((defined($values->{"max"})) && (defined($values->{"min"}))) {
my $largerid = $values->{"max"};
my $smallrid = $values->{"min"};
if ($flag eq "n") { # deleting number of records
#determine recid to delete all entries that come before like the -i flag
$RECID= $smallrid->{$attrrecid} + $numberentries ;
#get the smalled recid and add number to delete, that is where to start removing
$RECID= $smallrid + $numberentries ;
} else { # flag must be percentage
#take largest and smallest recid and percentage and determine the recid
# that will remove the requested percentage. If some are missing in the
# middle due to tabedit, we are not worried about it.
my $totalnumberrids = $largerid->{$attrrecid} - $smallrid->{$attrrecid} +1;
my $totalnumberrids = $largerid - $smallrid +1;
my $percent = $numberentries / 100;
my $percentage=$totalnumberrids * $percent ;
my $cnt=sprintf( "%d", $percentage ); # round to whole number
$RECID=$smallrid->{$attrrecid} + $cnt; # get recid to remove all before
$RECID=$smallrid + $cnt; # get recid to remove all before
}
# Now prune starting at $RECID
$rc=tabprune_recid($table,$cb,$RECID, $attrrecid,$VERBOSE);
} else {
} else {
my %rsp;
push @{$rsp{data}}, "Nothing to prune from $table.";
$rsp{errorcode} = $rc;
$cb->(\%rsp);
}
return $rc;
}
return $rc;
}
# prune all entries up to the record id input
@@ -2367,11 +2340,27 @@ else {
}
#commit all the changes
my $rollback;
foreach (keys %tables) {
if (exists($tableupdates{$_})) {
$tables{$_}->setAttribs(\%keyhash,\%{$tableupdates{$_}});
my @rc=$tables{$_}->setAttribs(\%keyhash,\%{$tableupdates{$_}});
if (not defined($rc[0]))
{
$rollback = 1;
$callback->({error => "DB error " . $rc[1] , errorcode=>[4]});
}
}
if ($rollback)
{
$tables{$_}->rollback();
$tables{$_}->close;
undef $tables{$_};
return;
}
else
{
$tables{$_}->commit;
}
$tables{$_}->commit;
}
}
}
+281 -108
View File
@@ -218,6 +218,7 @@ sub preprocess_updatenode
'v|version' => \$::VERSION,
'V|verbose' => \$::VERBOSE,
'F|sync' => \$::FILESYNC,
'g|genmypost' => \$::GENMYPOST,
'l|user:s' => \$::USER,
'f|snsync' => \$::SNFILESYNC,
'S|sw' => \$::SWMAINTENANCE,
@@ -226,6 +227,7 @@ sub preprocess_updatenode
'k|security' => \$::SECURITY,
'o|os:s' => \$::OS,
'fanout=i' => \$::fanout,
't|timetout=i' => \$::timeout,
)
)
@@ -249,6 +251,38 @@ sub preprocess_updatenode
$callback->($rsp);
return;
}
# Just generate mypostscripts file and get out
if ($::GENMYPOST)
{
my @entries = xCAT::TableUtils->get_site_attribute("precreatemypostscripts");
if ($entries[0] ) {
$entries[0] =~ tr/a-z/A-Z/;
if ($entries[0] =~ /^(1|YES)$/ ) {
my $notmpfiles=1;
my $nofiles=0;
xCAT::Postage::create_mypostscript_or_not($request, $callback, $subreq,$notmpfiles,$nofiles);
my $rsp = {};
$rsp->{data}->[0] = "Generated new mypostscript files";
$callback->($rsp);
} else { # not valid unless precreatemypostscripts enabled
my $rsp = {};
$rsp->{error}->[0] =
"This option is only valid if site table precreatemypostscripts attribute is 1 or YES";
$rsp->{errorcode}->[0] =1;
$callback->($rsp);
return ;
}
} else { # not in the site table
my $rsp = {};
$rsp->{error}->[0] =
"This option is only valid if site table precreatemypostscripts attribute is 1 or YES";
$rsp->{errorcode}->[0] =1;
$callback->($rsp);
return ;
}
return 0;
}
# -c must work with -S for AIX node
if ($::CMDLINE && !$::SWMAINTENANCE)
@@ -799,13 +833,18 @@ sub security_update_sshkeys
# call the xdsh -K to set up the ssh keys
my @envs = @{$request->{environment}};
my @args = ("-K");
my $args;
push @$args,"-K";
if (defined($::timeout)) { # timeout
push @$args,"-t" ;
push @$args,$::timeout;
}
my $res =
xCAT::Utils->runxcmd(
{
command => ['xdsh'],
node => \@$nodes,
arg => \@args,
arg => $args,
env => \@envs,
},
$subreq, 0, 1
@@ -816,7 +855,7 @@ sub security_update_sshkeys
my $rsp = {};
# not display password in verbose mode.
$rsp->{data}->[0] =
" $localhostname: Internal call command: xdsh -K. nodes = @$nodes, arguments = @args, env = xxxxxx";
" $localhostname: Internal call command: xdsh @$nodes " . join(' ', @$args);
$rsp->{data}->[1] =
" $localhostname: return messages of last command: @$res";
$callback->($rsp);
@@ -878,19 +917,15 @@ sub updatenode
@::FAILEDNODES=();
#print Dumper($request);
my $nodes = $request->{node};
# $request->{status}= "yes"; for testing
my $requeststatus;
if (defined($request->{status})) {
$requeststatus = $request->{status};
}
#$request->{status}= "yes"; # for testing
my $localhostname = hostname();
$::CALLERCALLBACK=$callback;
# if status return requested
my $numberofnodes;
# This is an internal call from another plugin requesting status
# currently this is not displayed is only returned and not displayed
# by updatenode.
if (defined($requeststatus) && ($requeststatus eq "yes")) {
if ((defined($request->{status})) && ($request->{status} eq "yes")) {
$numberofnodes = @$nodes;
my $rsp = {};
$rsp->{status}->[0] = "TOTAL NODES: $numberofnodes";
@@ -973,6 +1008,7 @@ sub updatenode
'k|security' => \$::SECURITY,
'o|os:s' => \$::OS,
'fanout=i' => \$::fanout,
't|timetout=i' => \$::timeout,
)
)
{
@@ -1009,6 +1045,8 @@ sub updatenode
xCAT::TableUtils->setUpdateStatus(\@$nodes, $stat);
}
#
# handle file synchronization
#
@@ -1134,39 +1172,27 @@ sub updatenode
waitpid($_, 0);
}
}
# update the node status, this is done when -F -S -P are run
# make sure the nodes only appear in one array good or bad
&cleanstatusarrays;
if(@::SUCCESSFULLNODES)
{
# if immediate return of status not requested (PCM), then update the DB here
# in one transaction, otherwise it is updated in getdata callback and buildnodestatus
if (!(defined($request->{status})) || ($request->{status} ne "yes")) {
# update the node status, this is done when -F -S -P are run
# make sure the nodes only appear in one array good or bad
&cleanstatusarrays;
if(@::SUCCESSFULLNODES)
{
my $stat="synced";
xCAT::TableUtils->setUpdateStatus(\@::SUCCESSFULLNODES, $stat);
}
if(@::FAILEDNODES)
{
}
if(@::FAILEDNODES)
{
my $stat="failed";
xCAT::TableUtils->setUpdateStatus(\@::FAILEDNODES, $stat);
}
}
# internal call request for status, not output to CLI
if (defined($requeststatus) && ($requeststatus eq "yes")) {
foreach my $n (@::SUCCESSFULLNODES) {
my $rsp = {};
$rsp->{status}->[0] = "$n: SUCCEEDED";
$callback->($rsp);
}
foreach my $n (@::FAILEDNODES) {
my $rsp = {};
$rsp->{status}->[0] = "$n: FAILED";
$callback->($rsp);
}
}
# if site.precreatemypostscripts = not 1 or yes or undefined,
# remove all the
# node files in the noderange in /tftpboot/mypostscripts
@@ -1225,8 +1251,13 @@ sub updatenoderunps
} else {
$nfsv4 = "no";
}
# if running postscript report status here, if requested.
if ((defined($request->{status})) && ($request->{status} eq "yes")) {
$::REPORTSTATUS="Y";
}
# this drives getdata to report status complete for postscripts
$::TYPECALL ="P";
if (($request->{postscripts}) && ($request->{postscripts}->[0]))
{
$orig_postscripts = $request->{postscripts}->[0];
@@ -1267,6 +1298,7 @@ sub updatenoderunps
# Note order of parameters to xcatdsklspost
#is important and cannot be changed
my $runpscmd;
if ($::SETSERVER){
$runpscmd =
"$installdir/postscripts/xcatdsklspost $mode -M $snkey '$postscripts' --tftp $tftpdir --installdir $installdir --nfsv4 $nfsv4 -c";
@@ -1274,11 +1306,20 @@ sub updatenoderunps
$runpscmd =
"$installdir/postscripts/xcatdsklspost $mode -m $snkey '$postscripts' --tftp $tftpdir --installdir $installdir --nfsv4 $nfsv4 -c"
}
# add verbose flag
if ($::VERBOSE){
$runpscmd .= " -V";
}
push @$args1,"--nodestatus"; # return nodestatus
if (defined($::fanout)) { # fanout
push @$args1,"-f" ;
push @$args1,$::fanout;
}
if (defined($::timeout)) { # timeout
push @$args1,"-t" ;
push @$args1,$::timeout;
}
if (defined($::USER)) { # -l contains sudo user
push @$args1,"--sudo" ;
push @$args1,"-l" ;
@@ -1334,7 +1375,12 @@ sub updatenoderunps
$subreq, 0, 1
);
}
# report final status PCM
if ((defined($request->{status})) && ($request->{status} eq "yes")) {
my $rsp = {};
$rsp->{status}->[0] = "Running of postscripts has completed.";
$callback->($rsp);
}
return;
}
@@ -1359,6 +1405,16 @@ sub updatenodesyncfiles
my $localhostname = hostname();
my %syncfile_node = ();
my %syncfile_rootimage = ();
# if running -P or -S do not report or no status requested
if ((defined($request->{status})) && ($request->{status} eq "yes")) { # status requested
if (($request->{rerunps} && $request->{rerunps}->[0] eq "yes") ||
($request->{swmaintenance} && $request->{swmaintenance}->[0] eq "yes")){
$::REPORTSTATUS="N";
} else { # report at sync time (-F)
$::REPORTSTATUS="Y";
}
}
my $node_syncfile = xCAT::SvrUtils->getsynclistfile($nodes);
foreach my $node (@$nodes)
{
@@ -1411,6 +1467,10 @@ sub updatenodesyncfiles
push @$args,"-f" ;
push @$args,$::fanout;
}
if (defined($::timeout)) { # timeout
push @$args,"-t" ;
push @$args,$::timeout;
}
if (defined($::USER)) { # -l must sudo
push @$args,"--sudo" ;
push @$args,"-l" ;
@@ -1459,6 +1519,12 @@ sub updatenodesyncfiles
xCAT::TableUtils->setUpdateStatus(\@$nodes, $stat);
}
# report final status PCM
if ((defined($request->{status})) && ($request->{status} eq "yes")) {
my $rsp = {};
$rsp->{status}->[0] = "File synchronization has completed.";
$callback->($rsp);
}
return;
}
@@ -1468,7 +1534,8 @@ sub updatenodesyncfiles
and then outputs the remaining user info
Arguments: output,callback
Globals @::SUCCESSFULLNODES, @::FAILEDNODES
Globals @::SUCCESSFULLNODES, @::FAILEDNODE
$::REPORTSTATUS if "Y" then imediately return status in $::CALLERCALLBACK (PCM)
=cut
@@ -1484,12 +1551,51 @@ sub buildnodestatus
if($line =~ /^\s*(\S+)\s*:\s*Remote_command_successful/)
{
my ($node,$info) = split (/:/, $line);
push(@::SUCCESSFULLNODES,$node);
if ($::REPORTSTATUS eq "Y" ) { # return status NOW
if (grep(/^$node$/, @::FAILEDNODES)) { # already on the fail buffer
my $rsp2 = {}; # report failed
$rsp2->{status}->[0] = "$node: FAILED";
$::CALLERCALLBACK->($rsp2);
# update the nodelist table updatestatus flag for the node
my $stat="failed";
my @nodearray=();
push @nodearray,$node;
xCAT::TableUtils->setUpdateStatus(\@nodearray, $stat);
} else { # completely successful
my $rsp2 = {};
$rsp2->{status}->[0] = "$node: SUCCEEDED";
$::CALLERCALLBACK->($rsp2);
# update the nodelist table updatestatus flag for the node
my $stat="synced";
my @nodearray=();
push @nodearray,$node;
xCAT::TableUtils->setUpdateStatus(\@nodearray, $stat);
}
}
if (grep(/^$node$/, @::SUCCESSFULLNODES)) { # already on the buffer
next;
} else {
push(@::SUCCESSFULLNODES,$node);
}
}
elsif($line =~ /^\s*(\S+)\s*:\s*Remote_command_failed/)
{
my ($node,$info)= split (/:/, $line);
push(@::FAILEDNODES,$node);
if ($::REPORTSTATUS eq "Y" ) { # return status NOW
my $rsp2 = {};
$rsp2->{status}->[0] = "$node: FAILED";
$::CALLERCALLBACK->($rsp2);
# update the nodelist table updatestatus flag for the node
my $stat="failed";
my @nodearray=();
push @nodearray,$node;
xCAT::TableUtils->setUpdateStatus(\@nodearray, $stat);
}
if (grep(/^$node$/, @::FAILEDNODES)) { # already on the buffer
next;
} else {
push(@::FAILEDNODES,$node);
}
}
else
{
@@ -1557,6 +1663,18 @@ sub updatenodesoftware
my $tftpdir = xCAT::TableUtils->getTftpDir();
my $localhostname = hostname();
my $rsp;
# Determine when to report status, do not report it here if -P is to run
if ((defined($request->{status})) && ($request->{status} eq "yes")) { # if status requested
if ($request->{rerunps} && $request->{rerunps}->[0] eq "yes") { # (-P) running postscripts
$::REPORTSTATUS="N";
} else {
$::REPORTSTATUS="Y";
}
}
# this drives getdata to report status complete for software updatees
$::TYPECALL ="S";
$CALLBACK = $callback;
push @{$rsp->{data}},
"Performing software maintenance operations. This could take a while, if there are packages to install.\n";
@@ -1596,6 +1714,10 @@ sub updatenodesoftware
$cmd =
"$installdir/postscripts/xcatdsklspost 2 -m $snkey 'ospkgs,otherpkgs' --tftp $tftpdir";
}
# add verbose flag
if ($::VERBOSE){
$cmd .= " -V";
}
# build xdsh command
push @$args1,"--nodestatus"; # return nodestatus
@@ -1603,6 +1725,10 @@ sub updatenodesoftware
push @$args1,"-f" ;
push @$args1,$::fanout;
}
if (defined($::timeout)) { # timeout
push @$args1,"-t" ;
push @$args1,$::timeout;
}
if (defined($::USER)) { # -l contains sudo user
push @$args1,"--sudo" ;
push @$args1,"-l" ;
@@ -1630,7 +1756,7 @@ sub updatenodesoftware
arg => $args1,
_xcatpreprocessed => [1]
},
\&getdata2
\&getdata
);
@@ -1660,74 +1786,27 @@ sub updatenodesoftware
return 1;
}
}
# report final status PCM
if ((defined($request->{status})) && ($request->{status} eq "yes")) {
my $rsp = {};
$rsp->{status}->[0] = "Running of Software maintenance has completed.";
$callback->($rsp);
}
return;
}
#-------------------------------------------------------------------------------
=head3 getdata - This is the local callback that handles the response from
the xdsh streaming calls when running postscripts
the xdsh streaming calls when running postscripts(-P) and software updates (-S)
$::TYPECALL = P from postscripts runs or S from Software updates
$::CALLERCALLBACK = saved callback from calling routine
$::REPORTSTATUS, if Y, return the good/bad status right away from this
routine to the $::CALLERCALLBACK ( PCM)
=cut
#-------------------------------------------------------------------------------
sub getdata
{
no strict;
my $response = shift;
my $rsp;
foreach my $type (keys %$response)
{
foreach my $output (@{$response->{$type}})
{
chomp($output);
$output =~ s/\\cM//;
if($output =~ /^\s*(\S+)\s*:\s*Remote_command_successful/)
{
my ($node,$info) = split (/:/, $output);
push(@::SUCCESSFULLNODES,$node);
}
if($output =~ /^\s*(\S+)\s*:\s*Remote_command_failed/)
{
my ($node,$info) = split (/:/, $output);
push(@::FAILEDNODES,$node);
}
if ($output =~ /returned from postscript/)
{
$output =~
s/returned from postscript/Running of postscripts has completed./;
}
if ($RERUNPS4SECURITY && $RERUNPS4SECURITY eq "yes")
{
if ($output =~ /Running of postscripts has completed/)
{
$output =~
s/Running of postscripts has completed/Redeliver security files has completed/;
push @{$rsp->{$type}}, $output;
}
elsif ($output !~ /Running postscript|Error loading module/)
{
push @{$rsp->{$type}}, "$output";
}
} else{ # for non -k option then get the rest of the output
if (($output !~ (/Error loading module/)) && ($output !~ /^\s*(\S+)\s*:\s*Remote_command_successful/) && ($output !~ /^\s*(\S+)\s*:\s*Remote_command_failed/))
{
push @{$rsp->{$type}}, "$output";
}
}
}
}
$CALLBACK->($rsp);
}
#-------------------------------------------------------------------------------
=head3 getdata2 - This is the local callback that handles the response from
the xdsh streaming calls when running software updates
=cut
#-------------------------------------------------------------------------------
sub getdata2
{
no strict;
my $response = shift;
@@ -1742,31 +1821,117 @@ sub getdata2
if($output =~ /^\s*(\S+)\s*:\s*Remote_command_successful/)
{
my ($node,$info) = split (/:/, $output);
push(@::SUCCESSFULLNODES,$node);
if ($::REPORTSTATUS eq "Y" ) { # return status NOW
if (grep(/^$node$/, @::FAILEDNODES)) { # already on the fail buffer
my $rsp2 = {}; # report failed
$rsp2->{status}->[0] = "$node: FAILED";
$::CALLERCALLBACK->($rsp2);
# update the nodelist table updatestatus flag for the node
my $stat="failed";
my @nodearray=();
push @nodearray,$node;
xCAT::TableUtils->setUpdateStatus(\@nodearray, $stat);
} else { # completely successful
my $rsp2 = {};
$rsp2->{status}->[0] = "$node: SUCCEEDED";
$::CALLERCALLBACK->($rsp2);
# update the nodelist table updatestatus flag for the node
my $stat="synced";
my @nodearray=();
push @nodearray,$node;
xCAT::TableUtils->setUpdateStatus(\@nodearray, $stat);
}
}
if (grep(/^$node$/, @::SUCCESSFULLNODES)) { # already on the buffer
next;
} else {
push(@::SUCCESSFULLNODES,$node);
}
}
# check for already installed, this is not an error
# check for already installed on software updates, this is not an error
if($output =~ /^\s*(\S+)\s*:\s*already installed/)
{
$alreadyinstalled = 1;
$alreadyinstalled = 1;
}
if($output =~ /^\s*(\S+)\s*:\s*Remote_command_failed/)
{
if ($alreadyinstalled == 0) { # not an already install error
my ($node,$info) = split (/:/, $output);
push(@::FAILEDNODES,$node);
}
my ($node,$info) = split (/:/, $output);
if ($alreadyinstalled == 0) { # not an already install error, then real error
if ($::REPORTSTATUS eq "Y" ) { # return status NOW
my $rsp2 = {};
$rsp2->{status}->[0] = "$node: FAILED";
$::CALLERCALLBACK->($rsp2);
# update the nodelist table updatestatus flag for the node
my $stat="failed";
my @nodearray=();
push @nodearray,$node;
xCAT::TableUtils->setUpdateStatus(\@nodearray, $stat);
}
if (grep(/^$node$/, @::FAILEDNODES)) { # already on the buffer
next;
} else {
push(@::FAILEDNODES,$node);
}
} else { # already installed is ok
if ($::REPORTSTATUS eq "Y" ) { # return status NOW
if (grep(/^$node$/, @::FAILEDNODES)) { # already on the fail buffer
my $rsp2 = {}; # report failed
$rsp2->{status}->[0] = "$node: FAILED";
$::CALLERCALLBACK->($rsp2);
# update the nodelist table updatestatus flag for the node
my $stat="failed";
my @nodearray=();
push @nodearray,$node;
xCAT::TableUtils->setUpdateStatus(\@nodearray, $stat);
} else { # completely successful
my $rsp2 = {};
$rsp2->{status}->[0] = "$node: SUCCEEDED";
$::CALLERCALLBACK->($rsp2);
# update the nodelist table updatestatus flag for the node
my $stat="synced";
my @nodearray=();
push @nodearray,$node;
xCAT::TableUtils->setUpdateStatus(\@nodearray, $stat);
}
}
if (grep(/^$node$/, @::SUCCESSFULLNODES)) { # already on the buffer
next;
} else {
push(@::SUCCESSFULLNODES,$node);
}
}
}
if ($output =~ /returned from postscript/)
{
if ($::TYPECALL eq "P") { # -P flag
$output =~
s/returned from postscript/Running of postscripts has completed./;
} else { # should be -S flag
$output =~
s/returned from postscript/Running of Software Maintenance has completed./;
}
}
if (($output !~ /^\s*(\S+)\s*:\s*Remote_command_successful/) && ($output !~ /^\s*(\S+)\s*:\s*Remote_command_failed/))
if ($RERUNPS4SECURITY && $RERUNPS4SECURITY eq "yes")
{
if ($output =~ /Running of postscripts has completed/)
{
$output =~
s/Running of postscripts has completed/Redeliver security files has completed/;
push @{$rsp->{$type}}, $output;
} else {
if (($output !~ (/Running postscript/)) && ($output !~ (/Error loading module/)) && ($output !~ /^\s*(\S+)\s*:\s*Remote_command_successful/) && ($output !~ /^\s*(\S+)\s*:\s*Remote_command_failed/))
{
push @{$rsp->{$type}}, "$output";
}
}
} else{ # for non -k option then get the rest of the output
if (($output !~ (/Error loading module/)) && ($output !~ /^\s*(\S+)\s*:\s*Remote_command_successful/) && ($output !~ /^\s*(\S+)\s*:\s*Remote_command_failed/))
{
push @{$rsp->{$type}}, "$output";
}
}
}
}
@@ -2343,6 +2508,10 @@ sub updateAIXsoftware
%nodeupdateinfo = %{$updates};
}
# this drives getdata to report status complete for software updatees
$::TYPECALL ="S";
my %bndloc;
# get the server name for each node - as known by the node
@@ -2579,6 +2748,10 @@ sub updateAIXsoftware
push @$args1,"-f" ;
push @$args1,$::fanout;
}
if (defined($::timeout)) { # timeout
push @$args1,"-t" ;
push @$args1,$::timeout;
}
push @$args1,"$installcmd";
$subreq->(
@@ -2588,7 +2761,7 @@ sub updateAIXsoftware
arg => $args1,
_xcatpreprocessed => [1]
},
\&getdata2
\&getdata
);
# remove pkglist_file from MN - local
+22 -4
View File
@@ -2,12 +2,15 @@
package xCAT_plugin::vsmppxe;
use Data::Dumper;
use Sys::Syslog;
use xCAT::Scope;
use xCAT::Utils;
use xCAT::NetworkUtils;
use Socket;
use File::Copy;
use Getopt::Long;
use xCAT::MsgUtils;
use xCAT::TableUtils qw(get_site_attribute);
use xCAT::ServiceNodeUtils;
use xCAT::TableUtils;
my $addkcmdlinehandled;
my $request;
my $callback;
@@ -210,6 +213,7 @@ sub preprocess_request {
my $callback1 = shift;
my $command = $req->{command}->[0];
my $sub_req = shift;
my $nodes = $req->{node};
my @args=();
if (ref($req->{arg})) {
@args=@{$req->{arg}};
@@ -254,15 +258,29 @@ sub preprocess_request {
return;
}
#my $sent = $stab->getAttribs({key=>'sharedtftp'},'value');
my @entries = xCAT::TableUtils->get_site_attribute("sharedtftp");
my $t_entry = $entries[0];
if ( defined($t_entry) and ($t_entry == 0 or $t_entry =~ /no/i)) {
# check for computenodes and servicenodes from the noderange, if so error out
my @SN;
my @CN;
xCAT::ServiceNodeUtils->getSNandCPnodes(\@$nodes, \@SN, \@CN);
if ((@SN > 0) && (@CN >0 )) { # there are both SN and CN
my $rsp;
$rsp->{data}->[0] =
"Nodeset was run with a noderange containing both service nodes and compute nodes. This is not valid. You must submit with either compute nodes in the noderange or service nodes. \n";
xCAT::MsgUtils->message("E", $rsp, $callback1);
return;
}
$req->{'_disparatetftp'}=[1];
if ($req->{inittime}->[0]) {
return [$req];
}
return xCAT::Scope->get_broadcast_scope($req,@_);
if (@CN >0 ) { # if there are compute nodes then broadcast to any servicenodes
return xCAT::Scope->get_broadcast_scope($req,@_);
}
}
return [$req];
}
+18 -57
View File
@@ -10,7 +10,7 @@ use xCAT::MsgUtils;
use Getopt::Long;
use xCAT::Utils;
use xCAT::TableUtils;
use xCAT::ServiceNodeUtils;
my $addkcmdlinehandled;
my $request;
my $callback;
@@ -294,6 +294,7 @@ sub preprocess_request {
my $callback1 = shift;
my $command = $req->{command}->[0];
my $sub_req = shift;
my $nodes = $req->{node};
my @args=();
if (ref($req->{arg})) {
@args=@{$req->{arg}};
@@ -345,72 +346,32 @@ sub preprocess_request {
#Assume shared tftp directory for boring people, but for cool people, help sync up tftpdirectory contents when
#they specify no sharedtftp in site table
#my $stab = xCAT::Table->new('site');
#my $sent = $stab->getAttribs({key=>'sharedtftp'},'value');i
my @entries = xCAT::TableUtils->get_site_attribute("sharedtftp");
my $t_entry = $entries[0];
if ( defined($t_entry) and ($t_entry == 0 or $t_entry =~ /no/i)) {
# check for computenodes and servicenodes from the noderange, if so error out
my @SN;
my @CN;
xCAT::ServiceNodeUtils->getSNandCPnodes(\@$nodes, \@SN, \@CN);
if ((@SN > 0) && (@CN >0 )) { # there are both SN and CN
my $rsp;
$rsp->{data}->[0] =
"Nodeset was run with a noderange containing both service nodes and compute nodes. This is not valid. You must submit with either compute nodes in the noderange or service nodes. \n";
xCAT::MsgUtils->message("E", $rsp, $callback1);
return;
}
$req->{'_disparatetftp'}=[1];
if ($req->{inittime}->[0]) {
return [$req];
}
return xCAT::Scope->get_broadcast_scope($req,@_);
if (@CN >0 ) { # if compute nodes broadcast to all servicenodes
return xCAT::Scope->get_broadcast_scope($req,@_);
}
}
return [$req];
}
#sub preprocess_request {
# my $req = shift;
# $callback = shift;
# if ($req->{_xcatpreprocessed}->[0] == 1) { return [$req]; }
# my @requests = ({%$req}); #Start with a straight copy to reflect local instance
# my $sitetab = xCAT::Table->new('site');
# (my $ent) = $sitetab->getAttribs({key=>'xcatservers'},'value');
# $sitetab->close;
# if ($ent and $ent->{value}) {
# foreach (split /,/,$ent->{value}) {
# if (xCAT::NetworkUtils->thishostisnot($_)) {
# my $reqcopy = {%$req};
# $reqcopy->{'_xcatdest'} = $_;
# $reqcopy->{_xcatpreprocessed}->[0] = 1;
# push @requests,$reqcopy;
# }
# }
# }
# return \@requests;
#}
#sub preprocess_request {
# my $req = shift;
# my $callback = shift;
# my %localnodehash;
# my %dispatchhash;
# my $nrtab = xCAT::Table->new('noderes');
# foreach my $node (@{$req->{node}}) {
# my $nodeserver;
# my $tent = $nrtab->getNodeAttribs($node,['tftpserver']);
# if ($tent) { $nodeserver = $tent->{tftpserver} }
# unless ($tent and $tent->{tftpserver}) {
# $tent = $nrtab->getNodeAttribs($node,['servicenode']);
# if ($tent) { $nodeserver = $tent->{servicenode} }
# }
# if ($nodeserver) {
# $dispatchhash{$nodeserver}->{$node} = 1;
# } else {
# $localnodehash{$node} = 1;
# }
# }
# my @requests;
# my $reqc = {%$req};
# $reqc->{node} = [ keys %localnodehash ];
# if (scalar(@{$reqc->{node}})) { push @requests,$reqc }
#
# foreach my $dtarg (keys %dispatchhash) { #iterate dispatch targets
# my $reqcopy = {%$req}; #deep copy
# $reqcopy->{'_xcatdest'} = $dtarg;
# $reqcopy->{node} = [ keys %{$dispatchhash{$dtarg}}];
# push @requests,$reqcopy;
# }
# return \@requests;
#}
sub process_request {
$request = shift;
+24 -43
View File
@@ -5,6 +5,7 @@ use Sys::Syslog;
use xCAT::Scope;
use xCAT::Utils;
use xCAT::TableUtils;
use xCAT::ServiceNodeUtils;
use xCAT::NetworkUtils;
use xCAT::MsgUtils;
use File::Path;
@@ -103,7 +104,7 @@ sub setstate {
if (xCAT::InstUtils->is_me($sn)) {
my @myself = xCAT::NetworkUtils->determinehostname();
my $myname = $myself[(scalar @myself)-1];
$callback->(
$::callback->(
{
error => [
"$myname: Unable to determine the image server for $node on service node $sn"
@@ -115,7 +116,7 @@ sub setstate {
}
}
} else {
$callback->(
$::callback->(
{
error => [
"$myname: Unable to determine the image server for $node"
@@ -296,7 +297,8 @@ sub setstate {
my $pname = "yaboot.conf-" . $tmp;
unlink($tftpdir."/".$pname);
link($tftpdir."/etc/".$node,$tftpdir."/".$pname);
}
}
return;
}
@@ -333,7 +335,7 @@ sub preprocess_request {
@args=($req->{arg});
}
@ARGV = @args;
my $nodes = $req->{node};
#use Getopt::Long;
Getopt::Long::Configure("bundling");
Getopt::Long::Configure("pass_through");
@@ -374,60 +376,39 @@ sub preprocess_request {
#Assume shared tftp directory for boring people, but for cool people, help sync up tftpdirectory contents when
#they specify no sharedtftp in site table
#my $stab = xCAT::Table->new('site');
#my $sent = $stab->getAttribs({key=>'sharedtftp'},'value');
#if they specify no sharedtftp in site table
my @entries = xCAT::TableUtils->get_site_attribute("sharedtftp");
my $t_entry = $entries[0];
if ( defined($t_entry) and ($t_entry == 0 or $t_entry =~ /no/i)) {
# check for computenodes and servicenodes from the noderange, if so error out
my @SN;
my @CN;
xCAT::ServiceNodeUtils->getSNandCPnodes(\@$nodes, \@SN, \@CN);
if ((@SN > 0) && (@CN >0 )) { # there are both SN and CN
my $rsp;
$rsp->{data}->[0] =
"Nodeset was run with a noderange containing both service nodes and compute nodes. This is not valid. You must submit with either compute nodes in the noderange or service nodes. \n";
xCAT::MsgUtils->message("E", $rsp, $callback1);
return;
}
$req->{'_disparatetftp'}=[1];
if ($req->{inittime}->[0]) {
return [$req];
}
return xCAT::Scope->get_broadcast_scope($req,@_);
if (@CN >0 ) { # if compute nodes broadcast to all servicenodes
return xCAT::Scope->get_broadcast_scope($req,@_);
}
}
return [$req];
}
#sub preprocess_request {
# my $req = shift;
# my $callback = shift;
# my %localnodehash;
# my %dispatchhash;
# my $nrtab = xCAT::Table->new('noderes');
# foreach my $node (@{$req->{node}}) {
# my $nodeserver;
# my $tent = $nrtab->getNodeAttribs($node,['tftpserver']);
# if ($tent) { $nodeserver = $tent->{tftpserver} }
# unless ($tent and $tent->{tftpserver}) {
# $tent = $nrtab->getNodeAttribs($node,['servicenode']);
# if ($tent) { $nodeserver = $tent->{servicenode} }
# }
# if ($nodeserver) {
# $dispatchhash{$nodeserver}->{$node} = 1;
# } else {
# $localnodehash{$node} = 1;
# }
# }
# my @requests;
# my $reqc = {%$req};
# $reqc->{node} = [ keys %localnodehash ];
# if (scalar(@{$reqc->{node}})) { push @requests,$reqc }
#
# foreach my $dtarg (keys %dispatchhash) { #iterate dispatch targets
# my $reqcopy = {%$req}; #deep copy
# $reqcopy->{'_xcatdest'} = $dtarg;
# $reqcopy->{node} = [ keys %{$dispatchhash{$dtarg}}];
# push @requests,$reqcopy;
# }
# return \@requests;
#}
#
sub process_request {
$request = shift;
$callback = shift;
$::callback=$callback;
$sub_req = shift;
my $command = $request->{command}->[0];
%breaknetbootnodes=();
+32 -17
View File
@@ -35,28 +35,43 @@ unless ($master && $cfgpath) {
}
# get the correct host name for the host
my $nodename;
my ($nodename, $nodename_short);
my $masterip = `getent hosts $master | awk {'print \$1'}`;
chomp($masterip);
my $myip = `ip route get $masterip| head -n 1 | sed 's/^.*src//g' | awk {'print \$1'}`;
my $myipinfo =`getent hosts $myip`;
if ($myipinfo =~ /([^\s]+)\s+([^\s]+)\s+([^\s]+)/) {
my $n1 = $2;
my $n2 = $3;
if (length($n1) > length($n2)) {
$nodename = $n2;
} else {
$nodename = $n1;
if ($masterip) {
chomp($masterip);
my $myip = `ip route get $masterip| head -n 1 | sed 's/^.*src//g' | awk {'print \$1'}`;
if ($myip) {
my $myipinfo =`getent hosts $myip`;
if ($myipinfo && $myipinfo =~ /([^\s]+)\s+([^\s]+)\s+([^\s]+)/) {
my $n1 = $2;
my $n2 = $3;
if (length($n1) > length($n2)) {
$nodename_short = $n2;
} else {
$nodename = $n1;
}
} elsif ($myipinfo && $myipinfo =~ /([^\s]+)\s+([^\s]+)/) {
$nodename_short = $2;
}
}
} elsif ($myipinfo =~ /([^\s]+)\s+([^\s]+)/) {
$nodename = $2;
} else {
outputmsg("Error: cannot get the hostname of the host node\n", 2);
}
unless ($nodename) {
$nodename = `hostname`;
chomp($nodename);
}
unless ($nodename_short) {
$nodename_short = `hostname -s`;
chomp($nodename_short);
}
# download the mic configuration file from master
my $cmd = "wget -N --waitretry=10 --random-wait -T 60 http://$master/$cfgpath/miccfg.$nodename -P $tmppath";
my ($rc, $output) = runsyscmd ($cmd, "Error: failed to download mic configuration file from $master\n", 3);
my $cmd = "wget -N --waitretry=10 --random-wait -T 60 http://$master/$cfgpath/miccfg.$nodename_short -P $tmppath";
my ($rc, $output) = runsyscmd ($cmd);
if ($rc) {
$cmd = "wget -N --waitretry=10 --random-wait -T 60 http://$master/$cfgpath/miccfg.$nodename -P $tmppath";
runsyscmd ($cmd, "Error: failed to download mic configuration file from $master\n", 3);
}
unless (-r "$tmppath/miccfg.$nodename") {
runsyscmd ("Error: cannot get the mic configuration file from http://$master/$cfgpath/miccfg.$nodename\n", 4);
+32 -17
View File
@@ -36,28 +36,43 @@ unless ($master && $cfgpath) {
}
# get the correct host name for the host
my $nodename;
my ($nodename, $nodename_short);
my $masterip = `getent hosts $master | awk {'print \$1'}`;
chomp($masterip);
my $myip = `ip route get $masterip| head -n 1 | sed 's/^.*src//g' | awk {'print \$1'}`;
my $myipinfo =`getent hosts $myip`;
if ($myipinfo =~ /([^\s]+)\s+([^\s]+)\s+([^\s]+)/) {
my $n1 = $2;
my $n2 = $3;
if (length($n1) > length($n2)) {
$nodename = $n2;
} else {
$nodename = $n1;
if ($masterip) {
chomp($masterip);
my $myip = `ip route get $masterip| head -n 1 | sed 's/^.*src//g' | awk {'print \$1'}`;
if ($myip) {
my $myipinfo =`getent hosts $myip`;
if ($myipinfo && $myipinfo =~ /([^\s]+)\s+([^\s]+)\s+([^\s]+)/) {
my $n1 = $2;
my $n2 = $3;
if (length($n1) > length($n2)) {
$nodename_short = $n2;
} else {
$nodename = $n1;
}
} elsif ($myipinfo && $myipinfo =~ /([^\s]+)\s+([^\s]+)/) {
$nodename_short = $2;
}
}
} elsif ($myipinfo =~ /([^\s]+)\s+([^\s]+)/) {
$nodename = $2;
} else {
outputmsg("Error: cannot get the hostname of the host node\n", 2);
}
unless ($nodename) {
$nodename = `hostname`;
chomp($nodename);
}
unless ($nodename_short) {
$nodename_short = `hostname -s`;
chomp($nodename_short);
}
# download the mic configuration file from master
my $cmd = "wget -N --waitretry=10 --random-wait -T 60 http://$master/$cfgpath/micflash.$nodename -P $tmppath";
my ($rc, $output) = runsyscmd ($cmd, "Error: failed to download mic configuration file from $master\n", 3);
my $cmd = "wget -N --waitretry=10 --random-wait -T 60 http://$master/$cfgpath/micflash.$nodename_short -P $tmppath";
my ($rc, $output) = runsyscmd ($cmd);
if ($rc) {
$cmd = "wget -N --waitretry=10 --random-wait -T 60 http://$master/$cfgpath/micflash.$nodename -P $tmppath";
runsyscmd ($cmd, "Error: failed to download mic configuration file from $master\n", 3);
}
unless (-r "$tmppath/micflash.$nodename") {
runsyscmd ("Error: cannot get the mic configuration file from http://$master/$cfgpath/micflash.$nodename\n", 4);
+72 -2
View File
@@ -64,6 +64,7 @@ if (
'k|sshkeys' => \$::genSSHRootKeys,
'm|mgtnode' => \$::setupMNinDB,
's|sshnodehostkeys' => \$::genSSHNodeHostKeys,
't|tunables' => \$::settunables,
'c|credentials' => \$::genCredentials,
'd|database' => \$::initDB,
'h|help' => \$::HELP,
@@ -101,6 +102,7 @@ if ($::FORCE)
|| $::genSSHRootKeys
|| $::genSSHNodeHostKey
|| $::genCredentials
|| $::settunables
|| $::initDB)
{
my $warning =
@@ -234,6 +236,22 @@ if (xCAT::Utils->isMN()) {
&genSSHNodeHostKey;
}
}
#
# Set tunables
#
#
if (($::settunables) && ( $::osname eq 'AIX')) { # not supported on AIX
xCAT::MsgUtils->message('E', "Setting tunables (-t) is not supported on AIX.");
exit 1;
}
if ($::FORCE || $::settunables || $::INITIALINSTALL )
{
if ($::osname eq 'Linux') {
&settunables;
}
}
#
# gen root's ssh keys, if needed and copy to appropriate directories to
# be used during install
@@ -628,11 +646,11 @@ sub usage
{
xCAT::MsgUtils->message(
'I',
"Usage:\nxcatconfig - Performs basic xCAT setup operations on an xCAT management node. This command should not be run on an xCAT Service Node, unless you are making it a Management Node.\n"
"Usage:\nxcatconfig - Performs basic xCAT setup operations on an xCAT management node. Only the -t option should be used on a Service Node.\n"
);
xCAT::MsgUtils->message(
'I',
"xcatconfig [-h|--help]\nxcatconfig [-v|--version]\nxcatconfig [-f|--force] [-V|--verbose]\nxcatconfig [-i|--initinstall] [-V|--verbose]\nxcatconfig [-u|--updateinstall] [-V|--verbose]\nxcatconfig [-k|--sshkeys] [-s|--sshnodehostkeys] [-c|--credentials] [-d|database] [-m|mgtnode] [-V|--verbose]"
"xcatconfig [-h|--help]\nxcatconfig [-v|--version]\nxcatconfig [-f|--force] [-V|--verbose]\nxcatconfig [-i|--initinstall] [-V|--verbose]\nxcatconfig [-u|--updateinstall] [-V|--verbose]\nxcatconfig [-k|--sshkeys] [-s|--sshnodehostkeys] [-c|--credentials] [-d|database] [-m|mgtnode] [-t|tunables] [-V|--verbose]"
);
}
@@ -822,7 +840,58 @@ sub genSSHRootKeys
);
}
}
#-----------------------------------------------------------------------------
=head3 settunables
Will set the default suggested tunables on the Management Node or service node for Linux
=cut
#-----------------------------------------------------------------------------
sub settunables
{
# tuning ARP on Linux
# set for right now
my $cmd = "/bin/echo '1024' >/proc/sys/net/ipv4/neigh/default/gc_thresh1";
my $outref = xCAT::Utils->runcmd("$cmd", 0);
if ($::RUNCMD_RC != 0)
{
xCAT::MsgUtils->message( 'E', "Could not run $cmd.");
}
$cmd = "/bin/echo '4096' >/proc/sys/net/ipv4/neigh/default/gc_thresh2";
my $outref = xCAT::Utils->runcmd("$cmd", 0);
if ($::RUNCMD_RC != 0)
{
xCAT::MsgUtils->message( 'E', "Could not run $cmd.");
}
$cmd = "/bin/echo '8192' >/proc/sys/net/ipv4/neigh/default/gc_thresh3";
my $outref = xCAT::Utils->runcmd("$cmd", 0);
if ($::RUNCMD_RC != 0)
{
xCAT::MsgUtils->message( 'E', "Could not run $cmd.");
}
# set for after reboot
if (!( -f "/etc/sysctl.conf.xcatbackup")){ # not already backed up
$cmd = "cp /etc/sysctl.conf /etc/sysctl.conf.xcatbackup";
my $outref = xCAT::Utils->runcmd("$cmd", 0);
if ($::RUNCMD_RC != 0)
{
xCAT::MsgUtils->message( 'E', "Could not backup /etc/sysctl.conf.");
exit 1;
}
}
#delete all occurance of the attribute and then add xCAT settings
`sed -i '/net.ipv4.neigh.default.gc_thresh1 /'d /etc/sysctl.conf`;
`echo "net.ipv4.neigh.default.gc_thresh1 = 1024" >>/etc/sysctl.conf`;
`sed -i '/net.ipv4.neigh.default.gc_thresh2 /'d /etc/sysctl.conf`;
`echo "net.ipv4.neigh.default.gc_thresh2 = 4096" >>/etc/sysctl.conf`;
`sed -i '/net.ipv4.neigh.default.gc_thresh3 /'d /etc/sysctl.conf`;
`echo "net.ipv4.neigh.default.gc_thresh3 = 8192" >>/etc/sysctl.conf`;
}
#-----------------------------------------------------------------------------
=head3 genSSHNodeHostKey
@@ -1174,6 +1243,7 @@ sub initDB
$chtabcmds .= "$::XCATROOT/sbin/chtab key=vsftp site.value=n;";
$chtabcmds .= "$::XCATROOT/sbin/chtab key=cleanupxcatpost site.value=no;";
$chtabcmds .= "$::XCATROOT/sbin/chtab key=dhcplease site.value=43200;";
$chtabcmds .= "$::XCATROOT/sbin/chtab key=useflowcontrol site.value=yes;";
if ($::osname eq 'AIX')
{
+119 -35
View File
@@ -18,6 +18,8 @@ BEGIN
}
}
my $sslctl;
my $udpctl;
# if AIX - make sure we include perl 5.8.2 in INC path.
# Needed to find perl dependencies shipped in deps tarball.
if ($^O =~ /^aix/i) {
@@ -48,6 +50,7 @@ use xCAT::Client qw(submit_request);
my $clientselect = new IO::Select;
my $sslclients = 0; #THROTTLE
my $maxsslclients = 64; #default
my $batchclients = 50;
my @deferredmsgargs; # hold argumentlist for MsgUtils call until after fork
#parallelizing logging overhead with real work
@@ -125,7 +128,7 @@ unless ($pidfile) {
#start syslog if it is not up
if (xCAT::Utils->isLinux()) {
my $init_file="/etc/init.d/syslog";
if ((-f "/etc/fedora-release") || (-f "/etc/redhat-release") || (-f "/etc/lsb-release")){
if ((-f "/etc/fedora-release") || (-f "/etc/redhat-release") || (-f "/etc/lsb-release")){
$init_file="/etc/init.d/rsyslog";
}
if ( -x $init_file ) {
@@ -174,6 +177,8 @@ if ($tmp) {
}
($tmp) = $sitetab->getAttribs({'key'=>'xcatmaxconnections'},'value');
if ($tmp and $tmp->{value}) { $maxsslclients = $tmp->{value}; }
($tmp) = $sitetab->getAttribs({'key'=>'xcatmaxbatchconnections'},'value');
if ($tmp and $tmp->{value}) { $batchclients = $tmp->{value}; }
my $plugins_dir=$::XCATROOT.'/lib/perl/xCAT_plugin';
@@ -479,6 +484,37 @@ if ($inet6support) {
}
}
sub update_udpcontext_from_sslctl {
my %args = @_;
my $udpcontext = $args{udpcontext};
my $select = $args{select};
my $msg;
eval { $msg = fd_retrieve($sslctl); };
if ($msg) {
#remember new count and, if new connection and we have a fudge factor, decrese fudge factor optimisticly assuming it's the right one
$udpcontext->{sslclientcount} = $msg->{sslclientcount};
if ($udpcontext->{clientfudge} and $msg->{clientcountchange} > 0) { $udpcontext->{clientfudge} -= $msg->{clientcountchange}; }
} else {
$select->remove($sslctl); close($sslctl); #something went horribly wrong
}
}
sub grant_tcrequests {
my $requestors = shift;
my $udpcontext = shift;
my $availableslots = $batchclients;
$availableslots -= $udpcontext->{clientfudge}; #value that forecasts the pressure
$availableslots -= $udpcontext->{sslclientcount}; #subtract all currently really active sessions
my $oldtime = time()-180; #drop requests older than three minutes if still around
foreach my $rkey (keys %{$requestors}) {
if ($requestors->{$rkey}->{timestamp} < $oldtime) { delete $requestors->{$rkey}; next; }
unless ($availableslots > 0) { next; } # no slots, ignore requests for now
$udpcontext->{clientfudge}+=1; #adjust forecast for being busy
$availableslots-=1;
$udpcontext->{socket}->send("resourcerequest: ok\n",0,$requestors->{$rkey}->{sockaddr});
delete ($requestors->{$rkey}); #we acknoweldged, assume consumer got it, they'll do retry if they failed
}
}
sub do_udp_service { #This function opens up a UDP port
#It will do similar to the standard service, except:
@@ -489,6 +525,9 @@ sub do_udp_service { #This function opens up a UDP port
#Explicitly, to handle whatever operations nodes periodically send during discover state
#Could be used for heartbeating and such as desired
$dispatch_requests=0;
my $udpcontext;
$udpcontext->{clientfudge}=0;
$udpcontext->{sslclientcount}=0;
my $udppidfile;
my $retry=1;
my $socket;
@@ -499,10 +538,10 @@ sub do_udp_service { #This function opens up a UDP port
xCAT::MsgUtils->message("S","xcatd udp service $$ quiescing");
}
};
if ($inet6support) {
if ($inet6support) {
$socket = IO::Socket::INET6->new(LocalPort => $port,
Proto => 'udp',
Domain => AF_INET);
);
} else {
$socket = IO::Socket::INET->new(LocalPort => $port,
Proto => 'udp',
@@ -519,10 +558,10 @@ sub do_udp_service { #This function opens up a UDP port
}
my $select = new IO::Select;
while (not $socket and $retry) {
if ($inet6support) {
if ($inet6support) {
$socket = IO::Socket::INET6->new(LocalPort => $port,
Proto => 'udp',
Domain => AF_INET);
);
} else {
$socket = IO::Socket::INET->new(LocalPort => $port,
Proto => 'udp',
@@ -542,6 +581,8 @@ sleep 0.05;
print $udppidfile $$;
close($udppidfile);
$select->add($socket);
$udpcontext->{socket} = $socket;
$select->add($sslctl);
my $data;
my $part;
my $sport;
@@ -551,6 +592,7 @@ sleep 0.05;
my $actualpid=$$;
until ($quit) {
eval {
my $tcclients; # hash reference to store traffic control requests
while (1) {
unless ($actualpid == $$) { #This really should be impossible now...
xCAT::MsgUtils->message("S","xcatd: Something absolutely ludicrous happpened, xCAT developers think this message is impossible to see, post if you see it, fork bomb averted");
@@ -561,57 +603,84 @@ sleep 0.05;
populate_site_hash();
yield;
}
while ($select->can_read(0)) { #Pull all buffer data that can be pulled
my @hdls;
while (@hdls = $select->can_read(0)) { #Pull all buffer data that can be pulled
my $hdl;
foreach $hdl (@hdls) {
if ($hdl == $socket) {
$part = $socket->recv($data,1500);
($sport,$client) = sockaddr_in($part);
if ($sport < 1000) { #Only remember udp packets from privileged ports
$packets{inet_ntoa($client)} = [$part,$data];
}
$packets{$part} = [$part,$data];
} elsif ($hdl == $sslctl) {
update_udpcontext_from_sslctl(udpcontext=>$udpcontext,select=>$select);
} else {
print "Something is wrong in udp process (search xcatd for this string)\n";
}
}
}
foreach my $pkey (keys %packets) {
($sport,$client) = sockaddr_in($packets{$pkey}->[0]);
my $saddr = $packets{$pkey}->[0];
my $clientn;
my $clientip;
if ($inet6support) {
($client,$sport) = Socket6::getnameinfo($saddr);
($clientip,$sport) = Socket6::getnameinfo($saddr,Socket6::NI_NUMERICHOST());
if ($clientip =~ /::ffff:.*\..*\./) {
$clientip =~ s/^::ffff://;
}
if ($client =~ /::ffff:.*\..*\./) {
$client =~ s/^::ffff://;
}
} else {
($sport,$clientn) = sockaddr_in($saddr);
$clientip = inet_ntoa($clientn);
$client=gethostbyaddr($clientn,AF_INET);
}
$data=$packets{$pkey}->[1];
$peerhost=gethostbyaddr($client,AF_INET);
$peerhost .="\n";
if ($data =~ /^\037\213/) { #per rfc 1952, these two bytes are gzip, and they are invalid for
#xcatrequest xml, so go ahead and decompress it
my $bigdata;
IO::Uncompress::Gunzip::gunzip(\$data,\$bigdata);
$data = $bigdata
}
if ($data =~ /^<xcat/) { #xml format
my $req = eval { XMLin($data, SuppressEmpty=>undef,ForceArray=>1) };
if ($req and $req->{command} and ($req->{command}->[0] eq "findme")) {
$req->{'_xcat_clienthost'}=gethostbyaddr($client,AF_INET);
$req->{'_xcat_clientip'}=inet_ntoa($client);
if ($req and $req->{command} and ($req->{command}->[0] eq "findme" and $sport < 1000)) { #only consider priveleged port requests to start with
$req->{'_xcat_clienthost'}=$client;
$req->{'_xcat_clientip'}=$clientip;
$req->{'_xcat_clientport'}=$sport;
if (defined($cmd_handlers{"findme"}) and xCAT::NetworkUtils->nodeonmynet(inet_ntoa($client))) { #only discover from ips that appear to be on a managed network
if (defined($cmd_handlers{"findme"}) and xCAT::NetworkUtils->nodeonmynet($clientip)) { #only discover from ips that appear to be on a managed network
xCAT::MsgUtils->message("S","xcatd: Processing discovery request from ".$req->{'_xcat_clientip'});
$req->{cacheonly}->[0] = 1;
plugin_command($req,undef,\&build_response);
if ($req->{cacheonly}->[0]) {
delete $req->{cacheonly};
plugin_command($req,undef,\&build_response);
#if ($req) {
# $req->{cacheonly}->[0] = 1;
# $req->{checkallmacs}->[0] = 1;
# plugin_command($req,undef,\&convey_response);
# }
}
} else {
xCAT::MsgUtils->message("S","xcatd: Skipping discovery from ".inet_ntoa($client)." because we either have no discovery plugins or the client address does not match an IP network that xCAT is managing");
xCAT::MsgUtils->message("S","xcatd: Skipping discovery from ".$client." because we either have no discovery plugins or the client address does not match an IP network that xCAT is managing");
}
}
} else { # for *now*, we'll do a tiny YAML subset
if ($data =~ /^resourcerequest: xcatd$/) {
$tcclients->{$pkey}={ sockaddr=>$packets{$pkey}->[0], timestamp=>time() }
}
} # JSON maybe one day if important
if ($quit) { last; }
while ($select->can_read(0)) { #grab any incoming requests during run
$part = $socket->recv($data,1500);
($sport,$client) = sockaddr_in($part);
$packets{inet_ntoa($client)} = [$part,$data];
while (@hdls = $select->can_read(0)) { #grab any incoming requests during run
foreach my $hdl (@hdls) {
if ($hdl == $socket) {
$part = $socket->recv($data,1500);
$packets{$part} = [$part,$data];
} elsif ($hdl == $sslctl) {
update_udpcontext_from_sslctl(udpcontext=>$udpcontext,select=>$select);
}
}
}
#Some of those 'future' packets might be stale dupes of this packet, so...
delete $packets{$pkey}; #Delete any duplicates of current packet
}
if ($quit) { last; }
grant_tcrequests($tcclients,$udpcontext);
}
};
if ($@) {
@@ -695,6 +764,7 @@ if (defined $pid_init) {
close($writepipe);
%cmd_handlers = %{fd_retrieve($readpipe)};
} else {
$$progname = "xcatd: plugin initialization";
scan_plugins($writepipe);
exit(0);
}
@@ -730,17 +800,20 @@ sub generic_reaper {
sub ssl_reaper {
local($!);
my $numdone = 0;
while (($CHILDPID=waitpid(-1,WNOHANG)) > 0) {
if ($immediatechildren{$CHILDPID}) {
delete $immediatechildren{$CHILDPID};
$sslclients--;
$numdone--;
}
$sslclients--;
}
store_fd({clientcountchange=>$numdone,sslclientcount=>$sslclients},$udpctl); #notify udp service of how many clients are active
$SIG{CHLD} = \&ssl_reaper;
}
sub dispatch_reaper {
local($!);
local($!);
while (($CHILDPID =waitpid(-1, WNOHANG)) > 0) {
if ($dispatched_children{$CHILDPID}) {
delete $dispatched_children{$CHILDPID};
@@ -789,16 +862,24 @@ $SIG{TERM} = $SIG{INT} = sub {
alarm(2);
};
socketpair($sslctl, $udpctl,AF_UNIX,SOCK_STREAM,PF_UNSPEC);
my $prevfh = select($udpctl);
$|=1;
select($sslctl);
$|=1;
select($prevfh);
$pid_UDP = xCAT::Utils->xfork;
if (! defined $pid_UDP) {
xCAT::MsgUtils->message("S", "Unable to fork for UDP/TCP");
die;
}
unless ($pid_UDP) {
close($udpctl);
$$progname="xcatd: UDP listener";
do_udp_service;
xexit(0);
}
close($sslctl);
$pid_MON = xCAT::Utils->xfork;
if (! defined $pid_MON) {
xCAT::MsgUtils->message("S", "Unable to fork installmonitor");
@@ -806,6 +887,7 @@ if (! defined $pid_MON) {
}
unless ($pid_MON) {
$$progname="xcatd: install monitor";
close($udpctl);
do_installm_service;
xexit(0);
}
@@ -946,6 +1028,7 @@ until ($quit) {
}
if ($child == 0) {
close($udpctl);
$SIG{TERM} = $SIG{INT} = {};
$SIG{CHLD} = \&generic_reaper; #THROTTLE
$listener->close;
@@ -1023,6 +1106,7 @@ if ($inet6support) {
xexit(0);
}
$sslclients++; #THROTTLE
store_fd({clientcountchange=>1,sslclientcount=>$sslclients},$udpctl); #notify udp service of how many clients are active
$cnnection->close();
}
if (open($mainpidfile,"<","/var/run/xcat/mainservice.pid")) {
@@ -1647,7 +1731,7 @@ sub dispatch_request {
#flock($dlock,LOCK_UN);
if ($errstr) {
if ($numdests == 1) {
dispatch_callback({error=>["Unable to dispatch hierarchical sub-command to ".$ENV{XCATHOST}.". Error: $errstr."],errorcode=>[1]});
dispatch_callback({error=>["Unable to dispatch hierarchical sub-command to ".$ENV{XCATHOST}.". This service node may be down or its xcatd daemon may not be responding."],errorcode=>[1]});
xCAT::MsgUtils->message("S","Error dispatching request to ".$ENV{XCATHOST}.": ".$errstr);
} else {
xCAT::MsgUtils->message("S","Error dispatching request to ".$ENV{XCATHOST}.", trying other service nodes: ".$errstr);
@@ -1861,7 +1945,7 @@ sub service_connection {
my $bytesread;
do { $bytesread=sysread($sock,$line,65536,length($line)) } while ($bytesread);
if (length($line)==0) {
if (not defined $bytesread and (($! == EAGAIN) or ($! == ECHILD))) { next; } #
if (not defined $bytesread and (($! == EAGAIN) or ($! == ECHILD))) { next; } #
last;
}
$flags=fcntl($sock,F_GETFL,0);
@@ -2014,9 +2098,9 @@ sub send_pending_responses {
$blocks += 1;
}
foreach (0..$blocks) {
do {
syswrite($sock,$resp,4096,$_*4096);
} while (($! == EAGAIN) or ($! == ECHILD));
do {
syswrite($sock,$resp,4096,$_*4096);
} while (($! == EAGAIN) or ($! == ECHILD));
}
};
}
+15 -3
View File
@@ -39,10 +39,18 @@
# This command can only be run by a root user.
#
####################################################################
BEGIN
{
$::XCATROOT =
$ENV{'XCATROOT'} ? $ENV{'XCATROOT'}
: -d '/opt/xcat' ? '/opt/xcat'
: '/usr';
}
use lib "$::XCATROOT/lib/perl";
use File::Spec;
use Getopt::Long;
use strict;
require xCAT::MsgUtils;
my $OSname;
my @Commands_array;
my $Command_name;
@@ -193,7 +201,7 @@ sub snap_it {
@files_array = (
"/etc/xcat/*","$::ROOTHOME/.xcat/*", "$INSTALLDIR/autoinst/*",
"$INSTALLDIR/postscripts/*", "$INSTALLDIR/prescripts/*",
"$INSTALLDIR/postscripts/*", "$INSTALLDIR/prescripts/*", "$INSTALLDIR/custom/*",
"/tftpboot/*", "/var/log/consoles/*",
"/etc/*-release", "/etc/dhcpd.conf",
"/var/lib/dhcpd/dhcpd.leases", "/etc/hosts", "/etc/resolv.conf",
@@ -332,7 +340,11 @@ if ($::HELP ) {
exit 0;
}
if ($::VERSION) {
print " xcatsnap tool version 1.0\n";
my $version = xCAT::Utils->Version();
$version .= "\n";
xCAT::MsgUtils->message("N", $version);
exit 0;
exit 0;
}
+1 -1
View File
@@ -109,7 +109,7 @@ until ($mm and $username and $slot) {
}
release_lock(); #done with xcatd, can run with near impunity
$sleepint=10+int(rand(30)); #Stagger sleep to take it easy on AMM/hosting server
exec "ssh -t $username"."@"."$mm";
exec "ssh -t $username"."@"."$mm vsp";
my $pathtochild= dirname($scriptname). "/";
#exec $pathtochild."hpblade.expect";
+3 -3
View File
@@ -51,9 +51,9 @@ import File::Basename;
my $scriptname = $0;
my $cmdref={
command=>"getcons",
arg=>"text",
noderange=>$ARGV[0]
command=>["getcons"],
arg=>["text"],
noderange=>[$ARGV[0]]
};
use Data::Dumper;
my $dsthost;
@@ -0,0 +1,10 @@
#Please make sure there is a space between @ and group name
yp-tools
wget
vim-minimal
ntpdate
nfs-utils
rsync
net-tools
openssh-server
util-linux-ng
@@ -0,0 +1,156 @@
#egan@us.ibm.com
#
#cmdline
lang en_US
#
# Where's the source?
# nfs --server hostname.of.server or IP --dir /path/to/RH/CD/image
#
#nfs --server #XCATVAR:INSTALL_NFS# --dir #XCATVAR:INSTALL_SRC_DIR#
%include /tmp/repos
#device ethernet e100
keyboard "us"
#
# Clear the MBR
#
zerombr
#
# Wipe out the disk
#
clearpart --all --initlabel
#clearpart --linux
#key --skip
#
# Customize to fit your needs
#
#XCAT_PARTITION_START#
#No RAID
#/boot really significant for this sort of setup nowadays?
#part /boot --size 50 --fstype ext3
%include /tmp/partitioning
#XCAT_PARTITION_END#
#RAID 0 /scr for performance
#part / --size 1024 --ondisk sda
#part swap --size 512 --ondisk sda
#part /var --size 1024 --ondisk sdb
#part swap --size 512 --ondisk sdb
#part raid.01 --size 1 --grow --ondisk sda
#part raid.02 --size 1 --grow --ondisk sdb
#raid /scr --level 0 --device md0 raid.01 raid.02
#Full RAID 1 Sample
#part raid.01 --size 50 --ondisk sda
#part raid.02 --size 50 --ondisk sdb
#raid /boot --level 1 --device md0 raid.01 raid.02
#
#part raid.11 --size 1024 --ondisk sda
#part raid.12 --size 1024 --ondisk sdb
#raid / --level 1 --device md1 raid.11 raid.12
#
#part raid.21 --size 1024 --ondisk sda
#part raid.22 --size 1024 --ondisk sdb
#raid /var --level 1 --device md2 raid.21 raid.22
#
#part raid.31 --size 1024 --ondisk sda
#part raid.32 --size 1024 --ondisk sdb
#raid swap --level 1 --device md3 raid.31 raid.32
#
#part raid.41 --size 1 --grow --ondisk sda
#part raid.42 --size 1 --grow --ondisk sdb
#raid /scr --level 1 --device md4 raid.41 raid.42
#
# bootloader config
# --append <args>
# --useLilo
# --md5pass <crypted MD5 password for GRUB>
#
bootloader
#
# install or upgrade
#
install
#
# text mode install (default is graphical)
#
text
#
# firewall
#
firewall --disabled
#
# mouse selection
#
#mouse genericps/2 --emulthree
#
# Select a zone
# Add the --utc switch if your hardware clock is set to GMT
#
#timezone US/Hawaii
#timezone US/Pacific
#timezone US/Mountain
#timezone US/Central
#timezone US/Eastern
timezone --utc "#TABLE:site:key=timezone:value#"
#
# Don't do X
#
skipx
#
# To generate an encrypted root password use:
#
# perl -e 'print crypt("blah","Xa") . "\n";'p
# openssl passwd -apr1 -salt xxxxxxxx password
#
# where "blah" is your root password.
#
#rootpw --iscrypted XaLGAVe1C41x2
#rootpw XaLGAVe1C41x2 --iscrypted
rootpw --iscrypted #CRYPT:passwd:key=system,username=root:password#
#
# NIS setup: auth --enablenis --nisdomain sensenet
# --nisserver neptune --useshadow --enablemd5
#
# OR
auth --useshadow --enablemd5
#
# SE Linux
#
selinux --disabled
#
# Reboot after installation
#
reboot
#
#end of section
#
%packages --ignoremissing
#INCLUDE_DEFAULT_PKGLIST#
%end
%pre
#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/pre.rh#
%end
%post
#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/post.rh#
%end
@@ -0,0 +1,148 @@
#
#cmdline
lang en_US
#
# Where's the source?
# nfs --server hostname.of.server or IP --dir /path/to/RH/CD/image
#
#nfs --server #XCATVAR:INSTALL_NFS# --dir #XCATVAR:INSTALL_SRC_DIR#
url --url http://#TABLE:noderes:$NODE:nfsserver#/install/#TABLE:nodetype:$NODE:os#/#TABLE:nodetype:$NODE:arch#
#device ethernet e100
keyboard "us"
#
# Clear the MBR
#
zerombr
#
# Wipe out the disk
#
clearpart --all --initlabel
#clearpart --linux
key --skip
#
# Customize to fit your needs
#
#XCAT_PARTITION_START#
#No RAID
#/boot really significant for this sort of setup nowadays?
#part /boot --size 50 --fstype ext3
%include /tmp/partitioning
#part swap --size 1024
#part / --size 1 --grow --fstype ext4
#XCAT_PARTITION_END#
#RAID 0 /scr for performance
#part / --size 1024 --ondisk sda
#part swap --size 512 --ondisk sda
#part /var --size 1024 --ondisk sdb
#part swap --size 512 --ondisk sdb
#part raid.01 --size 1 --grow --ondisk sda
#part raid.02 --size 1 --grow --ondisk sdb
#raid /scr --level 0 --device md0 raid.01 raid.02
#Full RAID 1 Sample
#part raid.01 --size 50 --ondisk sda
#part raid.02 --size 50 --ondisk sdb
#raid /boot --level 1 --device md0 raid.01 raid.02
#
#part raid.11 --size 1024 --ondisk sda
#part raid.12 --size 1024 --ondisk sdb
#raid / --level 1 --device md1 raid.11 raid.12
#
#part raid.21 --size 1024 --ondisk sda
#part raid.22 --size 1024 --ondisk sdb
#raid /var --level 1 --device md2 raid.21 raid.22
#
#part raid.31 --size 1024 --ondisk sda
#part raid.32 --size 1024 --ondisk sdb
#raid swap --level 1 --device md3 raid.31 raid.32
#
#part raid.41 --size 1 --grow --ondisk sda
#part raid.42 --size 1 --grow --ondisk sdb
#raid /scr --level 1 --device md4 raid.41 raid.42
#
# bootloader config
# --append <args>
# --useLilo
# --md5pass <crypted MD5 password for GRUB>
#
bootloader
#
# install or upgrade
#
install
#
# text mode install (default is graphical)
#
#text
#
# firewall
#
firewall --disabled
#
# Select a zone
# Add the --utc switch if your hardware clock is set to GMT
#
#timezone US/Hawaii
#timezone US/Pacific
#timezone US/Mountain
#timezone US/Central
#timezone US/Eastern
timezone --utc "#TABLE:site:key=timezone:value#"
#
# Don't do X
#
skipx
#
# To generate an encrypted root password use:
#
# perl -e 'print crypt("blah","Xa") . "\n";'p
# openssl passwd -apr1 -salt xxxxxxxx password
#
# where "blah" is your root password.
#
#rootpw --iscrypted XaLGAVe1C41x2
#rootpw XaLGAVe1C41x2 --iscrypted
rootpw --iscrypted #CRYPT:passwd:key=system,username=root:password#
#
# NIS setup: auth --enablenis --nisdomain sensenet
# --nisserver neptune --useshadow --enablemd5
#
# OR
auth --useshadow --enablemd5
#
# SE Linux
#
selinux --disabled
#
# Reboot after installation
#
reboot
#
#end of section
#
%packages
#INCLUDE_DEFAULT_PKGLIST#
%pre
#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/pre.rh#
%post
#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/post.rh#
@@ -0,0 +1,38 @@
#Please make sure there is a space between @ and group name
autofs
ksh
tcsh
ntp
tftp
xinetd
rsh
rsh-server
psacct
nfs-utils
net-snmp
rsync
yp-tools
ypserv
ypbind
m4
sendmail-cf
gdb
binutils
openssh-server
util-linux
compat-libstdc++-33
-kernel-xen
-kmod-cmirror-xen
-xen-devel
-kmod-gnbd-xen
-xen
-libvirt-devel
-libvirt-cim
-gnome-applet-vm
-kmod-gfs-xen
-xen-libs
-libvirt
-virt-viewer
-libvirt-python
-python-virtinst
-virt-manager
+16 -1
View File
@@ -13,6 +13,8 @@ if [ -r /tmp/updates/etc/pki/tls/certs/ca-bundle.crt ]; then
cp -f /tmp/updates/etc/pki/tls/certs/ca-bundle.crt /etc/pki/tls/certs/
fi
cat >/tmp/baz.py <<EOF
#!/usr/bin/python
import socket
@@ -150,7 +152,11 @@ if [ -z "$NODESTATUS" ] || [ "$NODESTATUS" != "0" -a "$NODESTATUS" != "N" -a
fi
/tmp/foo.py >/foo.log 2>&1 &
#time to ascertain fstype and PReP/UEFI/legacy
#also, find first available block device (sda or vda likely)
#TODO: pick a likely non-SAN target if possible
@@ -163,6 +169,7 @@ for disk in /dev/vd*[^0-9];do
break
fi
done
if [ -z "$instdisk" ]; then
for disk in /dev/sd*[^0-9]; do
eddname=$(/lib/udev/edd_id $disk 2> /dev/null)
@@ -184,6 +191,7 @@ if [ -z "$instdisk" ]; then
esac
done
fi
if [ -z "$instdisk" ]; then
if [ ! -z "$firstdirectdisk" ]; then
instdisk=$firstdirectdisk
@@ -204,6 +212,7 @@ elif grep ext4 /proc/filesystems > /dev/null; then
else
FSTYPE=ext3
fi
if [ `uname -m` = "ppc64" ]; then
echo 'part None --fstype "PPC PReP Boot" --ondisk '$instdisk' --size 8' >> /tmp/partitioning
fi
@@ -218,9 +227,15 @@ echo "part / --size 1 --grow --ondisk $instdisk --fstype $FSTYPE" >> /tmp/partit
#XCA_PARTITION_SCRIPT#
# The following code is to generate the repository for the installation
cat /proc/cmdline
export nextserver=`cat /proc/cmdline | grep http | head -n 1 | cut -d / -f 3 | cut -d : -f 1`
NEXTSERVER=`cat /proc/cmdline | grep http | head -n 1`
NEXTSERVER=${NEXTSERVER#*http://}
NEXTSERVER=${NEXTSERVER%%:*}
export nextserver=$NEXTSERVER
#INSTALL_SOURCES_IN_PRE#

Some files were not shown because too many files have changed in this diff Show More