Commit 3a9765aa authored by David Johnson's avatar David Johnson

Move fromtopo out of rc.hostnames to genhostslistfromtopo in libsetup.pm.

This allows other callers than rc.hostnames (i.e. docker clientside) to
generate the hostname list for an experiment.
parent 0136b0be
#!/usr/bin/perl -w
#
# Copyright (c) 2004, 2005 University of Utah and the Flux Group.
# Copyright (c) 2004, 2005, 2017 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -135,7 +135,8 @@ sub doboot()
# First see if we have a topo file; we can generate our own hosts
# file if we do, saving a lot of load on tmcd in big experiments.
#
if (fromtopo(\@tmccresults) < 0 &&
my $mapfile = "$BOOTDIR/hostmap";
if (genhostslistfromtopo($mapfile,\@tmccresults) < 0 &&
tmcc(TMCCCMD_HOSTS, undef, \@tmccresults) < 0) {
fatal("Could not get hosts file from server!");
}
......@@ -178,105 +179,3 @@ sub docleanup()
fatal("Could not copy default $HOSTSFILE into place!");
}
}
#
# Generate hosts file (as if it came from tmcd) locally if we have a topo file.
#
sub fromtopo($)
{
my ($rptr) = @_;
my @results = ();
my $topomap;
my $mapfile = "$BOOTDIR/hostmap";
my ($pid, $eid, $vname) = check_nickname();
my %nodes = ();
my %lans = ();;
if (gettopomap(\$topomap)) {
return -1;
}
# Special case of experiment with no lans; no hostfile stuff needed.
if (! scalar(@{ $topomap->{"lans"} })) {
@$rptr = ();
return 0;
}
# The nodes section tells us the name of each node, and all its links.
foreach my $noderef (@{ $topomap->{"nodes"} }) {
my $vname = $noderef->{"vname"};
my $links = $noderef->{"links"};
my $count = 0;
next
if (!defined($links));
$nodes{$vname} = [];
# Links is a string of "$lan1:$ip1 $lan2:$ip2 ..."
foreach my $link (split(" ", $links)) {
my ($lan,$ip) = split(":", $link);
push(@{ $nodes{$vname} }, "$count:$ip");
$lans{"$vname:$count"} = $lan;
$count++;
}
}
#
# Construct input for external program.
#
if (! open(MAP, ">$mapfile")) {
warn("*** WARNING: Could not create $mapfile!\n");
@$rptr = ();
return -1;
}
#
# First spit out virt_nodes
#
print MAP scalar(keys(%nodes)) . "\n";
foreach my $node (keys(%nodes)) {
my @members = @{ $nodes{$node} };
print MAP "$node,";
print MAP join(" ", @members);
print MAP "\n";
}
#
# Then spit out virt_lans.
#
print MAP scalar(keys(%lans)) . "\n";
foreach my $member (keys(%lans)) {
my $lan = $lans{$member};
print MAP "$lan,$member\n";
}
close(MAP);
#
# Now run the dijkstra program on the input.
#
if (!open(GENH, "cat $mapfile | $BINDIR/genhostsfile $vname |")) {
warn("*** WARNING: Could not invoke genhostsfile on mapfile!\n");
@$rptr = ();
return -1;
}
while (<GENH>) {
push(@results, $_);
}
if (! close(GENH)) {
if ($?) {
warn("*** WARNING: genhostsfile exited with status $?!\n");
}
else {
warn("*** WARNING: Error closing genhostsfile pipe: $!\n");
}
@$rptr = ();
return -1;
}
@$rptr = @results;
return 0;
}
......@@ -44,7 +44,7 @@ use Exporter;
getstorageconfig getstoragediskinfo getimagesize
getrcmanifest fetchrcmanifestblobs runbootscript runhooks
build_fake_macs getenvvars getpnetnodeattrs
sortedlistallfilesindir sortedreadallfilesindir
sortedlistallfilesindir sortedreadallfilesindir genhostslistfromtopo
TBDebugTimeStamp TBDebugTimeStampWithDate
TBDebugTimeStampsOn TBDebugTimeStampsOff
......@@ -1764,6 +1764,109 @@ sub genhostsfile($@)
return 0;
}
#
# Generate hosts list (as if it came from tmcd) locally if we have a topo file.
# You want to run the above genhostsfile on the result array of this, as
# rc.hostnames does.
#
sub genhostslistfromtopo($$)
{
my ($mapfile,$rptr) = @_;
my @results = ();
my $topomap;
my ($pid, $eid, $vname) = check_nickname();
my %nodes = ();
my %lans = ();;
if (gettopomap(\$topomap)) {
return -1;
}
# Special case of experiment with no lans; no hostfile stuff needed.
if (! scalar(@{ $topomap->{"lans"} })) {
@$rptr = ();
return 0;
}
# The nodes section tells us the name of each node, and all its links.
foreach my $noderef (@{ $topomap->{"nodes"} }) {
my $vname = $noderef->{"vname"};
my $links = $noderef->{"links"};
my $count = 0;
next
if (!defined($links));
$nodes{$vname} = [];
# Links is a string of "$lan1:$ip1 $lan2:$ip2 ..."
foreach my $link (split(" ", $links)) {
my ($lan,$ip) = split(":", $link);
push(@{ $nodes{$vname} }, "$count:$ip");
$lans{"$vname:$count"} = $lan;
$count++;
}
}
#
# Construct input for external program.
#
if (! open(MAP, ">$mapfile")) {
warn("*** WARNING: Could not create $mapfile!\n");
@$rptr = ();
return -1;
}
#
# First spit out virt_nodes
#
print MAP scalar(keys(%nodes)) . "\n";
foreach my $node (keys(%nodes)) {
my @members = @{ $nodes{$node} };
print MAP "$node,";
print MAP join(" ", @members);
print MAP "\n";
}
#
# Then spit out virt_lans.
#
print MAP scalar(keys(%lans)) . "\n";
foreach my $member (keys(%lans)) {
my $lan = $lans{$member};
print MAP "$lan,$member\n";
}
close(MAP);
#
# Now run the dijkstra program on the input.
#
if (!open(GENH, "cat $mapfile | $BINDIR/genhostsfile $vname |")) {
warn("*** WARNING: Could not invoke genhostsfile on mapfile!\n");
@$rptr = ();
return -1;
}
while (<GENH>) {
push(@results, $_);
}
if (! close(GENH)) {
if ($?) {
warn("*** WARNING: genhostsfile exited with status $?!\n");
}
else {
warn("*** WARNING: Error closing genhostsfile pipe: $!\n");
}
@$rptr = ();
return -1;
}
@$rptr = @results;
return 0;
}
#
# Convert from MAC to iface name (eth0/fxp0/etc) using little helper program.
#
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment