From b50ed51b906a1893b2f8592a86777f50bf033d96 Mon Sep 17 00:00:00 2001 From: nott Date: Tue, 15 Apr 2008 12:07:43 +0000 Subject: [PATCH] Change writescript() to use the postscripts table. git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@1052 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- perl-xCAT-2.0/xCAT/Postage.pm | 341 +++++++++------------------------- 1 file changed, 88 insertions(+), 253 deletions(-) diff --git a/perl-xCAT-2.0/xCAT/Postage.pm b/perl-xCAT-2.0/xCAT/Postage.pm index 15f1507e2..c275816e0 100644 --- a/perl-xCAT-2.0/xCAT/Postage.pm +++ b/perl-xCAT-2.0/xCAT/Postage.pm @@ -3,23 +3,45 @@ package xCAT::Postage; use xCAT::Table; use xCAT::NodeRange; use Data::Dumper; -my $depsfile = "/etc/xcat/postscripts.dep"; -my $rulesfile = "/etc/xcat/postscripts.rules"; -my $rules; -my $deps; -my $rulec; -my $node; +#------------------------------------------------------------------------------- + +=head1 Postage + +=head2 xCAT post script support. + +This program module file is a set of utilities to support xCAT post scripts. + +=cut + +#------------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- + +=head3 writescript + + Create a node-specific post script for an xCAT node + + Arguments: + Returns: + Globals: + Error: + Example: + + xCAT::Postage->writescript($node, "/install/postscripts/" . $node, $state); + + Comments: + +=cut + +#----------------------------------------------------------------------------- sub writescript { - if (scalar(@_) eq 3) { shift; } #Discard self - $node = shift; + if (scalar(@_) eq 4) { shift; } #Discard self + my $node = shift; my $scriptfile = shift; + my $nodesetstate = shift; # install or netboot + my $script; - open($rules,"<",$rulesfile); - open($deps,"<",$depsfile); - unless($rules) { - return undef; - } open($script,">",$scriptfile); unless ($scriptfile) { return undef; @@ -33,13 +55,37 @@ sub writescript { chmod 0755,$scriptfile; } +#---------------------------------------------------------------------------- + +=head3 makescript + + Determine the contents of a node-specific post script for an xCAT node + + Arguments: + Returns: + Globals: + Error: + Example: + + xCAT::Postage->writescript($node, "/install/postscripts/" . $node, $state); + + Comments: + +=cut + +#----------------------------------------------------------------------------- sub makescript { $node = shift; my @scriptd; + + my ($master, $ps, $os, $arch, $profile); + my $noderestab=xCAT::Table->new('noderes'); my $typetab=xCAT::Table->new('nodetype'); - unless ($noderestab and $typetab) { - die "Unable to open noderes or nodetype table"; + my $posttab = xCAT::Table->new('postscripts'); + + unless ($noderestab and $typetab and $posttab) { + die "Unable to open noderes or nodetype or site or postscripts table"; } my $master; my $sitetab = xCAT::Table->new('site'); @@ -58,256 +104,45 @@ sub makescript { unless ($master) { die "Unable to identify master for $node"; } + push @scriptd, "MASTER=".$master."\n"; push @scriptd, "export MASTER\n"; push @scriptd, "NODE=$node\n"; push @scriptd, "export NODE\n"; - my $et = $typetab->getNodeAttribs($node,['os','arch']); - unless ($et and $et->{'os'} and $et->{'arch'}) { - die "No os/arch setting in nodetype table for $node"; + my $et = $typetab->getNodeAttribs($node,['os','arch','profile']); + unless ($et and $et->{'os'} and $et->{'arch'} and $et->{'profile'}) { + die "No os or arch or profile setting in nodetype table for $node"; } push @scriptd, "OSVER=".$et->{'os'}."\n"; push @scriptd, "ARCH=".$et->{'arch'}."\n"; - push @scriptd, "export OSVER ARCH\n"; + push @scriptd, "PROFILE=".$et->{'profile'}."\n"; + push @scriptd, "export OSVER ARCH PROFILE\n"; push @scriptd, 'PATH=`dirname $0`:$PATH'."\n"; push @scriptd, "export PATH\n"; - $rulec=""; - my @scripts; - my $inlist = 0; - my $pushmode = 0; - my $critline=""; - while (<$rules>) { - my $line = $_; - $line =~ s/^\s*//; - $line =~ s/\s*$//; - $line =~ s/#.*//; - if ($line =~ /^$/) { - next; - } - # we are left with content lines.. - my $donewithline=0; - while (not $donewithline) { - if ($line =~ /^\s*$/) { - $donewithline=1; - next; - } - if ($inlist) { - if ($line =~/^[^\}]*\{/) { - #TODO: error unbalanced {} in postscripts.rules - die "Unbalanced {}"; - return undef; - } - if ($pushmode) { - my $toadd; - ($toadd) = $line =~ /(^[^\}]*)/; - $line =~ s/(^[^\}]*)//; - unless ($toadd =~ /^\s*$/) { - push @scripts,$toadd; - } - } else { #strip non } characters leading - $line =~ s/^[^\}]*//; - } - if ($line =~ /\}/) { - $line =~ s/\}//; - $inlist=0; - } - } else { - if ($line =~/^[^\{]*\}/) { - #TODO: error unbalanced {} in postscripts.rules - return undef; - } - (my $tcritline) = $line =~ /^([^\{]*)/; - $critline .= $tcritline . " "; - if ($line =~ /\{/) { - if (criteriamatches($critline)) { - $pushmode=1; - } else { - $pushmode=0; - } - $critline = ""; - $inlist = 1; - $line =~ s/[^\{]*\{//; - } else { - $donewithline=1; - } - } - } + if ($nodesetstate) { + push @scriptd, "NODESETSTATE=".$nodesetstate."\n"; + push @scriptd, "export NODESETSTATE\n"; } - foreach (@scripts) { - push @scriptd, $_."\n"; + + # get the xcatdefaults entry in the postscripts table + my $et = $posttab->getAttribs({node=>"xcatdefaults"},'postscripts'); + $defscripts = $et->{'postscripts'}; + if ($defscripts) { + foreach my $n (split(/,/, $defscripts)) { + push @scriptd, $n."\n"; + } } + + # get postscripts + my $et = $posttab->getNodeAttribs($node, ['postscripts']); + $ps = $et->{'postscripts'}; + if ($ps) { + foreach my $n (split(/,/, $ps)) { + push @scriptd, $n."\n"; + } + } + return @scriptd; } -#shamelessly brought forth from postrules.pl in xCAT 1.3 -sub criteriamatches { - my $cline = shift; - my $level=0; - my $pline; - my @opstack; - my @expstack; - my $r; - $cline =~ s/\{//g; - $cline =~ s/(\(|\))/ $1 /g; - $cline =~ s/\s*=\s*/=/g; - $cline =~ s/^\s*//; - $cline =~ s/\s*$//; - $cline =~ s/\s+/ /; - if ($cline =~ /^ALL$/) { - return 1; - } - my @tokens = split('\s+',$cline); - my $token; - foreach $token (@tokens) { - if ($token eq ')') { - $level--; - if ($level == 0) { - push @expstack,criteriamatches($pline); - $pline=""; - next; - } elsif ($level < 0) { - die "Unbalanecd () in postrules"; - } - } - if ($level) { - $pline .= " $token"; - } - if ($token eq '(') { - $level++; - next; - } - if ($level) { - next; - } - if ($token =~ /=/) { - push(@expstack,$token); - next; - } - if ($token =~ /^(and|or|not)$/i) { - push (@opstack,$token); - next; - } - die "Syntax error in postscripts rules, bad token $token"; - } - if ($level) { - die "Unbalanced () in postscripts rules"; - } - - while (@opstack) { - my $op; - my $r1 = 0; - my $r2 = 0; - - $op = pop(@opstack); - unless (defined $op) { - die "Stack underflow in postscripts rules"; - } - if ($op =~ /and/i) { - $r1 = popeval(\@expstack); - $r2 = popeval(\@expstack); - - if ($r1 && $r2) { - push(@expstack,1); - } else { - push(@expstack,0); - } - } elsif ($op =~ /or/i) { - $r1 = popeval(\@expstack); - $r2 = popeval(\@expstack); - if ($r1 || $r2) { - push(@expstack,1); - } else { - push(@expstack,0); - } - } elsif ($op =~ /not/i) { - $r1 = popeval(\@expstack); - if ($r1==0) { - push(@expstack,1); - } else { - push (@expstack,0); - } - } - } - if (@expstack == 1) { - $r = popeval(\@expstack); - push(@expstack,$r); - } - - $r = pop(@expstack); - unless (defined $r) { - die "Stack underflow in postscripts processing"; - } - if (@expstack != 0 || @opstack != 0) { - die "Stack underflow in postscripts processing"; - } - return $r; -} - - -sub popeval { - my ($expstack) = @_; - my $exp; - my $v; - my $r; - $exp = pop(@$expstack); - if (defined ($exp)) { - if ($exp =~ /=/) { - my @eqarr = split(/=/,$exp); - $r = $eqarr[$#eqarr]; - $v = join('=',@eqarr[0..($#eqarr-1)]); - #($v,$r) = split(/=/,$exp); - if ($v =~ /^OSVER$/) { #OSVER is redundant, but a convenient shortcut - $v = 'TABLE:nodetype:$NODE:os'; - } - if ($v =~ /^NODERANGE$/i) { - my @nr = noderange $r; - foreach (@nr) { - if ($node eq $_) { - return 1; - } - } - return 0; - } - if ($v =~ /^TABLE:/) { - my $table; - my $key; - my $field; - ($table,$key,$field) = $v =~ m/TABLE:([^:]+):([^:]+):(.*)/; - my $tabref = xCAT::Table->new($table); - unless ($tabref) { return 0; } - my $ent; - if ($key =~ /^\$NODE/) { - $ent = $tabref->getNodeAttribs($node,[$field]); - } else { - my @keys = split /,/,$key; - my %keyh; - foreach (@keys) { - my $keycol; - my $keyval; - ($keycol,$keyvol)=split /=/,$_; - $keyh{$keycol}=$keyvol; - } - ($ent)=$tabref->getAttribs(\%keyh,$field); - } - - unless ($ent and $ent->{$field}) { return 0; } - if ($ent->{$field} =~ /^$r$/) { - return 1; - } else { - return 0; - } - } - #TODO? support for env vars? Don't see much of a point now, but need input - } elsif ($exp == 0 || $exp == 1) { - return ($exp); - } else { - die "Invalid expression $exp in postcripts rules"; - } - } else { - die "Stack underflow in postscripts rules..."; - } -} - - - 1;