add rinstall plugin
This commit is contained in:
parent
3c327578e4
commit
b24d5bdda4
481
xCAT-server/lib/xcat/plugins/rinstall.pm
Normal file
481
xCAT-server/lib/xcat/plugins/rinstall.pm
Normal file
@ -0,0 +1,481 @@
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
#-------------------------------------------------------
|
||||
|
||||
=head1
|
||||
xCAT plugin package to handle rinstall and winstall
|
||||
|
||||
Supported command:
|
||||
rinstall - runs nodeset, rsetboot,rpower commands
|
||||
winstall - also opens the console
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------
|
||||
package xCAT_plugin::rinstall;
|
||||
use strict;
|
||||
|
||||
require xCAT::Utils;
|
||||
require xCAT::MsgUtils;
|
||||
use xCAT::NodeRange;
|
||||
use xCAT::Table;
|
||||
|
||||
use Data::Dumper;
|
||||
use Getopt::Long;
|
||||
|
||||
#-------------------------------------------------------
|
||||
|
||||
=head3 handled_commands
|
||||
|
||||
Return list of commands handled by this plugin
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------
|
||||
|
||||
sub handled_commands
|
||||
{
|
||||
return {
|
||||
rinstall => "rinstall",
|
||||
winstall => "rinstall",
|
||||
};
|
||||
}
|
||||
|
||||
#-------------------------------------------------------
|
||||
|
||||
=head3 Process the command
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------
|
||||
sub process_request
|
||||
{
|
||||
|
||||
my $request = shift;
|
||||
my $callback = shift;
|
||||
my $subreq = shift;
|
||||
|
||||
rinstall($request, $callback, $subreq);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------
|
||||
|
||||
=head3 rinstall
|
||||
|
||||
Wrapper around nodeset, rsetboot, rpower for the admin convenience
|
||||
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------
|
||||
sub rinstall
|
||||
{
|
||||
my ($req, $callback, $subreq) = @_;
|
||||
$::CALLBACK=$callback;
|
||||
my $OSVER;
|
||||
my $PROFILE;
|
||||
my $ARCH;
|
||||
my $CONSOLE;
|
||||
my $OSIMAGE;
|
||||
my $HELP;
|
||||
my $VERSION;
|
||||
my $command = $req->{command}->[0]; # could be rinstall on winstall
|
||||
my $args;
|
||||
if (defined($req->{arg}) ) { # there are arguments
|
||||
$args=$req->{arg}; # argument
|
||||
@ARGV = @{$args};
|
||||
}
|
||||
my $nodes;
|
||||
my @nodes;
|
||||
if (defined ($req->{node})) { # there are nodes
|
||||
$nodes = $req->{node};
|
||||
@nodes=@$nodes;
|
||||
}
|
||||
# no arguments, no nodes then input wrong
|
||||
if ((scalar(@nodes) == 0) && (scalar(@ARGV) == 0)){
|
||||
&usage($command,$callback);
|
||||
return 1;
|
||||
}
|
||||
#print Dumper($req);
|
||||
Getopt::Long::Configure("bundling");
|
||||
|
||||
unless (
|
||||
GetOptions(
|
||||
'o|osver=s' => \$OSVER,
|
||||
'p|profile=s' => \$PROFILE,
|
||||
'a|arch=s' => \$ARCH,
|
||||
'O|osimage=s' => \$OSIMAGE,
|
||||
'h|help' => \$HELP,
|
||||
'v|version' => \$VERSION,
|
||||
'c|console' => \$CONSOLE
|
||||
)
|
||||
)
|
||||
{
|
||||
&usage($command,$callback);
|
||||
return 1;
|
||||
}
|
||||
if ($HELP)
|
||||
{
|
||||
&usage($command,$callback);
|
||||
return 0;
|
||||
}
|
||||
if ($VERSION)
|
||||
{
|
||||
my $version = xCAT::Utils->Version();
|
||||
my $rsp = {};
|
||||
$rsp->{data}->[0] = "$version";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (scalar @$nodes eq 0)
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] ="noderange not supplied";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return 1;
|
||||
}
|
||||
|
||||
my $rc = 0;
|
||||
my %pnhash;
|
||||
|
||||
|
||||
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
|
||||
# verify input
|
||||
&checkoption("[-O|--osimage] $OSIMAGE",$OSVER,$PROFILE,$ARCH,$callback);
|
||||
|
||||
# run nodeset $noderange osimage=$OSIMAGE
|
||||
my @osimageargs;
|
||||
push @osimageargs,"osimage=$OSIMAGE" ;
|
||||
my $res =
|
||||
xCAT::Utils->runxcmd(
|
||||
{
|
||||
command => ["nodeset"],
|
||||
node => \@nodes,
|
||||
arg => \@osimageargs
|
||||
},
|
||||
$subreq, -1, 1);
|
||||
|
||||
my $rsp = {};
|
||||
if ($::RUNCMD_RC ==0 ) {
|
||||
foreach my $line (@$res) {
|
||||
$rsp->{data} ->[0] = $line;
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
} else {
|
||||
foreach my $line (@$res) {
|
||||
$rsp->{error} ->[0] = $line;
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
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 = <osimage>, 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, use 'install' as the default value
|
||||
|
||||
# group the nodes according to the nodetype.provmethod
|
||||
|
||||
foreach (@$nodes)
|
||||
{
|
||||
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
|
||||
{
|
||||
|
||||
#if nodetype.provmethod is not specified,
|
||||
push(@{$pnhash{'install'}}, $_);
|
||||
}
|
||||
}
|
||||
# Now for each group based on provmethod
|
||||
foreach my $key (keys %pnhash)
|
||||
{
|
||||
$::RUNCMD_RC =0;
|
||||
my $nodes = join(',', @{$pnhash{$key}});
|
||||
if ($key =~ /^(install|netboot|statelite)$/)
|
||||
{
|
||||
|
||||
# nodetype.provmethod = [install|netboot|statelite]
|
||||
my @nodechline;
|
||||
if ($OSVER)
|
||||
{
|
||||
push @nodechline, "nodetype.os=$OSVER";
|
||||
}
|
||||
if ($PROFILE)
|
||||
{
|
||||
push @nodechline, "nodetype.profile=$PROFILE";
|
||||
}
|
||||
if ($ARCH)
|
||||
{
|
||||
push @nodechline, "nodetype.arch=$ARCH";
|
||||
}
|
||||
if (@nodechline)
|
||||
{
|
||||
# run nodech $nodes $nodechline
|
||||
my $res =
|
||||
xCAT::Utils->runxcmd(
|
||||
{
|
||||
command => ["nodech"],
|
||||
node => \@nodes,
|
||||
arg => \@nodechline
|
||||
},
|
||||
$subreq, -1, 1);
|
||||
|
||||
my $rsp = {};
|
||||
$rc=$::RUNCMD_RC;
|
||||
if ($rc == 0 ) {
|
||||
foreach my $line (@$res) {
|
||||
$rsp->{data} ->[0] = $line;
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
} else { # error
|
||||
$rsp->{error} ->[0] = "nodech error";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
foreach my $line (@$res) {
|
||||
$rsp->{error} ->[0] = $line;
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
}
|
||||
}
|
||||
} # end nodechline
|
||||
|
||||
if ($rc == 0) # if no error from nodech then run nodeset
|
||||
{
|
||||
# run nodeset $nodes $key ( where key is install/netboot/statelite)
|
||||
my @nodesetarg;
|
||||
push @nodesetarg, "$key";
|
||||
my $res =
|
||||
xCAT::Utils->runxcmd(
|
||||
{
|
||||
command => ["nodeset"],
|
||||
node => \@nodes,
|
||||
arg => \@nodesetarg
|
||||
},
|
||||
$subreq, -1, 1);
|
||||
|
||||
my $rsp = {};
|
||||
$rc=$::RUNCMD_RC;
|
||||
if ($rc ==0 ) {
|
||||
foreach my $line (@$res) {
|
||||
$rsp->{data} ->[0] = $line;
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
} else { # error
|
||||
foreach my $line (@$res) {
|
||||
$rsp->{error} ->[0] = $line;
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else # if not install/netboot/statelite
|
||||
{
|
||||
|
||||
# nodetype.provmethod = <osimage>
|
||||
&checkoption("nodetype.provmethod=$key",$OSVER,$PROFILE,$ARCH,$callback);
|
||||
# run nodeset $nodes osimage
|
||||
my @nodesetarg;
|
||||
push @nodesetarg, "osimage";
|
||||
my $res =
|
||||
xCAT::Utils->runxcmd(
|
||||
{
|
||||
command => ["nodeset"],
|
||||
node => \@nodes,
|
||||
arg => \@nodesetarg
|
||||
},
|
||||
$subreq, -1, 1);
|
||||
|
||||
my $rsp = {};
|
||||
$rc=$::RUNCMD_RC;
|
||||
if ($rc ==0 ) {
|
||||
foreach my $line (@$res) {
|
||||
$rsp->{data} ->[0] = $line;
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
} else { # error
|
||||
foreach my $line (@$res) {
|
||||
$rsp->{error} ->[0] = $line;
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} # end nodech/nodeset for each group
|
||||
|
||||
if ($rc != 0) # we got an error with the nodeset
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] = "nodeset failure will not continue ";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return 1;
|
||||
}
|
||||
|
||||
# call "rsetboot" to set the boot order of the nodehm.mgt=ipmi nodes,for others,
|
||||
# assume user has set the correct boot order before "rinstall"
|
||||
|
||||
# run rsetboot $noderange net
|
||||
|
||||
my @rsetbootarg;
|
||||
push @rsetbootarg, "net";
|
||||
my $res =
|
||||
xCAT::Utils->runxcmd(
|
||||
{
|
||||
command => ["rsetboot"],
|
||||
node => \@nodes,
|
||||
arg => \@rsetbootarg
|
||||
},
|
||||
$subreq, -1, 1);
|
||||
# fix output it is a hash and you must get error out of the hash.
|
||||
my $rsp = {};
|
||||
$rc=$::RUNCMD_RC;
|
||||
if ($rc ==0 ) {
|
||||
foreach my $line (@$res) {
|
||||
$rsp->{data} ->[0] = $line;
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
} else { # error
|
||||
foreach my $line (@$res) {
|
||||
$rsp->{error} ->[0] = $line;
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
}
|
||||
}
|
||||
if ($rc != 0) # we got an error with the rsetboot
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] = "rsetboot failure will not continue ";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return 1;
|
||||
}
|
||||
|
||||
# call "rpower" to start the node provision process
|
||||
|
||||
#run rpower $noderange boot
|
||||
my @rpowerarg;
|
||||
push @rpowerarg, "boot";
|
||||
my $res =
|
||||
xCAT::Utils->runxcmd(
|
||||
{
|
||||
command => ["rpower"],
|
||||
node => \@nodes,
|
||||
arg => \@rpowerarg
|
||||
},
|
||||
$subreq, -1, 1);
|
||||
|
||||
my $rsp = {};
|
||||
$rc=$::RUNCMD_RC;
|
||||
if ($rc ==0 ) {
|
||||
foreach my $line (@$res) {
|
||||
$rsp->{data} ->[0] = $line;
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
} else { # error
|
||||
foreach my $line (@$res) {
|
||||
$rsp->{error} ->[0] = $line;
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
}
|
||||
}
|
||||
# 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 ne 1)
|
||||
{
|
||||
my $rsp = {};
|
||||
$rsp->{error}->[0] = "rinstall -c only accepts one node in the noderange. See winstall for support for support of consoles on multiple nodes.";
|
||||
xCAT::MsgUtils->message("E", $rsp, $callback);
|
||||
return 1;
|
||||
} else { # tell rinstall client ok to start rcons
|
||||
$req->{startconsole}->[0] =1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
elsif ($command =~ /winstall/)
|
||||
{
|
||||
|
||||
# winstall can start a wcons command to multiple nodes for monitoring the provision cycle
|
||||
$req->{startconsole}->[0] =1;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------
|
||||
|
||||
=head3 Usage
|
||||
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------
|
||||
|
||||
sub usage
|
||||
{
|
||||
my $command = shift;
|
||||
my $callback = shift;
|
||||
my $rsp = {};
|
||||
$rsp->{data}->[0] = "$command usage:";
|
||||
if ($command =~ /rinstall/) {
|
||||
$rsp->{data}->[1] = " [-o|--osver] [-p|--profile] [-a|--arch] [-c|--console] <noderange>";
|
||||
} else { # winstall
|
||||
$rsp->{data}->[1] = " [-o|--osver] [-p|--profile] [-a|--arch] <noderange>";
|
||||
}
|
||||
if ($command =~ /rinstall/) {
|
||||
$rsp->{data}->[2] = " [-O|--osimage] [-c|--console] <noderange>";
|
||||
} else { # wininstall
|
||||
$rsp->{data}->[2] = " [-O|--osimage] <noderange>";
|
||||
}
|
||||
|
||||
$rsp->{data}->[3] = " [-h|--help]";
|
||||
$rsp->{data}->[4] = " [-v|--version]";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
|
||||
# check and complain about the invalid combination of the options,
|
||||
# ignore -o,-p and -a options and prompt a warning message when provmethod=osimagename
|
||||
sub checkoption{
|
||||
my $optstring=shift;
|
||||
my $OSVER=shift;
|
||||
my $PROFILE=shift;
|
||||
my $ARCH=shift;
|
||||
my $callback=shift;
|
||||
my $rsp = {};
|
||||
if($OSVER) {
|
||||
$rsp->{data}->[0] = "-o option not valid with $optstring. It is ignored.";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
if($PROFILE) {
|
||||
$rsp->{data}->[0] = "-p option not valid with $optstring. It is ignored.";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
if($ARCH) {
|
||||
$rsp->{data}->[0] = "-a option not valid with $optstring. It is ignored.";
|
||||
xCAT::MsgUtils->message("I", $rsp, $callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
1;
|
Loading…
Reference in New Issue
Block a user