Added xcatsetup command

git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@7471 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
bp-sawyers 2010-09-16 02:05:28 +00:00
parent fe927896fc
commit bd4d516212
3 changed files with 802 additions and 0 deletions

View File

@ -0,0 +1,201 @@
=head1 NAME
B<xcatsetup> - Prime the xCAT database using naming conventions specified in a config file.
=head1 SYNOPSIS
B<xcatsetup> [I<cluster-config-file>]
B<xcatsetup> [B<-?> | B<-h> | B<--help> | B<-v> | B<--version>]
=head1 DESCRIPTION
The B<xcatsetup> command reads the specified config file that contains general information about the cluster being set up,
and naming conventions and IP addresses that you want to use. It then defines the basic objects in the xCAT database
representing this cluster configuration. The B<xcatsetup> command prepares the database for the step of discovering
the hardware that is connected to the service and cluster networks.
The B<xcatsetup> command is intended as a quick way to fill out the database for a cluster that has very regular
naming patterns. The only thing is done is fill in database attributes. If your cluster does not follow consistent
naming patterns, or has some other special configuration, you should define attribute values manually instead of using
B<xcatsetup>.
Note: currently the B<xcatsetup> command has only been implemented and tested for system p servers.
The B<config file> is organized in stanza format and supports the keywords in the sample file below. Comment lines
begin with "#". Stanzas can be ommitted if you do not want to define that type of object.
xcat-site:
domain = cluster.com
xcat-hmcs:
hostname-range = hmc1-hmc3
starting-ip = 10.201.0.1
xcat-frames:
# these are the connections to the BPCs
hostname-range = bpc1-bpc6
starting-ip = 10.202.0.1
num-frames-per-hmc = 2
vpd-file = vpd.stanza
xcat-cecs:
# these are the connections to the FSPs
hostname-range = cec01-cec60
starting-ip = 10.203.0.1
supernode-list = supernodelist.txt
xcat-building-blocks:
num-frames-per-bb = 2
num-cecs-per-bb = 20
xcat-lpars:
num-lpars-per-cec = 8
num-service-nodes-per-bb = 2
# this is for the ethernet NIC on each SN
service-node-hostname-range = sn1-sn6
service-node-starting-ip = 10.200.1.1
# this value is the same format as the hosts.otherinterfaces attribute except
# the IP addresses are starting IP addresses
service-node-otherinterfaces = -hf0:10.10.1.1,-hf1:10.11.1.1,-hf2:10.12.1.1,-hf3:10.13.1.1
num-storage-nodes-per-bb = 3
storage-node-hostname-range = stor01-stor09
storage-node-starting-ip = 10.20.1.1
storage-node-aliases = -hf0
storage-node-otherinterfaces = -hf1:10.21.1.1,-hf2:10.22.1.1,-hf3:10.23.1.1
num-compute-nodes-per-bb = 155
compute-node-hostname-range = n001-n465
compute-node-starting-ip = 10.30.1.1
compute-node-aliases = -hf0
# ml0 is for aix. For linux, use bond0 instead.
compute-node-otherinterfaces = -hf1:10.31.1.1,-hf2:10.32.1.1,-hf3:10.33.1.1,-ml0:10.34.1.1
The B<vpd-file> specifies the following vpd table attributes for the BPCs (frame power supplies): node,
serial, mtm, side. Use the same stanza format that accepted by the L<chdef(1)|chdef.1> command, as documented
in L<xcatstanzafile(5)|xcatstanzafile.5>. Here is a sample file:
bpc01:
objtype=node
serial=99200G1
mtm=9A00-100
side=A
bpc02:
objtype=node
serial=99200D1
mtm=9A00-100
side=A
The supernode-list file lists what supernode numbers should be given to each CEC in each frame.
Here is a sample file:
bpc01: 0, 1, 16
bpc02: 17, 32
bpc03: 33, 48, 49
bpc04: 64 , 65, 80
bpc05: 81, 96
bpc06: 97(1), 112(1), 113(1)
The name before the colon is the node name of the frame BPC. The numbers after the colon are the supernode numbers
to assign to the groups of CECs in that frame from bottom to top. Each supernode contains 4 CECs, unless it is immediately
followed by "(#)", in which case the number in parenthesis indicates how many CECs are in this supernode.
The following lists which database attributes are filled in for each stanza:
=over 15
=item B<xcat-site>
site table: domain, nameservers
=item B<xcat-hmcs>
nodelist table: node, groups
hosts table: node, ip
ppc table: node, comments
nodetype table: node, nodetype
=item B<xcat-frames>
nodelist table: node, groups
hosts table: node, ip
ppc table: node, id, hcp
nodetype table: node, nodetype
nodehm table: node, mgt
vpd table: node, serial, mtm, side
=item B<xcat-cecs>
nodelist table: node, groups
hosts table: node, ip
ppc table: node, supernode
nodetype table: node, nodetype
nodehm table: node, mgt
=item B<xcat-building-blocks>
site table: sharedtftp
ppc table: node, parent (for frame)
=item B<xcat-lpars>
nodelist table: node, groups
hosts table: node, ip, hostnames, otherinterfaces
ppc table: node, id
nodetype table: node, nodetype, arch
nodehm table: node, mgt, cons
noderes table: netboot
servicenode table: node, nameserver, dhcpserver, tftpserver, nfsserver, conserver, monserver, ftpserver, nimserver, ipforward
=back
=head1 OPTIONS
=over 10
=item B<-v|--version>
Command Version.
=item B<-?|-h|--help>
Display usage message.
=back
=head1 RETURN VALUE
0 The command completed successfully.
1 An error has occurred.
=head1 FILES
/opt/xcat/sbin/xcatsetup
=head1 SEE ALSO
L<mkdef(1)|mkdef.1>, L<chdef(1)|chdef.1>, L<xcatstanzafile(5)|xcatstanzafile.5>, L<noderange(3)|noderange.3>, L<nodeadd(8)|nodeadd.8>, L<lsdef(1)|lsdef.1>

View File

@ -151,6 +151,7 @@ ln -sf ../bin/xcatclientnnr $RPM_BUILD_ROOT/%{prefix}/sbin/rmimage
ln -sf ../bin/xcatclient $RPM_BUILD_ROOT/%{prefix}/sbin/makedns
ln -sf ../bin/xcatclientnnr $RPM_BUILD_ROOT/%{prefix}/bin/gettab
ln -sf ../bin/xcatclientnnr $RPM_BUILD_ROOT/%{prefix}/sbin/nodeadd
ln -sf ../bin/xcatclientnnr $RPM_BUILD_ROOT/%{prefix}/sbin/xcatsetup
ln -sf ../bin/xcatclientnnr $RPM_BUILD_ROOT/%{prefix}/sbin/makenetworks
ln -sf ../bin/xcatclientnnr $RPM_BUILD_ROOT/%{prefix}/sbin/copycds
ln -sf ../bin/xcatclientnnr $RPM_BUILD_ROOT/%{prefix}/bin/regnotif

View File

@ -0,0 +1,600 @@
#!/usr/bin/env perl -w
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
#####################################################
#
# Reads the cluster configuration file and primes the database in prep
# for HW discovery and node deployment.
#
# Preconditions before running the xcatsetup cmd:
# -
#
# Limitations on the values in the config file:
# - hostname ranges must have simple <alphachars><integer> format
# - IP address incrementing for ranges must currently be confined to the last field
# - the supernode-list file must contain all frames and the frame nodenames must sort correctly
#
#####################################################
package xCAT_plugin::setup;
use strict;
#use warnings;
use xCAT::NodeRange;
use xCAT::Schema;
use xCAT::Table;
use xCAT::Utils;
use xCAT::MsgUtils;
use Data::Dumper;
use xCAT::DBobjUtils;
my $CALLBACK;
my %STANZAS;
sub handled_commands {
return( { xcatsetup => "setup" } );
}
sub process_request
{
use Getopt::Long;
Getopt::Long::Configure("bundling");
#Getopt::Long::Configure("pass_through");
Getopt::Long::Configure("no_pass_through");
my $request = shift;
$CALLBACK = shift;
#my $nodes = $request->{node};
#my $command = $request->{command}->[0];
my $args = $request->{arg};
my $VERSION;
my $HELP;
my $setup_usage = sub {
my $exitcode = shift @_;
my %rsp;
push @{$rsp{data}}, "Usage: xcatsetup [-v|--version] [-?|-h|--help] <cluster-config-file>";
if ($exitcode) { $rsp{errorcode} = $exitcode; }
$CALLBACK->(\%rsp);
};
# Process the cmd line args
if ($args) { @ARGV = @{$args}; }
else { @ARGV = (); }
if (!GetOptions('h|?|help' => \$HELP, 'v|version' => \$VERSION) ) { $setup_usage->(1); return; }
if ($HELP || scalar(@ARGV)==0) { $setup_usage->(0); return; }
if ($VERSION) {
my %rsp;
my $version = xCAT::Utils->Version();
$rsp{data}->[0] = $version;
$CALLBACK->(\%rsp);
return;
}
my $input;
my $filename = fullpath($ARGV[0], $request->{cwd}->[0]);
if (!open($input, $filename)) {
errormsg("Can not open file $filename.", 2);
return;
}
# Parse the config file
my $success = readFileInput($input);
close($input);
if (!$success) { return; }
# Write the db entries
writedb($request->{cwd}->[0]);
}
sub readFileInput {
my $input = shift;
my $l;
my $stanza;
my $linenum = 0;
while ($l=<$input>) {
$linenum++;
# skip blank and comment lines
next if ( $l =~ /^\s*$/ || $l =~ /^\s*#/ );
# process a real line
if ( $l =~ /^\s*(\S+)\s*=\s*(.*)\s*$/ ) {
my $attr = $1;
my $val = $2;
#$attr =~ s/^\s*//; # Remove any leading whitespace - already did that
#$attr =~ s/\s*$//; # Remove any trailing whitespace - already did that
$attr =~ tr/A-Z/a-z/; # Convert to lowercase
#$val =~ s/^\s*//;
#$val =~ s/\s*$//;
# set the value in the hash for this stanza
if (!defined($stanza)) { errormsg("expected stanza header at line $linenum.", 3); return; }
$STANZAS{$stanza}->{$attr} = $val;
}
elsif ( $l =~ /^\s*(\S+)\s*:\s*$/) {
$stanza = $1;
}
else {
errormsg("syntax error on line $linenum.", 3);
return 0;
}
} # end while - go to next line
return 1;
}
# A few global variables for common tables that a lot of functions need
my %tables = ('site' => 0,
'nodelist' => 0,
'hosts' => 0,
'ppc' => 0,
'nodetype' => 0,
'nodehm' => 0,
'noderes' => 0,
);
sub writedb {
my $cwd = shift; # the current dir from the request
#todo: add syntax checking for input values
# Open some common tables that several of the stanzas need
foreach my $tab (keys %tables) {
$tables{$tab} = xCAT::Table->new($tab, -create=>1);
if (!$tables{$tab}) { errormsg("Can not open $tab table in database. Exiting config file processing.", 3); return; }
}
# Write site table attrs (hash key=xcat-site)
my $domain = $STANZAS{'xcat-site'}->{domain};
if ($domain) { writesite($domain); }
# Write service LAN info (hash key=xcat-service-lan)
#using hostname-range, write: nodelist.node, nodelist.groups, switches.switch
#using hostname-range and starting-ip, write regex for: hosts.node, hosts.ip
#using num-ports-per-switch, switch-port-prefix, switch-port-sequence, write: switch.node, switch.switch, switch.port
#using dhcp-dynamic-range, write: networks.dynamicrange for the service network.
# * Note: for AIX the permanent IPs for HMCs/FSPs/BPAs (specified in later stanzas) should be within this dynamic range, at the high end. For linux the permanent IPs should be outside this dynamic range.
# * use the first IP in the specified dynamic range to locate the service network in the networks table
#on aix stop bootp - see section 2.2.1.1 of p hw mgmt doc
#run makedhcp -n
# Write HMC info (hash key=xcat-hmcs)
my $hmcrange = $STANZAS{'xcat-hmcs'}->{'hostname-range'};
if ($hmcrange) { writehmc($hmcrange); }
# Write frame info (hash key=xcat-frames)
my $framerange = $STANZAS{'xcat-frames'}->{'hostname-range'};
if ($framerange) { writeframe($framerange, $cwd); }
# Write CEC info (hash key=xcat-cecs)
my $cecrange = $STANZAS{'xcat-cecs'}->{'hostname-range'};
if ($cecrange) { writecec($cecrange, $cwd); }
# Write BB info (hash key=xcat-building-blocks)
my $framesperbb = $STANZAS{'xcat-building-blocks'}->{'num-frames-per-bb'};
if ($framesperbb) { writebb($framesperbb); }
# Write lpar info in ppc, noderes, servicenode
my $snrange = $STANZAS{'xcat-lpars'}->{'service-node-hostname-range'};
if ($snrange) { writesn($snrange); }
my $storagerange = $STANZAS{'xcat-lpars'}->{'storage-node-hostname-range'};
if ($storagerange) { writestorage($storagerange); }
my $computerange = $STANZAS{'xcat-lpars'}->{'compute-node-hostname-range'};
if ($computerange) { writecompute($computerange); }
# Close all the open common tables to finish up
foreach my $tab (keys %tables) {
if ($tables{$tab}) { $tables{$tab}->close(); }
}
# Temporarily write out the contents of the hash
#foreach my $k (keys %STANZAS) {
# my $stanza = $STANZAS{$k};
# print "$k\n";
# foreach my $attr (keys %$stanza) {
# my $val = $$stanza{$attr};
# print " $attr=$val\n";
# }
#}
}
sub writesite {
#write: domain, nameservers=<MN>
my $domain = shift;
infomsg('Defining site attributes...');
# set the domain specified in the config file
#print "domain=$domain\n";
$tables{'site'}->setAttribs({key => 'domain'}, {value => $domain});
# set the site.nameservers value to the site.master value
my $ref = $tables{'site'}->getAttribs({key => 'master'}, 'value');
if ($ref) {
$tables{'site'}->setAttribs({key => 'nameservers'}, {value => $ref->{value} });
}
$tables{'site'}->close();
}
sub writehmc {
#using hostname-range, write: nodelist.node, nodelist.groups
my $hmcrange = shift;
infomsg('Defining HMCs...');
my $nodes = [noderange($hmcrange, 0)];
my ($hmcstartnum) = $$nodes[0] =~/^\D+(\d+)$/; # save this value for later
#print "$$nodes[0], $hmcstartnum\n";
if (scalar(@$nodes)) {
#my %nodehash;
#foreach my $n (@$nodes) { print "n=$n\n"; $nodehash{$n} = { node => $n, groups => 'hmc,all' }; }
$tables{'nodelist'}->setNodesAttribs($nodes, { groups => 'hmc,all' });
}
#using hostname-range and starting-ip, write regex for: hosts.node, hosts.ip
my $hmcstartip = $STANZAS{'xcat-hmcs'}->{'starting-ip'};
if ($hmcstartip) {
my ($ipbase, $ipstart) = $hmcstartip =~/^(\d+\.\d+\.\d+)\.(\d+)$/;
# take the number from the nodename, and as it increases, increase the ip addr
my $regex = '|\D+(\d+)|' . "$ipbase.($ipstart+" . '$1' . "-$hmcstartnum)|";
$tables{'hosts'}->setNodeAttribs('hmc', {ip => $regex});
}
#using hostname-range, write regex for: ppc.node, nodetype.nodetype
$tables{'ppc'}->setNodeAttribs('hmc', {comments => 'hmc'});
$tables{'nodetype'}->setNodeAttribs('hmc', {nodetype => 'hmc'});
}
sub writeframe {
# write hostname-range in nodelist table
my ($framerange, $cwd) = @_;
infomsg('Defining frames...');
my $nodes = [noderange($framerange, 0)];
my ($framestartnum) = $$nodes[0] =~/^\D+(\d+)$/; # save this value for later
#print "$$nodes[0], $framestartnum\n";
if (scalar(@$nodes)) {
#my %nodehash;
#foreach my $n (@$nodes) { print "n=$n\n"; $nodehash{$n} = { node => $n, groups => 'hmc,all' }; }
$tables{'nodelist'}->setNodesAttribs($nodes, { groups => 'frame,all' });
}
# Using the frame group, write starting-ip in hosts table
my $framestartip = $STANZAS{'xcat-frames'}->{'starting-ip'};
if ($framestartip) {
my ($ipbase, $ipstart) = $framestartip =~/^(\d+\.\d+\.\d+)\.(\d+)$/;
# take the number from the nodename, and as it increases, increase the ip addr
my $regex = '|\D+(\d+)|' . "$ipbase.($ipstart+" . '$1' . "-$framestartnum)|";
$tables{'hosts'}->setNodeAttribs('frame', {ip => $regex});
}
# Using the frame group, write: nodetype.nodetype, nodehm.mgt
$tables{'nodetype'}->setNodeAttribs('frame', {nodetype => 'bpa'});
$tables{'nodehm'}->setNodeAttribs('frame', {mgt => 'hmc'});
# Using the frame group, num-frames-per-hmc, hmc hostname-range, write regex for: ppc.node, ppc.hcp, ppc.id
# The frame # should come from the nodename
my $idregex = '|\D+(\d+)|(0+$1)|';
# Calculate which hmc manages this frame by dividing by num-frames-per-hmc
my $framesperhmc = $STANZAS{'xcat-frames'}->{'num-frames-per-hmc'};
#todo: this is wrong! Switch frames and cecs over to direct attach
my $hmcregex = '|\D+(\d+)|((($1-1)/' . $framesperhmc . ')+1)|';
$tables{'ppc'}->setNodeAttribs('frame', {id => $idregex, hcp => $hmcregex});
# Write vpd-file to vpd table
my $filename = fullpath($STANZAS{'xcat-frames'}->{'vpd-file'}, $cwd);
readwritevpd($filename);
}
sub readwritevpd {
my $filename = shift;
if (!defined($filename)) { return; }
my $content;
if (!open(STANZAF, $filename)) { errormsg("Can not open file $filename.", 2); return; }
while (my $line = <STANZAF>) { $content .= $line; }
close STANZAF;
#print "content=$content";
my $rc = xCAT::DBobjUtils->readFileInput($content);
if ($rc) { errormsg("Error in processing stanza file $filename, rc=$rc.", 2); return; }
$rc = xCAT::DBobjUtils->setobjdefs(\%::FILEATTRS);
if ($rc) { errormsg("Error setting database attributes from stanza file $filename, rc=$rc.", 2); return; }
}
sub writecec {
# write hostname-range in nodelist table
my ($cecrange, $cwd) = @_;
infomsg('Defining CECs...');
my $nodes = [noderange($cecrange, 0)];
my ($cecstartnum) = $$nodes[0] =~/^\D+(\d+)$/; # save this value for later
if (scalar(@$nodes)) {
#my %nodehash;
#foreach my $n (@$nodes) { print "n=$n\n"; $nodehash{$n} = { node => $n, groups => 'hmc,all' }; }
$tables{'nodelist'}->setNodesAttribs($nodes, { groups => 'cec,all' });
}
# Using the cec group, write starting-ip in hosts table
my $cecstartip = $STANZAS{'xcat-cecs'}->{'starting-ip'};
if ($cecstartip) {
my ($ipbase, $ipstart) = $cecstartip =~/^(\d+\.\d+\.\d+)\.(\d+)$/;
# take the number from the nodename, and as it increases, increase the ip addr
my $regex = '|\D+(\d+)|' . "$ipbase.($ipstart+" . '$1' . "-$cecstartnum)|";
$tables{'hosts'}->setNodeAttribs('cec', {ip => $regex});
}
# Using the cec group, write: nodetype.nodetype, nodehm.mgt
$tables{'nodetype'}->setNodeAttribs('cec', {nodetype => 'fsp'});
$tables{'nodehm'}->setNodeAttribs('cec', {mgt => 'hmc'});
# Do we need to write regex for ppc.hcp and ppc.parent? Of will lsslp do all that?
# Write supernode-list in ppc.supernode
#todo: handle the !sequential option
$nodes = [noderange($cecrange, 0)]; # the setNodesAttribs() function blanks out the nodes array
my %framesupers;
my $filename = fullpath($STANZAS{'xcat-cecs'}->{'supernode-list'}, $cwd);
readsupers($filename, \%framesupers);
my $i=0; # the index into the array of cecs
my %nodehash;
# Collect each nodes supernode num into a hash
foreach my $k (sort keys %framesupers) {
my $f = $framesupers{$k}; # $f is a ptr to an array of super node numbers
if (!$f) { next; } # in case some frame nums did not get filled in by user
foreach my $s (@$f) { # loop thru the supernode nums in this frame
my $supernum = $s;
my $numnodes = 4;
if ($s =~ /\(\d+\)/) { ($supernum, $numnodes) = $s =~ /^(\d+)\((\d+)\)/; }
for (my $j=0; $j<$numnodes; $j++) { # assign the next few nodes to this supernode num
my $nodename = $$nodes[$i++];
#print "Setting $nodename supernode attribute to $supernum,$j\n";
$nodehash{$nodename} = { supernode => "$supernum,$j" };
}
}
}
# Now write all of the supernode values to the ppc table
if (scalar(keys %framesupers)) { $tables{'ppc'}->setNodesAttribs(\%nodehash); }
}
# Read/parse the supernode-list file and return the values in a hash of arrays
sub readsupers {
my $filename = shift;
my $framesup = shift;
if (!defined($filename)) { return; }
my $input;
if (!open($input, $filename)) {
errormsg("Can not open file $filename.", 2);
return;
}
my $l;
my $linenum = 0;
while ($l=<$input>) {
$linenum++;
# skip blank and comment lines
next if ( $l =~ /^\s*$/ || $l =~ /^\s*#/ );
#print "l=$l\n";
# process a real line - name, then colon, then only whitespace, numbers, and parens
my ($frame, $supernums);
if ( ($frame, $supernums) = $l =~ /^\s*(\S+)\s*:\s*([\s,\(\)\d]+)$/ ) {
#print "frame=$frame, supernums=$supernums\n";
$$framesup{$frame} = [split(/[\s,]+/, $supernums)];
}
else {
errormsg("syntax error on line $linenum.", 3);
return;
}
} # end while - go to next line
close($input);
}
sub writebb {
my $framesperbb = shift;
infomsg('Defining building blocks...');
# Set site.sharedtftp=1 since we have bldg blocks
$tables{'site'}->setAttribs({key => 'sharedtftp'}, {value => 1});
# Write num-frames-per-bb in ppc.parent for bpas
my $bbregex = '|\D+(\d+)|((($1-1)/' . $framesperbb . ')+1)|';
$tables{'ppc'}->setNodeAttribs('frame', {parent => $bbregex});
}
# Create service node definitions
sub writesn {
my $range = shift;
infomsg('Defining service nodes...');
my $nodes = [noderange($range, 0)];
my ($startnum) = $$nodes[0] =~/^\D+(\d+)$/; # save this value for later
if (scalar(@$nodes)) {
$tables{'nodelist'}->setNodesAttribs($nodes, { groups => 'service,all' });
}
# Write regex for: hosts.node, hosts.ip
my $startip = $STANZAS{'xcat-lpars'}->{'service-node-starting-ip'};
if ($startip) {
my ($ipbase, $ipstart) = $startip =~/^(\d+\.\d+\.\d+)\.(\d+)$/;
# take the number from the nodename, and as it increases, increase the ip addr
my $regex = '|\D+(\d+)|' . "$ipbase.($ipstart+" . '$1' . "-$startnum)|";
my %hash = (ip => $regex);
my $otherint = $STANZAS{'xcat-lpars'}->{'service-node-otherinterfaces'};
if ($otherint) {
# need to replace each ip addr in otherinterfaces with a regex
my @ifs = split(/[\s,]+/, $otherint);
foreach my $if (@ifs) {
my ($nic, $startip) = split(/:/, $if);
($ipbase, $ipstart) = $startip =~/^(\d+\.\d+\.\d+)\.(\d+)$/;
$if = "$nic:$ipbase.($ipstart+" . '$1' . "-$startnum)";
}
$regex = '|\D+(\d+)|' . join(',', @ifs) . '|';
#print "regex=$regex\n";
$hash{otherinterfaces} = $regex;
}
$tables{'hosts'}->setNodeAttribs('service', \%hash);
}
# Write regex for: ppc.node, nodetype.nodetype
$tables{'ppc'}->setNodeAttribs('service', {id => '1'});
$tables{'nodetype'}->setNodeAttribs('service', {nodetype => 'osi', arch => 'ppc64'});
$tables{'nodehm'}->setNodeAttribs('service', {mgt => 'fsp', cons => 'fsp'});
$tables{'noderes'}->setNodeAttribs('service', {netboot => 'yaboot'});
my $sntab = xCAT::Table->new('servicenode', -create=>1);
if (!$sntab) { errormsg("Can not open servicenode table in database.", 3); }
else {
$sntab->setNodeAttribs('service', {nameserver=>1, dhcpserver=>1, tftpserver=>1, nfsserver=>1, conserver=>1, monserver=>1, ftpserver=>1, nimserver=>1, ipforward=>1});
}
#todo: Write ppc.hcp and ppc.parent
#my $cecsperbb = $STANZAS{'xcat-building-blocks'}->{'num-cecs-per-bb'};
#my $regex = '|\D+(\d+)|((($1-1)/' . $cecsperbb . ')+1)|';
#$tables{'ppc'}->setNodeAttribs('service', {parent => $regex});
}
# Create storage node definitions
sub writestorage {
my $range = shift;
infomsg('Defining storage nodes...');
my $nodes = [noderange($range, 0)];
my ($startnum) = $$nodes[0] =~/^\D+(\d+)$/; # save this value for later
if (scalar(@$nodes)) {
$tables{'nodelist'}->setNodesAttribs($nodes, { groups => 'storage,all' });
}
# Write regex for: hosts.node, hosts.ip
my $startip = $STANZAS{'xcat-lpars'}->{'storage-node-starting-ip'};
if ($startip) {
my ($ipbase, $ipstart) = $startip =~/^(\d+\.\d+\.\d+)\.(\d+)$/;
# take the number from the nodename, and as it increases, increase the ip addr
my $regex = '|\D+(\d+)|' . "$ipbase.($ipstart+" . '$1' . "-$startnum)|";
my %hash = (ip => $regex);
my $otherint = $STANZAS{'xcat-lpars'}->{'storage-node-otherinterfaces'};
if ($otherint) {
# need to replace each ip addr in otherinterfaces with a regex
my @ifs = split(/[\s,]+/, $otherint);
foreach my $if (@ifs) {
my ($nic, $startip) = split(/:/, $if);
($ipbase, $ipstart) = $startip =~/^(\d+\.\d+\.\d+)\.(\d+)$/;
$if = "$nic:$ipbase.($ipstart+" . '$1' . "-$startnum)";
}
$regex = '|\D+(\d+)|' . join(',', @ifs) . '|';
#print "regex=$regex\n";
$hash{otherinterfaces} = $regex;
}
my $aliases = $STANZAS{'xcat-lpars'}->{'storage-node-aliases'};
if ($aliases) {
#todo: support more than 1 alias
$regex = '|(.+)|($1)' . "$aliases|";
$hash{hostnames} = $regex;
}
$tables{'hosts'}->setNodeAttribs('storage', \%hash);
}
# Write regex for: ppc.node, nodetype.nodetype
$tables{'ppc'}->setNodeAttribs('storage', {id => '1'});
$tables{'nodetype'}->setNodeAttribs('storage', {nodetype => 'osi', arch => 'ppc64'});
$tables{'nodehm'}->setNodeAttribs('storage', {mgt => 'fsp', cons => 'fsp'});
$tables{'noderes'}->setNodeAttribs('storage', {netboot => 'yaboot'});
#todo: Write regex for xcatmaster and servicenode to point it to its SN
#todo: Write ppc.hcp and ppc.parent
#my $cecsperbb = $STANZAS{'xcat-building-blocks'}->{'num-cecs-per-bb'};
#my $regex = '|\D+(\d+)|((($1-1)/' . $cecsperbb . ')+1)|';
#$tables{'ppc'}->setNodeAttribs('service', {parent => $regex});
}
# Create storage node definitions
sub writecompute {
my $range = shift;
infomsg('Defining compute nodes...');
my $nodes = [noderange($range, 0)];
my ($startnum) = $$nodes[0] =~/^\D+(\d+)$/; # save this value for later
if (scalar(@$nodes)) {
$tables{'nodelist'}->setNodesAttribs($nodes, { groups => 'compute,all' });
}
# Write regex for: hosts.node, hosts.ip
my $startip = $STANZAS{'xcat-lpars'}->{'compute-node-starting-ip'};
if ($startip) {
my ($ipbase, $ipstart) = $startip =~/^(\d+\.\d+\.\d+)\.(\d+)$/;
# take the number from the nodename, and as it increases, increase the ip addr
my $regex = '|\D+(\d+)|' . "$ipbase.($ipstart+" . '$1' . "-$startnum)|";
my %hash = (ip => $regex);
my $otherint = $STANZAS{'xcat-lpars'}->{'compute-node-otherinterfaces'};
if ($otherint) {
# need to replace each ip addr in otherinterfaces with a regex
my @ifs = split(/[\s,]+/, $otherint);
foreach my $if (@ifs) {
my ($nic, $startip) = split(/:/, $if);
($ipbase, $ipstart) = $startip =~/^(\d+\.\d+\.\d+)\.(\d+)$/;
$if = "$nic:$ipbase.($ipstart+" . '$1' . "-$startnum)";
}
$regex = '|\D+(\d+)|' . join(',', @ifs) . '|';
#print "regex=$regex\n";
$hash{otherinterfaces} = $regex;
}
my $aliases = $STANZAS{'xcat-lpars'}->{'compute-node-aliases'};
if ($aliases) {
#todo: support more than 1 alias
$regex = '|(.+)|($1)' . "$aliases|";
$hash{hostnames} = $regex;
}
$tables{'hosts'}->setNodeAttribs('compute', \%hash);
}
# Write regex for: nodetype.nodetype, etc.
$tables{'nodetype'}->setNodeAttribs('compute', {nodetype => 'osi', arch => 'ppc64'});
$tables{'nodehm'}->setNodeAttribs('compute', {mgt => 'fsp', cons => 'fsp'});
$tables{'noderes'}->setNodeAttribs('compute', {netboot => 'yaboot'});
#todo: Write the lpar id
#$tables{'ppc'}->setNodeAttribs('compute', {id => '1'});
#todo: Write regex for xcatmaster and servicenode to point it to its SN
#todo: Write ppc.hcp and ppc.parent
#my $cecsperbb = $STANZAS{'xcat-building-blocks'}->{'num-cecs-per-bb'};
#my $regex = '|\D+(\d+)|((($1-1)/' . $cecsperbb . ')+1)|';
#$tables{'ppc'}->setNodeAttribs('service', {parent => $regex});
}
sub errormsg {
my $msg = shift;
my $exitcode = shift;
my %rsp;
push @{$rsp{error}}, $msg;
xCAT::MsgUtils->message('E', \%rsp, $CALLBACK, $exitcode);
return;
}
sub infomsg {
my $msg = shift;
my %rsp;
push @{$rsp{info}}, $msg;
xCAT::MsgUtils->message('I', \%rsp, $CALLBACK);
return;
}
sub fullpath {
my ($filename, $cwd) = @_;
if ($filename =~ /^\s*\//) { return $filename; } # it was already a full path
return xCAT::Utils->full_path($filename, $cwd);
}
1;