From 06d2048be2c330a2380e8118d1766a61ae73d991 Mon Sep 17 00:00:00 2001 From: nott <nott@8638fb3e-16cb-4fca-ae20-7b5d299a9bcd> Date: Mon, 3 Dec 2012 20:23:33 +0000 Subject: [PATCH] add domain and nics table support git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@14529 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- xCAT-server/lib/xcat/plugins/hosts.pm | 690 +++++++++++++++++--------- 1 file changed, 466 insertions(+), 224 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/hosts.pm b/xCAT-server/lib/xcat/plugins/hosts.pm index 58594e9ab..3042585ed 100644 --- a/xCAT-server/lib/xcat/plugins/hosts.pm +++ b/xCAT-server/lib/xcat/plugins/hosts.pm @@ -10,264 +10,506 @@ use File::Copy; use Getopt::Long; use Fcntl ':flock'; - -my @hosts; #Hold /etc/hosts data to be written back +my @hosts; #Hold /etc/hosts data to be written back my $LONGNAME; my $OTHERNAMESFIRST; my $ADDNAMES; my $MACTOLINKLOCAL; +my %usage = + (makehosts => + "Usage: makehosts <noderange> [-d] [-n] [-l] [-a] [-o] [-m]\n makehosts -h", + ); -my %usage=( - makehosts => "Usage: makehosts <noderange> [-d] [-n] [-l] [-a] [-o] [-m]\n makehosts -h", -); -sub handled_commands { - return { - makehosts => "hosts", - } +sub handled_commands +{ + return {makehosts => "hosts",}; } - -sub delnode { - my $node = shift; - my $ip = shift; - unless ($node and $ip) { return; } #bail if requested to do something that could zap /etc/hosts badly - my $othernames = shift; - my $domain = shift; - my $idx=0; - - while ($idx <= $#hosts) { - if (($ip and $hosts[$idx] =~ /^${ip}\s/) or $hosts[$idx] =~ /^\d+\.\d+\.\d+\.\d+\s+${node}[\s\.r]/) { - $hosts[$idx]=""; +sub delnode +{ + my $node = shift; + my $ip = shift; + + unless ($node and $ip) + { + return; + } #bail if requested to do something that could zap /etc/hosts badly + + my $othernames = shift; + my $domain = shift; + my $idx = 0; + + while ($idx <= $#hosts) + { + if (($ip and $hosts[$idx] =~ /^${ip}\s/) + or $hosts[$idx] =~ /^\d+\.\d+\.\d+\.\d+\s+${node}[\s\.r]/) + { + $hosts[$idx] = ""; + } + $idx++; } - $idx++; - } } -sub addnode { - my $node = shift; - my $ip = shift; - unless ($node and $ip) { return; } #bail if requested to do something that could zap /etc/hosts badly - my $othernames = shift; - my $domain = shift; - my $idx=0; - my $foundone=0; - - while ($idx <= $#hosts) { - if ($hosts[$idx] =~ /^${ip}\s/ or $hosts[$idx] =~ /^\d+\.\d+\.\d+\.\d+\s+${node}[\s\.r]/) { - if ($foundone) { - $hosts[$idx]=""; - } else { - $hosts[$idx]=build_line($ip, $node, $domain, $othernames); - } - $foundone=1; +sub addnode +{ + my $node = shift; + my $ip = shift; + + unless ($node and $ip) + { + return; + } #bail if requested to do something that could zap /etc/hosts badly + + my $othernames = shift; + my $domain = shift; + my $idx = 0; + my $foundone = 0; + + while ($idx <= $#hosts) + { + if ( $hosts[$idx] =~ /^${ip}\s/ + or $hosts[$idx] =~ /^\d+\.\d+\.\d+\.\d+\s+${node}[\s\.r]/) + { + if ($foundone) + { + $hosts[$idx] = ""; + } + else + { + $hosts[$idx] = build_line($ip, $node, $domain, $othernames); + } + $foundone = 1; + } + $idx++; } - $idx++; - } - if ($foundone) { return;} + if ($foundone) { return; } - my $line=build_line($ip, $node, $domain, $othernames); - push @hosts, $line; + my $line = build_line($ip, $node, $domain, $othernames); + push @hosts, $line; } -sub build_line { - my $ip=shift; - my $node=shift; - my $domain=shift; - my $othernames=shift; - my @o_names=(); - my @n_names=(); - if (defined $othernames) { - @o_names=split(/,| /, $othernames); +sub build_line +{ + my $ip = shift; + my $node = shift; + my $domain = shift; + my $othernames = shift; + my @o_names = (); + my @n_names = (); + if (defined $othernames) + { + @o_names = split(/,| /, $othernames); } my $longname; - foreach (@o_names) { - if (($_ eq $node) || ( $domain && ($_ eq "$node.$domain"))) { - $longname="$node.$domain"; - $_=""; - } elsif ( $_ =~ /\./) { - if (!$longname) { - $longname=$_; - $_=""; - } - } elsif ($ADDNAMES) { - unshift(@n_names,"$_.$domain"); - } + foreach (@o_names) + { + if (($_ eq $node) || ($domain && ($_ eq "$node.$domain"))) + { + $longname = "$node.$domain"; + $_ = ""; + } + elsif ($_ =~ /\./) + { + if (!$longname) + { + $longname = $_; + $_ = ""; + } + } + elsif ($ADDNAMES) + { + unshift(@n_names, "$_.$domain"); + } } - unshift(@o_names,@n_names); + unshift(@o_names, @n_names); - if ($node =~ m/\.$domain$/i) { + if ($node =~ m/\.$domain$/i) + { $longname = $node; $node =~ s/\.$domain$//; - } elsif ($domain && !$longname) { - $longname="$node.$domain"; - } + } + elsif ($domain && !$longname) + { + $longname = "$node.$domain"; + } - $othernames=join(' ', @o_names); - if ($LONGNAME) { return "$ip $longname $node $othernames\n"; } + $othernames = join(' ', @o_names); + if ($LONGNAME) { return "$ip $longname $node $othernames\n"; } elsif ($OTHERNAMESFIRST) { return "$ip $othernames $longname $node\n"; } else { return "$ip $node $longname $othernames\n"; } } +sub addotherinterfaces +{ + my $node = shift; + my $otherinterfaces = shift; + my $domain = shift; -sub addotherinterfaces { - my $node = shift; - my $otherinterfaces = shift; - my $domain = shift; - - my @itf_pairs=split(/,/, $otherinterfaces); - foreach (@itf_pairs) { - my ($itf,$ip)=split(/:/, $_); - if ( $ip && xCAT::NetworkUtils->isIpaddr($ip) ) { - if ($itf =~ /^-/ ) { - $itf = $node.$itf }; - addnode $itf,$ip,'',$domain; - } - } -} - - -sub process_request { - Getopt::Long::Configure("bundling") ; - $Getopt::Long::ignorecase=0; - Getopt::Long::Configure("no_pass_through"); - - my $req = shift; - my $callback = shift; - my $HELP; - my $REMOVE; - my $DELNODE; - - # parse the options - if ($req && $req->{arg}) {@ARGV = @{$req->{arg}};} - else { @ARGV = (); } - -# print "argv=@ARGV\n"; - if(!GetOptions( - 'h|help' => \$HELP, - 'n' => \$REMOVE, - 'd' => \$DELNODE, - 'o|othernamesfirst' => \$OTHERNAMESFIRST, - 'a|adddomaintohostnames' => \$ADDNAMES, - 'm|mactolinklocal' => \$MACTOLINKLOCAL, - 'l|longnamefirst' => \$LONGNAME,)) - { - $callback->({data=>$usage{makehosts}}); - return; - } - - # display the usage if -h - if ($HELP) { - $callback->({data=>$usage{makehosts}}); - return; - } - - - my $hoststab = xCAT::Table->new('hosts'); - #my $sitetab = xCAT::Table->new('site'); - my $domain; - my $lockh; - #if ($sitetab) { - #my $dent = $sitetab->getAttribs({key=>'domain'},'value'); - my @entries = xCAT::TableUtils->get_site_attribute("domain"); - my $t_entry = $entries[0]; - if ( defined($t_entry) ) { - $domain=$t_entry; - } - #} - - @hosts = (); - if ($REMOVE) { - if (-e "/etc/hosts") { - my $bakname = "/etc/hosts.xcatbak"; - rename("/etc/hosts",$bakname); - - # add the localhost entry if trying to create the /etc/hosts from scratch - if ($^O =~ /^aix/i) { - push @hosts, "127.0.0.1 loopback localhost\n"; - } else { - push @hosts, "127.0.0.1 localhost\n"; - } - } - } else { - if (-e "/etc/hosts") { - my $bakname = "/etc/hosts.xcatbak"; - copy("/etc/hosts",$bakname); - } - open($lockh,">","/tmp/xcat/hostsfile.lock"); - flock($lockh,LOCK_EX); - my $rconf; - open($rconf,"/etc/hosts"); # Read file into memory - if ($rconf) { - while (<$rconf>) { - push @hosts,$_; - } - close($rconf); - } - } - - if ($req->{node}) { - if ($MACTOLINKLOCAL) { - my $mactab = xCAT::Table->new("mac"); - my $machash = $mactab->getNodesAttribs($req->{node},['mac']); - foreach my $node (keys %{$machash}) + my @itf_pairs = split(/,/, $otherinterfaces); + foreach (@itf_pairs) + { + my ($itf, $ip) = split(/:/, $_); + if ($ip && xCAT::NetworkUtils->isIpaddr($ip)) { - my $mac = $machash->{$node}->[0]->{mac}; - if (!$mac) { - next; + if ($itf =~ /^-/) + { + $itf = $node . $itf; } - my $linklocal = xCAT::NetworkUtils->linklocaladdr($mac); - if ($DELNODE) { - delnode $node,$linklocal,$node,$domain; - } else { - addnode $node,$linklocal,$node,$domain; - } - } - } else { - my $hostscache = $hoststab->getNodesAttribs($req->{node},[qw(ip node hostnames otherinterfaces)]); - foreach(@{$req->{node}}) { - my $ref = $hostscache->{$_}->[0]; #$hoststab->getNodeAttribs($_,[qw(ip node hostnames otherinterfaces)]); - if ($DELNODE) { - delnode $ref->{node},$ref->{ip},$ref->{hostnames},$domain; - } else { - if ( xCAT::NetworkUtils->isIpaddr($ref->{ip}) ) { - addnode $ref->{node},$ref->{ip},$ref->{hostnames},$domain; - } - if (defined($ref->{otherinterfaces})){ - addotherinterfaces $ref->{node},$ref->{otherinterfaces},$domain; - } - } - } #end foreach - } # end else - } else { - if ($DELNODE) { - return; - } - my @hostents = $hoststab->getAllNodeAttribs(['ip','node','hostnames','otherinterfaces']); - foreach (@hostents) { - if ( xCAT::NetworkUtils->isIpaddr($_->{ip}) ) { - addnode $_->{node},$_->{ip},$_->{hostnames},$domain; - } - if (defined($_->{otherinterfaces})){ - addotherinterfaces $_->{node},$_->{otherinterfaces},$domain; + addnode $itf, $ip, '', $domain; } } - } - writeout(); - - if ($lockh) { - flock($lockh,LOCK_UN); - } } +sub process_request +{ + Getopt::Long::Configure("bundling"); + $Getopt::Long::ignorecase = 0; + Getopt::Long::Configure("no_pass_through"); -sub writeout { - my $targ; - open($targ,'>',"/etc/hosts"); - foreach (@hosts) { - print $targ $_; - } - close($targ) + my $req = shift; + my $callback = shift; + my $HELP; + my $REMOVE; + + # parse the options + if ($req && $req->{arg}) { @ARGV = @{$req->{arg}}; } + else { @ARGV = (); } + + # print "argv=@ARGV\n"; + if ( + !GetOptions( + 'h|help' => \$HELP, + 'n' => \$REMOVE, + 'd' => \$::DELNODE, + 'o|othernamesfirst' => \$OTHERNAMESFIRST, + 'a|adddomaintohostnames' => \$ADDNAMES, + 'm|mactolinklocal' => \$MACTOLINKLOCAL, + 'l|longnamefirst' => \$LONGNAME, + ) + ) + { + $callback->({data => $usage{makehosts}}); + return; + } + + # display the usage if -h + if ($HELP) + { + $callback->({data => $usage{makehosts}}); + return; + } + + my $hoststab = xCAT::Table->new('hosts'); + my $domain; + my $lockh; + + @hosts = (); + if ($REMOVE) + { + if (-e "/etc/hosts") + { + my $bakname = "/etc/hosts.xcatbak"; + rename("/etc/hosts", $bakname); + + # add the localhost entry if trying to create the /etc/hosts from scratch + if ($^O =~ /^aix/i) + { + push @hosts, "127.0.0.1 loopback localhost\n"; + } + else + { + push @hosts, "127.0.0.1 localhost\n"; + } + } + } + else + { + if (-e "/etc/hosts") + { + my $bakname = "/etc/hosts.xcatbak"; + copy("/etc/hosts", $bakname); + } + open($lockh, ">", "/tmp/xcat/hostsfile.lock"); + flock($lockh, LOCK_EX); + my $rconf; + open($rconf, "/etc/hosts"); # Read file into memory + if ($rconf) + { + while (<$rconf>) + { + push @hosts, $_; + } + close($rconf); + } + } + + if ($req->{node}) + { + if ($MACTOLINKLOCAL) + { + my $mactab = xCAT::Table->new("mac"); + my $machash = $mactab->getNodesAttribs($req->{node}, ['mac']); + foreach my $node (keys %{$machash}) + { + + my $mac = $machash->{$node}->[0]->{mac}; + if (!$mac) + { + next; + } + my $linklocal = xCAT::NetworkUtils->linklocaladdr($mac); + + $domain = &getIPdomain($linklocal, $callback); + + if ($::DELNODE) + { + delnode $node, $linklocal, $node, $domain; + } + else + { + addnode $node, $linklocal, $node, $domain; + } + } + } + else + { + my $hostscache = + $hoststab->getNodesAttribs($req->{node}, + [qw(ip node hostnames otherinterfaces)]); + foreach (@{$req->{node}}) + { + + my $ref = $hostscache->{$_}->[0]; + $domain = &getIPdomain($ref->{ip}, $callback); + + if ($::DELNODE) + { + delnode $ref->{node}, $ref->{ip}, $ref->{hostnames}, $domain; + } + else + { + if (xCAT::NetworkUtils->isIpaddr($ref->{ip})) + { + addnode $ref->{node}, $ref->{ip}, $ref->{hostnames}, $domain; + } + if (defined($ref->{otherinterfaces})) + { + addotherinterfaces $ref->{node}, $ref->{otherinterfaces}, $domain; + } + } + } #end foreach + } # end else + + # do the other node nics - if any + &donics($req->{node}, $callback); + + } + else + { + if ($::DELNODE) + { + return; + } + my @hostents = + $hoststab->getAllNodeAttribs( + ['ip', 'node', 'hostnames', 'otherinterfaces']); + + my @allnodes; + foreach (@hostents) + { + + push @allnodes, $_->{node}; + + $domain = &getIPdomain($_->{ip}); + + if (xCAT::NetworkUtils->isIpaddr($_->{ip})) + { + addnode $_->{node}, $_->{ip}, $_->{hostnames}, $domain; + } + if (defined($_->{otherinterfaces})) + { + addotherinterfaces $_->{node}, $_->{otherinterfaces}, $domain; + } + } + + # also do nics table + &donics(\@allnodes, $callback); + } + + writeout(); + + if ($lockh) + { + flock($lockh, LOCK_UN); + } +} + +sub writeout +{ + my $targ; + open($targ, '>', "/etc/hosts"); + foreach (@hosts) + { + print $targ $_; + } + close($targ); +} + +#------------------------------------------------------------------------------- + +=head3 donics + + Add the additional network interfaces for a list of nodes as + indicated in the nics table + + Arguments: + node name + Returns: + 0 - ok + 1 - error + + Globals: + + Example: + my $rc = &donics($node, $callback); + + Comments: + none +=cut + +#------------------------------------------------------------------------------- +sub donics +{ + my $nodes = shift; + my $callback = shift; + + my @nodelist = @{$nodes}; + + my $nicstab = xCAT::Table->new('nics'); + my $nettab = xCAT::Table->new('networks'); + + foreach my $node (@nodelist) + { + my %nichash; + + # get the nic info + my $et = + $nicstab->getNodeAttribs( + $node, + [ + 'nicips', 'nichostnamesuffixes', + 'nicnetworks' + ] + ); + + if ( + !( + $et->{nicips} + && $et->{'nichostnamesuffixes'} + && $et->{'nicnetworks'} + ) + ) + { + next; + } + + # $et->{nicips} looks like "eth0:ip1,eth1:ip2,bmc:ip3..." + my @nicandiplist = split(',', $et->{'nicips'}); + foreach (@nicandiplist) + { + my ($nicname, $nicip) = split(':', $_); + $nichash{$nicname}{nicip} = $nicip; + } + my @nicandsufx = split(',', $et->{'nichostnamesuffixes'}); + foreach (@nicandsufx) + { + my ($nicname, $nicsufx) = split(':', $_); + $nichash{$nicname}{nicsufx} = $nicsufx; + } + my @nicandnetwrk = split(',', $et->{'nicnetworks'}); + foreach (@nicandnetwrk) + { + my ($nicname, $netwrk) = split(':', $_); + $nichash{$nicname}{netwrk} = $netwrk; + } + + foreach my $nic (keys %nichash) + { + # make sure we have the short hostname + my $shorthost; + ($shorthost = $node) =~ s/\..*$//; + + # construct hostname for nic + my $nichostname = "$shorthost$nichash{$nic}{nicsufx}"; + + # get domain from network def + my $nt = $nettab->getAttribs({ netname => "$nichash{$nic}{netwrk}"}, 'domain'); + + if ($::DELNODE) + { + delnode $nichostname, $nichash{$nic}{nicip}, '', $nt->{domain}; + } + else + { + addnode $nichostname, $nichash{$nic}{nicip}, '', $nt->{domain}; + } + } # end for each nic + } # end for each node + + $nettab->close; + $nicstab->close; + + return 0; +} + +#------------------------------------------------------------------------------- + +=head3 getIPdomain + + Find the xCAT network definition match the IP and then return the + domain value from that network def. + + Arguments: + node IP + callback + Returns: + domain name - ok + 1 - error + + Globals: + + Example: + my $rc = &getIPdomain($nodeIP, $callback); + + Comments: + none +=cut + +#------------------------------------------------------------------------------- +sub getIPdomain +{ + my $nodeIP = shift; + my $callback = shift; + + # get the network defs + my $nettab = xCAT::Table->new('networks'); + my @nets = $nettab->getAllAttribs('netname', 'net', 'mask', 'domain'); + + # foreach network def + foreach my $enet (@nets) + { + my $NM = $enet->{'mask'}; + my $net = $enet->{'net'}; + if (xCAT::NetworkUtils->ishostinsubnet($nodeIP, $NM, $net)) + { + return $enet->{'domain'}; + last; + } + } + + # could not find the network domain for this IP address + return 1; } 1;