mirror of
https://github.com/xcat2/xcat-core.git
synced 2025-05-21 19:22:05 +00:00
244 lines
7.8 KiB
Perl
244 lines
7.8 KiB
Perl
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
|
package xCAT_plugin::copycds;
|
|
use strict;
|
|
use warnings;
|
|
use Storable qw(dclone);
|
|
use xCAT::Table;
|
|
use Thread qw(yield);
|
|
use Data::Dumper;
|
|
use Getopt::Long;
|
|
use File::Basename;
|
|
use File::Spec;
|
|
use Digest::MD5 qw(md5_hex);
|
|
use Cwd;
|
|
Getopt::Long::Configure("bundling");
|
|
Getopt::Long::Configure("pass_through");
|
|
|
|
my $xcatdebugmode = 0;
|
|
my $processed = 0;
|
|
my $callback;
|
|
|
|
sub handled_commands {
|
|
return {
|
|
copycds => "copycds",
|
|
}
|
|
}
|
|
|
|
my $identified;
|
|
|
|
sub take_answer {
|
|
|
|
#TODO: Intelligently filter and decide things
|
|
my $resp = shift;
|
|
$callback->($resp);
|
|
$identified = 1;
|
|
}
|
|
|
|
sub process_request {
|
|
my $request = shift;
|
|
$callback = shift;
|
|
my $doreq = shift;
|
|
my $distname = undef;
|
|
my $arch = undef;
|
|
my $help = undef;
|
|
my $inspection = undef;
|
|
my $path = undef;
|
|
my $noosimage = undef;
|
|
my $nonoverwrite = undef;
|
|
my $specific = undef;
|
|
|
|
$identified = 0;
|
|
$::CDMOUNTPATH = "/var/run/xcat/mountpoint";
|
|
my $existdir = getcwd;
|
|
|
|
if ($request->{arg}) {
|
|
@ARGV = @{ $request->{arg} };
|
|
}
|
|
GetOptions(
|
|
'n|name|osver=s' => \$distname,
|
|
'a|arch=s' => \$arch,
|
|
'h|help' => \$help,
|
|
'i|inspection' => \$inspection,
|
|
'p|path=s' => \$path,
|
|
'o|noosimage' => \$noosimage,
|
|
's|specific' => \$specific,
|
|
'w|nonoverwrite' => \$nonoverwrite,
|
|
);
|
|
if ($help) {
|
|
$callback->({ info => "copycds [{-p|--path} path] [{-n|--name|--osver} distroname] [{-a|--arch} architecture] [-i|--inspection] [{-o|--noosimage}] [{-w|--nonoverwrite}] 1st.iso [2nd.iso ...]." });
|
|
return;
|
|
}
|
|
if ($arch and $arch =~ /i.86/) {
|
|
$arch = 'x86';
|
|
}
|
|
my @args = @ARGV; #copy ARGV
|
|
unless ($#args >= 0) {
|
|
$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;
|
|
|
|
unless (/^\//) { #If not an absolute path, concatenate with client specified cwd
|
|
s/^/$request->{cwd}->[0]\//;
|
|
}
|
|
|
|
# /dev/cdrom is a symlink on some systems. We need to be able to determine
|
|
# if the arg points to a block device.
|
|
if (-l $_) {
|
|
my $link = readlink($_);
|
|
|
|
# Symlinks can be relative, i.e., "../../foo"
|
|
if ($link =~ m{^/})
|
|
{ $file = $link; }
|
|
else
|
|
{ $file = dirname($_) . "/" . $link; } # Unix can handle "/foo/../bar"
|
|
}
|
|
else { $file = $_; }
|
|
|
|
# handle the copycds for tar file
|
|
# if the source file is tar format, call the 'copytar' command to handle it.
|
|
# currently it's used for Xeon Phi (mic) support
|
|
if (-r $file) {
|
|
my @filestat = `file $file`;
|
|
if (grep /tar archive/, @filestat) {
|
|
|
|
# this is a tar file, call the 'copytar' to generate the image
|
|
my $newreq = dclone($request);
|
|
$newreq->{command} = ['copytar']; #Note the singular, it's different
|
|
$newreq->{arg} = [ "-f", $file, "-n", $distname ];
|
|
$doreq->($newreq, $callback);
|
|
|
|
return;
|
|
}
|
|
if ((grep /$file: data/, @filestat) || (grep /$file: .* \(binary 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
|
|
if (-r $file and -b $file) # Block device?
|
|
{ $mntopts .= " -o ro"; }
|
|
elsif (-r $file and -f $file) # Assume ISO file
|
|
{ $mntopts .= " -o ro,loop"; }
|
|
else {
|
|
$callback->({ error => "The management server was unable to find/read $file. Ensure that file exists on the server at the specified location.", errorcode => [1] });
|
|
return;
|
|
}
|
|
|
|
#let the MD5 Digest of isofullpath as the default mount point of the iso
|
|
my $isofullpath = File::Spec->rel2abs($file);
|
|
my $mntpath = File::Spec->catpath("", $::CDMOUNTPATH, md5_hex($isofullpath));
|
|
|
|
system("mkdir -p $mntpath");
|
|
system("umount $mntpath >/dev/null 2>&1");
|
|
|
|
|
|
|
|
if (system("mount $mntopts '$file' $mntpath")) {
|
|
eval { $callback->({ error => "copycds was unable to mount $file to $mntpath.", errorcode => [1] }) };
|
|
chdir("/");
|
|
system("umount $mntpath");
|
|
return;
|
|
}
|
|
eval {
|
|
my $newreq = dclone($request);
|
|
$newreq->{command} = ['copycd']; #Note the singular, it's different
|
|
$newreq->{arg} = [ "-m", $mntpath ];
|
|
|
|
if ($path)
|
|
{
|
|
|
|
if(-e $path) {
|
|
$path=Cwd::realpath($path);
|
|
}
|
|
unless((substr($path,0,length("/install/")) eq "/install/") or ($path eq "/install")){
|
|
$callback->({ warning => "copycds: the specified path \"$path\" is not a subdirectory under /install. Make sure this path is configured for httpd/apache, otherwise, the provisioning with this iso will fail!" });
|
|
}
|
|
push @{ $newreq->{arg} }, ("-p", $path);
|
|
}
|
|
if ($specific)
|
|
{
|
|
push @{ $newreq->{arg} }, ("-s");
|
|
}
|
|
|
|
if ($inspection)
|
|
{
|
|
push @{ $newreq->{arg} }, ("-i");
|
|
$callback->({ info => "OS Image:" . $_ });
|
|
}
|
|
|
|
if ($distname) {
|
|
if ($inspection) {
|
|
$callback->({ warning => "copycds: option --inspection specified, argument specified with option --name is ignored" });
|
|
}
|
|
else {
|
|
push @{ $newreq->{arg} }, ("-n", $distname);
|
|
}
|
|
}
|
|
if ($arch) {
|
|
if ($inspection) {
|
|
$callback->({ warning => "copycds: option --inspection specified, argument specified with option --arch is ignored" });
|
|
}
|
|
else {
|
|
push @{ $newreq->{arg} }, ("-a", $arch);
|
|
}
|
|
}
|
|
|
|
if (!-l $file) {
|
|
push @{ $newreq->{arg} }, ("-f", $file);
|
|
}
|
|
|
|
|
|
if ($noosimage) {
|
|
push @{ $newreq->{arg} }, ("-o");
|
|
}
|
|
|
|
if ($nonoverwrite) {
|
|
push @{ $newreq->{arg} }, ("-w");
|
|
}
|
|
|
|
$doreq->($newreq, \&take_answer);
|
|
|
|
#$::CDMOUNTPATH="";
|
|
|
|
chdir($existdir);
|
|
while (wait() > 0) { yield(); } #Make sure all children exit before trying umount
|
|
};
|
|
chdir("/");
|
|
system("umount $mntpath");
|
|
system("rm -rf $mntpath");
|
|
unless ($identified) {
|
|
$callback->({ error => ["copycds could not identify the ISO supplied, you may wish to try -n <osver>"], errorcode => [1] });
|
|
}
|
|
}
|
|
}
|
|
|
|
1;
|
|
|
|
# vim: set ts=2 sts=2 sw=2 et ai:
|