#!/usr/bin/env perl # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html # Used as a convience command combined of [nodech]-nodeset-rpower-[rcons/wcons] # to make ease of node OS provision # To use this, sym link your cmd name to this script. use strict; BEGIN { $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr'; } use lib "$::XCATROOT/lib/perl"; use File::Basename; use Getopt::Long; use xCAT::Table; use xCAT::NodeRange; sub usage { print basename($0)." usage:\n"; print " ".basename($0)." [-o|--osver] [-p|--profile] [-a|--arch] [-O|--osimage] [-c|--console] \n" } my $OSVER; my $PROFILE; my $ARCH; my $CONSOLE; my $OSIMAGE; Getopt::Long::Configure("bundling"); unless (GetOptions( 'o|osver=s' => \$OSVER, 'p|profile=s' => \$PROFILE, 'a|arch=s' => \$ARCH, 'O|osimage=s' => \$OSIMAGE, 'c|console' => \$CONSOLE )) { usage; exit 1; } my $arraysize=@ARGV; if ($arraysize > 1) { print "noderange invalid\n"; usage; exit 1; } if ($arraysize == 0) { print "noderange not supplied\n"; usage; exit 1; } my $noderange=@ARGV[0]; my $rc=0; my %pnhash; my @allnodes; #use Data::Dumper; # check and complain about the invalid combination of the options, # called when -O is specified or nodetype.provmethod=, # ignore -o,-p and -a options and prompt a warning message sub checkoption{ my $optstring=shift; if($OSVER) {print 'warning: "'.$optstring.'" specified, "[-o|--osver] '.$OSVER."\" ignored\n"}; if($PROFILE) {print 'warning: "'.$optstring.'" specified, "[-p|--profile] '.$PROFILE."\" ignored\n"}; if($ARCH) {print 'warning: "'.$optstring.'" specified, "[-a|--arch] '.$OSVER."\" ignored\n"}; } if($OSIMAGE){ # -O|--osimage is specified, ignore any -a,-p,-o options, # call "nodeset ... osimage= ..." to set the boot state of the noderange to the specified osimage, # "nodeset" will handle the updating of node attributes such as os,arch,profile,provmethod &checkoption("[-O|--osimage] $OSIMAGE"); $rc=system("nodeset $noderange osimage=$OSIMAGE"); if ($rc) { die "nodeset failure" }; }else { # no osimage specified, update the node attributes specified by -a,-p,-o options thru "nodech", # then set the boot state of each node based on the nodetype.provmethod: # 1) if nodetype.provmethod = , ignore any -p,-o,-a option, then call "nodeset ... osimage" # 2) if nodetype.provmethod = [install/netboot/statelite], update the node attributes specified by -a,-p,-o options thru "nodech", call "nodeset ... [install/netboot/statelite]" # 3) if nodetype.provmethod is not set, complain and return # group the nodes according to the nodetype.provmethod @allnodes=noderange($noderange); foreach(@allnodes){ my $tab=xCAT::Table->new("nodetype"); my $nthash=$tab->getNodeAttribs($_,['provmethod']); $tab->close(); if(defined($nthash) and defined($nthash->{'provmethod'})) { push(@{$pnhash{$nthash->{'provmethod'}}},$_); } else { push(@{$pnhash{'BLANK###'}},$_); } } foreach my $key (keys %pnhash) { my $rclocal=0; my $nodes=join(',',@{$pnhash{$key}}); if($key =~ /^(install|netboot|statelite)$/) { # nodetype.provmethod = [install|netboot|statelite] my $nodechline = ""; if ($OSVER) { $nodechline = "nodetype.os=$OSVER"; } if ($PROFILE) { $nodechline .= " nodetype.profile=$PROFILE"; } if ($ARCH) { $nodechline .= " nodetype.arch=$ARCH"; } if ($nodechline) { $rclocal=system("nodech $nodes $nodechline"); if ($rclocal) { print "nodech failure\n"; $rc=$rclocal; } } unless($rc){ $rclocal=system("nodeset $nodes $key"); if ($rclocal) { print "nodeset $nodes failure\n"; $rc=$rclocal; } } } elsif($key eq 'BLANK###') { # nodetype.provmethod is not set print "nodetype.provmethod must be specified for nodes: $nodes\n"; $rc=1; } else { # nodetype.provmethod = &checkoption("nodetype.provmethod=$key"); $rclocal=system("nodeset $nodes osimage"); if ($rclocal) { print "nodeset $nodes failure\n"; $rc=$rclocal; } } } } if($rc){ die "nodeset failure"; } # call "rpower" to start the node provision process $rc=system("rpower $noderange boot"); if ($rc) { die "rpower failure" }; if (basename($0) =~ /rinstall/) { # for rinstall, the -c|--console option can provide the remote console for only 1 node if ($CONSOLE) { if(scalar @allnodes ne 1){ die "rinstall [-c|--console] will only work if there is only one node in the noderange. See winstall(8) for consoles on multiple systems"; } exec("rcons $noderange"); } } elsif (basename($0) =~ /winstall/) { # winstall can commence a wcons command to the noderange for monitoring the provision cycle exec("wcons $noderange"); }