diff --git a/.travis.yml b/.travis.yml index a04874d6c..25ab2393e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ sudo: required before_install: - sudo apt-get install -y git reprepro devscripts debhelper libsoap-lite-perl libdbi-perl quilt openssh-server dpkg looptools genometools software-properties-common - perl -v +- echo "yes" | sudo cpan -f -i Capture::Tiny script: - echo $TRAVIS_BUILD_ID diff --git a/build-ubunturepo b/build-ubunturepo index 4d1fbfb04..65e44c88d 100755 --- a/build-ubunturepo +++ b/build-ubunturepo @@ -338,7 +338,7 @@ __EOF__ echo "SignWith: yes" >> conf/distributions echo "" >> conf/distributions fi - done + done cat << __EOF__ > conf/options verbose @@ -457,15 +457,18 @@ Architectures: $tmp_out_arch Components: main Description: Repository automatically genereted conf __EOF__ + + if [ "$GPGSIGN" = "0" ];then + echo "GPGSIGN=$GPGSIGN specified, the repo will not be signed" + echo "" >> conf/distributions + else + echo "SignWith: yes" >> conf/distributions + echo "" >> conf/distributions + fi + done - if [ "$GPGSIGN" = "0" ];then - echo "GPGSIGN=$GPGSIGN specified, the repo will not be signed" - echo "" >> conf/distributions - else - echo "SignWith: yes" >> conf/distributions - echo "" >> conf/distributions - fi + cat << __EOF__ > conf/options verbose diff --git a/docs/source/guides/admin-guides/references/man5/bootparams.5.rst b/docs/source/guides/admin-guides/references/man5/bootparams.5.rst index e6596fcb4..13f261616 100644 --- a/docs/source/guides/admin-guides/references/man5/bootparams.5.rst +++ b/docs/source/guides/admin-guides/references/man5/bootparams.5.rst @@ -62,7 +62,7 @@ bootparams Attributes: \ **addkcmdline**\ - User specified one or more parameters to be passed to the kernel. For the kernel options need to be persistent after installation, specify them with prefix "R::" + User specified kernel options for os provision process(no prefix) or the provisioned os(with prefix "R::"). The options should be delimited with spaces(" ") diff --git a/docs/source/guides/admin-guides/references/man5/linuximage.5.rst b/docs/source/guides/admin-guides/references/man5/linuximage.5.rst index 74810be1c..66569e8c4 100644 --- a/docs/source/guides/admin-guides/references/man5/linuximage.5.rst +++ b/docs/source/guides/admin-guides/references/man5/linuximage.5.rst @@ -56,7 +56,7 @@ linuximage Attributes: \ **addkcmdline**\ - User specified arguments to be passed to the kernel. The user arguments are appended to xCAT.s default kernel arguments. For the kernel options need to be persistent after installation, specify them with prefix "R::". This attribute is ignored if linuximage.boottarget is set. + User specified kernel options for os provision process(no prefix) or the provisioned os(with prefix "R::"). The options should be delimited with spaces(" "). This attribute is ignored if linuximage.boottarget is set. diff --git a/docs/source/guides/admin-guides/references/man5/site.5.rst b/docs/source/guides/admin-guides/references/man5/site.5.rst index 9e48d38c2..7fb2bf6cc 100644 --- a/docs/source/guides/admin-guides/references/man5/site.5.rst +++ b/docs/source/guides/admin-guides/references/man5/site.5.rst @@ -110,8 +110,9 @@ site Attributes: dhcplease: The lease time for the dhcp client. The default value is 43200. disjointdhcps: If set to '1', the .leases file on a service node only contains - the nodes it manages. The default value is '0'. - '0' value means include all the nodes in the subnet. + the nodes it manages. And when 'sharedtftp' is disabled, nodeset handles + boot loader configuration on a service node only for the nodes it manages. + The default value is '0'. It means include all the nodes in the subnet. pruneservices: Whether to enable service pruning when noderm is run (i.e. removing DHCP entries when noderm is executed) diff --git a/docs/source/guides/admin-guides/references/man8/nodeset.8.rst b/docs/source/guides/admin-guides/references/man8/nodeset.8.rst index 1186b8b91..aeb8275c6 100644 --- a/docs/source/guides/admin-guides/references/man8/nodeset.8.rst +++ b/docs/source/guides/admin-guides/references/man8/nodeset.8.rst @@ -19,7 +19,7 @@ Name **************** -\ **nodeset**\ \ *noderange*\ [\ **boot**\ | \ **stat**\ | \ **offline**\ | \ **runcmd=bmcsetup**\ | \ **osimage**\ [=\ *imagename*\ ] | \ **shell**\ | \ **shutdown**\ ] [\ **-V | -**\ **-verbose**\ ] +\ **nodeset**\ \ *noderange*\ [\ **boot**\ | \ **stat**\ [\ **-a**\ ]| \ **offline**\ | \ **runcmd=bmcsetup**\ | \ **osimage**\ [=\ *imagename*\ ] | \ **shell**\ | \ **shutdown**\ ] [\ **-V | -**\ **-verbose**\ ] \ **nodeset**\ \ *noderange*\ \ **osimage**\ [=\ *imagename*\ ] [\ **-**\ **-noupdateinitrd**\ ] [\ **-**\ **-ignorekernelchk**\ ] @@ -109,7 +109,7 @@ A user can supply their own scripts to be run on the mn or on the service node ( \ **stat**\ - Display the current boot loader config file description for the nodes requested + Display the current boot loader config file description for the nodes requested. When \ **disjointdhcps**\ is set, using \ **-a**\ to display them on all available service nodes. diff --git a/perl-xCAT/xCAT/NetworkUtils.pm b/perl-xCAT/xCAT/NetworkUtils.pm index d54bf253b..9b65054a2 100755 --- a/perl-xCAT/xCAT/NetworkUtils.pm +++ b/perl-xCAT/xCAT/NetworkUtils.pm @@ -1645,10 +1645,14 @@ sub getNodeIPaddress { require xCAT::Table; my $nodetocheck = shift; - my $port = shift; - my $nodeip; + if ($nodetocheck eq 'xCAT::NetworkUtils') { #was called with -> syntax + $nodetocheck = shift; + } - $nodeip = xCAT::NetworkUtils->getipaddr($nodetocheck); + # Quick return if pass in an IP + return $nodetocheck if (xCAT::NetworkUtils->isIpaddr($nodetocheck)); + + my $nodeip = xCAT::NetworkUtils->getipaddr($nodetocheck); if (!$nodeip) { my $hoststab = xCAT::Table->new('hosts'); @@ -1666,6 +1670,51 @@ sub getNodeIPaddress } +#------------------------------------------------------------------------------- + +=head3 checkNodeIPaddress + Arguments: + Node name only one at a time + Returns: a hash object contains IP or Error + Globals: + none + Example: my $ipresult = xCAT::NetworkUtils::checkNodeIPaddress($nodetocheck); + +=cut + +#------------------------------------------------------------------------------- + +sub checkNodeIPaddress +{ + require xCAT::Table; + my $nodetocheck = shift; + if ($nodetocheck eq 'xCAT::NetworkUtils') { #was called with -> syntax + $nodetocheck = shift; + } + my $ret; + + my $nodeip; + my $hoststab = xCAT::Table->new('hosts'); + my $ent = $hoststab->getNodeAttribs($nodetocheck, ['ip']); + if ($ent->{'ip'}) { + $nodeip = $ent->{'ip'}; + } + + # Get the IP from DNS + my $dnsip = xCAT::NetworkUtils->getipaddr($nodetocheck); + if (!$dnsip) + { + $ret->{'error'} = "The $nodetocheck can not be resolved."; + $ret->{'ip'} = $nodeip if ($nodeip); + } elsif (!$nodeip) { + $ret->{'ip'} = $dnsip; + } else { + $ret->{'ip'} = $nodeip; + $ret->{'error'} = "Defined IP address of $nodetocheck is inconsistent with DNS." if ($nodeip ne $dnsip); + } + return $ret; +} + #------------------------------------------------------------------------------- diff --git a/perl-xCAT/xCAT/Schema.pm b/perl-xCAT/xCAT/Schema.pm index 832c8566d..2dfdb7076 100755 --- a/perl-xCAT/xCAT/Schema.pm +++ b/perl-xCAT/xCAT/Schema.pm @@ -331,8 +331,8 @@ passed as argument rather than by table value', 'kernel' => 'The kernel that network boot actions should currently acquire and use. Note this could be a chained boot loader such as memdisk or a non-linux boot loader', 'initrd' => 'The initial ramdisk image that network boot actions should use (could be a DOS floppy or hard drive image if using memdisk as kernel)', 'kcmdline' => 'Arguments to be passed to the kernel', -'addkcmdline' => 'User specified one or more parameters to be passed to the kernel. For the kernel options need to be persistent after installation, specify them with prefix "R::"', -'dhcpstatements' => 'xCAT manipulated custom dhcp statements (not intended for user manipulation)', + 'addkcmdline' => 'User specified kernel options for os provision process(no prefix) or the provisioned os(with prefix "R::"). The options should be delimited with spaces(" ")', + 'dhcpstatements' => 'xCAT manipulated custom dhcp statements (not intended for user manipulation)', 'adddhcpstatements' => 'Custom dhcp statements for administrator use (not implemneted yet)', comments => 'Any user-written notes.', disable => "Set to 'yes' or '1' to comment out this row.", @@ -799,7 +799,7 @@ passed as argument rather than by table value', imagename => 'The name of this xCAT OS image definition.', template => 'The fully qualified name of the template file that will be used to create the OS installer configuration file for stateful installations (e.g. kickstart for RedHat, autoyast for SLES).', boottarget => 'The name of the boottarget definition. When this attribute is set, xCAT will use the kernel, initrd and kernel params defined in the boottarget definition instead of the default.', - addkcmdline => 'User specified arguments to be passed to the kernel. The user arguments are appended to xCAT.s default kernel arguments. For the kernel options need to be persistent after installation, specify them with prefix "R::". This attribute is ignored if linuximage.boottarget is set.', + addkcmdline => 'User specified kernel options for os provision process(no prefix) or the provisioned os(with prefix "R::"). The options should be delimited with spaces(" "). This attribute is ignored if linuximage.boottarget is set.', pkglist => 'The fully qualified name of the file that stores the distro packages list that will be included in the image. Make sure that if the pkgs in the pkglist have dependency pkgs, the dependency pkgs should be found in one of the pkgdir', pkgdir => 'The name of the directory where the distro packages are stored. It could be set to multiple paths. The multiple paths must be separated by ",". The first path in the value of osimage.pkgdir must be the OS base pkg dir path, such as pkgdir=/install/rhels6.2/x86_64,/install/updates . In the os base pkg path, there are default repository data. And in the other pkg path(s), the users should make sure there are repository data. If not, use "createrepo" command to create them. For ubuntu, multiple mirrors can be specified in the pkgdir attribute, the mirrors must be prefixed by the protocol(http/ssh) and delimited with "," between each other.', otherpkglist => 'The fully qualified name of the file that stores non-distro package lists that will be included in the image. It could be set to multiple paths. The multiple paths must be separated by ",".', @@ -1029,8 +1029,9 @@ passed as argument rather than by table value', " dhcpsetup: If set to 'n', it will skip the dhcp setup process in the nodeset cmd.\n\n" . " dhcplease: The lease time for the dhcp client. The default value is 43200.\n\n" . " disjointdhcps: If set to '1', the .leases file on a service node only contains\n" . -" the nodes it manages. The default value is '0'.\n" . -" '0' value means include all the nodes in the subnet.\n\n" . +" the nodes it manages. And when 'sharedtftp' is disabled, nodeset handles\n" . +" boot loader configuration on a service node only for the nodes it manages.\n" . +" The default value is '0'. It means include all the nodes in the subnet.\n\n" . " pruneservices: Whether to enable service pruning when noderm is run (i.e.\n" . " removing DHCP entries when noderm is executed)\n\n" . " managedaddressmode: The mode of networking configuration during node provision.\n" . diff --git a/perl-xCAT/xCAT/Scope.pm b/perl-xCAT/xCAT/Scope.pm index a7aaf2588..39bb3da44 100644 --- a/perl-xCAT/xCAT/Scope.pm +++ b/perl-xCAT/xCAT/Scope.pm @@ -2,6 +2,7 @@ package xCAT::Scope; use xCAT::Utils; use xCAT::Table; +use xCAT::TableUtils; use xCAT::ServiceNodeUtils qw(getSNList); @@ -125,16 +126,17 @@ sub get_parallel_scope { =head3 get_broadcast_scope_with_parallel Convert a request object to an array of multiple requests according to the - splitted node range. + splitted node range. Also it replicates the requests to all required service + nodes or management node. Arguments: Reference of request - Callback: TODO, Optional, the Callback will be used to filter the nodes + SN list: Array of target service nodes Returns: An array of requests Error: none Example: - my $reqs = xCAT::Scope->get_broadcast_scope($request); + my $reqs = xCAT::Scope->get_broadcast_scope_with_parallel($request, \@snlist); =cut #----------------------------------------------------------------------------- @@ -145,25 +147,118 @@ sub get_broadcast_scope_with_parallel { } #Exit if the packet has been preprocessed in its history if ($req->{_xcatpreprocessed}->[0] == 1) { return [$req]; } + $req->{_xcatpreprocessed}->[0] = 1; - #Handle the one for current management/service node - my $reqs = get_parallel_scope($req); - my @requests = @$reqs; + my $snlist = shift; - #Broadcast the request to other management/service nodes - foreach (xCAT::ServiceNodeUtils->getSNList()) { - if (xCAT::NetworkUtils->thishostisnot($_)) { - my $xcatdest = $_; - my $reqcopy = {%$req}; - $reqcopy->{'_xcatdest'} = $_; - $reqcopy->{_xcatpreprocessed}->[0] = 1; - #Apply callback to filter the node range in future. - $reqs = get_parallel_scope($reqcopy); - foreach (@$reqs) { - push @requests, {%$_}; - } + my $reqs = get_parallel_scope($req); + + my @requests = (); # The request array will be return. + push @requests, @$reqs; + + # when this method is called on service node, it is required to broadcast to MN too. + # get site.master from DB in order to dispatch to MN ( MN will not be added in servicenode table) + if ( xCAT::Utils->isServiceNode() ) { + my @entries = xCAT::TableUtils->get_site_attribute("master"); + my $master = $entries[0]; + foreach (@$reqs) { + my $reqcopy = {%$_}; + $reqcopy->{'_xcatdest'} = $master; + push @requests, $reqcopy; } } + + #Broadcast the request to all service nodes + foreach (@$snlist) { + my $xcatdest = $_; + next unless (xCAT::NetworkUtils->thishostisnot($xcatdest)); + + foreach (@$reqs) { + my $reqcopy = {%$_}; + $reqcopy->{'_xcatdest'} = $xcatdest; + push @requests, $reqcopy; + } + } + return \@requests; +} + +#----------------------------------------------------------------------------- + +=head3 get_broadcast_disjoint_scope_with_parallel + + Convert a request object to an array of multiple requests according to the + splitted node range. Also it replicates the requests to all required service + nodes or management node, but the request to a service node will only contains + the node range it manages. + + Arguments: + Reference of request + SN hash: Hash of target service nodes => Managed CNs + Special servers: Array of servers, those servers are required to handle whole noderange. + Returns: An array of requests + Error: + none + Example: + my $reqs = xCAT::Scope->get_broadcast_disjoint_scope_with_parallel($request, \@snhash); +=cut + +#----------------------------------------------------------------------------- +sub get_broadcast_disjoint_scope_with_parallel { + my $req = shift; + if ($req =~ /xCAT::Scope/) { + $req = shift; + } + #Exit if the packet has been preprocessed in its history + if ($req->{_xcatpreprocessed}->[0] == 1) { return [$req]; } + $req->{_xcatpreprocessed}->[0] = 1; + + my $sn_hash = shift; + my $extras = shift; + + my @requests = (); # The request array will be return. + my $reqs = get_parallel_scope($req); + + my $handled4me = 0; # indicate myself is already handled. + my %prehandledhash = ();# the servers which is already handled. + foreach (@$extras) { + my $xcatdest = $_; + if (xCAT::NetworkUtils->thishostisnot($xcatdest)) { + # TODO, To avoid sending request to a multi-home server many times. + foreach (@$reqs) { + my $reqcopy = {%$_}; + $reqcopy->{'_xcatdest'} = $xcatdest; + push @requests, $reqcopy; + } + $prehandledhash{$xcatdest} = 1; + } elsif ($handled4me == 0) { + push @requests, @$reqs; + $handled4me = 1; + } + } + + #Broadcast the request to all available service nodes + foreach (keys %$sn_hash) { + my $xcatdest = $_; + # to check if the SN already handled + next if (exists($prehandledhash{$xcatdest})); + + if (xCAT::NetworkUtils->thishostisnot($xcatdest)) { + my $reqcopy = {%$req}; + $reqcopy->{'_xcatdest'} = $xcatdest; + $reqcopy->{'node'} = $sn_hash->{$xcatdest}; + + $reqs = get_parallel_scope($reqcopy); + push @requests, @$reqs; + } elsif ($handled4me == 0) { + my $reqcopy = {%$req}; + $reqcopy->{'node'} = $sn_hash->{$xcatdest}; + + $reqs = get_parallel_scope($reqcopy); + push @requests, @$reqs; + $handled4me = 1; + } + } + return \@requests; } diff --git a/perl-xCAT/xCAT/Usage.pm b/perl-xCAT/xCAT/Usage.pm index 82ac2eff8..94b1c94af 100755 --- a/perl-xCAT/xCAT/Usage.pm +++ b/perl-xCAT/xCAT/Usage.pm @@ -484,7 +484,7 @@ Options: "Usage: Common: nodeset [-h|--help|-v|--version] - nodeset [shell|boot|runcmd=bmcsetup|osimage[=]|offline|shutdown|stat]", + nodeset [shell|boot|runcmd=bmcsetup|osimage[=]|offline|shutdown|stat [-a]]", "rmflexnode" => "Usage: rmflexnode [-h|--help|-v|--version] diff --git a/xCAT-client/bin/pgsqlsetup b/xCAT-client/bin/pgsqlsetup index 7446f7aeb..5e9152c3c 100755 --- a/xCAT-client/bin/pgsqlsetup +++ b/xCAT-client/bin/pgsqlsetup @@ -760,7 +760,7 @@ sub initpgdb { $insertstr .= "host all all "; $insertstr .= $hbaaccess; - $insertstr .= "\/32 md5\n "; # add entry line to string + $insertstr .= "\/32 md5\\n "; # add entry line to string } } $cmd = "awk '{gsub(\"\IPv4 local connections:\",\"\IPv4 local connections:\\n$insertstr \"); print}' $hbafile > $hbafile.xcat"; diff --git a/xCAT-client/bin/rinstall b/xCAT-client/bin/rinstall index 8ca3357ec..d23b65f94 100755 --- a/xCAT-client/bin/rinstall +++ b/xCAT-client/bin/rinstall @@ -21,6 +21,7 @@ use Getopt::Long; use xCAT::MsgUtils; use xCAT::Utils; use xCAT::Client; +use xCAT::NodeRange; use Cwd; use strict; @@ -65,7 +66,18 @@ while ($arg =~ /^-/) { $cmdref->{noderange}->[0] = $arg; push(@{ $cmdref->{arg} }, @ARGV); +my $startconsole=0; +if(grep m/^-c|--console$/,@ARGV){ + $startconsole=1; +} + my $noderange = $cmdref->{noderange}->[0]; # save the noderange +my @noderange=xCAT::NodeRange::noderange($noderange); + +if($bname eq "rinstall" and $startconsole==1 and scalar @noderange!=1 ){ + xCAT::MsgUtils->message("E", "Error: rinstall can only be run against one node! Please use winstall for multiple nodes."); + exit 1; +} # Allow to print server information when -V/--verbose foreach (reverse(@ARGV)) { @@ -77,11 +89,8 @@ foreach (reverse(@ARGV)) { # ok call Client to run the plugin rinstall.pm xCAT::Client::submit_request($cmdref, \&xCAT::Client::handle_response); - if ($xCAT::Client::EXITCODE == 0) # no errors { - my $startconsole = $cmdref->{startconsole}->[0]; - # if startconsole requested ( -c flag) for rinstall always for winstall # This is set in the rinstall plugin if ($startconsole == 1) { @@ -90,9 +99,7 @@ if ($xCAT::Client::EXITCODE == 0) # no errors exec("rcons $noderange"); } elsif (basename($0) =~ /winstall/) { - # winstall can commence a wcons command to the noderange for monitoring the provision cycle - exec("wcons $noderange"); } } diff --git a/xCAT-client/pods/man8/nodeset.8.pod b/xCAT-client/pods/man8/nodeset.8.pod index bd53594fd..bf6692de5 100644 --- a/xCAT-client/pods/man8/nodeset.8.pod +++ b/xCAT-client/pods/man8/nodeset.8.pod @@ -4,7 +4,7 @@ B - set the boot state for a noderange =head1 B -B I [B | B | B | B | B[=I] | B | B] [B<-V>|B<--verbose>] +B I [B | B [B<-a>]| B | B | B[=I] | B | B] [B<-V>|B<--verbose>] B I B[=I] [B<--noupdateinitrd>] [B<--ignorekernelchk>] @@ -76,7 +76,7 @@ If you would like to run a task after deployment, you can define that task with =item B -Display the current boot loader config file description for the nodes requested +Display the current boot loader config file description for the nodes requested. When B is set, using B<-a> to display them on all available service nodes. =item B diff --git a/xCAT-genesis-builder/buildrpm b/xCAT-genesis-builder/buildrpm index 45de0953a..2b4a42964 100755 --- a/xCAT-genesis-builder/buildrpm +++ b/xCAT-genesis-builder/buildrpm @@ -5,7 +5,7 @@ # this whole dir into it somewhere (like /tmp). # Then run this script. The optional 1st arg should be mcp if you are building against mcp. -# Currently, *Fedora 23* is the only OS supported to build genesis-base for ppc64, and Centos 6.5 for x86_64 +# Currently, *Fedora 26* is the only OS supported to build genesis-base for ppc64, and Centos 6.5 for x86_64 HOSTOS="$1" DIR=`dirname $0` @@ -18,37 +18,9 @@ if [ $BUILDARCH = "ppc64le" ]; then BUILDARCH="ppc64" fi -# For xcat-genesis-base-ppc64, we need to update mlx4-en driver for Mellanox ethernet nics. -# IF you are sure you have installed newer driver on the build server you can use 'buildrpm -y' to skip the nodification if [ -z $1 ]; then - HOSTOS="fedora23" + HOSTOS="fedora26" fi -if [ $BUILDARCH = 'ppc64' -a $HOSTOS != 'mcp' -a $HOSTOS != '-y' ]; then - echo "The steps below are used to install mlnx driver 3.2-1 and i40e driver 1.5.16, if you are sure you have these or newer drivers, pls use \"-y\" to skip!" - echo "1. Install OS related packages" - echo " yum install rpmbuild" - echo " yum install kernel-devel-`uname -r`" - echo " yum install kernel-headers-`uname -r`" - echo " yum install gcc-c++" - echo "2. Download Mellanox EN Driver for Linux from http://www.mellanox.com/downloads/Drivers/mlnx-en-3.2-1.0.1.1.tgz" - echo " Download Intel EN Driver follow this link and download from webpage https://downloadcenter.intel.com/downloads/eula/26370/Intel-Network-Adapter-Driver-for-PCI-E-Intel-40-Gigabit-Ethernet-Network-Connections-under-Linux-?httpDown=https%3A%2F%2Fdownloadmirror.intel.com%2F26370%2Feng%2Fi40e-1.5.16.tar.gz" - echo "3. To install Mellanox Driver, extract it and run ./install.sh from the extracted directory" - echo " tar -xvf mlnx-en-3.2-1.0.1.1.tgz" - echo " ./mlnx-en-3.2-1.0.1.1/install.sh" - echo " To install Intel Driver, create rpm and install" - echo " rpmbuild -tb i40e-1.5.16.tar.gz" - echo " rpm -i //i40e-1.5.16-1.ppc64le.rpm" - echo " Additional Intel instructions can be found in README included in i40e-1.5.16.tar.gz" - echo "4. Check whether the drivers are updated" - echo " modprobe mlx4-en" - echo " modinfo mlx4-en | grep version" - echo " version: 3.2-1.0.1.1 (31 Jan 2016)" - echo " modinfo i40e | grep version" - echo " version: 1.5.16" - echo "5. Once the steps above done, run \"$0 -y\" to build xCAT-genesis-base-ppc64" - exit 0 -fi - # get the input files for dracut in the right place # Fedora 20 ppc64 uses /usr/lib/dracut/modules.d diff --git a/xCAT-genesis-builder/xCAT-genesis-base.spec b/xCAT-genesis-builder/xCAT-genesis-base.spec index 95e1e719d..f716c87db 100755 --- a/xCAT-genesis-builder/xCAT-genesis-base.spec +++ b/xCAT-genesis-builder/xCAT-genesis-base.spec @@ -37,6 +37,7 @@ Packager: IBM Corp. %Description xCAT genesis (Genesis Enhanced Netboot Environment for System Information and Servicing) is a small, embedded-like environment for xCAT's use in discovery and management actions when interaction with an OS is infeasible. This package comprises the base platform with most of the xCAT specific behavior left to xCAT-genesis-scripts package. +Built in environment "%dist" on %{_arch}. %Prep diff --git a/xCAT-server/lib/xcat/plugins/grub2.pm b/xCAT-server/lib/xcat/plugins/grub2.pm index f6600d22c..03482eeb4 100644 --- a/xCAT-server/lib/xcat/plugins/grub2.pm +++ b/xCAT-server/lib/xcat/plugins/grub2.pm @@ -1,6 +1,6 @@ # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html package xCAT_plugin::grub2; -use Data::Dumper; + use Sys::Syslog; use xCAT::Scope; use xCAT::Utils; @@ -123,12 +123,10 @@ sub setstate { # We are in the service node pools, print error if no facing ip. if (xCAT::InstUtils->is_me($sn)) { - my @myself = xCAT::NetworkUtils->determinehostname(); - my $myname = $myself[ (scalar @myself) - 1 ]; $::callback->( { error => [ - "$myname: $ipfnd[1] on service node $sn" + "$::myxcatname: $ipfnd[1] on service node $sn" ], errorcode => [1] } @@ -140,7 +138,7 @@ sub setstate { $::callback->( { error => [ - "$myname: $ipfnd[1]" + "$::myxcatname: $ipfnd[1]" ], errorcode => [1] } @@ -176,9 +174,9 @@ sub setstate { $kern->{kcmdline} .= " " . $cmdhashref->{volatile}; } - my $pcfg; - unless (-d "$tftpdir/boot/grub2") { - mkpath("$tftpdir/boot/grub2"); + my $bootloader_root = "$tftpdir/boot/grub2"; + unless (-d "$bootloader_root") { + mkpath("$bootloader_root"); } my $nodemac; my %client_nethash = xCAT::DBobjUtils->getNetwkInfo([$node]); @@ -186,9 +184,10 @@ sub setstate { my $cref = $chainhash{$node}->[0]; #$chaintab->getNodeAttribs($node,['currstate']); # remove the old boot configuration files and create a new one, but only if not offline directive - system("find $tftpdir/boot/grub2/ -inum \$(stat --printf \%i $tftpdir/boot/grub2/$node 2>/dev/null) -exec rm -f {} \\; 2>/dev/null"); + system("find $bootloader_root/ -inum \$(stat --printf \%i $bootloader_root/$node 2>/dev/null) -exec rm -f {} \\; 2>/dev/null"); + my $pcfg; if ($cref and $cref->{currstate} ne "offline") { - open($pcfg, '>', $tftpdir . "/boot/grub2/" . $node); + open($pcfg, '>', "$bootloader_root/" . $node); print $pcfg "#" . $cref->{currstate} . "\n"; if (($::XCATSITEVALS{xcatdebugmode} eq "1") or ($::XCATSITEVALS{xcatdebugmode} eq "2")) { @@ -294,11 +293,6 @@ sub setstate { print $pcfg "}"; close($pcfg); } - my $inetn = xCAT::NetworkUtils->getipaddr($node); - unless ($inetn) { - syslog("local1|err", "xCAT unable to resolve IP for $node in grub2 plugin"); - return; - } } else { close($pcfg); } @@ -334,9 +328,9 @@ sub setstate { my $pname = "grub.cfg-" . sprintf("%02X%02X%02X%02X", @ipa); # remove the old boot configuration file and copy (link) a new one, but only if not offline directive - unlink($tftpdir . "/boot/grub2/" . $pname); + unlink("$bootloader_root/" . $pname); if ($cref and $cref->{currstate} ne "offline") { - link($tftpdir . "/boot/grub2/" . $node, $tftpdir . "/boot/grub2/" . $pname); + link("$bootloader_root/" . $node, "$bootloader_root/" . $pname); } } @@ -359,9 +353,9 @@ sub setstate { my $pname = "grub.cfg-01-" . $tmp; # remove the old boot configuration file and copy (link) a new one, but only if not offline directive - unlink($tftpdir . "/boot/grub2/" . $pname); + unlink("$bootloader_root/" . $pname); if ($cref and $cref->{currstate} ne "offline") { - link($tftpdir . "/boot/grub2/" . $node, $tftpdir . "/boot/grub2/" . $pname); + link("$bootloader_root/" . $node, "$bootloader_root/" . $pname); } } return; @@ -402,12 +396,14 @@ sub preprocess_request { #use Getopt::Long; my $HELP; + my $ALLFLAG; my $VERSION; my $VERBOSE; Getopt::Long::Configure("bundling"); Getopt::Long::Configure("pass_through"); if (!GetOptions('h|?|help' => \$HELP, 'v|version' => \$VERSION, + 'a' =>\$ALLFLAG, 'V' => \$VERBOSE #>>>>>>>used for trace log>>>>>>> )) { if ($usage{$command}) { @@ -469,12 +465,12 @@ sub preprocess_request { xCAT::ServiceNodeUtils->getSNandCPnodes(\@$nodes, \@SN, \@CN); unless (($args[0] eq 'stat') or ($args[0] eq 'enact')) { if ((@SN > 0) && (@CN > 0)) { # there are both SN and CN - my $rsp; - $rsp->{data}->[0] = + my %rsp; + $rsp{errorcode}->[0] = 1; + $rsp{error}->[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); + $callback1->(\%rsp); return; - } } @@ -482,10 +478,40 @@ sub preprocess_request { if ($req->{inittime}->[0]) { return [$req]; } - if (@CN > 0) { # if compute nodes broadcast to all servicenodes - return xCAT::Scope->get_broadcast_scope_with_parallel($req); + if (@CN > 0) { # if compute nodes only, then broadcast to servic enodes + + my @sn = xCAT::ServiceNodeUtils->getSNList(); + unless ( @sn > 0 ) { + return xCAT::Scope->get_parallel_scope($req) + } + + my $mynodeonly = 0; + my @entries = xCAT::TableUtils->get_site_attribute("disjointdhcps"); + my $t_entry = $entries[0]; + if (defined($t_entry)) { + $mynodeonly = $t_entry; + } + $req->{'_disjointmode'} = [$mynodeonly]; + xCAT::MsgUtils->trace(0, "d", "grub2: disjointdhcps=$mynodeonly"); + + if ($mynodeonly == 0 || $ALLFLAG) { # broadcast to all service nodes + return xCAT::Scope->get_broadcast_scope_with_parallel($req, \@sn); + } + + my $sn_hash = xCAT::ServiceNodeUtils->getSNformattedhash(\@CN, "xcat", "MN"); + my @dhcpsvrs = (); + my $ntab = xCAT::Table->new('networks'); + if ($ntab) { + foreach (@{ $ntab->getAllEntries() }) { + next unless ($_->{dynamicrange}); + # if dynamicrange specified but dhcpserver was not - issue error message + push @dhcpsvrs, $_->{dhcpserver} if ($_->{dhcpserver}) + } + } + return xCAT::Scope->get_broadcast_disjoint_scope_with_parallel($req, $sn_hash, \@dhcpsvrs); } } + # Do not dispatch to service nodes if non-sharedtftp or the node range contains only SNs. return xCAT::Scope->get_parallel_scope($req); } @@ -496,19 +522,16 @@ sub process_request { $sub_req = shift; my $command = $request->{command}->[0]; %breaknetbootnodes = (); - %normalnodes = (); + %normalnodes = (); # It will be fill-up by method: setstate. my @args; - my @nodes; - my @rnodes; - #>>>>>>>used for trace log start>>>>>>> my %opt; my $verbose_on_off = 0; - if (ref($::XNBA_request->{arg})) { - @args = @{ $::XNBA_request->{arg} }; + if (ref($request->{arg})) { + @args = @{ $request->{arg} }; } else { - @args = ($::XNBA_request->{arg}); + @args = ($request->{arg}); } @ARGV = @args; GetOptions('V' => \$opt{V}); @@ -516,6 +539,10 @@ sub process_request { #>>>>>>>used for trace log end>>>>>>> + my @hostinfo = xCAT::NetworkUtils->determinehostname(); + $::myxcatname = $hostinfo[-1]; + xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: running on $::myxcatname"); + my @rnodes; if (ref($request->{node})) { @rnodes = @{ $request->{node} }; } else { @@ -528,61 +555,101 @@ sub process_request { return; } - #if not shared tftpdir, then filter, otherwise, set up everything - if ($request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command - @nodes = (); - my @hostinfo = xCAT::NetworkUtils->determinehostname(); - my $cur_xmaster = pop @hostinfo; - xCAT::MsgUtils->trace(0, "d", "grub2: running on $cur_xmaster"); - - # Get current server managed node list - my $sn_hash = xCAT::ServiceNodeUtils->getSNformattedhash(\@rnodes, "xcat", "MN"); - my %managed = {}; - foreach (@{ $sn_hash->{$cur_xmaster} }) { $managed{$_} = 1; } - - foreach (@rnodes) { - if (xCAT::NetworkUtils->nodeonmynet($_)) { - push @nodes, $_; + if ($args[0] eq 'stat') { + my $noderestab = xCAT::Table->new('noderes'); #in order to detect per-node tftp directories + my %nrhash = %{ $noderestab->getNodesAttribs(\@rnodes, [qw(tftpdir)]) }; + foreach my $node (@rnodes) { + my %response; + my $tftpdir; + if ($nrhash{$node}->[0] and $nrhash{$node}->[0]->{tftpdir}) { + $tftpdir = $nrhash{$node}->[0]->{tftpdir}; } else { - my $msg = "grub2 configuration file was not created for node [$_] because sharedtftp attribute is not set and the node is not on same network as this xcatmaster"; - if ( $cur_xmaster ) { - $msg .= ": $cur_xmaster"; - } - if ( exists( $managed{$_} ) ) { - # report error when it is under my control but I cannot handle it. - my $rsp; - $rsp->{data}->[0] = $msg; - xCAT::MsgUtils->message("E", $rsp, $callback); - } else { - xCAT::MsgUtils->message("S", $msg); - } + $tftpdir = $globaltftpdir; } + $response{node}->[0]->{name}->[0] = $node; + $response{node}->[0]->{data}->[0] = getstate($node, $tftpdir); + $callback->(\%response); } - } else { - @nodes = @rnodes; - } - - #>>>>>>>used for trace log>>>>>>> - my $str_node = join(" ", @nodes); - xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: nodes are $str_node"); - - # return directly if no nodes in the same network - unless (@nodes) { - xCAT::MsgUtils->message("S", "xCAT: grub2 netboot: no valid nodes. Stop the operation on this server."); return; } - if (ref($request->{arg})) { - @args = @{ $request->{arg} }; + my @nodes = (); + # Filter those nodes which have bad DNS: not resolvable or inconsistent IP + my %failurenodes = (); + my %preparednodes = (); + foreach (@rnodes) { + my $ipret = xCAT::NetworkUtils->checkNodeIPaddress($_); + my $errormsg = $ipret->{'error'}; + my $nodeip = $ipret->{'ip'}; + if ($errormsg) {# Add the node to failure set + xCAT::MsgUtils->trace(0, "E", "grub2: Defined IP address of $_ is $nodeip. $errormsg"); + unless ($nodeip) { + $failurenodes{$_} = 1; + } + } + if ($nodeip) { + $preparednodes{$_} = $nodeip; + } + } + + #if not shared tftpdir, then filter, otherwise, set up everything + if ($request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command + # Filter those nodes not in the same subnet, and print error message in log file. + foreach (keys %preparednodes) { + # Only handle its boot configuration files if the node in same subnet + if (xCAT::NetworkUtils->nodeonmynet($preparednodes{$_})) { + push @nodes, $_; + } else { + xCAT::MsgUtils->trace(0, "W", "grub2: configuration file was not created for [$_] because the node is not on the same network as this server"); + delete $preparednodes{$_}; + } + } } else { - @args = ($request->{arg}); + @nodes = keys %preparednodes; + } + + my $str_node = join(" ", @nodes); + xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: nodes are $str_node") if ($str_node); + + # Return directly if no nodes in the same network, need to report error on console if its managed nodes are not handled. + unless (@nodes) { + xCAT::MsgUtils->message("S", "xCAT: grub2 netboot: no valid nodes. Stop the operation on this server."); + + # If non-shared tftproot and non disjoint mode, need to figure out if no nodes here is a normal case. + if ($request->{'_disparatetftp'}->[0] && $request->{'_disjointmode'}->[0] != 1) { + # Find out which nodes are really mine only when not sharedtftp and not disjoint mode. + my %iphash = (); + # flag the IPs or names in iphash + foreach (@hostinfo) { $iphash{$_} = 1; } + + # Get managed node list under current server + # The node will be under under 'site.master' if no 'noderes.servicenode' is defined + my $sn_hash = xCAT::ServiceNodeUtils->getSNformattedhash(\@rnodes, "xcat", "MN"); + my $req2manage = 0; + foreach (keys %$sn_hash) { + if (exists($iphash{$_})) { + $req2manage = 1; + last; + } + } + # Okay, now report error as no nodes are handled. + if ($req2manage == 0) { + xCAT::MsgUtils->trace(0, "d", "grub2: No nodes are required to be managed on this server"); + return; + } + } + my $rsp; + $rsp->{errorcode}->[0] = 1; + $rsp->{error}->[0] = "Failed to generate grub2 configurations for some node(s) on $::myxcatname. Check xCAT log file for more details."; + $callback->($rsp); + return; } #now run the begin part of the prescripts - unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') { + unless ($args[0] eq '') { # or $args[0] eq 'enact') { $errored = 0; - if ($request->{'_disparatetftp'}->[0]) { #the call is distrubuted to the service node already, so only need to handles my own children - xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: the call is distrubuted to the service node already, so only need to handles my own children"); + if ($request->{'_disparatetftp'}->[0]) { #the call is distrubuted to the service node already, so only need to handle my own children + xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: the call is distrubuted to the service node already, so only need to handle my own children"); xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: issue runbeginpre request"); $sub_req->({ command => ['runbeginpre'], node => \@nodes, @@ -609,7 +676,7 @@ sub process_request { if (!$inittime) { $inittime = 0; } my %bphash; - unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') { + unless ($args[0] eq '') { # or $args[0] eq 'enact') { $errored = 0; xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: issue setdestiny request"); $sub_req->({ command => ['setdestiny'], @@ -619,11 +686,12 @@ sub process_request { bootparams => \%bphash }, \&pass_along); if ($errored) { - xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: Failed in processing setdestiny. Processing will not continue."); + xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: Failed in processing setdestiny. Processing will not continue."); return; } } + xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: starting to handle configuration..."); my $chaintab = xCAT::Table->new('chain', -create => 1); my $chainhash = $chaintab->getNodesAttribs(\@nodes, ['currstate']); my $noderestab = xCAT::Table->new('noderes', -create => 1); @@ -649,10 +717,7 @@ sub process_request { $tftpdir = $globaltftpdir; } $response{node}->[0]->{name}->[0] = $_; - if ($args[0] eq 'stat') { - $response{node}->[0]->{data}->[0] = getstate($_, $tftpdir); - $callback->(\%response); - } elsif ($args[0]) { #If anything else, send it on to the destiny plugin, then setstate + if ($args[0]) { # Send it on to the destiny plugin, then setstate my $ent = $typehash->{$_}->[0]; my $osimgname = $ent->{'provmethod'}; my $linuximghash = undef; @@ -668,11 +733,11 @@ sub process_request { } } } # end of foreach node + xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: Finish to handle configurations"); my @normalnodeset = keys %normalnodes; my @breaknetboot = keys %breaknetbootnodes; - #print "grub2 :inittime=$inittime; normalnodeset=@normalnodeset; breaknetboot=@breaknetboot\n"; my %osimagenodehash; for my $nn (@normalnodeset) { @@ -693,7 +758,7 @@ sub process_request { } #Don't bother to try dhcp binding changes if sub_req not passed, i.e. service node build time - unless (($args[0] eq 'stat') || ($inittime) || ($args[0] eq 'offline')) { + unless (($inittime) || ($args[0] eq 'offline')) { foreach my $osimage (keys %osimagenodehash) { #TOTO check the existence of grub2 executable files for corresponding arch @@ -793,7 +858,7 @@ sub process_request { } #now run the end part of the prescripts - unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') + unless ($args[0] eq '') { # or $args[0] eq 'enact') $errored = 0; if ($request->{'_disparatetftp'}->[0]) { #the call is distrubuted to the service node already, so only need to handles my own children xCAT::MsgUtils->trace($verbose_on_off, "d", "grub2: issue runendpre request"); @@ -814,6 +879,16 @@ sub process_request { return; } } + + # Return error codes if there are failed nodes + if (%failurenodes) { + my $rsp; + $rsp->{errorcode}->[0] = 1; + $rsp->{error}->[0] = "Failed to generate grub2 configurations for some node(s) on $::myxcatname. Check xCAT log file for more details."; + $callback->($rsp); + return; + } + } #---------------------------------------------------------------------------- diff --git a/xCAT-server/lib/xcat/plugins/ipmi.pm b/xCAT-server/lib/xcat/plugins/ipmi.pm index 3627df69b..82f43f460 100644 --- a/xCAT-server/lib/xcat/plugins/ipmi.pm +++ b/xCAT-server/lib/xcat/plugins/ipmi.pm @@ -1622,6 +1622,13 @@ sub isopenpower { sub check_firmware_version { + sub _on_receive_ugp { + my $rsp = shift; + my $sessdta = shift; + shift @{ $rsp->{data} }; + return; + } + sub _on_receive_version { my $rsp = shift; my $sessdata = shift; @@ -1650,6 +1657,15 @@ sub check_firmware_version { my $sessdata = shift; my $firmware_version = shift; my $component_string = shift; + + # GET TARGET UPGRADE CAPABILITIES + $sessdata->{ipmisession}->subcmd(netfn => 0x2c, command => 0x2e, + data => [ 0 ], + callback => \&_on_receive_ugp, + callback_args => $sessdata); + while (xCAT::IPMI->waitforrsp()) { yield } + + foreach my $c_id (@{ $sessdata->{component_ids} }) { $sessdata->{c_id} = $c_id; @@ -1705,6 +1721,10 @@ sub calc_ipmitool_version { # zz_retry: minimum number of 00 to receive before exiting # sessdata: session data for display # verbose: verbose output +# use_rc: Some machines, like IBM Power S822LC for Big Data (Supermicro), do not return +# a "00" ready string from calling ipmi raw command. Instead they return RC=0. This +# flag if 1, tells the check_bmc_status_with_ipmitool() to check the RC +# instead of "00" string. If set to 0, the "00" ready string is checked. # Returns: # 1 when bmc is up # 0 when no response from bmc @@ -1716,11 +1736,19 @@ sub check_bmc_status_with_ipmitool { my $zz_retry = shift; my $sessdata = shift; my $verbose = shift; + my $use_rc = shift; my $count = 0; my $zz_count = 0; my $bmc_response = 0; my $cmd = $pre_cmd . " raw 0x3a 0x0a"; + my $bmc_ready_code = "00"; + my $code_type = "ready"; + if ($use_rc) { + $cmd = $cmd . " >> /dev/null 2>&1 ; echo \$?"; + $bmc_ready_code = "0"; + $code_type = "return"; + } # BMC response of " c0" means BMC still running IPL # BMC response of " 00" means ready to flash # @@ -1730,18 +1758,18 @@ sub check_bmc_status_with_ipmitool { # interrupts it. while ($count < $retry) { $bmc_response = xCAT::Utils->runcmd($cmd, -1); - if ($bmc_response =~ /00/) { + if ($bmc_response =~ /$bmc_ready_code/) { if ($zz_count > $zz_retry) { # zero-zero ready code was received for $zz_count iterations - good to exit if ($verbose) { - xCAT::SvrUtils::sendmsg("Received BMC ready code 00 for $zz_count iterations - BMC is ready.", $callback, $sessdata->{node}, %allerrornodes); + xCAT::SvrUtils::sendmsg("Received BMC $code_type code $bmc_ready_code for $zz_count iterations - BMC is ready.", $callback, $sessdata->{node}, %allerrornodes); } return 1; } else { # check to make sure zero-zero is received again if ($verbose) { - xCAT::SvrUtils::sendmsg("($zz_count) BMC ready code - 00", $callback, $sessdata->{node}, %allerrornodes); + xCAT::SvrUtils::sendmsg("($zz_count) BMC $code_type code - $bmc_ready_code", $callback, $sessdata->{node}, %allerrornodes); } $zz_count++; } @@ -1751,7 +1779,7 @@ sub check_bmc_status_with_ipmitool { # zero-zero was received before, but now we get something else. # reset the zero-zero counter to make sure we get $zz_count iterations of zero-zero if ($verbose) { - xCAT::SvrUtils::sendmsg("Resetting counter because BMC ready code - $bmc_response", $callback, $sessdata->{node}, %allerrornodes); + xCAT::SvrUtils::sendmsg("Resetting counter because BMC $code_type code - $bmc_response", $callback, $sessdata->{node}, %allerrornodes); } $zz_count = 0; } @@ -1760,7 +1788,7 @@ sub check_bmc_status_with_ipmitool { $count++; } if ($verbose) { - xCAT::SvrUtils::sendmsg("Never received 00 code after $count retries - BMC not ready.", $callback, $sessdata->{node}, %allerrornodes); + xCAT::SvrUtils::sendmsg("Never received $code_type code $bmc_ready_code after $count retries - BMC not ready.", $callback, $sessdata->{node}, %allerrornodes); } return 0; } @@ -1863,7 +1891,7 @@ sub do_firmware_update { # only 1.8.15 or above support hpm update for firestone machines. if (calc_ipmitool_version($ipmitool_ver) < calc_ipmitool_version("1.8.15")) { $callback->({ error => "IPMITool $ipmitool_ver do not support firmware update for " . - "firestone mathines, please setup IPMITool 1.8.15 or above.", + "firestone machines, please setup IPMITool 1.8.15 or above.", errorcode => 1 }); exit -1; } @@ -2005,6 +2033,22 @@ sub do_firmware_update { # the specified data directory xCAT::SvrUtils::sendmsg("rflash started, Please wait...", $callback, $sessdata->{node}); + # step 1 power off + $cmd = $pre_cmd . " chassis power off"; + if ($verbose) { + xCAT::SvrUtils::sendmsg("Preparing to upgrade firmware, powering chassis off...", $callback, $sessdata->{node}, %allerrornodes); + } + $output = xCAT::Utils->runcmd($cmd, -1); + if ($::RUNCMD_RC != 0) { + $exit_with_error_func->($sessdata->{node}, $callback, + "Running ipmitool command $cmd failed: $output"); + } + unless (check_bmc_status_with_ipmitool($pre_cmd, 5, 10, 2, $sessdata, $verbose, 1)) { + $exit_with_error_func->($sessdata->{node}, $callback, + "Timeout to check the bmc status"); + } + + # step 2 update BMC file or PNOR file, or both if ($bmc_file) { # BMC file was found in data directory, run update with it my $pUpdate_bmc_cmd = "$pUpdate_directory/pUpdate -f $bmc_file -i lan -h $bmc_addr -u $bmc_userid -p $bmc_password >".$rflash_log_file." 2>&1"; @@ -2018,10 +2062,12 @@ sub do_firmware_update { $exit_with_error_func->($sessdata->{node}, $callback, "Error running command $pUpdate_bmc_cmd"); } - if ($verbose) { - xCAT::SvrUtils::sendmsg([ 0, "Waiting for BMC to reboot (2 min)..." ], $callback, $sessdata->{node}); + # Wait for BMC to reboot before continuing to next step. + # Since this is a IBM Power S822LC for Big Data (Supermicro) machine, use RC to check if ready + unless (check_bmc_status_with_ipmitool($pre_cmd, 5, 60, 10, $sessdata, $verbose, 1)) { + $exit_with_error_func->($sessdata->{node}, $callback, + "Timeout to check the bmc status"); } - sleep (120); } @@ -2039,8 +2085,15 @@ sub do_firmware_update { "Error running command $pUpdate_pnor_cmd"); } } + # step 3 power on + $cmd = $pre_cmd . " chassis power on"; + $output = xCAT::Utils->runcmd($cmd, -1); + if ($::RUNCMD_RC != 0) { + $exit_with_error_func->($sessdata->{node}, $callback, + "Running ipmitool command $cmd failed: $output"); + } - $exit_with_success_func->($sessdata->{node}, $callback, "Firmware updated"); + $exit_with_success_func->($sessdata->{node}, $callback, "Firmware updated, powering chassis on to populate FRU information..."); } if (($hpm_data_hash{deviceID} ne $sessdata->{device_id}) || @@ -2155,7 +2208,7 @@ RETRY_UPGRADE: } # check reset status - unless (check_bmc_status_with_ipmitool($pre_cmd, 5, 60, 2, $sessdata, $verbose)) { + unless (check_bmc_status_with_ipmitool($pre_cmd, 5, 60, 2, $sessdata, $verbose, 0)) { $exit_with_error_func->($sessdata->{node}, $callback, "Timeout to check the bmc status"); } @@ -2221,7 +2274,7 @@ RETRY_UPGRADE: } # Wait for BMC to reboot before continuing to next step - unless (check_bmc_status_with_ipmitool($pre_cmd, 5, 60, 10, $sessdata, $verbose)) { + unless (check_bmc_status_with_ipmitool($pre_cmd, 5, 60, 10, $sessdata, $verbose, 0)) { $exit_with_error_func->($sessdata->{node}, $callback, "Timeout waiting for the bmc ready status. Firmware update suspended"); } @@ -2285,7 +2338,7 @@ RETRY_UPGRADE: # step 5 power on # check reset status - unless (check_bmc_status_with_ipmitool($pre_cmd, 5, 60, 10, $sessdata, $verbose)) { + unless (check_bmc_status_with_ipmitool($pre_cmd, 5, 60, 10, $sessdata, $verbose, 0)) { $exit_with_error_func->($sessdata->{node}, $callback, "Timeout to check the bmc status"); } @@ -2339,7 +2392,7 @@ sub rflash { $sessdata->{subcommand} = "check"; # support verbose options for ipmitool command } elsif ($opt !~ /.*\.hpm$/i && $opt !~ /^-V{1,4}$|^--buffersize=|^--retry=|^-d=/) { - $callback->({ error => "The option $opt is not supported", + $callback->({ error => "The option $opt is not supported or invalid update file specified", errorcode => 1 }); return; } @@ -6702,9 +6755,9 @@ sub vitals { if ($sensor_filters{energy}) { if ($iem_support) { push @{ $sessdata->{sensorstoread} }, "energy"; - } elsif (not $doall) { - xCAT::SvrUtils::sendmsg([ 1, ":Energy data requires additional IBM::EnergyManager plugin in conjunction with IMM managed IBM equipment" ], $callback, $sessdata->{node}, %allerrornodes); - } + } #elsif (not $doall) { + #xCAT::SvrUtils::sendmsg([ 1, ":Energy data requires additional IBM::EnergyManager plugin in conjunction with IMM managed IBM equipment" ], $callback, $sessdata->{node}, %allerrornodes); + #} #my @energies; #($rc,@energies)=readenergy(); diff --git a/xCAT-server/lib/xcat/plugins/openbmc.pm b/xCAT-server/lib/xcat/plugins/openbmc.pm index 6f1b8f448..9b1ebd55b 100644 --- a/xCAT-server/lib/xcat/plugins/openbmc.pm +++ b/xCAT-server/lib/xcat/plugins/openbmc.pm @@ -217,15 +217,15 @@ my %status_info = ( RSETBOOT_SET_REQUEST => { method => "PUT", - init_url => "$openbmc_project_url/control/boot/bootsource/attr/Sources", - data => "xyz.openbmc_project.Control.Boot.Sources.", + init_url => "$openbmc_project_url/control/host0/boot_source/attr/BootSource", + data => "xyz.openbmc_project.Control.Boot.Source.Sources.", }, RSETBOOT_SET_RESPONSE => { process => \&rsetboot_response, }, RSETBOOT_STATUS_REQUEST => { method => "GET", - init_url => "$openbmc_project_url/control/boot/bootsource", + init_url => "$openbmc_project_url/control/host0/boot_source", }, RSETBOOT_STATUS_RESPONSE => { process => \&rsetboot_response, @@ -467,9 +467,6 @@ sub parse_args { my $extrargs = shift; my $noderange = shift; my $check = undef; - - xCAT::SvrUtils::sendmsg("[OpenBMC development support] Using this version of xCAT, ensure firmware level is at v1.99.6-0-r1, or higher.", $callback); - my $subcommand = undef; my $verbose = undef; unless (GetOptions( @@ -877,7 +874,7 @@ sub parse_node_info { if ($openbmc_hash->{$node}->[0]->{'bmc'}) { $node_info{$node}{bmc} = $openbmc_hash->{$node}->[0]->{'bmc'}; } else { - xCAT::SvrUtils::sendmsg("Unable to get attribute bmc", $callback, $node); + xCAT::SvrUtils::sendmsg("Error: Unable to get attribute bmc", $callback, $node); $rst = 1; next; } @@ -887,7 +884,7 @@ sub parse_node_info { } elsif ($passwd_hash and $passwd_hash->{username}) { $node_info{$node}{username} = $passwd_hash->{username}; } else { - xCAT::SvrUtils::sendmsg("Unable to get attribute username", $callback, $node); + xCAT::SvrUtils::sendmsg("Error: Unable to get attribute username", $callback, $node); delete $node_info{$node}; $rst = 1; next; @@ -898,7 +895,7 @@ sub parse_node_info { } elsif ($passwd_hash and $passwd_hash->{password}) { $node_info{$node}{password} = $passwd_hash->{password}; } else { - xCAT::SvrUtils::sendmsg("Unable to get attribute password", $callback, $node); + xCAT::SvrUtils::sendmsg("Error: Unable to get attribute password", $callback, $node); delete $node_info{$node}; $rst = 1; next; @@ -906,7 +903,7 @@ sub parse_node_info { $node_info{$node}{cur_status} = "LOGIN_REQUEST"; } else { - xCAT::SvrUtils::sendmsg("Unable to get information from openbmc table", $callback, $node); + xCAT::SvrUtils::sendmsg("Error: Unable to get information from openbmc table", $callback, $node); $rst = 1; next; } @@ -1361,11 +1358,19 @@ sub rsetboot_response { my $response_info = decode_json $response->content; - if ($node_info{$node}{cur_status} eq "RSETBOOT_GET_RESPONSE") { - xCAT::SvrUtils::sendmsg("Hard Drive", $callback, $node) if ($response_info->{'data'}->{BootSource} =~ /Disk$/); - xCAT::SvrUtils::sendmsg("Network", $callback, $node) if ($response_info->{'data'}->{BootSource} =~ /Network$/); - xCAT::SvrUtils::sendmsg("CD/DVD", $callback, $node) if ($response_info->{'data'}->{BootSource} =~ /ExternalMedia$/); - xCAT::SvrUtils::sendmsg("boot override inactive", $callback, $node) if ($response_info->{'data'}->{BootSource} =~ /Default$/); + if ($node_info{$node}{cur_status} eq "RSETBOOT_STATUS_RESPONSE") { + if ($response_info->{'data'}->{BootSource} =~ /Disk$/) { + xCAT::SvrUtils::sendmsg("Hard Drive", $callback, $node); + } elsif ($response_info->{'data'}->{BootSource} =~ /Network$/) { + xCAT::SvrUtils::sendmsg("Network", $callback, $node); + } elsif ($response_info->{'data'}->{BootSource} =~ /ExternalMedia$/) { + xCAT::SvrUtils::sendmsg("CD/DVD", $callback, $node); + } elsif ($response_info->{'data'}->{BootSource} =~ /Default$/) { + xCAT::SvrUtils::sendmsg("Default", $callback, $node); + } else { + my $error_msg = "Can not get valid rsetboot status, the data is " . $response_info->{'data'}->{BootSource}; + xCAT::SvrUtils::sendmsg("$error_msg", $callback, $node); + } } if ($next_status{ $node_info{$node}{cur_status} }) { diff --git a/xCAT-server/lib/xcat/plugins/pdu.pm b/xCAT-server/lib/xcat/plugins/pdu.pm index e79b906e0..c4e71ef96 100644 --- a/xCAT-server/lib/xcat/plugins/pdu.pm +++ b/xCAT-server/lib/xcat/plugins/pdu.pm @@ -36,6 +36,8 @@ use Class::Struct; use XML::Simple; use Storable qw(dclone); use SNMP; +use Expect; +use Net::Ping; my $VERBOSE = 0; my %allerrornodes = (); @@ -62,6 +64,7 @@ sub handled_commands rpower => ["nodehm:mgt","pduoutlet:pdu=\.\*"], rinv => ["nodehm:mgt"], nodeset => ["nodehm:mgt"], + rspconfig => ["nodehm:mgt"], pdudiscover => "pdu", }; } @@ -170,6 +173,13 @@ sub process_request } } } + }elsif($command eq "rspconfig") { + my $subcmd = $exargs[0]; + if ($subcmd eq 'sshcfg') { + process_sshcfg($noderange, $subcmd, $callback); + } else { + $callback->({ errorcode => [1],error => "The input $command $subcmd is not support for pdu"}); + } }elsif($command eq "pdudiscover") { process_pdudiscover($request, $subreq, $callback); }elsif($command eq "nodeset") { @@ -457,6 +467,124 @@ sub connectTopdu { } +sub process_sshcfg { + my $noderange = shift; + my $subcmd = shift; + my $callback = shift; + + my $password = "password8"; + my $userid = "root"; + my $timeout = 10; + my $keyfile = "/root/.ssh/id_rsa.pub"; + my $rootkey = `cat /root/.ssh/id_rsa.pub`; + my $cmd; + + my $nodetab = xCAT::Table->new('hosts'); + my $nodehash = $nodetab->getNodesAttribs($noderange,['ip','otherinterfaces']); + + foreach my $pdu (@$noderange) { + my $msg = " process_sshcfg"; + xCAT::SvrUtils::sendmsg($msg, $callback, $pdu, %allerrornodes); + + #remove old host key from /root/.ssh/known_hosts + $cmd = "ssh-keygen -R $pdu"; + xCAT::Utils->runcmd($cmd, 0); + + my $static_ip = $nodehash->{$pdu}->[0]->{ip}; + my $discover_ip = $nodehash->{$pdu}->[0]->{otherinterfaces}; + my $ssh_ip; + + my $p = Net::Ping->new(); + if ($p->ping($static_ip)) { + $ssh_ip = $static_ip; + } elsif ($p->ping($discover_ip)) { + $ssh_ip = $discover_ip; + } else { + $msg = " is not reachable"; + xCAT::SvrUtils::sendmsg($msg, $callback, $pdu, %allerrornodes); + next; + } + + my ($exp, $errstr) = session_connect($ssh_ip, $userid, $password, $timeout); + if (!defined $exp) { + $msg = " Failed to connect $errstr"; + xCAT::SvrUtils::sendmsg($msg, $callback, $pdu, %allerrornodes); + next; + } + + my $ret; + my $err; + + ($ret, $err) = session_exec($exp, "mkdir -p /home/root/.ssh"); + ($ret, $err) = session_exec($exp, "chmod 700 /home/root/.ssh"); + ($ret, $err) = session_exec($exp, "echo \"$rootkey\" >/home/root/.ssh/authorized_keys"); + ($ret, $err) = session_exec($exp, "chmod 644 /home/root/.ssh/authorized_keys"); + #config dhcp ip address to static + if ($ssh_ip eq $discover_ip) { + # ($ret, $err) = session_exec($exp, "ifconfig eth0 $static_ip"); + } + + $exp->hard_close(); + } + + return; +} + +sub session_connect { + my $server = shift; + my $userid = shift; + my $password = shift; + my $timeout = shift; + + my $ssh = Expect->new; + my $command = 'ssh'; + my @parameters = ($userid . "@" . $server); + + $ssh->debug(0); + $ssh->log_stdout(0); # suppress stdout output.. + $ssh->slave->stty(qw(sane -echo)); + + unless ($ssh->spawn($command, @parameters)) + { + my $err = $!; + $ssh->soft_close(); + my $rsp; + return(undef, "unable to run command $command $err\n"); + } + + $ssh->expect($timeout, + [ "-re", qr/WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED/, sub {die "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!\n"; } ], + [ "-re", qr/\(yes\/no\)\?\s*$/, sub { $ssh->send("yes\n"); exp_continue; } ], + [ "-re", qr/ password:/, sub {$ssh->send("$password\n"); exp_continue; } ], + [ "-re", qr/:~\$/, sub { $ssh->send("sudo su\n"); exp_continue; } ], + [ "-re", qr/.*#/, sub { $ssh->clear_accum(); } ], + [ timeout => sub { die "No login.\n"; } ] + ); + $ssh->clear_accum(); + return ($ssh); +} + + +sub session_exec { + my $exp = shift; + my $cmd = shift; + my $timeout = shift; + my $prompt = shift; + + $timeout = 10 unless defined $timeout; + $prompt = qr/.*#/ unless defined $prompt; + + + $exp->clear_accum(); + $exp->send("$cmd\n"); + my ($mpos, $merr, $mstr, $mbmatch, $mamatch) = $exp->expect(6, "-re", $prompt); + + if (defined $merr) { + return(undef,$merr); + } + return($mbmatch); +} + sub process_pdudiscover { my $request = shift; my $sub_req = shift; diff --git a/xCAT-server/lib/xcat/plugins/petitboot.pm b/xCAT-server/lib/xcat/plugins/petitboot.pm index 04f7bcdf7..af3320ae2 100644 --- a/xCAT-server/lib/xcat/plugins/petitboot.pm +++ b/xCAT-server/lib/xcat/plugins/petitboot.pm @@ -78,7 +78,7 @@ sub setstate { =pod - This function will manipulate the yaboot structure to match what the noderes/chain tables indicate the node should be booting. + This function will manipulate the petitboot structure to match what the noderes/chain tables indicate the node should be booting. =cut @@ -125,12 +125,10 @@ sub setstate { # We are in the service node pools, print error if no facing ip. if (xCAT::InstUtils->is_me($sn)) { - my @myself = xCAT::NetworkUtils->determinehostname(); - my $myname = $myself[ (scalar @myself) - 1 ]; $::callback->( { error => [ - "$myname: $ipfnd[1] on service node $sn" + "$::myxcatname: $ipfnd[1] on service node $sn" ], errorcode => [1] } @@ -142,7 +140,7 @@ sub setstate { $::callback->( { error => [ - "$myname: $ipfnd[1]" + "$::myxcatname: $ipfnd[1]" ], errorcode => [1] } @@ -170,18 +168,19 @@ sub setstate { } } - my $pcfg; - unless (-d "$tftpdir/petitboot") { - mkpath("$tftpdir/petitboot"); + my $bootloader_root = "$tftpdir/petitboot"; + unless (-d "$bootloader_root") { + mkpath("$bootloader_root"); } my $nodemac; my $cref = $chainhash{$node}->[0]; #$chaintab->getNodeAttribs($node,['currstate']); + my $pcfg; # remove the old boot configuration file and create a new one, but only if not offline directive - unlink($tftpdir . "/petitboot/" . $node); + unlink("$bootloader_root/" . $node); if ($cref and $cref->{currstate} ne "offline") { - open($pcfg, '>', $tftpdir . "/petitboot/" . $node); + open($pcfg, '>', "$bootloader_root/" . $node); print $pcfg "#" . $cref->{currstate} . "\n"; } $normalnodes{$node} = 1; #Assume a normal netboot (well, normal dhcp, @@ -217,18 +216,13 @@ sub setstate { print $pcfg "\tappend \"" . $kern->{kcmdline} . "\"\n"; } close($pcfg); - my $inetn = xCAT::NetworkUtils->getipaddr($node); - unless ($inetn) { - syslog("local1|err", "xCAT unable to resolve IP for $node in petitboot plugin"); - return; - } } else { #TODO: actually, should possibly default to xCAT image? #print $pcfg "bye\n"; close($pcfg); } my $ip = xCAT::NetworkUtils->getipaddr($node); unless ($ip) { - syslog("local1|err", "xCAT unable to resolve IP in petitboot plugin"); + syslog("local1|err", "xCAT unable to resolve IP for $node in petitboot plugin"); return; } @@ -237,9 +231,9 @@ sub setstate { $pname = uc($pname); # remove the old boot configuration file and copy (link) a new one, but only if not offline directive - unlink($tftpdir . "/" . $pname); + unlink("$tftpdir/" . $pname); if ($cref and $cref->{currstate} ne "offline") { - link($tftpdir . "/petitboot/" . $node, $tftpdir . "/" . $pname); + link("$bootloader_root/" . $node, "$tftpdir/" . $pname); } return; } @@ -283,12 +277,14 @@ sub preprocess_request { #use Getopt::Long; my $HELP; + my $ALLFLAG; my $VERSION; my $VERBOSE; Getopt::Long::Configure("bundling"); Getopt::Long::Configure("pass_through"); if (!GetOptions('h|?|help' => \$HELP, 'v|version' => \$VERSION, + 'a' =>\$ALLFLAG, 'V' => \$VERBOSE #>>>>>>>used for trace log>>>>>>> )) { if ($usage{$command}) { @@ -334,6 +330,13 @@ sub preprocess_request { return; } + if ($ARGV[0] ne "stat" && $ALLFLAG) { + my %rsp; + $rsp{error}->[0] = "'-a' could only be used with 'stat' subcommand."; + $rsp{errorcode}->[0] = 1; + $callback1->(\%rsp); + return; + } #Assume shared tftp directory for boring people, but for cool people, help sync up tftpdirectory contents when #if they specify no sharedtftp in site table @@ -346,23 +349,55 @@ sub preprocess_request { 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; - + unless (($args[0] eq 'stat') or ($args[0] eq 'enact')) { + if ((@SN > 0) && (@CN > 0)) { # there are both SN and CN + my %rsp; + $rsp{errorcode}->[0] = 1; + $rsp{error}->[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"; + $callback1->(\%rsp); + return; + } } $req->{'_disparatetftp'} = [1]; if ($req->{inittime}->[0]) { return [$req]; } - if (@CN > 0) { # if compute nodes broadcast to all servicenodes - return xCAT::Scope->get_broadcast_scope_with_parallel($req); + if (@CN > 0) { # if compute nodes only, then broadcast to servic enodes + + my @sn = xCAT::ServiceNodeUtils->getSNList(); + unless ( @sn > 0 ) { + return xCAT::Scope->get_parallel_scope($req) + } + + my $mynodeonly = 0; + my @entries = xCAT::TableUtils->get_site_attribute("disjointdhcps"); + my $t_entry = $entries[0]; + if (defined($t_entry)) { + $mynodeonly = $t_entry; + } + $req->{'_disjointmode'} = [$mynodeonly]; + xCAT::MsgUtils->trace(0, "d", "petitboot: disjointdhcps=$mynodeonly"); + + if ($mynodeonly == 0 || $ALLFLAG) { # broadcast to all service nodes + return xCAT::Scope->get_broadcast_scope_with_parallel($req, \@sn); + } + + my $sn_hash = xCAT::ServiceNodeUtils->getSNformattedhash(\@CN, "xcat", "MN"); + my @dhcpsvrs = (); + my $ntab = xCAT::Table->new('networks'); + if ($ntab) { + foreach (@{ $ntab->getAllEntries() }) { + next unless ($_->{dynamicrange}); + # if dynamicrange specified but dhcpserver was not - issue error message + push @dhcpsvrs, $_->{dhcpserver} if ($_->{dhcpserver}) + } + } + return xCAT::Scope->get_broadcast_disjoint_scope_with_parallel($req, $sn_hash, \@dhcpsvrs); } } + # Do not dispatch to service nodes if non-sharedtftp or the node range contains only SNs. return xCAT::Scope->get_parallel_scope($req); } @@ -374,16 +409,16 @@ sub process_request { $sub_req = shift; my $command = $request->{command}->[0]; %breaknetbootnodes = (); - %normalnodes = (); + %normalnodes = (); # It will be fill-up by method: setstate. #>>>>>>>used for trace log start>>>>>>> my @args = (); my %opt; my $verbose_on_off = 0; - if (ref($::request->{arg})) { - @args = @{ $::request->{arg} }; + if (ref($request->{arg})) { + @args = @{ $request->{arg} }; } else { - @args = ($::request->{arg}); + @args = ($request->{arg}); } @ARGV = @args; GetOptions('V' => \$opt{V}); @@ -394,7 +429,9 @@ sub process_request { if ($::XCATSITEVALS{"httpmethod"}) { $httpmethod = $::XCATSITEVALS{"httpmethod"}; } if ($::XCATSITEVALS{"httpport"}) { $httpport = $::XCATSITEVALS{"httpport"}; } - my @nodes; + my @hostinfo = xCAT::NetworkUtils->determinehostname(); + $::myxcatname = $hostinfo[-1]; + xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: running on $::myxcatname"); my @rnodes; if (ref($request->{node})) { @rnodes = @{ $request->{node} }; @@ -408,61 +445,101 @@ sub process_request { return; } - #if not shared tftpdir, then filter, otherwise, set up everything - if ($request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command - @nodes = (); - my @hostinfo = xCAT::NetworkUtils->determinehostname(); - my $cur_xmaster = pop @hostinfo; - xCAT::MsgUtils->trace(0, "d", "petitboot: running on $cur_xmaster"); - - # Get current server managed node list - my $sn_hash = xCAT::ServiceNodeUtils->getSNformattedhash(\@rnodes, "xcat", "MN"); - my %managed = {}; - foreach (@{ $sn_hash->{$cur_xmaster} }) { $managed{$_} = 1; } - - foreach (@rnodes) { - if (xCAT::NetworkUtils->nodeonmynet($_)) { - push @nodes, $_; + if ($args[0] eq 'stat') { + my $noderestab = xCAT::Table->new('noderes'); #in order to detect per-node tftp directories + my %nrhash = %{ $noderestab->getNodesAttribs(\@rnodes, [qw(tftpdir)]) }; + foreach my $node (@rnodes) { + my %response; + my $tftpdir; + if ($nrhash{$node}->[0] and $nrhash{$node}->[0]->{tftpdir}) { + $tftpdir = $nrhash{$node}->[0]->{tftpdir}; } else { - my $msg = "petitboot configuration file was not created for node [$_] because sharedtftp attribute is not set and the node is not on same network as this xcatmaster"; - if ( $cur_xmaster ) { - $msg .= ": $cur_xmaster"; - } - if ( exists( $managed{$_} ) ) { - # report error when it is under my control but I cannot handle it. - my $rsp; - $rsp->{data}->[0] = $msg; - xCAT::MsgUtils->message("E", $rsp, $callback); - } else { - xCAT::MsgUtils->message("S", $msg); - } + $tftpdir = $globaltftpdir; } + $response{node}->[0]->{name}->[0] = $node; + $response{node}->[0]->{data}->[0] = getstate($node, $tftpdir); + $callback->(\%response); } - } else { - @nodes = @rnodes; - } - - #>>>>>>>used for trace log>>>>>>> - my $str_node = join(" ", @nodes); - xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: nodes are $str_node"); - - # return directly if no nodes in the same network - unless (@nodes) { - xCAT::MsgUtils->message("S", "xCAT: petitboot netboot: no valid nodes. Stop the operation on this server."); return; } - if (ref($request->{arg})) { - @args = @{ $request->{arg} }; + my @nodes = (); + # Filter those nodes which have bad DNS: not resolvable or inconsistent IP + my %failurenodes = (); + my %preparednodes = (); + foreach (@rnodes) { + my $ipret = xCAT::NetworkUtils->checkNodeIPaddress($_); + my $errormsg = $ipret->{'error'}; + my $nodeip = $ipret->{'ip'}; + if ($errormsg) {# Add the node to failure set + xCAT::MsgUtils->trace(0, "E", "petitboot: Defined IP address of $_ is $nodeip. $errormsg"); + unless ($nodeip) { + $failurenodes{$_} = 1; + } + } + if ($nodeip) { + $preparednodes{$_} = $nodeip; + } + } + + #if not shared tftpdir, then filter, otherwise, set up everything + if ($request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command + # Filter those nodes not in the same subnet, and print error message in log file. + foreach (keys %preparednodes) { + # Only handle its boot configuration files if the node in same subnet + if (xCAT::NetworkUtils->nodeonmynet($preparednodes{$_})) { + push @nodes, $_; + } else { + xCAT::MsgUtils->trace(0, "W", "petitboot: configuration file was not created for [$_] because the node is not on the same network as this server"); + delete $preparednodes{$_}; + } + } } else { - @args = ($request->{arg}); + @nodes = keys %preparednodes; + } + + my $str_node = join(" ", @nodes); + xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: nodes are $str_node") if ($str_node); + + # Return directly if no nodes in the same network, need to report error on console if its managed nodes are not handled. + unless (@nodes) { + xCAT::MsgUtils->message("S", "xCAT: petitboot netboot: no valid nodes. Stop the operation on this server."); + + # If non-shared tftproot and non disjoint mode, need to figure out if no nodes here is a normal case. + if ($request->{'_disparatetftp'}->[0] && $request->{'_disjointmode'}->[0] != 1) { + # Find out which nodes are really mine only when not sharedtftp and not disjoint mode. + my %iphash = (); + # flag the IPs or names in iphash + foreach (@hostinfo) { $iphash{$_} = 1; } + + # Get managed node list under current server + # The node will be under under 'site.master' if no 'noderes.servicenode' is defined + my $sn_hash = xCAT::ServiceNodeUtils->getSNformattedhash(\@rnodes, "xcat", "MN"); + my $req2manage = 0; + foreach (keys %$sn_hash) { + if (exists($iphash{$_})) { + $req2manage = 1; + last; + } + } + if ($req2manage == 0) { + #No nodes are required to be handled, quit without error. + return; + } + } + # Okay, now report error as no nodes are handled. + my $rsp; + $rsp->{errorcode}->[0] = 1; + $rsp->{error}->[0] = "Failed to generate petitboot configurations for some node(s) on $::myxcatname. Check xCAT log file for more details."; + $callback->($rsp); + return; } #now run the begin part of the prescripts - unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') { + unless ($args[0] eq '') { # or $args[0] eq 'enact') { $errored = 0; - if ($request->{'_disparatetftp'}->[0]) { #the call is distrubuted to the service node already, so only need to handles my own children - xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: the call is distrubuted to the service node already, so only need to handles my own children"); + if ($request->{'_disparatetftp'}->[0]) { #the call is distrubuted to the service node already, so only need to handle my own children + xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: the call is distrubuted to the service node already, so only need to handle my own children"); xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: issue runbeginpre request"); $sub_req->({ command => ['runbeginpre'], node => \@nodes, @@ -471,7 +548,7 @@ sub process_request { xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: nodeset did not distribute to the service node"); xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: issue runbeginpre request"); $sub_req->({ command => ['runbeginpre'], - node => \@rnodes, + node => \@nodes, arg => [ $args[0] ] }, \&pass_along); } if ($errored) { @@ -489,7 +566,7 @@ sub process_request { if (!$inittime) { $inittime = 0; } my %bphash; - unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') { + unless ($args[0] eq '') { # or $args[0] eq 'enact') { $errored = 0; xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: issue setdestiny request"); $sub_req->({ command => ['setdestiny'], @@ -515,6 +592,8 @@ sub process_request { }); xCAT::MsgUtils->message("S", "xCAT: petitboot netboot: clear node(s): @nodes boot device setting."); } + + xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: starting to handle configuration..."); my $chaintab = xCAT::Table->new('chain', -create => 1); my $chainhash = $chaintab->getNodesAttribs(\@nodes, ['currstate']); my $noderestab = xCAT::Table->new('noderes', -create => 1); @@ -538,13 +617,10 @@ sub process_request { $tftpdir = $globaltftpdir; } $response{node}->[0]->{name}->[0] = $_; - if ($args[0] eq 'stat') { - $response{node}->[0]->{data}->[0] = getstate($_, $tftpdir); - $callback->(\%response); - } elsif ($args[0]) { #If anything else, send it on to the destiny plugin, then setstate + if ($args[0]) { # send it on to the destiny plugin, then setstate my $ent = $typehash->{$_}->[0]; my $osimgname = $ent->{'provmethod'}; - my $linuximghash = $linuximghash = $linuximgtab->getAttribs({ imagename => $osimgname }, 'boottarget', 'addkcmdline'); + my $linuximghash = $linuximgtab->getAttribs({ imagename => $osimgname }, 'boottarget', 'addkcmdline'); ($rc, $errstr) = setstate($_, \%bphash, $chainhash, $machash, $tftpdir, $nodereshash, $linuximghash); @@ -555,11 +631,10 @@ sub process_request { } } } # end of foreach node + xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: Finish to handle configurations"); my @normalnodeset = keys %normalnodes; my @breaknetboot = keys %breaknetbootnodes; - - #print "yaboot:inittime=$inittime; normalnodeset=@normalnodeset; breaknetboot=@breaknetboot\n"; my %osimagenodehash; for my $nn (@normalnodeset) { @@ -570,7 +645,7 @@ sub process_request { } #Don't bother to try dhcp binding changes if sub_req not passed, i.e. service node build time - unless (($args[0] eq 'stat') || ($inittime) || ($args[0] eq 'offline')) { + unless (($inittime) || ($args[0] eq 'offline')) { #dhcp stuff my $do_dhcpsetup = 1; @@ -580,16 +655,17 @@ sub process_request { if ($t_entry =~ /0|n|N/) { $do_dhcpsetup = 0; } } if ($do_dhcpsetup) { - if ($::request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command - xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: issue makedhcp request"); - $sub_req->({ command => ['makedhcp'], arg => ['-l'], - node => \@normalnodeset }, $callback); - } else { - xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: issue makedhcp request"); - $sub_req->({ command => ['makedhcp'], - node => \@normalnodeset }, $callback); - } + my @parameter; + push @parameter, '-l' if ($::request->{'_disparatetftp'}->[0]); + xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: issue makedhcp request"); + + $sub_req->({ command => ['makedhcp'], + arg => \@parameter, + node => \@normalnodeset }, $callback); + } else { + xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: dhcpsetup=$do_dhcpsetup"); } + } if ($args[0] eq 'offline') { @@ -599,7 +675,7 @@ sub process_request { } #now run the end part of the prescripts - unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') + unless ($args[0] eq '') { # or $args[0] eq 'enact') $errored = 0; if ($request->{'_disparatetftp'}->[0]) { #the call is distrubuted to the service node already, so only need to handles my own children xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: issue runendpre request"); @@ -609,7 +685,7 @@ sub process_request { } else { #nodeset did not distribute to the service node, here we need to let runednpre to distribute the nodes to their masters xCAT::MsgUtils->trace($verbose_on_off, "d", "petitboot: issue runendpre request"); $sub_req->({ command => ['runendpre'], - node => \@rnodes, + node => \@nodes, arg => [ $args[0] ] }, \&pass_along); } if ($errored) { @@ -620,6 +696,15 @@ sub process_request { return; } } + + # Return error codes if there are failed nodes + if (%failurenodes) { + my $rsp; + $rsp->{errorcode}->[0] = 1; + $rsp->{error}->[0] = "Failed to generate petitboot configurations for some node(s) on $::myxcatname. Check xCAT log file for more details."; + $callback->($rsp); + return; + } } #---------------------------------------------------------------------------- diff --git a/xCAT-server/lib/xcat/plugins/rinstall.pm b/xCAT-server/lib/xcat/plugins/rinstall.pm index ea2f0003a..787fbc63d 100644 --- a/xCAT-server/lib/xcat/plugins/rinstall.pm +++ b/xCAT-server/lib/xcat/plugins/rinstall.pm @@ -335,6 +335,7 @@ sub rinstall { $rsp->{data}->[0] = "Provision node(s): @nodes"; xCAT::MsgUtils->message("I", $rsp, $callback); } + %nodes = map { $_, 1 } @nodes; # Run nodeset $noderange $parameter @@ -355,8 +356,8 @@ sub rinstall { push @{ $rsp->{data} }, @$res; xCAT::MsgUtils->message("D", $rsp, $callback); } - unless ($rc == 0) { + unless ($rc == 0) { # We got an error with the nodeset my @successnodes; my @failurenodes; @@ -364,12 +365,8 @@ sub rinstall { my @lines = @$res; foreach my $line (@lines) { $rsp->{data}->[0] = $line; - if (($line =~ /: install/) or ($line =~ /: netboot/)) { - my $successnode; - my $restline; - ($successnode, $restline) = split(/:/, $line, 2); - $nodes{$successnode} = 0; - push @successnodes, $successnode; + if($line =~ /The (\S+) can not be resolved/){ + push @failurenodes,$1; } if ($line =~ /dhcp server is not running/) { my $rsp = {}; @@ -380,18 +377,18 @@ sub rinstall { } xCAT::MsgUtils->message("I", $rsp, $callback); } - foreach my $node (@nodes) { - if ($nodes{$node} == 1) { - push @failurenodes, $node; - } + + foreach my $node (@failurenodes) { + delete $nodes{$node}; } + my $rsp = {}; if (0+@failurenodes > 0) { $rsp->{error}->[0] = "Failed to run 'nodeset' against the following nodes: @failurenodes"; $rsp->{errorcode}->[0] = 1; xCAT::MsgUtils->message("E", $rsp, $callback); } - @nodes = @successnodes; + @nodes = keys %nodes; } # Group the nodes according to the nodehm.mgt @@ -591,30 +588,6 @@ sub rinstall { } } - # Check if they asked to bring up a console (-c) from rinstall always for winstall - $req->{startconsole}->[0] = 0; - if ($command =~ /rinstall/) { - - # For rinstall, the -c|--console option can provide the remote console for only 1 node - if ($CONSOLE) { - if (scalar @nodes != 1) { - my $rsp = {}; - $rsp->{error}->[0] = "rinstall -c only accepts one node in the noderange. See winstall for support of consoles on multiple nodes."; - $rsp->{errorcode}->[0] = 1; - xCAT::MsgUtils->message("E", $rsp, $callback); - return 1; - } - else { - # Tell rinstall client ok to start rcons - $req->{startconsole}->[0] = 1; - } - } - } - elsif ($command =~ /winstall/) { - - # Command winstall can start a wcons command to multiple nodes for monitoring the provision cycle - $req->{startconsole}->[0] = 1; - } return 0; } diff --git a/xCAT-server/lib/xcat/plugins/xnba.pm b/xCAT-server/lib/xcat/plugins/xnba.pm index dd8fe9d1c..7250f1b6c 100644 --- a/xCAT-server/lib/xcat/plugins/xnba.pm +++ b/xCAT-server/lib/xcat/plugins/xnba.pm @@ -331,10 +331,12 @@ sub preprocess_request { Getopt::Long::Configure("bundling"); Getopt::Long::Configure("pass_through"); my $HELP; + my $ALLFLAG; my $VERSION; my $VERBOSE; if (!GetOptions('h|?|help' => \$HELP, 'v|version' => \$VERSION, + 'a' =>\$ALLFLAG, 'V' => \$VERBOSE #>>>>>>>used for trace log>>>>>>> )) { if ($usage{$command}) { @@ -380,6 +382,13 @@ sub preprocess_request { return; } + if ($ARGV[0] ne "stat" && $ALLFLAG) { + my %rsp; + $rsp{error}->[0] = "'-a' could only be used with 'stat' subcommand."; + $rsp{errorcode}->[0] = 1; + $callback1->(\%rsp); + return; + } #Assume shared tftp directory for boring people, but for cool people, help sync up tftpdirectory contents when #they specify no sharedtftp in site table @@ -394,12 +403,12 @@ sub preprocess_request { xCAT::ServiceNodeUtils->getSNandCPnodes(\@$nodes, \@SN, \@CN); unless (($args[0] eq 'stat') or ($args[0] eq 'enact')) { # mix is ok for these options if ((@SN > 0) && (@CN > 0)) { # there are both SN and CN - my $rsp; - $rsp->{data}->[0] = + my %rsp; + $rsp{errorcode}->[0] = 1; + $rsp{error}->[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); + $callback1->(\%rsp); return; - } } @@ -408,9 +417,39 @@ sub preprocess_request { return [$req]; } if (@CN > 0) { # if compute nodes broadcast to all servicenodes - return xCAT::Scope->get_broadcast_scope_with_parallel($req); + + my @sn = xCAT::ServiceNodeUtils->getSNList(); + unless ( @sn > 0 ) { + return xCAT::Scope->get_parallel_scope($req) + } + + my $mynodeonly = 0; + my @entries = xCAT::TableUtils->get_site_attribute("disjointdhcps"); + my $t_entry = $entries[0]; + if (defined($t_entry)) { + $mynodeonly = $t_entry; + } + $req->{'_disjointmode'} = [$mynodeonly]; + xCAT::MsgUtils->trace(0, "d", "xnba: disjointdhcps=$mynodeonly"); + + if ($mynodeonly == 0 || $ALLFLAG) { # broadcast to all service nodes + return xCAT::Scope->get_broadcast_scope_with_parallel($req, \@sn); + } + + my $sn_hash = xCAT::ServiceNodeUtils->getSNformattedhash(\@CN, "xcat", "MN"); + my @dhcpsvrs = (); + my $ntab = xCAT::Table->new('networks'); + if ($ntab) { + foreach (@{ $ntab->getAllEntries() }) { + next unless ($_->{dynamicrange}); + # if dynamicrange specified but dhcpserver was not - issue error message + push @dhcpsvrs, $_->{dhcpserver} if ($_->{dhcpserver}) + } + } + return xCAT::Scope->get_broadcast_disjoint_scope_with_parallel($req, $sn_hash, \@dhcpsvrs); } } + # Do not dispatch to service nodes if non-sharedtftp or the node range contains only SNs. return xCAT::Scope->get_parallel_scope($req); } @@ -437,12 +476,14 @@ sub process_request { #>>>>>>>used for trace log end>>>>>>> + my @hostinfo = xCAT::NetworkUtils->determinehostname(); + $::myxcatname = $hostinfo[-1]; + xCAT::MsgUtils->trace(0, "d", "xnba: running on $::myxcatname"); if (ref($::XNBA_request->{node})) { @rnodes = @{ $::XNBA_request->{node} }; } else { if ($::XNBA_request->{node}) { @rnodes = ($::XNBA_request->{node}); } } - unless (@rnodes) { if ($usage{ $::XNBA_request->{command}->[0] }) { $::XNBA_callback->({ data => $usage{ $::XNBA_request->{command}->[0] } }); @@ -450,60 +491,98 @@ sub process_request { return; } - #if not shared, then help sync up - if ($::XNBA_request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command - @nodes = (); - my @hostinfo = xCAT::NetworkUtils->determinehostname(); - my $cur_xmaster = pop @hostinfo; - xCAT::MsgUtils->trace(0, "d", "xnba: running on $cur_xmaster"); - - # Get current server managed node list - my $sn_hash = xCAT::ServiceNodeUtils->getSNformattedhash(\@rnodes, "xcat", "MN"); - my %managed = {}; - foreach (@{ $sn_hash->{$cur_xmaster} }) { $managed{$_} = 1; } - - # Whatever the node managed by this xcatmaster explicitly, if the node in same subnet, we need to handle its boot configuration files - foreach (@rnodes) { - if (xCAT::NetworkUtils->nodeonmynet($_)) { - push @nodes, $_; + if ($args[0] eq 'stat') { + my $noderestab = xCAT::Table->new('noderes'); #in order to detect per-node tftp directories + my %nrhash = %{ $noderestab->getNodesAttribs(\@rnodes, [qw(tftpdir)]) }; + foreach my $node (@rnodes) { + my %response; + my $tftpdir; + if ($nrhash{$node}->[0] and $nrhash{$node}->[0]->{tftpdir}) { + $tftpdir = $nrhash{$node}->[0]->{tftpdir}; } else { - my $msg = "xnba configuration file was not created for node [$_] because sharedtftp attribute is not set and the node is not on same network as this xcatmaster"; - if ( $cur_xmaster ) { - $msg .= ": $cur_xmaster"; - } - if ( exists( $managed{$_} ) ) { - # report error when it is under my control but I cannot handle it. - my $rsp; - $rsp->{data}->[0] = $msg; - xCAT::MsgUtils->message("E", $rsp, $::XNBA_callback); - } else { - xCAT::MsgUtils->message("S", $msg); - } - + $tftpdir = $globaltftpdir; } + $response{node}->[0]->{name}->[0] = $node; + $response{node}->[0]->{data}->[0] = getstate($node, $tftpdir); + $::XNBA_callback->(\%response); } - } else { - @nodes = @rnodes; - } - - #>>>>>>>used for trace log>>>>>>> - my $str_node = join(" ", @nodes); - xCAT::MsgUtils->trace(0, "d", "xnba: nodes are $str_node"); - - # return directly if no nodes in the same network - unless (@nodes) { - xCAT::MsgUtils->message("S", "xCAT: xnba netboot: no valid nodes. Stop the operation on this server."); return; } - if (ref($::XNBA_request->{arg})) { - @args = @{ $::XNBA_request->{arg} }; + my @nodes = (); + # Filter those nodes which have bad DNS: not resolvable or inconsistent IP + my %failurenodes = (); + my %preparednodes = (); + foreach (@rnodes) { + my $ipret = xCAT::NetworkUtils->checkNodeIPaddress($_); + my $errormsg = $ipret->{'error'}; + my $nodeip = $ipret->{'ip'}; + if ($errormsg) {# Add the node to failure set + xCAT::MsgUtils->trace(0, "E", "xnba: Defined IP address of $_ is $nodeip. $errormsg"); + unless ($nodeip) { + $failurenodes{$_} = 1; + } + } + if ($nodeip) { + $preparednodes{$_} = $nodeip; + } + } + + #if not shared tftpdir, then filter, otherwise, set up everything + if ($::XNBA_request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command + # Filter those nodes not in the same subnet, and print error message in log file. + foreach (keys %preparednodes) { + # Only handle its boot configuration files if the node in same subnet + if (xCAT::NetworkUtils->nodeonmynet($preparednodes{$_})) { + push @nodes, $_; + } else { + xCAT::MsgUtils->trace(0, "W", "xnba: configuration file was not created for [$_] because the node is not on the same network as this server"); + delete $preparednodes{$_}; + } + } } else { - @args = ($::XNBA_request->{arg}); + @nodes = keys %preparednodes; + } + + my $str_node = join(" ", @nodes); + xCAT::MsgUtils->trace(0, "d", "xnba: nodes are $str_node") if ($str_node); + + # Return directly if no nodes in the same network, need to report error on console if its managed nodes are not handled. + unless (@nodes) { + xCAT::MsgUtils->message("S", "xCAT: xnba netboot: no valid nodes. Stop the operation on this server."); + + # If non-shared tftproot and non disjoint mode, need to figure out if no nodes here is a normal case. + if ($::XNBA_request->{'_disparatetftp'}->[0] && $::XNBA_request->{'_disjointmode'}->[0] != 1) { + # Find out which nodes are really mine only when not sharedtftp and not disjoint mode. + my %iphash = (); + # flag the IPs or names in iphash + foreach (@hostinfo) { $iphash{$_} = 1; } + + # Get managed node list under current server + # The node will be under under 'site.master' if no 'noderes.servicenode' is defined + my $sn_hash = xCAT::ServiceNodeUtils->getSNformattedhash(\@rnodes, "xcat", "MN"); + my $req2manage = 0; + foreach (keys %$sn_hash) { + if (exists($iphash{$_})) { + $req2manage = 1; + last; + } + } + if ($req2manage == 0) { + #No nodes are required to be handled, quit without error. + return; + } + } + # Okay, now report error as no nodes are handled. + my $rsp; + $rsp->{errorcode}->[0] = 1; + $rsp->{error}->[0] = "Failed to generate xnba configurations for some node(s) on $::myxcatname. Check xCAT log file for more details."; + $::XNBA_callback->($rsp); + return; } #now run the begin part of the prescripts - unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') { + unless ($args[0] eq '') { # or $args[0] eq 'enact') { $errored = 0; if ($::XNBA_request->{'_disparatetftp'}->[0]) { #the call is distrubuted to the service node already, so only need to handles my own children xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: the call is distrubuted to the service node already, so only need to handles my own children"); @@ -515,7 +594,7 @@ sub process_request { xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: nodeset did not distribute to the service node"); xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: issue runbeginpre request"); $sub_req->({ command => ['runbeginpre'], - node => \@rnodes, + node => \@nodes, arg => [ $args[0] ] }, \&pass_along); } if ($errored) { @@ -547,7 +626,7 @@ sub process_request { if (!$inittime) { $inittime = 0; } my %bphash; - unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') { + unless ($args[0] eq '') { # or $args[0] eq 'enact') { $errored = 0; xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: issue setdestiny request"); $sub_req->({ command => ['setdestiny'], @@ -562,6 +641,7 @@ sub process_request { } } + xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: starting to handle configuration..."); #Time to actually configure the nodes, first extract database data with the scalable calls my $chaintab = xCAT::Table->new('chain'); my $noderestab = xCAT::Table->new('noderes'); #in order to detect per-node tftp directories @@ -589,10 +669,7 @@ sub process_request { mkpath($tftpdir . "/xcat/xnba/nodes/"); my %response; $response{node}->[0]->{name}->[0] = $_; - if ($args[0] eq 'stat') { - $response{node}->[0]->{data}->[0] = getstate($_, $tftpdir); - $::XNBA_callback->(\%response); - } elsif ($args[0]) { #If anything else, send it on to the destiny plugin, then setstate + if ($args[0]) { # Send it on to the destiny plugin, then setstate my $rc; my $errstr; my $ent = $typehash->{$_}->[0]; @@ -617,45 +694,38 @@ sub process_request { } } } + xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: Finish to handle configurations"); # for offline operation, remove the dhcp entries if ($args[0] eq 'offline') { $sub_req->({ command => ['makedhcp'], arg => ['-d'], node => \@nodes }, $::XNBA_callback); } - #dhcp stuff -- inittime is set when xcatd on sn is started - unless (($args[0] eq 'stat') || ($inittime) || ($args[0] eq 'offline')) { + unless (($inittime) || ($args[0] eq 'offline')) { my $do_dhcpsetup = 1; - - #my $sitetab = xCAT::Table->new('site'); - #if ($sitetab) { - #(my $ref) = $sitetab->getAttribs({key => 'dhcpsetup'}, 'value'); my @entries = xCAT::TableUtils->get_site_attribute("dhcpsetup"); my $t_entry = $entries[0]; if (defined($t_entry)) { if ($t_entry =~ /0|n|N/) { $do_dhcpsetup = 0; } } - - #} - if ($do_dhcpsetup) { - if ($::XNBA_request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command - xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: issue makedhcp request"); - $sub_req->({ command => ['makedhcp'], arg => ['-l'], - node => \@nodes }, $::XNBA_callback); - } else { - xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: issue makedhcp request"); - $sub_req->({ command => ['makedhcp'], - node => \@nodes }, $::XNBA_callback); - } + my @parameter; + push @parameter, '-l' if ($::request->{'_disparatetftp'}->[0]); + xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: issue makedhcp request"); + + $sub_req->({ command => ['makedhcp'], + arg => \@parameter, + node => \@nodes }, $::XNBA_callback); + } else { + xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: dhcpsetup=$do_dhcpsetup"); } } #now run the end part of the prescripts - unless ($args[0] eq 'stat') { # or $args[0] eq 'enact') + unless ($args[0] eq '') { # or $args[0] eq 'enact') $errored = 0; - if ($::XNBA_request->{'_disparatetftp'}->[0]) { #the call is distrubuted to the service node already, so only need to handles my own children + if ($::XNBA_request->{'_disparatetftp'}->[0]) { #the call is distrubuted to the service node already, so only need to handle my own children xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: issue runendpre request"); $sub_req->({ command => ['runendpre'], node => \@nodes, @@ -663,7 +733,7 @@ sub process_request { } else { #nodeset did not distribute to the service node, here we need to let runednpre to distribute the nodes to their masters xCAT::MsgUtils->trace($verbose_on_off, "d", "xnba: issue runendpre request"); $sub_req->({ command => ['runendpre'], - node => \@rnodes, + node => \@nodes, arg => [ $args[0] ] }, \&pass_along); } if ($errored) { @@ -674,6 +744,15 @@ sub process_request { } } + # Return error codes if there are failed nodes + if (%failurenodes) { + my $rsp; + $rsp->{errorcode}->[0] = 1; + $rsp->{error}->[0] = "Failed to generate xnba configurations for some node(s) on $::myxcatname. Check xCAT log file for more details."; + $::XNBA_callback->($rsp); + return; + } + } diff --git a/xCAT-server/share/xcat/netboot/ubuntu/compute.ubuntu16.04.2.pkglist b/xCAT-server/share/xcat/netboot/ubuntu/compute.ubuntu16.04.2.pkglist new file mode 120000 index 000000000..e08894338 --- /dev/null +++ b/xCAT-server/share/xcat/netboot/ubuntu/compute.ubuntu16.04.2.pkglist @@ -0,0 +1 @@ +compute.ubuntu16.04.1.pkglist \ No newline at end of file diff --git a/xCAT-test/autotest/bundle/rhels7.4_ppc64.bundle b/xCAT-test/autotest/bundle/rhels7.4_ppc64.bundle new file mode 100644 index 000000000..34e13e857 --- /dev/null +++ b/xCAT-test/autotest/bundle/rhels7.4_ppc64.bundle @@ -0,0 +1,314 @@ +reg_linux_diskfull_installation_flat +updatenode_h +updatenode_v +updatenode_diskful_syncfiles +updatenode_diskful_syncfiles_rename +updatenode_diskful_syncfiles_dir +updatenode_diskful_syncfiles_multi_files +updatenode_syncfile_EXECUTE +updatenode_syncfile_EXECUTEALWAYS +updatenode_syncfile_APPEND +updatenode_syncfile_MERGE +updatenode_P_script1 +updatenode_P_script2 +updatenode_f_incompatible_flags +updatenode_k_incompatible_flags +updatenode_diskful_syncfiles_P_script1 +updatenode_script3 +updatenode_P_script1_script2 +updatenode_without_flag +confignetwork_secondarynic_nicnetworks_updatenode_false +confignetwork_secondarynic_nicips_updatenode_false +confignetwork_secondarynic_nictype_updatenode_false +chdef_null +chdef_t_node +chdef_t_network +chdef_p +chdef_m +chdef_z +chdef_group +chdef_group_p +chdef_dynamic_group +chdef_multiple_keys +chdef_n +chdef_t_o_error +chtab_null +chtab_d +chtab_modify_node +chtab_modify_key +chtab_h +chtab_v +copycds_n +copycds_a_err +copycds_n_err +packimage_o_p_a_m +packimage_imagename +packimage_h +packimage_v +pping_h +pping_v +pping_node +getmacs_noderange +getmacs_d +getmacs_f_D +gettab_key_table +gettab_H +gettab_err +gettab_h +lsdef_null +lsdef_a +lsdef_t_o_l +lsdef_t_o_l_z +lsdef_t +lsdef_t_i_o +lsdef_t_w +lsdef_t_err +lslite_i +lslite_noderange +lslite_h +makeconservercf_null +makeconservercf_noderange +makeconservercf_d +makedhcp_n +makedhcp_a +makedhcp_a_d +makedhcp_d +mkdef_null +mkdef_z +mkdef_t_o_error +nodeadd_noderange +nodeadd_err_symbol +nodeadd_null +nodeadd_noderange_nodetype +nodeadd_v +nodeadd_h +nodegrpch_v +nodegrpch_h +nodegrpch_groups +nodegrpch_err +nodech_noderange_table +nodech_noderange_table_comma +nodech_noderange_table_arrow +nodech_noderanage_table_at +nodech_delete +nodech_error_node +nodech_error_table +nodech_h +nodech_v +nodech_noderange_table_include +nodech_noderange_table_uninclude +nodech_noderange_table_equal +nodech_noderange_table_unequal +nodech_noderange_shortname_groups +nodech_noderange_shortname_tags +nodech_noderange_shortname_mgt +nodels_null +nodels_H +nodels_noderange +nodels_err_symbol +nodels_err_noderange +nodels_noderange_shortname_groups +nodels_noderange_shortname_tags +nodels_noderange_shortname_mgt +nodels_table_include +nodels_noderange_table_uninclude +nodels_noderange_table_equal +nodels_noderange_table_unequal +nodels_b +nodels_S +nodels_noderange_table +nodels_tablevalue +nodels_tablevalue_tablecolumn +nodels_noderange_tablecolumn +nodels_h +nodels_v +xcatstanzafile_normal +xcatstanzafile_colon +xcatstanzafile_attribute +xcatstanzafile_objtype +xcatstanzafile_tab +xcatstanzafile_multattr +xcatstanzafile_defaultvalue +xcatstanzafile_specificvalue +noderm_noderange +noderm_h +noderm_null +noderm_err_node +nodeset_stat +nodeset_noderange +nodestat_err_node +rinv_bus +rinv_config +rinv_serial +rinv_model +rinv_firm +rinv_all +rinv_noderange_err +rmdef_null +rmdef_t_err +rpower_off +rpower_stat +rpower_boot +rpower_on +rpower_reset +rpower_noderange +rpower_noderange_nodeps +rpower_err_noderange +rscan_noderange +rscan_x +rscan_z +rscan_w +rscan_x_w +rscan_z_w +rvitals_lcds +rvitals_all +rvitals_noderange_err +tabdump_table +tabdump_d +tabdump_v +tabdump_h +tabdump_help +tabdump_w_match +tabdump_w_equal +tabdump_w_ne +tabdump_w_notmatch +tabdump_w_gt +tabdump_w_ge +tabdump_w_lt +tabdump_w_le +tabdump_f_d +tabdump_d_nodehm +tabprune_h +tabprune_v +tabprune_a_eventlog +tabprune_V_a_eventlog +tabprune_p_auditlog +tabprune_i_auditlog +tabprune_V_n_auditlog +tabgrep_node +tabgrep_null +tabgrep_h +tabgrep_err +tabrestore_table +tabrestore_null +tabrestore_h +tabrestore_err +dumpxCATdb_h +dumpxCATdb_v +dumpxCATdb_p_nullskiptables +dumpxCATdb_a_p_nullskiptables +dumpxCATdb_p_skiptables +dumpxCATdb_a_p_skiptables +dumpxCATdb_p_nullskiptables_V +dumpxCATdb_a_p_nullskiptables_V +dumpxCATdb_p_V +restorexCAT_h +restorexCATdb_v +restorexCATdb_p_V +restorexCATdb_a_p_V +restorexCATdb_wrongpath +regnotif_null +regnotif_o +regnotif_err +regnotif_h +regnotif_v +unregnotif_null +unregnotif_f +unregnotif_h +unregnotif_v +lsxcatd_null +lsxcatd_h +lsxcatd_d +lsxcatd_a +makehosts_help +makehosts_n_noderange +makehosts_h +makehosts_null +makehosts_l +makehosts_d +makehosts_n +makehost_n_r +xdcp_src_dst +makedns_h +makedns_d_node +makedns_n +makedns +noderange_individual_node +noderange_individual_grp +noderange_node01-node10 +noderange_group1-group3 +noderange_10-20 +noderange_XCAT_NODE_PREFIX +noderange_XCAT_NODE_SUFFIX +noderange_exclusion +noderange_group_intersection +copycds_iso +copycds_a +copycds_n_a +xdsh_h +xdsh_V +xdsh_regular_command +xdsh_Q_command +xdsh_c_cn +xdsh_e_filename +xdsh_E +xdsh_i_linux +xdsh_t +xdsh_q +xdsh_T +xdsh_o +psh_h +psh_v +psh_node_cmd_linux +psh_l +psh_i +prsync_h +prsync_v +prsync_dir_node +prsync_file_node +switchdiscover_range_default +switchdiscover_h +switchdiscover_range_s +switchdiscover_range_default_w +switchdiscover_range_r +switchdiscover_range_x +switchdiscover_range_z +switchdiscover_range_z_V +makentp_v +makentp_h +nodeset_check_warninginfo +runcmdinstaller_h +runcmdinstaller_command +get_xcat_postscripts_loginfo +updatenode_postscripts_loginfo +bmcdiscover_h +bmcdiscover_nmap_range +bmcdiscover_v +bmcdiscover_check_paswd +bmcdiscover_check_passwd_wrong +bmcdiscover_get_ipsource +bmcdiscover_range_w +bmcdiscover_range_z +xcatd_start +xcatd_stop +xcatd_restart +run_command_with_XCATBYPASS +disable_root_permission_in_policy_table +assign_certain_command_permission +xcatconfig_u_check_xcatsslversion_rhels_sles +reg_linux_diskless_installation_flat +packimage_m_cpio_c_gzip +packimage_m_cpio_c_xz +packimage_m_tar_c_gzip +packimage_m_tar_c_xz +packimage_m_invalid_archive_method +packimage_m_invalid_compress_method +reg_linux_statelite_installation_flat +SN_setup_case +reg_linux_diskfull_installation_hierarchy +reg_linux_diskless_installation_hierarchy +reg_linux_statelite_installation_hierarchy_by_ramdisk +reg_linux_statelite_installation_hierarchy_by_nfs +redhat_migration1 +redhat_migration2 +clean_up_env diff --git a/xCAT-test/autotest/bundle/rhels7.4_ppc64le.bundle b/xCAT-test/autotest/bundle/rhels7.4_ppc64le.bundle new file mode 100644 index 000000000..2984952bb --- /dev/null +++ b/xCAT-test/autotest/bundle/rhels7.4_ppc64le.bundle @@ -0,0 +1,310 @@ +setup_vm +reg_linux_diskless_installation_flat +reg_linux_diskfull_installation_flat +go_xcat_noinput +updatenode_h +updatenode_v +updatenode_diskful_syncfiles +updatenode_diskful_syncfiles_rename +updatenode_diskful_syncfiles_dir +updatenode_diskful_syncfiles_multi_files +updatenode_syncfile_EXECUTE +updatenode_syncfile_EXECUTEALWAYS +updatenode_syncfile_APPEND +updatenode_syncfile_MERGE +updatenode_P_script1 +updatenode_P_script2 +updatenode_f_incompatible_flags +updatenode_k_incompatible_flags +updatenode_diskful_syncfiles_P_script1 +updatenode_script3 +updatenode_P_script1_script2 +updatenode_without_flag +confignetwork_s_installnic_secondarynic_updatenode +confignetwork_secondarynic_updatenode +confignetwork_secondarynic_nicaliases_updatenode +confignetwork_secondarynic_nicextraparams_updatenode +confignetwork_disable_set_to_yes +confignetwork_disable_set_to_1 +confignetwork_niccustomscripts +confignetwork_secondarynic_thirdnic_multiplevalue_updatenode +confignetwork_secondarynic_nicnetworks_updatenode_false +confignetwork_secondarynic_nicips_updatenode_false +confignetwork_secondarynic_nictype_updatenode_false +chdef_null +chdef_t_node +chdef_t_network +chdef_p +chdef_m +chdef_z +chdef_group +chdef_group_p +chdef_dynamic_group +chdef_multiple_keys +chdef_n +chdef_t_o_error +chtab_null +chtab_d +chtab_modify_node +chtab_modify_key +chtab_h +chtab_v +copycds_iso +copycds_n +copycds_a +copycds_n_a +copycds_a_err +copycds_n_err +packimage_o_p_a_m +packimage_imagename +packimage_h +packimage_v +pping_h +pping_v +pping_node +gettab_key_table +gettab_H +gettab_err +gettab_h +lsdef_null +lsdef_a +lsdef_t_o_l +lsdef_t_o_l_z +lsdef_t +lsdef_t_i_o +lsdef_t_w +lsdef_t_err +lslite_i +lslite_noderange +lslite_h +makeconservercf_null +makeconservercf_noderange +makeconservercf_d +makedhcp_n +makedhcp_a +makedhcp_a_d +makedhcp_d +mkdef_null +mkdef_z +mkdef_t_o_error +nodeadd_noderange +nodeadd_err_symbol +nodeadd_null +nodeadd_noderange_nodetype +nodeadd_v +nodeadd_h +nodegrpch_v +nodegrpch_h +nodegrpch_groups +nodegrpch_err +nodech_noderange_table +nodech_noderange_table_comma +nodech_noderange_table_arrow +nodech_noderanage_table_at +nodech_delete +nodech_error_node +nodech_error_table +nodech_h +nodech_v +nodech_noderange_table_include +nodech_noderange_table_uninclude +nodech_noderange_table_equal +nodech_noderange_table_unequal +nodech_noderange_shortname_groups +nodech_noderange_shortname_tags +nodech_noderange_shortname_mgt +nodels_null +nodels_H +nodels_noderange +nodels_err_symbol +nodels_err_noderange +nodels_noderange_shortname_groups +nodels_noderange_shortname_tags +nodels_noderange_shortname_mgt +nodels_table_include +nodels_noderange_table_uninclude +nodels_noderange_table_equal +nodels_noderange_table_unequal +nodels_b +nodels_S +nodels_noderange_table +nodels_tablevalue +nodels_tablevalue_tablecolumn +nodels_noderange_tablecolumn +nodels_h +nodels_v +xcatstanzafile_normal +xcatstanzafile_colon +xcatstanzafile_attribute +xcatstanzafile_objtype +xcatstanzafile_tab +xcatstanzafile_multattr +xcatstanzafile_defaultvalue +xcatstanzafile_specificvalue +noderm_noderange +noderm_h +noderm_null +noderm_err_node +nodeset_stat +nodeset_noderange +nodestat_err_node +rinv_noderange_err +rmdef_null +rmdef_t_err +rpower_off +rpower_stat +rpower_boot +rpower_on +rpower_reset +rpower_noderange +rpower_noderange_nodeps +rpower_err_noderange +rvitals_noderange_err +tabdump_table +tabdump_d +tabdump_v +tabdump_h +tabdump_help +tabdump_w_match +tabdump_w_equal +tabdump_w_ne +tabdump_w_notmatch +tabdump_w_gt +tabdump_w_ge +tabdump_w_lt +tabdump_w_le +tabdump_f_d +tabdump_d_nodehm +tabprune_h +tabprune_v +tabprune_a_eventlog +tabprune_V_a_eventlog +tabprune_p_auditlog +tabprune_i_auditlog +tabprune_V_n_auditlog +tabgrep_node +tabgrep_null +tabgrep_h +tabgrep_err +tabrestore_table +tabrestore_null +tabrestore_h +tabrestore_err +dumpxCATdb_h +dumpxCATdb_v +dumpxCATdb_p_nullskiptables +dumpxCATdb_a_p_nullskiptables +dumpxCATdb_p_skiptables +dumpxCATdb_a_p_skiptables +dumpxCATdb_p_nullskiptables_V +dumpxCATdb_a_p_nullskiptables_V +dumpxCATdb_p_V +restorexCAT_h +restorexCATdb_v +restorexCATdb_p_V +restorexCATdb_a_p_V +restorexCATdb_wrongpath +regnotif_null +regnotif_o +regnotif_err +regnotif_h +regnotif_v +unregnotif_null +unregnotif_f +unregnotif_h +unregnotif_v +lsxcatd_null +lsxcatd_h +lsxcatd_d +lsxcatd_a +makehosts_h +makehosts_help +makehosts_null +makehosts_l +makehosts_d +makehosts_n +makehosts_n_noderange +makehost_n_r +xdcp_src_dst +makedns_h +makedns_d_node +makedns_n +makedns +noderange_individual_node +noderange_individual_grp +noderange_node01-node10 +noderange_group1-group3 +noderange_10-20 +noderange_XCAT_NODE_PREFIX +noderange_XCAT_NODE_SUFFIX +noderange_exclusion +noderange_group_intersection +xdsh_h +xdsh_V +xdsh_regular_command +xdsh_Q_command +xdsh_c_cn +xdsh_e_filename +xdsh_E +xdsh_i_linux +xdsh_t +xdsh_q +xdsh_T +xdsh_o +psh_h +psh_v +psh_node_cmd_linux +psh_l +psh_i +prsync_h +prsync_v +prsync_dir_node +prsync_file_node +switchdiscover_range_default +switchdiscover_h +switchdiscover_range_s +switchdiscover_range_default_w +switchdiscover_range_r +switchdiscover_range_x +switchdiscover_range_z +switchdiscover_range_z_V +nodeset_shell +nodeset_cmdline +nodeset_runimg +makentp_v +makentp_h +nodeset_check_warninginfo +runcmdinstaller_h +runcmdinstaller_command +get_xcat_postscripts_loginfo +updatenode_postscripts_loginfo +bmcdiscover_h +bmcdiscover_nmap_range +bmcdiscover_v +bmcdiscover_check_paswd +bmcdiscover_check_passwd_wrong +bmcdiscover_get_ipsource +bmcdiscover_range_w +bmcdiscover_range_z +xcatd_start +xcatd_stop +xcatd_restart +run_command_with_XCATBYPASS +disable_root_permission_in_policy_table +assign_certain_command_permission +xcatconfig_u_check_xcatsslversion_rhels_sles +packimage_m_cpio_c_gzip +packimage_m_cpio_c_xz +packimage_m_tar_c_gzip +packimage_m_tar_c_xz +packimage_m_invalid_archive_method +packimage_m_invalid_compress_method +reg_linux_statelite_installation_flat +SN_setup_case +reg_linux_diskfull_installation_hierarchy +reg_linux_diskless_installation_hierarchy +reg_linux_statelite_installation_hierarchy_by_ramdisk +reg_linux_statelite_installation_hierarchy_by_nfs +redhat_migration1 +redhat_migration2 +clean_up_env diff --git a/xCAT-test/autotest/bundle/rhels7.4_x86_64.bundle b/xCAT-test/autotest/bundle/rhels7.4_x86_64.bundle new file mode 100644 index 000000000..13f6f53c7 --- /dev/null +++ b/xCAT-test/autotest/bundle/rhels7.4_x86_64.bundle @@ -0,0 +1,239 @@ +setup_vm +reg_linux_diskfull_installation_flat +makehosts_h +makehosts_help +makehosts_n +makehosts_n_noderange +makehost_n_r +confignetwork_s_installnic_secondarynic_updatenode +confignetwork_secondarynic_updatenode +confignetwork_secondarynic_nicaliases_updatenode +confignetwork_secondarynic_nicextraparams_updatenode +confignetwork_disable_set_to_yes +confignetwork_disable_set_to_1 +confignetwork_niccustomscripts +confignetwork_secondarynic_thirdnic_multiplevalue_updatenode +confignetwork_secondarynic_nicnetworks_updatenode_false +confignetwork_secondarynic_nicips_updatenode_false +confignetwork_secondarynic_nictype_updatenode_false +chdef_null +chdef_z +chdef_t_o_error +chtab_null +chtab_d +chtab_modify_node +chtab_modify_key +chtab_h +chtab_v +packimage_o_p_a_m +packimage_imagename +packimage_h +packimage_v +packimage_m_cpio_c_gzip +packimage_m_cpio_c_xz +packimage_m_tar_c_gzip +packimage_m_tar_c_xz +packimage_m_invalid_archive_method +packimage_m_invalid_compress_method +pping_h +pping_v +pping_node +gettab_key_table +gettab_H +gettab_err +gettab_h +lsdef_null +lsdef_a +lsdef_t_o_l +lsdef_t_o_l_z +lsdef_t +lsdef_t_i_o +lsdef_t_w +lsdef_t_err +lslite_i +lslite_noderange +lslite_h +makeconservercf_null +makeconservercf_noderange +makeconservercf_d +makedhcp_n +makedhcp_a +makedhcp_a_d +makedhcp_d +mkdef_null +mkdef_z +mkdef_t_o_error +nodeadd_noderange +nodeadd_err_symbol +nodeadd_null +nodeadd_noderange_nodetype +nodeadd_v +nodeadd_h +nodegrpch_v +nodegrpch_h +nodegrpch_groups +nodegrpch_err +nodech_noderange_table +nodech_noderange_table_comma +nodech_noderange_table_arrow +nodech_noderanage_table_at +nodech_delete +nodech_error_node +nodech_error_table +nodech_h +nodech_v +nodech_noderange_table_include +nodech_noderange_table_uninclude +nodech_noderange_table_equal +nodech_noderange_table_unequal +nodech_noderange_shortname_groups +nodech_noderange_shortname_tags +nodech_noderange_shortname_mgt +nodels_null +nodels_H +nodels_noderange +nodels_err_symbol +nodels_err_noderange +nodels_noderange_shortname_groups +nodels_noderange_shortname_tags +nodels_noderange_shortname_mgt +nodels_table_include +nodels_noderange_table_uninclude +nodels_noderange_table_equal +nodels_noderange_table_unequal +nodels_b +nodels_S +nodels_noderange_table +nodels_tablevalue +nodels_tablevalue_tablecolumn +nodels_noderange_tablecolumn +nodels_h +nodels_v +xcatstanzafile_normal +xcatstanzafile_colon +xcatstanzafile_attribute +xcatstanzafile_objtype +xcatstanzafile_tab +xcatstanzafile_multattr +xcatstanzafile_defaultvalue +xcatstanzafile_specificvalue +noderm_noderange +noderm_h +noderm_null +noderm_err_node +nodeset_stat +nodeset_noderange +nodestat_noderange +nodestat_err_node +rinv_noderange_err +rmdef_null +rmdef_t_err +rpower_err_noderange +rvitals_noderange_err +tabdump_table +tabdump_d +tabdump_v +tabdump_h +tabdump_help +tabdump_w_match +tabdump_w_equal +tabdump_w_ne +tabdump_w_notmatch +tabdump_w_gt +tabdump_w_ge +tabdump_w_lt +tabdump_w_le +tabdump_f_d +tabdump_d_nodehm +tabprune_h +tabprune_v +tabprune_a_eventlog +tabprune_V_a_eventlog +tabprune_i_auditlog +tabprune_V_n_auditlog +tabgrep_node +tabgrep_null +tabgrep_h +tabgrep_err +tabrestore_table +tabrestore_null +tabrestore_h +tabrestore_err +dumpxCATdb_h +dumpxCATdb_v +dumpxCATdb_p_nullskiptables +dumpxCATdb_a_p_nullskiptables +dumpxCATdb_p_skiptables +dumpxCATdb_a_p_skiptables +dumpxCATdb_p_nullskiptables_V +dumpxCATdb_a_p_nullskiptables_V +dumpxCATdb_p_V +restorexCAT_h +restorexCATdb_v +restorexCATdb_p_V +restorexCATdb_a_p_V +restorexCATdb_wrongpath +regnotif_null +regnotif_o +regnotif_err +regnotif_h +regnotif_v +unregnotif_null +unregnotif_f +unregnotif_h +unregnotif_v +lsxcatd_null +lsxcatd_h +lsxcatd_d +lsxcatd_a +makedns_d_node +makedns_n +makedns +copycds_iso +copycds_n +copycds_a +copycds_n_a +xdsh_h +xdsh_V +xdsh_regular_command +xdsh_Q_command +xdsh_c_cn +xdsh_e_filename +xdsh_E +xdsh_i_linux +xdsh_t +xdsh_q +xdsh_T +xdsh_o +psh_h +psh_v +psh_node_cmd_linux +psh_l +psh_i +prsync_h +prsync_v +prsync_dir_node +prsync_file_node +switchdiscover_range_default +switchdiscover_h +switchdiscover_range_s +switchdiscover_range_default_w +switchdiscover_range_r +switchdiscover_range_x +switchdiscover_range_z +switchdiscover_range_z_V +nodeset_check_warninginfo +nodeset_shell +nodeset_cmdline +nodeset_runimg +xcatconfig_u_check_xcatsslversion_rhels_sles +reg_linux_diskless_installation_flat +reg_linux_statelite_installation_flat +SN_setup_case +reg_linux_diskfull_installation_hierarchy +reg_linux_diskless_installation_hierarchy +reg_linux_statelite_installation_hierarchy_by_ramdisk +reg_linux_statelite_installation_hierarchy_by_nfs +redhat_migration1 +redhat_migration2 +clean_up_env diff --git a/xCAT-test/autotest/testcase/confignetwork/cases0 b/xCAT-test/autotest/testcase/confignetwork/cases0 index 55c1f07cc..f0a21ea0e 100644 --- a/xCAT-test/autotest/testcase/confignetwork/cases0 +++ b/xCAT-test/autotest/testcase/confignetwork/cases0 @@ -422,7 +422,7 @@ cmd:mkdef -t network -o 14_1_0_0-255_255_0_0 net=14.1.0.0 mask=255.255.0.0 mgtif check:rc==0 cmd:chdef $$CN nicips.$$SECONDNIC="11.1.0.100|12.1.0.100" nictypes.$$SECONDNIC=Ethernet nicnetworks.$$SECONDNIC="11_1_0_0-255_255_0_0|12_1_0_0-255_255_0_0" nichostnamesuffixes.$$SECONDNIC="-$$SECONDNIC-1|-$$SECONDNIC-2" check:rc==0 -cmd:chdef $$CN nicips.$$THIRDNIC="13.1.0.100|14.1.0.100" nictypes.$$THIRDNIC=Ethernet nicnetworks.$$THIRDNIC="13_1_0_0-255_255_0_0|14_1_0_0-255_255_0_0" nichostnamesuffixes.$$THIRDNIC="-$$THIRDNIC-1|-$$THIRDNIC-2" +cmd:chdef $$CN nicips.$$THIRDNIC="13.1.0.200|14.1.0.100" nictypes.$$THIRDNIC=Ethernet nicnetworks.$$THIRDNIC="13_1_0_0-255_255_0_0|14_1_0_0-255_255_0_0" nichostnamesuffixes.$$THIRDNIC="-$$THIRDNIC-1|-$$THIRDNIC-2" check:rc==0 cmd:cp /etc/hosts /etc/hosts.bak cmd:rc==0 @@ -439,8 +439,8 @@ cmd:if grep SUSE /etc/*release;then xdsh $$CN "grep 11.1.0.100 /etc/sysconfig/ne check:output=~11.1.0.100 cmd:if grep SUSE /etc/*release;then xdsh $$CN "grep 12.1.0.100 /etc/sysconfig/network/ifcfg-$$SECONDNIC"; elif grep "Red Hat" /etc/*release;then xdsh $$CN "grep 12.1.0.100 /etc/sysconfig/network-scripts/ifcfg-$$SECONDNIC:1"; elif grep Ubuntu /etc/*release;then xdsh $$CN "grep 12.1.0.100 /etc/network/interfaces.d/$$SECONDNIC";else echo "Sorry,this is not supported os"; fi check:output=~12.1.0.100 -cmd:if grep SUSE /etc/*release;then xdsh $$CN "grep 13.1.0.100 /etc/sysconfig/network/ifcfg-$$THIRDNIC"; elif grep "Red Hat" /etc/*release;then xdsh $$CN "grep 13.1.0.100 /etc/sysconfig/network-scripts/ifcfg-$$THIRDNIC"; elif grep Ubuntu /etc/*release;then xdsh $$CN "grep 13.1.0.100 /etc/network/interfaces.d/$$THIRDNIC";else echo "Sorry,this is not supported os"; fi -check:output=~13.1.0.100 +cmd:if grep SUSE /etc/*release;then xdsh $$CN "grep 13.1.0.200 /etc/sysconfig/network/ifcfg-$$THIRDNIC"; elif grep "Red Hat" /etc/*release;then xdsh $$CN "grep 13.1.0.200 /etc/sysconfig/network-scripts/ifcfg-$$THIRDNIC"; elif grep Ubuntu /etc/*release;then xdsh $$CN "grep 13.1.0.200 /etc/network/interfaces.d/$$THIRDNIC";else echo "Sorry,this is not supported os"; fi +check:output=~13.1.0.200 cmd:if grep SUSE /etc/*release;then xdsh $$CN "grep 14.1.0.100 /etc/sysconfig/network/ifcfg-$$THIRDNIC"; elif grep "Red Hat" /etc/*release;then xdsh $$CN "grep 14.1.0.100 /etc/sysconfig/network-scripts/ifcfg-$$THIRDNIC:1"; elif grep Ubuntu /etc/*release;then xdsh $$CN "grep 14.1.0.100 /etc/network/interfaces.d/$$THIRDNIC";else echo "Sorry,this is not supported os"; fi check:output=~14.1.0.100 cmd:rmdef -t network -o 11_1_0_0-255_255_0_0 @@ -453,7 +453,7 @@ cmd:if grep SUSE /etc/*release;then xdsh $$CN "rm -rf /etc/sysconfig/network/ifc check:rc==0 cmd:xdsh $$CN "ip addr del 11.1.0.100/16 dev $$SECONDNIC" cmd:xdsh $$CN "ip addr del 12.1.0.100/16 dev $$SECONDNIC" -cmd:xdsh $$CN "ip addr del 13.1.0.100/16 dev $$THIRDNIC" +cmd:xdsh $$CN "ip addr del 13.1.0.200/16 dev $$THIRDNIC" cmd:xdsh $$CN "ip addr del 14.1.0.100/16 dev $$THIRDNIC" cmd:if [ -e /tmp/CN.standa ]; then rmdef $$CN; cat /tmp/CN.standa | mkdef -z; rm -rf /tmp/CN.standa; fi check:rc==0 diff --git a/xCAT-test/autotest/testcase/genesis/genesistest.pl b/xCAT-test/autotest/testcase/genesis/genesistest.pl index f7b376049..5d24812a0 100755 --- a/xCAT-test/autotest/testcase/genesis/genesistest.pl +++ b/xCAT-test/autotest/testcase/genesis/genesistest.pl @@ -18,6 +18,7 @@ my $check_genesis_file; my $noderange; my $clear_env; my $help = 0; +my $nodestanza; $::USAGE = "Usage: $program_name -h $program_name -n -s @@ -79,7 +80,11 @@ my $master=`lsdef -t site -i master -c 2>&1 | awk -F'=' '{print \$2}'`; if (!$master) { $master=hostname(); } chomp($master); print "master is $master\n"; - +$nodestanza="/tmp/$noderange.stanza"; +if (!(-e $nodestanza)) { + `lsdef $noderange -z > $nodestanza`; + `chdef $noderange xcatmaster= `; +} #################################### ####nodesetshell test for genesis #################################### @@ -306,6 +311,10 @@ sub clearenv { send_msg(0, "rinstall node failed"); exit 1; } + if (-e "$nodestanza") { + `cat $nodestanza | chdef -z`; + unlink("$nodestanza"); + } return 0; } #################################### diff --git a/xCAT-test/autotest/testcase/reventlog/cases0 b/xCAT-test/autotest/testcase/reventlog/cases0 index d772ed285..cbb3aceba 100644 --- a/xCAT-test/autotest/testcase/reventlog/cases0 +++ b/xCAT-test/autotest/testcase/reventlog/cases0 @@ -1,6 +1,6 @@ start:reventlog_null cmd:reventlog -check:rc!=0 +check:rc==0 check:output=~Usage end start:reventlog_all @@ -11,12 +11,12 @@ end start:reventlog_clear cmd:reventlog $$CN clear check:rc==0 -check:output=~$$CN\s*:\s*clear +check:output=~$$CN\s*:\s*clear|SEL cleared end start:reventlog_numofentries cmd:reventlog $$CN 5 check:rc==0 -check:output=~$$CN\s*:\s*.*\d\d/\d\d/\d\d\s*\S+ +check:output=~$$CN\s*:\s*.*\d\d/\d\d/\d\d\s*\S+|$$CN: no SEL entries cmd:reventlog $$CN 3 | wc -l -check:output=~\s*3\s* +check:output=~\s*1\s* end diff --git a/xCAT-test/autotest/testcase/rinv/cases0 b/xCAT-test/autotest/testcase/rinv/cases0 index 68fb4b2c7..8e9c3f1cf 100644 --- a/xCAT-test/autotest/testcase/rinv/cases0 +++ b/xCAT-test/autotest/testcase/rinv/cases0 @@ -106,7 +106,7 @@ cmd:chdef -p -t node -o $$CN groups="test" check:rc==0 cmd:rinv test all check:rc==1 -check:output=~$$CN: SYSTEM +check:output=~$$CN: SYSTEM|$$CN: System cmd:chdef -m -t node -o $$CN groups="test" check:rc==0 cmd:rmdef testnode;if [[ -e /tmp/testnode.stanza ]]; then cat /tmp/testnode.stanza | chdef -z;rm -rf /tmp/testnode.stanza;fi @@ -129,5 +129,5 @@ start:rinv_errorcommand description:get right return if input error command cmd:rinv $$CN dafds check:rc==1 -check:output=~Unsupported command +check:output=~Unsupported command|Error: Usage: end diff --git a/xCAT-test/autotest/testcase/rpower/cases0 b/xCAT-test/autotest/testcase/rpower/cases0 index c7a1f70af..94fde2054 100644 --- a/xCAT-test/autotest/testcase/rpower/cases0 +++ b/xCAT-test/autotest/testcase/rpower/cases0 @@ -91,15 +91,8 @@ end start:rpower_reset description:This case is to test reset option could hard reset nodes when nodes are in on state. Attribute: $$CN-The operation object of rpower command -cmd:rpower $$CN on -cmd:a=0;while ! `rpower $$CN stat|grep "Running\|on" >/dev/null`; do sleep 5;((a++));if [ $a -gt 11 ];then break;fi done -cmd:rpower $$CN stat -check:ouptut=~Running|on -cmd:rpower $$CN reset +cmd:stat=`rpower $$CN stat`;if ([[ $stat =~ on ]] || [[ $stat =~ Running ]]) ;then rpower $$CN reset;sleep 300;stat1=`rpower $$CN stat`;if ([[ $stat1 =~ on ]] || [[ $stat1 =~ Running ]]);then exit 0;else exit 1;fi;else rpower $$CN reset;sleep 300;stat1=`rpower $$CN stat`;if ([[ $stat1 =~ off ]] || [[ $stat1 =~ "Not Activated" ]]);then exit 0;else exit 1;fi;fi check:rc==0 -cmd:a=0;while ! `rpower $$CN stat|grep "Running\|on" >/dev/null`; do sleep 5;((a++));if [ $a -gt 11 ];then break;fi done -cmd:rpower $$CN stat -check:output=~Running|on end start:rpower_noderange @@ -107,7 +100,7 @@ description:This case is to test rpower could process error usage and return hel Attribute: $$CN-The operation object of rpower command cmd:rpower $$CN check:rc!=0 -check:output=~Unsupported|Usage +check:output=~Unsupported|Usage|Please enter an action end start:rpower_noderange_nodeps diff --git a/xCAT-test/autotest/testcase/rsetboot/cases0 b/xCAT-test/autotest/testcase/rsetboot/cases0 index 63b280588..bcec836d4 100644 --- a/xCAT-test/autotest/testcase/rsetboot/cases0 +++ b/xCAT-test/autotest/testcase/rsetboot/cases0 @@ -56,10 +56,10 @@ cmd:if [[ -f /tmp/rsetboot.stat ]];then mv -f /tmp/rsetboot.stat /tmp/rsetboot.s check:rc==0 cmd:rsetboot $$CN default check:rc==0 -check:output=~boot override inactive +check:output=~boot override inactive|Default cmd:rsetboot $$CN stat check:rc==0 -check:output=~$$CN: boot override inactive +check:output=~boot override inactive|$$CN: Default cmd:if [[ `grep CD /tmp/rsetboot.stat` ]];then rsetboot $$CN cd;elif [[ `grep Network /tmp/rsetboot.stat` ]];then rsetboot $$CN net;else rsetboot $$CN hd;fi check:rc==0 cmd:if [[ -f /tmp/rsetboot.stat.bak ]];then mv -f /tmp/rsetboot.stat.bak /tmp/rsetboot.stat;else rm -rf /tmp/rsetboot.stat;fi @@ -120,7 +120,7 @@ description:rsetboot node using invalidaction Attribute: $$CN-The operation object of rsetboot command. cmd:rsetboot $$CN dsdf check:rc!=0 -check:output=~Error: unsupported command +check:output=~Error: unsupported command|Unsupported command end start:rsetboot_group_net diff --git a/xCAT/postscripts/setbootfromnet b/xCAT/postscripts/setbootfromnet index df5a898e4..a979a03f3 100755 --- a/xCAT/postscripts/setbootfromnet +++ b/xCAT/postscripts/setbootfromnet @@ -47,7 +47,7 @@ if [ ! -z $NODE_NAME ]; then if [[ $OS = "Linux" ]]; then CLIENT_IP=`ping -c 3 $NODE_NAME | sed '/icmp_seq/!d;s/.*(\([0-9.]\+\)).*/\1/' | uniq 2>&1` RET=`echo $?` - NIC=`ip route | grep "src $CLIENT_IP" | sed -r 's/.*dev (.*) proto.*/\1/' 2>&1` + NIC=`ip route | grep "src $CLIENT_IP" | sed -r 's/.*dev (.*) +proto.*/\1/' 2>&1` NRET=`echo $?` else ## for AIX CLIENT_IP=`ping -c 3 $NODE_NAME | grep "icmp_seq" | sed 's/.*from \([0-9.]*\):.*/\1/' | uniq 2>&1` diff --git a/xCAT/postscripts/syslog b/xCAT/postscripts/syslog index 8705aa168..2cb1a7824 100755 --- a/xCAT/postscripts/syslog +++ b/xCAT/postscripts/syslog @@ -219,7 +219,6 @@ config_rsyslog_V8() # Need to uncomment the lines $ModLoad imudp.so and $UDPServerRun 514, # to make the MN be able to receive syslog from remote hosts if [ -f "$remoteconf" ]; then - ##listen on tcp and udp port to enable receiving the xcat debug logs ##forwarded via tcp/udp protocol sed -i 's/#\$ModLoad imudp.so/\$ModLoad imudp.so/; @@ -228,9 +227,17 @@ config_rsyslog_V8() s/#\$InputTCPServerRun /\$InputTCPServerRun 514/' $remoteconf fi - #ubuntu16.04 ships rsyslog 8.16.0,which does not ship remote.conf - #the configuration for UDP and TCP syslog reception is in rsyslog.conf + + ##listen on tcp and udp port to enable receiving the xcat debug logs + ##forwarded via tcp/udp protocol if [ -f "$conf_file" ]; then + #rhels7.4 ships rsyslogd 8.24.0, which does not ship remote.conf + #the relevant sections are included in rsyslog.conf + sed -i '/#\$ModLoad \+imudp\|imtcp\|imudp.so\|imtcp.so/s/^#//; + /#\$InputTCPServerRun\|UDPServerRun.*/s/^#//' $conf_file + + #ubuntu16.04 ships rsyslog 8.16.0,which does not ship remote.conf + #the configuration for UDP and TCP syslog reception is in rsyslog.conf sed -i 's/#module(load="imudp")/module(load="imudp")/; s/#input(type="imudp" port="514")/input(type="imudp" port="514")/; s/#module(load="imtcp")/module(load="imtcp")/; @@ -242,17 +249,18 @@ config_rsyslog_V8() else # not logging local, forward logging # backup the existing remote.conf file from the install - if [ ! -f $remoteconf.XCATORIG ]; then - cp -f $remoteconf $remoteconf.XCATORIG + if [ -f $remoteconf ] && [ ! -f $remoteconf.XCATORIG ]; then + cp -f $remoteconf $remoteconf.XCATORIG fi if [ $isSN -eq 1 ];then - ##listen on tcp and udp port to enable receiving the xcat debug logs - ##forwarded via tcp/udp protocol - sed -i 's/#\$ModLoad imudp.so/\$ModLoad imudp.so/; - s/#\$UDPServerRun 514/\$UDPServerRun 514/; - s/#\$ModLoad imtcp.so/\$ModLoad imtcp.so/; - s/#\$InputTCPServerRun /\$InputTCPServerRun 514/' $remoteconf + ##listen on tcp and udp port to enable receiving the xcat debug logs + ##forwarded via tcp/udp protocol + [ -f "$remoteconf" ] && sed -i '/#\$ModLoad \+imudp\|imtcp\|imudp.so\|imtcp.so/s/^#//; + /#\$InputTCPServerRun\|UDPServerRun.*/s/^#//' $remoteconf + + [ -f "$conf_file" ] && sed -i '/#\$ModLoad \+imudp\|imtcp\|imudp.so\|imtcp.so/s/^#//; + /#\$InputTCPServerRun\|UDPServerRun.*/s/^#//' $conf_file fi