From 42961504e0da22932cc90b7b6a4cf05fd008926b Mon Sep 17 00:00:00 2001 From: nott Date: Tue, 11 Aug 2009 17:18:27 +0000 Subject: [PATCH] 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 --- mkAIXsnap | 4 +- xCAT-client/pods/man8/makenetworks.8.pod | 73 ++++- xCAT-server/lib/xcat/plugins/networks.pm | 383 +++++++++++++++++------ 3 files changed, 356 insertions(+), 104 deletions(-) diff --git a/mkAIXsnap b/mkAIXsnap index 4910138a8..2486ba2ef 100755 --- a/mkAIXsnap +++ b/mkAIXsnap @@ -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 diff --git a/xCAT-client/pods/man8/makenetworks.8.pod b/xCAT-client/pods/man8/makenetworks.8.pod index 36db53c4f..4d9009512 100644 --- a/xCAT-client/pods/man8/makenetworks.8.pod +++ b/xCAT-client/pods/man8/makenetworks.8.pod @@ -1,24 +1,55 @@ =head1 NAME -B - populates the xCAT networks table, using network information from the local system +B - Gather cluster network information and add it to the xCAT database. =head1 SYNOPSIS -B +I +I + +I =head1 DESCRIPTION -The B 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 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 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 -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 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 command. + + tabedit networks + + +Note: The B 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 or B 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 - diff --git a/xCAT-server/lib/xcat/plugins/networks.pm b/xCAT-server/lib/xcat/plugins/networks.pm index c1f32ebf5..6ac469c59 100644 --- a/xCAT-server/lib/xcat/plugins/networks.pm +++ b/xCAT-server/lib/xcat/plugins/networks.pm @@ -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;