Author: jfthomps
Date: Fri Nov 13 15:44:38 2009
New Revision: 835884
URL: http://svn.apache.org/viewvc?rev=835884&view=rev
Log:
initial add
Added:
incubator/vcl/sandbox/xcat2partimageng/partimageng.pm
Added: incubator/vcl/sandbox/xcat2partimageng/partimageng.pm
URL:
http://svn.apache.org/viewvc/incubator/vcl/sandbox/xcat2partimageng/partimageng.pm?rev=835884&view=auto
==============================================================================
--- incubator/vcl/sandbox/xcat2partimageng/partimageng.pm (added)
+++ incubator/vcl/sandbox/xcat2partimageng/partimageng.pm Fri Nov 13 15:44:38
2009
@@ -0,0 +1,559 @@
+# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
+package xCAT_plugin::partimageng;
+use Storable qw(dclone);
+use Sys::Syslog;
+use Thread qw(yield);
+use POSIX qw(WNOHANG nice);
+use xCAT::Table;
+use xCAT::Utils;
+use xCAT::MsgUtils;
+use xCAT::Yum;
+use xCAT::Template;
+use xCAT::Postage;
+use Data::Dumper;
+use Getopt::Long;
+Getopt::Long::Configure("bundling");
+Getopt::Long::Configure("pass_through");
+use File::Path;
+use File::Copy;
+my $cpiopid;
+
+sub handled_commands
+{
+ return {
+ mkinstall => "nodetype:os=image",
+ mkimage => "nodetype:os=image",
+ };
+}
+
+sub preprocess_request
+{
+ my $req = shift;
+ my $callback = shift;
+ if ($req->{command}->[0] eq 'copycd')
+ { #don't farm out copycd
+ return [$req];
+ }
+
+ my $stab = xCAT::Table->new('site');
+ my $sent;
+ ($sent) = $stab->getAttribs({key => 'sharedtftp'}, 'value');
+ unless ( $sent
+ and defined($sent->{value})
+ and ($sent->{value} =~ /no/i or $sent->{value} =~ /0/))
+ {
+
+ #unless requesting no sharedtftp, don't make hierarchical call
+ return [$req];
+ }
+
+ my %localnodehash;
+ my %dispatchhash;
+ my $nrtab = xCAT::Table->new('noderes');
+ foreach my $node (@{$req->{node}})
+ {
+ my $nodeserver;
+ my $tent = $nrtab->getNodeAttribs($node, ['tftpserver']);
+ if ($tent) { $nodeserver = $tent->{tftpserver} }
+ unless ($tent and $tent->{tftpserver})
+ {
+ $tent = $nrtab->getNodeAttribs($node, ['servicenode']);
+ if ($tent) { $nodeserver = $tent->{servicenode} }
+ }
+ if ($nodeserver)
+ {
+ $dispatchhash{$nodeserver}->{$node} = 1;
+ }
+ else
+ {
+ $localnodehash{$node} = 1;
+ }
+ }
+ my @requests;
+ my $reqc = {%$req};
+ $reqc->{node} = [keys %localnodehash];
+ if (scalar(@{$reqc->{node}})) { push @requests, $reqc }
+
+ foreach my $dtarg (keys %dispatchhash)
+ { #iterate dispatch targets
+ my $reqcopy = {%$req}; #deep copy
+ $reqcopy->{'_xcatdest'} = $dtarg;
+ $reqcopy->{node} = [keys %{$dispatchhash{$dtarg}}];
+ push @requests, $reqcopy;
+ }
+ return \...@requests;
+}
+
+sub process_request
+{
+ my $request = shift;
+ my $callback = shift;
+ my $doreq = shift;
+
+ if ($request->{command}->[0] eq 'mkinstall')
+ {
+ return mkinstall($request, $callback, $doreq);
+ }
+ elsif ($request->{command}->[0] eq 'mkimage')
+ {
+ return mkimage($request, $callback, $doreq);
+ }
+}
+
+sub mkinstall
+{
+ my $request = shift;
+ my $callback = shift;
+ my $doreq = shift;
+ my @nodes = @{$request->{node}};
+ my $installroot;
+ $installroot = "/install";
+
+ my $node;
+ my $ostab = xCAT::Table->new('nodetype');
+ foreach $node (@nodes)
+ {
+ my $osinst;
+ my $ent = $ostab->getNodeAttribs($node, ['profile', 'os', 'arch']);
+ my @missingparms;
+ unless ($ent->{os}) {
+ push @missingparms,"nodetype.os";
+ }
+ unless ($ent->{arch}) {
+ push @missingparms,"nodetype.arch";
+ }
+ unless ($ent->{profile}) {
+ push @missingparms,"nodetype.profile";
+ }
+ unless ($ent->{os} and $ent->{arch} and $ent->{profile})
+ {
+ $callback->(
+ {
+ error => ["Missing ".join(',',@missingparms)." for
$node"],
+ errorcode => [1]
+ }
+ );
+ next; #No profile
+ }
+ my $os = $ent->{os};
+ my $arch = $ent->{arch};
+ my $profile = $ent->{profile};
+ # check for /install/image/$arch/$profile
+ unless (-r "$installroot/image/$arch/$profile.img" or
+ -r "$installroot/image/$arch/$profile.gz" or
+ -r "$installroot/image/$arch/$profile-parta1.gz")
+ {
+ $callback->(
+ {
+ error => [
+ "No image file found for $profile in
$installroot/image/$arch"
+ ],
+ errorcode => [1]
+ }
+ );
+ next;
+ }
+
+ #Call the Template class to do substitution to produce a kickstart
file in the autoinst dir
+ my $tmperr =
+ "Unable to find template in $::XCATROOT/share/xcat/install/image
(for $profile/$os/$arch combination)";
+ if (-r $::XCATROOT
+ . "/share/xcat/install/image/$profile.$arch.tmpl")
+ {
+ $tmperr =
+ xCAT::Template->subvars(
+ $::XCATROOT
+ . "/share/xcat/install/image/$profile.$arch.tmpl",
+ "$installroot/autoinst/" . $node,
+ $node
+ );
+ }
+ elsif (-r $::XCATROOT
+ . "/share/xcat/install/image/$profile.tmpl")
+ {
+ $tmperr =
+ xCAT::Template->subvars(
+ $::XCATROOT
+ . "/share/xcat/install/image/$profile.tmpl",
+ "$installroot/autoinst/" . $node,
+ $node
+ );
+ }
+ elsif (-r $::XCATROOT
+ . "/share/xcat/install/image/default.tmpl")
+ {
+ $tmperr =
+ xCAT::Template->subvars(
+ $::XCATROOT
+ . "/share/xcat/install/image/default.tmpl",
+ "$installroot/autoinst/" . $node,
+ $node
+ );
+ }
+ if ($tmperr)
+ {
+ $callback->(
+ {
+ node =>
+ [{name => [$node], error => [$tmperr], errorcode =>
[1]}]
+ }
+ );
+ next;
+ }
+
+ # copy partimageng script to the node-specific post scripts area
+ #mkpath "$installroot/postscripts/$node";
+ #xCAT::Postage->writescript($node,"/install/postscripts/".$node,
"install", $callback);
+ #copy("$installroot/postscripts/partimageng",
+ # "/$installroot/postscripts/$node/");
+
+ if (
+ -r "/tftpboot/xcat/image/$arch/vmlinuz"
+ and -r "/tftpboot/xcat/image/$arch/initrd.img"
+ and -r "$installroot/image/$arch/installer_files/rootimg.gz"
+ )
+ {
+
+ #We have a shot...
+ my $restab = xCAT::Table->new('noderes');
+ my $bptab = xCAT::Table->new('bootparams',-create=>1);
+ my $hmtab = xCAT::Table->new('nodehm');
+ my $ent =
+ $restab->getNodeAttribs($node,
+ ['nfsserver', 'primarynic', 'installnic',
'kcmdline']);
+ my $sent =
+ $hmtab->getNodeAttribs(
+ $node,
+ [
+ 'serialport', 'serialspeed', 'serialflow'
+ ]
+ );
+ unless ($ent and $ent->{nfsserver})
+ {
+ $callback->(
+ {
+ error => ["No noderes.nfsserver defined for " .
$node],
+ errorcode => [1]
+ }
+ );
+ next;
+ }
+
+
+ # determine image server, if tftpserver use it, else use xcatmaster
+ # else use site.Master, last resort use self
+ my $imgsrv;
+ my $ient;
+ $ient = $restab->getNodeAttribs($node, ['tftpserver']);
+ if ($ient and $ient->{tftpserver})
+ {
+ $imgsrv = $ient->{tftpserver};
+ }
+ else
+ {
+ $ient = $restab->getNodeAttribs($node, ['xcatmaster']);
+ if ($ient and $ient->{xcatmaster})
+ {
+ $imgsrv = $ient->{xcatmaster};
+ }
+ else
+ {
+ $ient = $sitetab->getAttribs({key => master}, value);
+ if ($ient and $ient->{value})
+ {
+ $imgsrv = $ient->{value};
+ }
+ else
+ {
+ my $ipfn = xCAT::Utils->my_ip_facing($node);
+ if ($ipfn)
+ {
+ $imgsrv = $ipfn; #guessing self is second best
+
+ }
+ }
+ }
+ }
+ unless ($imgsrv)
+ {
+ $callback->(
+ {
+ error => [
+ "Unable to determine or reasonably guess the image
server for $node"
+ ],
+ errorcode => [1]
+ }
+ );
+ next;
+ }
+
+ my $kcmdline =
"imgurl=http://$imgsrv/$installroot/image/$arch/installer_files/rootimg.gz
image=$installroot/image/$arch/$profile.img blocks=512 action=restore reboot "
. $ent->{kcmdline};
+
+ if (defined($sent->{serialport}))
+ {
+ unless ($sent->{serialspeed})
+ {
+ $callback->(
+ {
+ error => [
+ "serialport defined, but no serialspeed for $node
in nodehm table"
+ ],
+ errorcode => [1]
+ }
+ );
+ next;
+ }
+ $kcmdline .=
+ " console=ttyS"
+ . $sent->{serialport} . ","
+ . $sent->{serialspeed};
+ if ($sent->{serialflow} =~ /(hard|cts|ctsrts)/)
+ {
+ $kcmdline .= "n8r";
+ }
+ }
+ $kcmdline .= " noipv6";
+
+ $bptab->setNodeAttribs(
+ $node,
+ {
+ kernel => "xcat/image/$arch/vmlinuz",
+ initrd => "xcat/image/$arch/initrd.img",
+ kcmdline => $kcmdline
+ }
+ );
+ }
+ else
+ {
+ $callback->(
+ {
+ error => ["vmlinuz and initrd.img not found at
/tftpboot/xcat/image/$arch"],
+ errorcode => [1]
+ }
+ );
+ }
+ }
+ #my $rc = xCAT::Utils->create_postscripts_tar();
+ #if ($rc != 0)
+ #{
+ # xCAT::MsgUtils->message("S", "Error creating postscripts tar file.");
+ #}
+}
+
+sub mkimage
+{
+ my $request = shift;
+ my $callback = shift;
+ my $doreq = shift;
+ my @nodes = @{$request->{node}};
+ my $installroot;
+ $installroot = "/install";
+
+ my $node;
+ my $ostab = xCAT::Table->new('nodetype');
+ foreach $node (@nodes)
+ {
+ my $osinst;
+ my $ent = $ostab->getNodeAttribs($node, ['profile', 'os', 'arch']);
+ my @missingparms;
+ unless ($ent->{os}) {
+ push @missingparms,"nodetype.os";
+ }
+ unless ($ent->{arch}) {
+ push @missingparms,"nodetype.arch";
+ }
+ unless ($ent->{profile}) {
+ push @missingparms,"nodetype.profile";
+ }
+ unless ($ent->{os} and $ent->{arch} and $ent->{profile})
+ {
+ $callback->(
+ {
+ error => ["Missing ".join(',',@missingparms)." for
$node"],
+ errorcode => [1]
+ }
+ );
+ next; #No profile
+ }
+ my $os = $ent->{os};
+ my $arch = $ent->{arch};
+ my $profile = $ent->{profile};
+ # check for /install/image/$arch/$profile
+ if (-r "$installroot/image/$arch/$profile.img")
+ {
+ $callback->(
+ {
+ error => [
+ "Image file already exists for $profile in
$installroot/image/$arch"
+ ],
+ errorcode => [1]
+ }
+ );
+ next;
+ }
+
+ #Call the Template class to do substitution to produce a kickstart
file in the autoinst dir
+ my $tmperr =
+ "Unable to find template
$::XCATROOT/share/xcat/install/image/createimage.$arch.tmpl";
+ if (-r $::XCATROOT
+ . "/share/xcat/install/image/createimage.$arch.tmpl")
+ {
+ $tmperr =
+ xCAT::Template->subvars(
+ $::XCATROOT
+ . "/share/xcat/install/image/createimage.$arch.tmpl",
+ "$installroot/autoinst/" . $node,
+ $node
+ );
+ }
+ if ($tmperr)
+ {
+ $callback->(
+ {
+ node =>
+ [{name => [$node], error => [$tmperr], errorcode =>
[1]}]
+ }
+ );
+ next;
+ }
+
+ # copy partimageng script to the node-specific post scripts area
+ #mkpath "$installroot/postscripts/$node";
+ #xCAT::Postage->writescript($node,"/install/postscripts/".$node,
"install", $callback);
+ #copy("$installroot/postscripts/partimageng",
+ # "/$installroot/postscripts/$node/");
+
+ if (
+ -r "/tftpboot/xcat/image/$arch/vmlinuz"
+ and -r "/tftpboot/xcat/image/$arch/initrd.img"
+ and -r "$installroot/image/$arch/installer_files/rootimg.gz"
+ )
+ {
+
+ #We have a shot...
+ my $restab = xCAT::Table->new('noderes');
+ my $bptab = xCAT::Table->new('bootparams',-create=>1);
+ my $hmtab = xCAT::Table->new('nodehm');
+ my $ent =
+ $restab->getNodeAttribs($node,
+ ['nfsserver', 'primarynic', 'installnic',
'kcmdline']);
+ my $sent =
+ $hmtab->getNodeAttribs(
+ $node,
+ [
+ 'serialport', 'serialspeed', 'serialflow'
+ ]
+ );
+ unless ($ent and $ent->{nfsserver})
+ {
+ $callback->(
+ {
+ error => ["No noderes.nfsserver defined for " .
$node],
+ errorcode => [1]
+ }
+ );
+ next;
+ }
+
+
+ # determine image server, if tftpserver use it, else use xcatmaster
+ # else use site.Master, last resort use self
+ my $imgsrv;
+ my $ient;
+ $ient = $restab->getNodeAttribs($node, ['tftpserver']);
+ if ($ient and $ient->{tftpserver})
+ {
+ $imgsrv = $ient->{tftpserver};
+ }
+ else
+ {
+ $ient = $restab->getNodeAttribs($node, ['xcatmaster']);
+ if ($ient and $ient->{xcatmaster})
+ {
+ $imgsrv = $ient->{xcatmaster};
+ }
+ else
+ {
+ $ient = $sitetab->getAttribs({key => master}, value);
+ if ($ient and $ient->{value})
+ {
+ $imgsrv = $ient->{value};
+ }
+ else
+ {
+ my $ipfn = xCAT::Utils->my_ip_facing($node);
+ if ($ipfn)
+ {
+ $imgsrv = $ipfn; #guessing self is second best
+
+ }
+ }
+ }
+ }
+ unless ($imgsrv)
+ {
+ $callback->(
+ {
+ error => [
+ "Unable to determine or reasonably guess the image
server for $node"
+ ],
+ errorcode => [1]
+ }
+ );
+ next;
+ }
+
+ my $kcmdline =
"imgurl=http://$imgsrv/$installroot/image/$arch/installer_files/rootimg.gz
image=$installroot/image/$arch/$profile.img blocks=512 action=save reboot " .
$ent->{kcmdline};
+
+ if (defined($sent->{serialport}))
+ {
+ unless ($sent->{serialspeed})
+ {
+ $callback->(
+ {
+ error => [
+ "serialport defined, but no serialspeed for $node
in nodehm table"
+ ],
+ errorcode => [1]
+ }
+ );
+ next;
+ }
+ $kcmdline .=
+ " console=ttyS"
+ . $sent->{serialport} . ","
+ . $sent->{serialspeed};
+ if ($sent->{serialflow} =~ /(hard|cts|ctsrts)/)
+ {
+ $kcmdline .= "n8r";
+ }
+ }
+ $kcmdline .= " noipv6";
+
+ $bptab->setNodeAttribs(
+ $node,
+ {
+ kernel => "xcat/image/$arch/vmlinuz",
+ initrd => "xcat/image/$arch/initrd.img",
+ kcmdline => $kcmdline
+ }
+ );
+ }
+ else
+ {
+ $callback->(
+ {
+ error => ["vmlinuz and initrd.img not found at
/tftpboot/xcat/image/$arch"],
+ errorcode => [1]
+ }
+ );
+ }
+ }
+ #my $rc = xCAT::Utils->create_postscripts_tar();
+ #if ($rc != 0)
+ #{
+ # xCAT::MsgUtils->message("S", "Error creating postscripts tar file.");
+ #}
+}
+
+1;