mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-08-22 11:10:24 +00:00
Support copycds command to create cumulus osimage (#5122)
* Support copycds command to create cumulus osimage * Add Error handler * fix a typo * Add VERBOSE * Modify a error message * modify per yangSong's comment * Add '-i' and '-o' flag * remove nooverwrite when checking pkgdir
This commit is contained in:
@@ -14,6 +14,7 @@ use Cwd;
|
||||
Getopt::Long::Configure("bundling");
|
||||
Getopt::Long::Configure("pass_through");
|
||||
|
||||
my $xcatdebugmode = 0;
|
||||
my $processed = 0;
|
||||
my $callback;
|
||||
|
||||
@@ -75,6 +76,9 @@ sub process_request {
|
||||
$callback->({ error => "copycds needs at least one full path to ISO currently.", errorcode => [1] });
|
||||
return;
|
||||
}
|
||||
|
||||
if ($::XCATSITEVALS{xcatdebugmode}) { $xcatdebugmode = $::XCATSITEVALS{xcatdebugmode} }
|
||||
|
||||
my $file;
|
||||
foreach (@args) {
|
||||
$identified = 0;
|
||||
@@ -111,6 +115,29 @@ sub process_request {
|
||||
|
||||
return;
|
||||
}
|
||||
if (grep /$file: data/, @filestat) {
|
||||
if ($xcatdebugmode) {
|
||||
$callback->({ info => "run copydata for data file = $file" });
|
||||
}
|
||||
my $newreq = dclone($request);
|
||||
$newreq->{command} = ['copydata']; #Note the singular, it's different
|
||||
$newreq->{arg} = [ "-f", $file ];
|
||||
if ($inspection)
|
||||
{
|
||||
push @{ $newreq->{arg} }, ("-i");
|
||||
}
|
||||
if ($nonoverwrite)
|
||||
{
|
||||
push @{ $newreq->{arg} }, ("-w");
|
||||
}
|
||||
if ($noosimage)
|
||||
{
|
||||
push @{ $newreq->{arg} }, ("-o");
|
||||
}
|
||||
|
||||
$doreq->($newreq, $callback);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
my $mntopts = "-t udf,iso9660"; #Prefer udf formate to iso when media supports both, like MS media
|
||||
|
301
xCAT-server/lib/xcat/plugins/onie.pm
Normal file
301
xCAT-server/lib/xcat/plugins/onie.pm
Normal file
@@ -0,0 +1,301 @@
|
||||
#!/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};
|
||||
|
||||
my %hosts;
|
||||
|
||||
if ($::XCATSITEVALS{xcatdebugmode} != 0) { $::VERBOSE = 1}
|
||||
|
||||
if ($command eq "copydata") {
|
||||
copydata($request, $callback);
|
||||
} elsif ($command eq "nodeset") {
|
||||
nodeset($request, $callback, $subreq, \%hosts);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# 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;
|
||||
$nodetab->setAttribs({ 'node' => $switch }, {'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 $imagetab = $linuximagetab->getAttribs({ imagename => $provmethod }, 'pkgdir');
|
||||
$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;
|
Reference in New Issue
Block a user