Enhance makenetworks to support AIX and display option.

git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@3985 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
This commit is contained in:
nott 2009-08-11 17:18:27 +00:00
parent 3db6884c4e
commit 42961504e0
3 changed files with 356 additions and 104 deletions

View File

@ -18,8 +18,8 @@
# /home/groups/x/xc/xcat/htdocs/aix/devel/core-snap
# - nothing is added to the release download area
#
# scp *.rpm nott,xcat@web.sourceforge.net:/home/groups/x/xc/xcat/htdocs/aix/devel/core-snap
#scp core-aix-snap.tar.gz nott,xcat@web.sourceforge.net:/home/groups/x/xc/xcat/htdocs/aix/devel
# scp *.rpm nott,xcat@web.sourceforge.net:/home/groups/x/xc/xcat/htdocs/aix/devel/xcat-core
#scp core-aix-2.3.tar.gz nott,xcat@web.sourceforge.net:/home/groups/x/xc/xcat/htdocs/aix/devel
#scp *.rpm nott,xcat@web.sourceforge.net:/home/groups/x/xc/xcat/htdocs/aix/2.2/core-snap
#scp core-aix-snap.tar.gz nott,xcat@web.sourceforge.net:/home/groups/x/xc/xcat/htdocs/aix/2.2

View File

@ -1,24 +1,55 @@
=head1 NAME
B<makenetworks> - populates the xCAT networks table, using network information from the local system
B<makenetworks> - Gather cluster network information and add it to the xCAT database.
=head1 SYNOPSIS
B<makenetworks>
I<makenetworks [-h|--help ]>
I<makenetworks [-v| --version]>
I<makenetworks [-V|--verbose] [-d|--display]>
=head1 DESCRIPTION
The B<makenetworks> command is run by xCAT automatically, when xCAT is installed on the management node.
It queries the network configuration of the management node and uses that information to populate the
networks table in the xCAT database. After that, you may want to update the networks table manually to,
for example, disable the public network entry and add networks that service nodes are on that the management
node can't see directly.
The B<makenetworks> command can be used to gather network information from an xCAT cluster environment and create corresponding network definitions in the xCAT database.
You normally do not need to run the B<makenetworks> command yourself. But if you want to reset the networks
table to its original state, remove all the entries from it (using tabedit), and then run B<makenetworks>
again.
Every network that will be used to install a cluster node must be defined in the xCAT database.
The default behavior is to gather network information from the managment node, and any configured xCAT service nodes, and automatically save this information in the xCAT database.
You can use the "-d" option to display the network information without writing it to the database.
You can also redirect the output to a file that can be used with the xCAT B<mkdef> command to define the networks.
For example:
makenetworks -d > mynetstanzas
cat mynetstanzas | mkdef -z
This features allows you to verify and modify the network information before writing it to the database.
When the network information is gathered a default value is created for the "netname" attribute. This is done to make it possible to use the mkdef, chdef, lsdef, and rmdef commands to manage this data.
The default naming convention is to use a hyphen separated "net" and "mask" value with the "." replace by "_". (ex. "8_124_47_64-255_255_255_0")
You can also modify the xCAT "networks" database table directly using the xCAT B<tabedit> command.
tabedit networks
Note: The B<makenetworks> command is run automatically when xCAT is installed on a Linux management node.
=head1 OPTIONS
B<-d|--display> Display the network definitions but do not write to the definitions to the xCAT database. The output will be in stanza file format and can be redirected to a stanza file that can be used with B<mkdef> or B<chdef> commands to create or modify the network definitions.
B<-h | --help> Display usage message.
B<-v | --version> Command Version.
B<-V |--verbose> Verbose mode.
=head1 RETURN VALUE
@ -26,8 +57,28 @@ again.
1 An error has occurred.
=head1 EXAMPLES
1. Gather cluster network information and create xCAT network definitions.
makenetworks
2. Display cluster network information but do not write the network definitions to the xCAT database.
makenetworks -d
The output would be one or more stanzas of information similar to the following. The line that ends with a colon is the value of the "netname" attribute and is the name of the network object to use with the lsdef, mkdef, chdef and rmdef commands.
9_114_37_0-255_255_255_0:
objtype=network
gateway=9.114.37.254
mask=255.255.255.0
net=9.114.37.0
=head1 FILES
/opt/xcat/sbin/makenetworks
=head1 SEE ALSO
L<makedhcp(8)|makedhcp.8>

View File

@ -5,6 +5,7 @@ use Data::Dumper;
use Sys::Syslog;
use Socket;
use xCAT::Utils;
use Getopt::Long;
sub handled_commands
{
@ -14,16 +15,52 @@ sub handled_commands
sub preprocess_request
{
my $req = shift;
my $cb = shift;
if ($req->{_xcatpreprocessed}->[0] == 1) { return [$req]; }
my $callback = shift;
if ($req->{_xcatpreprocessed}->[0] == 1) { return [$req]; }
# exit if preprocessed
my @requests = ({%$req}); #first element is local instance
$::args = $req->{arg};
if (defined(@{$::args})) {
@ARGV = @{$::args};
}
Getopt::Long::Configure("no_pass_through");
if (
!GetOptions(
'help|h|?' => \$::HELP,
'display|d' => \$::DISPLAY,
'mnonly|m' => \$::MNONLY,
'verbose|V' => \$::VERBOSE,
'version|v' => \$::VERSION,
)
)
{
# return 1;
}
# Option -h for Help
if ($::HELP )
{
&makenetworks_usage($callback);
return undef;
}
# Option -v for version - do we need this???
if ($::VERSION)
{
my $rsp;
my $version=xCAT::Utils->Version();
$rsp->{data}->[0] = "makenetworks - $version";
xCAT::MsgUtils->message("I", $rsp, $callback);
return undef;
}
my @sn = xCAT::Utils->getSNList();
foreach my $s (@sn)
{
my $reqcopy = {%$req};
$reqcopy->{'_xcatdest'} = $s;
$reqcopy->{_xcatpreprocessed}->[0] = 1;
push @requests, $reqcopy;
}
return \@requests;
@ -31,98 +68,262 @@ sub preprocess_request
sub process_request
{
my $nettab = xCAT::Table->new('networks', -create => 1, -autocommit => 0);
my @rtable = split /\n/, `/bin/netstat -rn`;
open($rconf, "/etc/resolv.conf");
my @nameservers;
if ($rconf)
my $request = shift;
my $callback = shift;
my $host = `hostname`;
chomp $host;
$::args = $request->{arg};
if (defined(@{$::args})) {
@ARGV = @{$::args};
}
Getopt::Long::Configure("no_pass_through");
if (
!GetOptions(
'help|h|?' => \$::HELP,
'display|d' => \$::DISPLAY,
'mnonly|m' => \$::MNONLY,
'verbose|V' => \$::VERBOSE,
'version|v' => \$::VERSION,
)
)
{
my @rcont;
while (<$rconf>)
{
push @rcont, $_;
}
close($rconf);
foreach (grep /nameserver/, @rcont)
{
my $line = $_;
my @pair;
$line =~ s/#.*//;
@pair = split(/\s+/, $line);
push @nameservers, $pair[1];
}
# return 1;
}
splice @rtable, 0, 2;
foreach (@rtable)
{ #should be the lines to think about, do something with U, and something else with UG
my $net;
my $mask;
my $mgtifname;
my $gw;
my @ent = split /\s+/, $_;
my $firstoctet = $ent[0];
$firstoctet =~ s/^(\d+)\..*/$1/;
if ($ent[0] eq "169.254.0.0" or ($firstoctet >= 224 and $firstoctet <= 239) or $ent[0] eq "127.0.0.0")
{
next;
}
if ($ent[3] eq 'U')
{
$net = $ent[0];
$mask = $ent[2];
$mgtifname = $ent[7];
$nettab->setAttribs({'net' => $net},
{'mask' => $mask, 'mgtifname' => $mgtifname});
my $tent = $nettab->getAttribs({'net' => $net}, 'nameservers');
unless ($tent and $tent->{nameservers})
{
my $text = join ',', @nameservers;
$nettab->setAttribs({'net' => $net}, {nameservers => $text});
}
unless ($tent and $tent->{tftpserver})
{
my $netdev = $ent[7];
my @netlines = split /\n/, `/sbin/ip addr show dev $netdev`;
foreach (grep /\s*inet\b/, @netlines)
{
my @row = split(/\s+/, $_);
my $ipaddr = $row[2];
$ipaddr =~ s/\/.*//;
my @maska = split(/\./, $mask);
my @ipa = split(/\./, $ipaddr);
my @neta = split(/\./, $net);
my $isme = 1;
foreach (0 .. 3)
{
my $oct = (0 + $maska[$_]) & ($ipa[$_] + 0);
unless ($oct == $neta[$_])
{
$isme = 0;
last;
}
}
if ($isme)
{
$nettab->setAttribs({'net' => $net},
{tftpserver => $ipaddr});
last;
}
}
}
$nettab->commit;
#Nothing much sane to do for the other fields at the moment?
}
elsif ($ent[3] eq 'UG')
{
my $nettab = xCAT::Table->new('networks', -create => 1, -autocommit => 0);
#TODO: networks through gateway. and how we might care..
}
else
{
if (xCAT::Utils->isAIX()) {
#TODO: anything to do with such entries?
}
}
# get list of interfaces "ifconfig -l"
my $ifgcmd = "ifconfig -l";
my @interfaces = split(/\s+/, xCAT::Utils->runcmd($ifgcmd, 0));
if ($::RUNCMD_RC != 0) {
my $rsp;
push @{$rsp->{data}}, "Could not run \'$ifgcmd\'.\n";
xCAT::MsgUtils->message("E", $rsp, $callback);
return 1;
}
# do each ethernet interface
foreach my $i (@interfaces) {
if ($i =~ /^en/) {
# "mktcpip -S en0" to get nm & gw
my $mkcmd = "mktcpip -S $i";
my @netinfo = xCAT::Utils->runcmd($mkcmd, 0);
if ($::RUNCMD_RC != 0) {
my $rsp;
push @{$rsp->{data}}, "Could not run \'$mkcmd\'.\n";
xCAT::MsgUtils->message("E", $rsp, $callback);
return 1;
}
my $netmask;
my $ipaddr;
my @fields;
my $gateway;
foreach my $line (@netinfo) {
next if ($line =~ /^\s*#/);
@fields = split(/:/, $line);
}
$ipaddr = $fields[1];
$netmask = $fields[2];
$gateway = $fields[6];
# split interface IP
my ($ip1, $ip2, $ip3, $ip4) = split('\.', $ipaddr);
# split mask
my ($m1, $m2, $m3, $m4) = split('\.', $netmask);
# AND nm and ip to get net attribute
my $n1 = ((int $ip1) & (int $m1));
my $n2 = ((int $ip2) & (int $m2));
my $n3 = ((int $ip3) & (int $m3));
my $n4 = ((int $ip4) & (int $m4));
my $net = "$n1.$n2.$n3.$n4";
# use convention for netname attr
my $netn;
my $maskn;
($netn = $net) =~ s/\./\_/g;
($maskn = $netmask) =~ s/\./\_/g;
# ( 1_2_3_4-255_255_255_192 - ugh!)
my $netname = $netn . "-" . $maskn;
if ($::DISPLAY) {
my $rsp;
push @{$rsp->{data}}, "\n#From $host.";
push @{$rsp->{data}}, "$netname:";
push @{$rsp->{data}}, " objtype=network";
push @{$rsp->{data}}, " net=$net";
push @{$rsp->{data}}, " mask=$netmask";
push @{$rsp->{data}}, " gateway=$gateway\n";
xCAT::MsgUtils->message("I", $rsp, $callback);
} else {
# add new network def
$nettab->setAttribs({'net' => $net}, {'mask' => $mask}, {'netname' => $netname}, {'gateway' => $gateway});
}
}
}
} else {
# For Linux systems
my @rtable = split /\n/, `/bin/netstat -rn`;
open($rconf, "/etc/resolv.conf");
my @nameservers;
if ($rconf)
{
my @rcont;
while (<$rconf>)
{
push @rcont, $_;
}
close($rconf);
foreach (grep /nameserver/, @rcont)
{
my $line = $_;
my @pair;
$line =~ s/#.*//;
@pair = split(/\s+/, $line);
push @nameservers, $pair[1];
}
}
splice @rtable, 0, 2;
foreach (@rtable)
{ #should be the lines to think about, do something with U, and something else with UG
my $rsp;
my $net;
my $mask;
my $mgtifname;
my $gw;
my @ent = split /\s+/, $_;
my $firstoctet = $ent[0];
$firstoctet =~ s/^(\d+)\..*/$1/;
if ($ent[0] eq "169.254.0.0" or ($firstoctet >= 224 and $firstoctet <= 239) or $ent[0] eq "127.0.0.0")
{
next;
}
if ($ent[3] eq 'U')
{
$net = $ent[0];
$mask = $ent[2];
$mgtifname = $ent[7];
# use convention for netname attr
my $netn;
my $maskn;
($netn = $net) =~ s/\./\_/g;
($maskn = $mask) =~ s/\./\_/g;
# ( 1_2_3_4-255_255_255_192 - ugh!)
my $netname = $netn . "-" . $maskn;
if ($::DISPLAY) {
push @{$rsp->{data}}, "\n#From $host.";
push @{$rsp->{data}}, "$netname:";
push @{$rsp->{data}}, " objtype=network";
push @{$rsp->{data}}, " net=$net";
push @{$rsp->{data}}, " mask=$mask";
push @{$rsp->{data}}, " mgtifname=$mgtifname";
} else {
$nettab->setAttribs({'net' => $net}, {'mask' => $mask, 'mgtifname' => $mgtifname}, {'netname' => $netname});
}
my $tent = $nettab->getAttribs({'net' => $net}, 'nameservers');
unless ($tent and $tent->{nameservers})
{
my $text = join ',', @nameservers;
if ($::DISPLAY) {
push @{$rsp->{data}}, " nameservers=$text";
} else {
$nettab->setAttribs({'net' => $net}, {nameservers => $text});
}
}
unless ($tent and $tent->{tftpserver})
{
my $netdev = $ent[7];
my @netlines = split /\n/, `/sbin/ip addr show dev $netdev`;
foreach (grep /\s*inet\b/, @netlines)
{
my @row = split(/\s+/, $_);
my $ipaddr = $row[2];
$ipaddr =~ s/\/.*//;
my @maska = split(/\./, $mask);
my @ipa = split(/\./, $ipaddr);
my @neta = split(/\./, $net);
my $isme = 1;
foreach (0 .. 3)
{
my $oct = (0 + $maska[$_]) & ($ipa[$_] + 0);
unless ($oct == $neta[$_])
{
$isme = 0;
last;
}
}
if ($isme)
{
if ($::DISPLAY) {
push @{$rsp->{data}}, " tftpserver=$ipaddr";
} else {
$nettab->setAttribs({'net' => $net}, {tftpserver => $ipaddr});
}
last;
}
}
}
#Nothing much sane to do for the other fields at the moment?
}
elsif ($ent[3] eq 'UG')
{
#TODO: networks through gateway. and how we might care..
}
else
{
#TODO: anything to do with such entries?
}
if ($::DISPLAY) {
xCAT::MsgUtils->message("I", $rsp, $callback);
}
}
}
$nettab->commit;
}
#----------------------------------------------------------------------------
=head3 makenetworks_usage
=cut
#-----------------------------------------------------------------------------
sub makenetworks_usage
{
my $callback = shift;
my $rsp;
push @{$rsp->{data}}, "\nUsage: makenetworks - Gather cluster network information and add it to the xCAT database.\n";
push @{$rsp->{data}}, " makenetworks [-h|--help ]\n";
push @{$rsp->{data}}, " makenetworks [-v|--version]\n";
push @{$rsp->{data}}, " makenetworks [-V|--verbose] [-d|--display]\n";
xCAT::MsgUtils->message("I", $rsp, $callback);
return 0;
}
1;