image import and export work. 4: added postscripts support

git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@7395 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
linggao 2010-09-09 19:05:29 +00:00
parent a31322f37b
commit b8645cd151

View File

@ -1,4 +1,3 @@
# Sumavi Inc (C) 2010
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
@ -8,6 +7,11 @@
# This will make it so that you can easily share your images with others.
# All your images are belong to us!
package xCAT_plugin::imgport;
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
}
use lib "$::XCATROOT/lib/perl";
use strict;
use warnings;
#use xCAT::Table;
@ -22,6 +26,7 @@ use File::Temp;
use File::Copy;
use File::Path qw/mkpath/;
use File::Basename;
use xCAT::NodeRange;
use Cwd;
my $requestcommand;
$::VERBOSE = 0;
@ -81,15 +86,17 @@ sub ximport {
my $callback = shift;
my %rsp; # response
my $help;
my $nodes;
my $new_profile;
my $xusage = sub {
my $ec = shift;
push@{ $rsp{data} }, "imgimport: Takes in an xCAT image bundle and defines it to xCAT so you can use it";
push@{ $rsp{data} }, "Usage: ";
push@{ $rsp{data} }, "\timgimport [-h|--help] - displays this help message";
push@{ $rsp{data} }, "\timgimport <image name> - imports image. Image should be an xCAT bundle";
if($ec){ $rsp{errorcode} = $ec; }
$callback->(\%rsp);
my $ec = shift;
push@{ $rsp{data} }, "imgimport: Takes in an xCAT image bundle and defines it to xCAT so you can use it";
push@{ $rsp{data} }, "Usage: ";
push@{ $rsp{data} }, "\timgimport [-h|--help]";
push@{ $rsp{data} }, "\timgimport <bundle_file_name> [-p|--postscripts <nodelist>] [-f|--profile <new_profile>] [-v]";
if($ec){ $rsp{errorcode} = $ec; }
$callback->(\%rsp);
};
unless(defined($request->{arg})){ $xusage->(1); return; }
@ARGV = @{ $request->{arg}};
@ -101,6 +108,8 @@ sub ximport {
GetOptions(
'h|?|help' => \$help,
'v|verbose' => \$::VERBOSE,
'p|postscripts=s' => \$nodes,
'f|profile=s' => \$new_profile,
);
if($help){
@ -109,7 +118,7 @@ sub ximport {
}
# first extract the bundle
extract_bundle($request, $callback);
extract_bundle($request, $callback,$nodes,$new_profile);
}
@ -123,11 +132,14 @@ sub xexport {
my %rsp; # response
my $help;
my @extra;
my $node;
my $xusage = sub {
my $ec = shift;
push@{ $rsp{data} }, "imgexport: Creates a tarball of an existing xCAT image";
push@{ $rsp{data} }, "Usage: imgexport [-f] <image name> [directory] [[--extra <file:dir> ] ... ]";
push@{ $rsp{data} }, "imgexport: Creates a tarball (bundle) of an existing xCAT image";
push@{ $rsp{data} }, "Usage: ";
push@{ $rsp{data} }, "\timgexport [-h|--help]";
push@{ $rsp{data} }, "\timgexport <image_name> [directory] [[-e|--extra <file:dir> ] ... ] [-p|--postscripts <node_name>] [-v]";
if($ec){ $rsp{errorcode} = $ec; }
$callback->(\%rsp);
};
@ -140,7 +152,8 @@ sub xexport {
GetOptions(
'h|?|help' => \$help,
'extra=s' => \@extra,
'p|postscripts=s' => \$node,
'e|extra=s' => \@extra,
'v|verbose' => \$::VERBOSE
);
@ -157,11 +170,11 @@ sub xexport {
$callback->( {data => ["Exporting $img_name to $cwd..."]});
# check if all files are in place
my $attrs = get_image_info($img_name, $callback, @extra);
my $attrs = get_image_info($img_name, $callback, $node, @extra);
#print Dumper($attrs);
unless($attrs){
return 1;
return 1;
}
# make manifest and tar it up.
@ -177,6 +190,7 @@ sub xexport {
sub get_image_info {
my $imagename = shift;
my $callback = shift;
my $node = shift;
my @extra = @_;
my $errors = 0;
@ -253,11 +267,75 @@ sub get_image_info {
}
}
#get postscripts
if ($node) {
$attrs = get_postscripts($node, $callback, $attrs)
}
# if we get nothing back, then we couldn't find the files. How sad, return nuthin'
return $attrs;
}
sub get_postscripts {
my $node = shift;
my $errors = 0;
my $callback = shift;
my $attrs = shift;
my @nodes = noderange($node);
if (@nodes > 0) { $node = $nodes[0]; }
else {
$callback->(
{error => ["Unable to get postscripts, $node is not a valide node."],errorcode=>1}
);
return 0;
}
my $postscripts;
my $postbootscripts;
my $ptab = new xCAT::Table('postscripts', -create=>1);
unless($ptab){
$callback->(
{error => ["Unable to open table 'postscripts'."],errorcode=>1}
);
return 0;
}
my $ent = $ptab->getNodeAttribs($node, ['postscripts', 'postbootscripts']);
if ($ent)
{
if ($ent->{postscripts}) { $postscripts = $ent->{postscripts}; }
if ($ent->{postbootscripts}) { $postbootscripts = $ent->{postbootscripts}; }
}
(my $attrs1) = $ptab->getAttribs({node => "xcatdefaults"}, 'postscripts', 'postbootscripts');
if ($attrs1) {
if ($attrs1->{postscripts}) {
if ($postscripts) {
$postscripts = $attrs1->{postscripts} . ",$postscripts";
} else {
$postscripts = $attrs1->{postscripts};
}
}
if ($attrs1->{postbootscripts}) {
if ($postbootscripts) {
$postbootscripts = $attrs1->{postbootscripts} . ",$postbootscripts";
} else {
$postbootscripts = $attrs1->{postbootscripts};
}
}
}
if ($postscripts) {
$attrs->{postscripts} = $postscripts;
}
if ($postbootscripts) {
$attrs->{postbootscripts} = $postbootscripts;
}
return $attrs;
}
# returns a hash of files
# extra {
@ -545,108 +623,120 @@ 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 $request = shift;
#print Dumper($request);
my $callback = shift;
my $nodes=shift;
my $new_profile=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 = $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..."]});
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]});
}
# get all the files in the tpath. These should be all the image names.
my @files = < $tpath/* >;
# 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";
unless(-r "$imgdir/manifest.xml"){
$callback->({error=>["Failed to find manifest.xml file in image bundle"],errorcode=>[1]});
return;
}
$xml = new XML::Simple;
# get the data!
# put it in an eval string so that it
$data = eval { $xml->XMLin("$imgdir/manifest.xml") };
if($@){
$callback->({error=>["invalid 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);
#push @{$datas}, $data;
my $bundle = shift @ARGV;
# extract the image in temp path in cwd
my $dir = $request->{cwd}; #getcwd;
$dir = $dir->[0];
#print Dumper($dir);
unless(-r $bundle){
$bundle = "$dir/$bundle";
# now we need to import the files...
unless(verify_manifest($data, $callback)){
$error++;
next;
}
unless(-r $bundle){
$callback->({error => ["Can not find $bundle"],errorcode=>[1]});
return;
}
my $tpath = mkdtemp("$dir/imgimport.$$.XXXXXX");
$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");
# check media first
unless(check_media($data, $callback)){
$error++;
next;
}
if($rc){
$callback->({error => ["Failed to extract bundle $bundle"],errorcode=>[1]});
#import manifest.xml into xCAT database
unless(set_config($data, $callback)){
$error++;
next;
}
# get all the files in the tpath. These should be all the image names.
my @files = < $tpath/* >;
# 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";
unless(-r "$imgdir/manifest.xml"){
$callback->({error=>["Failed to find manifest.xml file in image bundle"],errorcode=>[1]});
return;
}
$xml = new XML::Simple;
# get the data!
# put it in an eval string so that it
$data = eval { $xml->XMLin("$imgdir/manifest.xml") };
if($@){
$callback->({error=>["invalid 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);
#push @{$datas}, $data;
# now we need to import the files...
unless(verify_manifest($data, $callback)){
$error++;
next;
}
# 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.
unless(make_files($data, $imgdir, $callback)){
$error++;
next;
}
my $osimage = $data->{imagename};
$callback->({data=>["Successfully imported $osimage"]});
# now place files in appropriate directories.
unless(make_files($data, $imgdir, $callback)){
$error++;
next;
}
# 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;
}
# put postscripts in the postsctipts table
if ($nodes) {
unless(set_postscripts($data, $callback, $nodes)){
$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;
}
}
}
@ -675,6 +765,90 @@ sub check_media {
}
sub set_postscripts {
my $data = shift;
my $callback = shift;
my $nodes=shift;
$callback->({data=>["Adding postscripts..."]});
my @good_nodes=noderange($nodes);
if (@good_nodes > 0) {
my @missed = nodesmissed();
if (@missed > 0) {
$callback->(
{warning => ["The following nodes will be skipped because they are not in the nodelist table.\n " . join(',', @missed)],errorcode=>1}
);
}
} else {
$callback->(
{error => ["The nodes $nodes are not defined in xCAT DB."],errorcode=>1}
);
return 0;
}
my $ptab = xCAT::Table->new('postscripts',-create => 1,-autocommit => 0);
unless($ptab){
$callback->(
{error => ["Unable to open table 'postscripts'"],errorcode=>1}
);
return 0;
}
# get xcatdefaults settings
my @a1=();
my @a2=();
(my $attrs1) = $ptab->getAttribs({node => "xcatdefaults"}, 'postscripts', 'postbootscripts');
if ($attrs1) {
if ($attrs1->{postscripts}) {
@a1=split(',', $attrs1->{postscripts});
}
if ($attrs1->{postbootscripts}) {
@a2=split(',', $attrs1->{postbootscripts});
}
}
#remove the script if it is already in xcatdefaults
my @a3=();
my @a4=();
my $postscripts = $data->{postscripts};
my $postbootscripts = $data->{postbootscripts};
if ($postscripts) { @a3 = split(',', $postscripts); }
if ($postbootscripts) { @a4 = split(',', $postbootscripts); }
my @a30;
my @a40;
if (@a1>0 && @a3>0) {
foreach my $tmp1 (@a3) {
if (! grep /^$tmp1$/, @a1) {
push(@a30, $tmp1);
}
}
$postscripts=join(',', @a30);
}
if (@a2>0 && @a4>0) {
foreach my $tmp2 (@a4) {
if (! grep /^$tmp2$/, @a2) {
push(@a40, $tmp2);
}
}
$postbootscripts=join(',', @a40);
}
#now save to the db
my %keyhash;
if ($postscripts || $postbootscripts) {
$keyhash{postscripts} = $postscripts;
$keyhash{postbootscripts} = $postbootscripts;
$ptab->setNodesAttribs(\@good_nodes, \%keyhash );
$ptab->commit;
}
return 1;
}
sub set_config {
my $data = shift;
my $callback = shift;