mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-05-22 03:32:04 +00:00
311 lines
9.2 KiB
Perl
311 lines
9.2 KiB
Perl
#!/usr/bin/env perl
|
|
## IBM(c) 20013 EPL license http://www.eclipse.org/legal/epl-v10.html
|
|
#
|
|
# This plugin is used to handle the command requests for cumulus OS support
|
|
#
|
|
|
|
|
|
package xCAT_plugin::onie;
|
|
|
|
BEGIN
|
|
{
|
|
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
|
|
}
|
|
use lib "$::XCATROOT/lib/perl";
|
|
|
|
use strict;
|
|
use Getopt::Long;
|
|
use File::Path;
|
|
use File::Basename;
|
|
|
|
use xCAT::Utils;
|
|
use xCAT::MsgUtils;
|
|
use xCAT::TableUtils;
|
|
use xCAT::SvrUtils;
|
|
use xCAT::Table;
|
|
my $xcatdebugmode = 0;
|
|
$::VERBOSE = 0;
|
|
|
|
sub handled_commands {
|
|
return {
|
|
nodeset => 'nodehm:mgt=switch',
|
|
copydata => 'onie',
|
|
}
|
|
}
|
|
|
|
my $CALLBACK; # used to hanel the output from xdsh
|
|
|
|
sub preprocess_request {
|
|
my $request = shift;
|
|
my $callback = shift;
|
|
|
|
if ($request->{command}->[0] eq 'copydata')
|
|
{
|
|
return [$request];
|
|
}
|
|
|
|
# if already preprocessed, go straight to request
|
|
if ((defined($request->{_xcatpreprocessed}->[0]))
|
|
&& ($request->{_xcatpreprocessed}->[0] == 1)) {
|
|
return [$request];
|
|
}
|
|
|
|
my $nodes = $request->{node};
|
|
my $command = $request->{command}->[0];
|
|
my $extraargs = $request->{arg};
|
|
|
|
if ($extraargs) {
|
|
@ARGV = @{$extraargs};
|
|
my ($verbose, $help, $ver);
|
|
GetOptions("V" => \$verbose, 'h|help' => \$help, 'v|version' => \$ver);
|
|
if ($help) {
|
|
my $usage_string = xCAT::Usage->getUsage($command);
|
|
my $rsp;
|
|
push @{ $rsp->{data} }, $usage_string;
|
|
xCAT::MsgUtils->message("I", $rsp, $callback);
|
|
return ();
|
|
}
|
|
if ($ver) {
|
|
my $ver_string = xCAT::Usage->getVersion($command);
|
|
my $rsp;
|
|
push @{ $rsp->{data} }, $ver_string;
|
|
xCAT::MsgUtils->message("I", $rsp, $callback);
|
|
return ();
|
|
}
|
|
|
|
if ($verbose) {
|
|
$::VERBOSE = 1;
|
|
}
|
|
}
|
|
|
|
return [$request];
|
|
}
|
|
|
|
sub process_request {
|
|
my $request = shift;
|
|
my $callback = shift;
|
|
my $subreq = shift;
|
|
|
|
my $nodes = $request->{node};
|
|
my $command = $request->{command}->[0];
|
|
my $args = $request->{arg};
|
|
|
|
if ($::XCATSITEVALS{xcatdebugmode} != 0) { $::VERBOSE = 1}
|
|
|
|
if ($command eq "copydata") {
|
|
copydata($request, $callback);
|
|
} elsif ($command eq "nodeset") {
|
|
nodeset($request, $callback, $subreq);
|
|
}
|
|
|
|
}
|
|
|
|
# build cumulus OS image
|
|
sub copydata {
|
|
my $request = shift;
|
|
my $callback = shift;
|
|
my $file;
|
|
my $inspection = undef;
|
|
my $noosimage = undef;
|
|
my $nooverwrite = undef;
|
|
|
|
# get arguments
|
|
my $args = $request->{arg};
|
|
if ($args) {
|
|
@ARGV = @{$args};
|
|
GetOptions(
|
|
'w' => \$nooverwrite,
|
|
'o' => \$noosimage,
|
|
'i' => \$inspection,
|
|
'f=s' => \$file
|
|
);
|
|
}
|
|
|
|
if (!(-x $file)) {
|
|
xCAT::MsgUtils->message("E", { error => ["$file is not executable, will not process"], errorcode => ["1"] }, $callback);
|
|
return;
|
|
}
|
|
|
|
#get install dir
|
|
my $installroot = "/install";
|
|
my $sitetab = xCAT::Table->new('site');
|
|
my @ents = xCAT::TableUtils->get_site_attribute("installdir");
|
|
my $site_ent = $ents[0];
|
|
if (defined($site_ent))
|
|
{
|
|
$installroot = $site_ent;
|
|
}
|
|
|
|
my $arch;
|
|
my $desc;
|
|
my $release;
|
|
my $osname;
|
|
my $filename = basename($file);
|
|
my $output = `$file`;
|
|
if ($inspection) {
|
|
$callback->({ data => "file output: $output" });
|
|
return;
|
|
}
|
|
foreach my $line (split /[\r\n]+/, $output) {
|
|
if ($line =~ /^Architecture/) {
|
|
($desc, $arch) = split /: /, $line ;
|
|
chomp $arch;
|
|
}
|
|
if ($line =~ /^Release/) {
|
|
($desc, $release) = split /: /, $line ;
|
|
chomp $release;
|
|
}
|
|
if ($line =~ /cumulus/) {
|
|
$osname = "cumulus" ;
|
|
}
|
|
}
|
|
unless ($osname) {
|
|
$osname="image";
|
|
}
|
|
|
|
my $distname = $osname . $release;
|
|
my $imagename = $distname . "-" . $arch;
|
|
my $defaultpath = "$installroot/$distname/$arch";
|
|
|
|
#check if file exists
|
|
if ( (-e "$defaultpath/$filename") && ($nooverwrite)){
|
|
$callback->({ data => "$defaultpath/$filename is already exists, will not overwrite" });
|
|
} else {
|
|
$callback->({ data => "Copying media to $defaultpath" });
|
|
mkpath ("$defaultpath");
|
|
system("cp $file $defaultpath");
|
|
$callback->({ data => "Media copy operation successful" });
|
|
}
|
|
|
|
if ($noosimage) {
|
|
$callback->({ data => "Option noosimage is specified, will not create osimage definition" });
|
|
return;
|
|
}
|
|
|
|
# generate the image objects
|
|
my $oitab = xCAT::Table->new('osimage');
|
|
unless ($oitab) {
|
|
xCAT::MsgUtils->message("E", { error => ["Error: Cannot open table osimage."], errorcode => ["1"] }, $callback);
|
|
return 1;
|
|
}
|
|
my $litab = xCAT::Table->new('linuximage');
|
|
unless ($litab) {
|
|
xCAT::MsgUtils->message("E", { error => ["Error: Cannot open table linuximage."], errorcode => ["1"] }, $callback);
|
|
return 1;
|
|
}
|
|
my $pkgdir = "$defaultpath/$filename";
|
|
my $imgdir = $litab->getAttribs({ 'imagename' => $imagename }, 'pkgdir');
|
|
|
|
if ($::VERBOSE) {
|
|
$callback->({ data => "creating image $imagename with osarch=$arch, osvers=$distname" });
|
|
}
|
|
|
|
my %values;
|
|
$values{'imagetype'} = "linux";
|
|
$values{'provmethod'} = "install";
|
|
$values{'description'} = "Cumulus Linux";
|
|
$values{'osname'} = "$osname";
|
|
$values{'osvers'} = "$distname";
|
|
$values{'osarch'} = "$arch";
|
|
|
|
$oitab->setAttribs({ 'imagename' => $imagename }, \%values);
|
|
|
|
# set a default package list
|
|
$litab->setAttribs({ 'imagename' => $imagename }, { 'pkgdir' => $pkgdir });
|
|
if ($::VERBOSE) {
|
|
$callback->({ data => "setting pkgdir=$pkgdir for image $imagename" });
|
|
}
|
|
|
|
#Need to update osdistro table?
|
|
my @ret = xCAT::SvrUtils->update_osdistro_table($distname, $arch, $defaultpath, $imagename);
|
|
if ($ret[0] != 0) {
|
|
xCAT::MsgUtils->message("E", { error => ["Error when updating the osdistro tables."], errorcode => ["1"] }, $callback);
|
|
}
|
|
|
|
xCAT::MsgUtils->message("I", { data => ["The image $imagename is created."] }, $callback);
|
|
}
|
|
|
|
|
|
# run the nodeset to updatenode provmethod
|
|
sub nodeset {
|
|
my $request = shift;
|
|
my $callback = shift;
|
|
my $subreq = shift;
|
|
|
|
my $switches = $request->{'node'};
|
|
my $args = $request->{arg};
|
|
my $provmethod;
|
|
my $image_pkgdir;
|
|
|
|
my $setosimg;
|
|
foreach (@$args) {
|
|
if (/osimage=(.*)/) {
|
|
$setosimg = $1;
|
|
}
|
|
}
|
|
|
|
my $switchestab = xCAT::Table->new('switches');
|
|
my $switcheshash = $switchestab->getNodesAttribs($switches, ['switchtype']);
|
|
|
|
my $nodetab = xCAT::Table->new('nodetype');
|
|
my $nodehash = $nodetab->getNodesAttribs($switches, [ 'provmethod' ]);
|
|
|
|
foreach my $switch (@$switches) {
|
|
if ($switcheshash->{$switch}->[0]->{switchtype} ne "onie") {
|
|
xCAT::MsgUtils->message("E", { error => ["nodeset command is not processed for $switch, only supports switchtype=onie"], errorcode => ["1"] }, $callback);
|
|
next;
|
|
}
|
|
|
|
|
|
if ($setosimg) {
|
|
$provmethod = $setosimg;
|
|
} else {
|
|
$provmethod = $nodehash->{$switch}->[0]->{provmethod};
|
|
}
|
|
if ($::VERBOSE) {
|
|
xCAT::MsgUtils->message("I", { data => ["$switch has provmethod=$provmethod"] }, $callback);
|
|
}
|
|
|
|
#get pkgdir from osimage
|
|
my $linuximagetab = xCAT::Table->new('linuximage');
|
|
my $osimagetab = xCAT::Table->new('osimage');
|
|
my $imagetab = $linuximagetab->getAttribs({ imagename => $provmethod },'pkgdir');
|
|
my $osimghash = $osimagetab->getAttribs({ imagename => $provmethod },'osvers','osarch');
|
|
unless($imagetab and $osimghash){
|
|
xCAT::MsgUtils->message("E", { error => ["cannot find osimage \"$provmethod\" for $switch, please make sure the osimage specified in command line or node.provmethod exists!"], errorcode => ["1"] }, $callback);
|
|
next;
|
|
}
|
|
|
|
|
|
my %attribs=('provmethod' => $provmethod,'os'=>$osimghash->{'osvers'},'arch'=>$osimghash->{'osarch'} );
|
|
$nodetab->setAttribs({ 'node' => $switch }, \%attribs);
|
|
$image_pkgdir = $imagetab->{'pkgdir'};
|
|
|
|
#validate the image pkgdir
|
|
my $flag=0;
|
|
if (-r $image_pkgdir) {
|
|
my @filestat = `file $image_pkgdir`;
|
|
if (grep /$image_pkgdir: data/, @filestat) {
|
|
$flag=1;
|
|
}
|
|
}
|
|
unless ($flag) {
|
|
xCAT::MsgUtils->message("E", { error => ["The image '$image_pkgdir' is invalid"], errorcode => ["1"] }, $callback);
|
|
next;
|
|
}
|
|
if ($::VERBOSE) {
|
|
xCAT::MsgUtils->message("I", { data => ["osimage=$provmethod, pkgdir=$image_pkgdir"] }, $callback);
|
|
}
|
|
|
|
#updateing DHCP entries
|
|
my $ret = xCAT::Utils->runxcmd({ command => ["makedhcp"], node => [$switch] }, $subreq, 0, 1);
|
|
if ($::RUNCMD_RC) {
|
|
xCAT::MsgUtils->message("E", { error => ["Failed to run 'makedhcp' command"], errorcode => ["$::RUNCMD_RC"] }, $callback);
|
|
}
|
|
|
|
xCAT::MsgUtils->message("I", { data => ["$switch: install $provmethod"] }, $callback);
|
|
}
|
|
return;
|
|
}
|
|
1;
|