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:
parent
fe927896fc
commit
bd4d516212
201
xCAT-client/pods/man8/xcatsetup.8.pod
Normal file
201
xCAT-client/pods/man8/xcatsetup.8.pod
Normal 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>
|
||||
|
@ -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
|
||||
|
600
xCAT-server/lib/xcat/plugins/setup.pm
Normal file
600
xCAT-server/lib/xcat/plugins/setup.pm
Normal 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;
|
Loading…
Reference in New Issue
Block a user