finished imgimport and updated some fixes to imgexport
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@5721 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
parent
c44b5bfc51
commit
664cd8be8e
@ -6,19 +6,21 @@
|
||||
package xCAT_plugin::imgport;
|
||||
use strict;
|
||||
use warnings;
|
||||
use xCAT::Table;
|
||||
use xCAT::Schema;
|
||||
#use xCAT::Table;
|
||||
#use xCAT::Schema;
|
||||
#use xCAT::NodeRange qw/noderange abbreviate_noderange/;
|
||||
#use xCAT::Utils;
|
||||
use Data::Dumper;
|
||||
use XML::Simple;
|
||||
use xCAT::NodeRange qw/noderange abbreviate_noderange/;
|
||||
use xCAT::Utils;
|
||||
use POSIX qw/strftime/;
|
||||
use Getopt::Long;
|
||||
use File::Temp;
|
||||
use File::Copy;
|
||||
use File::Path;
|
||||
use File::Path qw/mkpath/;
|
||||
use File::Basename;
|
||||
use Cwd;
|
||||
my $requestcommand;
|
||||
$::VERBOSE = 0;
|
||||
|
||||
1;
|
||||
|
||||
@ -94,6 +96,7 @@ sub ximport {
|
||||
|
||||
GetOptions(
|
||||
'h|?|help' => \$help,
|
||||
'v|verbose' => \$::VERBOSE
|
||||
);
|
||||
|
||||
if($help){
|
||||
@ -133,7 +136,8 @@ sub xexport {
|
||||
|
||||
GetOptions(
|
||||
'h|?|help' => \$help,
|
||||
'extra=s' => \@extra
|
||||
'extra=s' => \@extra,
|
||||
'v|verbose' => \$::VERBOSE
|
||||
);
|
||||
|
||||
if($help){
|
||||
@ -144,8 +148,10 @@ sub xexport {
|
||||
# ok, we're done with all that. Now lets actually start doing some work.
|
||||
my $img_name = shift @ARGV;
|
||||
my $dest = shift @ARGV;
|
||||
my $cwd = $request->{cwd}; #getcwd;
|
||||
$cwd = $cwd->[0];
|
||||
|
||||
$callback->( {data => ["Exporting $img_name..."]});
|
||||
$callback->( {data => ["Exporting $img_name to $cwd..."]});
|
||||
# check if all files are in place
|
||||
my $attrs = get_image_info($img_name, $callback, @extra);
|
||||
#print Dumper($attrs);
|
||||
@ -155,7 +161,7 @@ sub xexport {
|
||||
}
|
||||
|
||||
# make manifest and tar it up.
|
||||
make_bundle($img_name, $dest, $attrs, $callback);
|
||||
make_bundle($img_name, $dest, $attrs, $callback,$cwd);
|
||||
|
||||
}
|
||||
|
||||
@ -402,8 +408,12 @@ sub make_bundle {
|
||||
# tar ball is made in local working directory. Sometimes doing this in /tmp
|
||||
# is bad. In the case of my development machine, the / filesystem was nearly full.
|
||||
# so doing it in cwd is easy and predictable.
|
||||
my $dir = getcwd;
|
||||
my $dir = shift;
|
||||
#my $dir = getcwd;
|
||||
|
||||
# we may find that cwd doesn't work, so we use the request cwd.
|
||||
my $ttpath = mkdtemp("$dir/imgexport.$$.XXXXXX");
|
||||
$callback->({data=>["Creating $ttpath..."]}) if $::VERBOSE;
|
||||
my $tpath = "$ttpath/$imagename";
|
||||
mkdir("$tpath");
|
||||
chmod 0755,$tpath;
|
||||
@ -446,7 +456,13 @@ sub make_bundle {
|
||||
}
|
||||
|
||||
$callback->( {data => ["Compressing $imagename bundle. Please be patient."]});
|
||||
my $rc = system("tar czvf $dest . ");
|
||||
my $rc;
|
||||
if($::VERBOSE){
|
||||
$callback->({data => ["tar czvf $dest . "]});
|
||||
$rc = system("tar czvf $dest . ");
|
||||
}else{
|
||||
$rc = system("tar czf $dest . ");
|
||||
}
|
||||
if($rc) {
|
||||
$callback->({error=>["Failed to compress archive! (Maybe there was no space left?)"],errorcode=>[1]});
|
||||
return;
|
||||
@ -461,20 +477,39 @@ sub make_bundle {
|
||||
|
||||
sub extract_bundle {
|
||||
my $request = shift;
|
||||
#print Dumper($request);
|
||||
my $callback = shift;
|
||||
@ARGV = @{ $request->{arg} };
|
||||
my $xml;
|
||||
my $data;
|
||||
my $datas;
|
||||
my $error = 0;
|
||||
|
||||
|
||||
my $bundle = shift @ARGV;
|
||||
# extract the image in temp path in cwd
|
||||
my $dir = getcwd;
|
||||
my $dir = $request->{cwd}; #getcwd;
|
||||
$dir = $dir->[0];
|
||||
#print Dumper($dir);
|
||||
unless(-r $bundle){
|
||||
$bundle = "$dir/$bundle";
|
||||
}
|
||||
|
||||
unless(-r $bundle){
|
||||
$callback->({error => ["Can not find $bundle"],errorcode=>[1]});
|
||||
return;
|
||||
}
|
||||
|
||||
my $tpath = mkdtemp("$dir/imgimport.$$.XXXXXX");
|
||||
|
||||
$callback->({data=>["Unbundling image..."],errorcode=>[1]});
|
||||
my $rc = system("tar zxf $bundle -C $tpath");
|
||||
$callback->({data=>["Unbundling image..."]});
|
||||
my $rc;
|
||||
if($::VERBOSE){
|
||||
$callback->({data=>["tar zxvf $bundle -C $tpath"]});
|
||||
$rc = system("tar zxvf $bundle -C $tpath");
|
||||
$rc = system("tar zxvf $bundle -C $tpath");
|
||||
}else{
|
||||
$rc = system("tar zxf $bundle -C $tpath");
|
||||
}
|
||||
if($rc){
|
||||
$callback->({error => ["Failed to extract bundle $bundle"],errorcode=>[1]});
|
||||
}
|
||||
@ -484,7 +519,7 @@ sub extract_bundle {
|
||||
# go through each image directory. Find the XML and put it into the array. If there are any
|
||||
# errors then the whole thing is over and we error and leave.
|
||||
foreach my $imgdir (@files){
|
||||
print "$imgdir \n";
|
||||
#print "$imgdir \n";
|
||||
unless(-r "$imgdir/manifest.xml"){
|
||||
$callback->({error=>["Failed to find manifest.xml file in image bundle"],errorcode=>[1]});
|
||||
return;
|
||||
@ -494,23 +529,80 @@ sub extract_bundle {
|
||||
# put it in an eval string so that it
|
||||
$data = eval { $xml->XMLin("$imgdir/manifest.xml") };
|
||||
if($@){
|
||||
$callback->({error=>$@,errorcode=>[1]});
|
||||
$callback->({error=>["None valid manifest.xml file inside the bundle. Please verify the XML"],errorcode=>[1]});
|
||||
#my $foo = $@;
|
||||
#$foo =~ s/\n//;
|
||||
#$callback->({error=>[$foo],errorcode=>[1]});
|
||||
#foreach($@){
|
||||
# last;
|
||||
#}
|
||||
return;
|
||||
}
|
||||
print Dumper($data);
|
||||
#print Dumper($data);
|
||||
#push @{$datas}, $data;
|
||||
|
||||
# now we need to import the files...
|
||||
unless(verify_manifest($data, $callback)){
|
||||
$error++;
|
||||
next;
|
||||
}
|
||||
|
||||
#print "manifest looks good, lets import!\n";
|
||||
set_config($data, $callback);
|
||||
# check media first
|
||||
unless(check_media($data, $callback)){
|
||||
$error++;
|
||||
next;
|
||||
}
|
||||
|
||||
#import manifest.xml into xCAT database
|
||||
unless(set_config($data, $callback)){
|
||||
$error++;
|
||||
next;
|
||||
}
|
||||
|
||||
# now place files in appropriate directories.
|
||||
make_files($data, $callback);
|
||||
unless(make_files($data, $imgdir, $callback)){
|
||||
$error++;
|
||||
next;
|
||||
}
|
||||
|
||||
my $osimage = $data->{imagename};
|
||||
$callback->({data=>["Successfully imported $osimage"]});
|
||||
|
||||
}
|
||||
|
||||
# remove temp file only if there were no problems.
|
||||
unless($error){
|
||||
$rc = system("rm -rf $tpath");
|
||||
if ($rc) {
|
||||
$callback->({error=>["Failed to clean up temp space $tpath"],errorcode=>[1]});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# return 1 for true 0 for false.
|
||||
# need to make sure media is copied before importing image.
|
||||
sub check_media {
|
||||
my $data = shift;
|
||||
my $callback = shift;
|
||||
my $rc = 0;
|
||||
unless( $data->{'media'}) {
|
||||
$rc = 1;
|
||||
}elsif($data->{media} eq 'required'){
|
||||
my $os = $data->{osvers};
|
||||
my $arch = $data->{osarch};
|
||||
my $installroot = xCAT::Utils->getInstallDir();
|
||||
unless($installroot){
|
||||
$installroot = '/install';
|
||||
}
|
||||
unless(-d "$installroot/$os/$arch"){
|
||||
$callback->({error=>["This image requires that you first copy media for $os-$arch"],errorcode=>[1]});
|
||||
}else{
|
||||
$rc = 1;
|
||||
}
|
||||
}
|
||||
return $rc;
|
||||
}
|
||||
|
||||
|
||||
@ -521,7 +613,7 @@ sub set_config {
|
||||
my %keyhash;
|
||||
my $osimage = $data->{imagename};
|
||||
|
||||
$callback->({data=>["Adding $osimage"],errorcode=>[1]});
|
||||
$callback->({data=>["Adding $osimage"]}) if $::VERBOSE;
|
||||
|
||||
# now we make a quick hash of what we want to put into this
|
||||
$keyhash{provmethod} = $data->{provmethod};
|
||||
@ -530,6 +622,7 @@ sub set_config {
|
||||
$keyhash{osarch} = $data->{osarch};
|
||||
$ostab->setAttribs({imagename => $osimage }, \%keyhash );
|
||||
$ostab->commit;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -603,26 +696,96 @@ sub verify_manifest {
|
||||
|
||||
sub make_files {
|
||||
my $data = shift;
|
||||
my $imgdir = shift;
|
||||
my $callback = shift;
|
||||
my $os = $data->{osvers};
|
||||
my $arch = $data->{osarch};
|
||||
my $profile = $data->{profile};
|
||||
my $installroot = xCAT::Utils->getInstallDir();
|
||||
unless($installroot){
|
||||
$installroot = '/install';
|
||||
}
|
||||
|
||||
if($data->{provmethod} =~ /install/){
|
||||
my $template = $data->{template};
|
||||
print "mkdir -p /install/custom/$os/$arch/$profile\n";
|
||||
print "cp $template /install/netboot/$os/$arch/$profile\n";
|
||||
# you'll get a hash like this:
|
||||
#$VAR1 = {
|
||||
# 'provmethod' => 'install',
|
||||
# 'profile' => 'all',
|
||||
# 'template' => '/opt/xcat/share/xcat/install/centos/all.tmpl',
|
||||
# 'imagename' => 'Default_Stateful',
|
||||
# 'osarch' => 'x86_64',
|
||||
# 'media' => 'required',
|
||||
# 'osvers' => 'centos5.4'
|
||||
# };
|
||||
my $template = basename($data->{template});
|
||||
my $instdir = "$installroot/custom/$os/$arch";
|
||||
#mkpath("$instdir", { verbose => 1, mode => 0755, error => \my $err });
|
||||
mkpath("$instdir", { verbose => 1, mode => 0755 });
|
||||
|
||||
# it could be that the old one already exists, in this case back it up.
|
||||
|
||||
if(-r "$instdir/$template"){
|
||||
$callback->( {data => ["$instdir/$template already exists. Moving to $instdir/$template.ORIG..."]});
|
||||
move("$instdir/$template", "$instdir/$template.ORIG");
|
||||
}
|
||||
move("$imgdir/$template", $instdir);
|
||||
|
||||
}elsif($data->{provmethod} =~/netboot|statelite/){
|
||||
print "mkdir -p /install/netboot/$os/$arch/$profile\n";
|
||||
print "cp kernel /install/netboot/$os/$arch/$profile\n";
|
||||
print "cp initrd.gz /install/netboot/$os/$arch/$profile\n";
|
||||
print "cp rootimg.gz /install/netboot/$os/$arch/$profile\n";
|
||||
|
||||
# data will look something like this:
|
||||
#$VAR1 = {
|
||||
# 'provmethod' => 'netboot',
|
||||
# 'profile' => 'compute',
|
||||
# 'ramdisk' => '/install/netboot/centos5.4/x86_64/compute/initrd.gz',
|
||||
# 'kernel' => '/install/netboot/centos5.4/x86_64/compute/kernel',
|
||||
# 'imagename' => 'Default_Stateless_1265981465',
|
||||
# 'osarch' => 'x86_64',
|
||||
# 'extra' => [
|
||||
# {
|
||||
# 'dest' => '/install/custom/netboot/centos',
|
||||
# 'src' => '/opt/xcat/share/xcat/netboot/centos/compute.centos5.4.pkglist'
|
||||
# },
|
||||
# {
|
||||
# 'dest' => '/install/custom/netboot/centos',
|
||||
# 'src' => '/opt/xcat/share/xcat/netboot/centos/compute.exlist'
|
||||
# }
|
||||
# ],
|
||||
# 'osvers' => 'centos5.4',
|
||||
# 'rootimg' => '/install/netboot/centos5.4/x86_64/compute/rootimg.gz'
|
||||
# };
|
||||
my $kernel = basename($data->{kernel});
|
||||
my $ramdisk = basename($data->{ramdisk});
|
||||
my $rootimg = basename($data->{rootimg});
|
||||
|
||||
my $netdir = "$installroot/netboot/$os/$arch/$profile";
|
||||
mkpath("$netdir", {verbose => 1, mode => 0755 });
|
||||
|
||||
# save the old one off
|
||||
foreach my $f ($kernel, $ramdisk, $rootimg){
|
||||
if(-r "$netdir/$kernel"){
|
||||
$callback->( {data => ["Moving old $netdir/$f to $netdir/$f.ORIG..."]}) if $::VERBOSE;
|
||||
move("$netdir/$f", "$netdir/$f.ORIG");
|
||||
}
|
||||
copy("$imgdir/$f", $netdir);
|
||||
}
|
||||
# TODO: for statelite we should expand the rootimg and get the table values in place.
|
||||
}
|
||||
|
||||
if($data->{extra}){
|
||||
# have to copy extras
|
||||
print "copying extras...\n";
|
||||
print "copying extras...\n" if $::VERBOSE;
|
||||
foreach(@{ $data->{extra} }) {
|
||||
my $f = basename($_->{src});
|
||||
my $dest = $_->{dest};
|
||||
print "cp $imgdir/extra/$f $dest\n" if $::VERBOSE;
|
||||
if(-r "$dest/$f"){
|
||||
$callback->( {data => ["Moving old $dest/$f to $dest/$f.ORIG..."]}) if $::VERBOSE;
|
||||
move("$dest/$f", "$dest/$f.ORIG");
|
||||
}
|
||||
copy("$imgdir/extra/$f", $dest);
|
||||
}
|
||||
}
|
||||
|
||||
# return 1 meant everything was successful!
|
||||
return 1;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user