X-Git-Url: https://git.openstreetmap.org/dns.git/blobdiff_plain/78a238580de6026bab03a51d76663896c53059d0..cd47d6d0c42b26d828549be805dd987d6f3a305f:/bin/mkgeo diff --git a/bin/mkgeo b/bin/mkgeo index fd04593..b2c1d4f 100755 --- a/bin/mkgeo +++ b/bin/mkgeo @@ -18,7 +18,8 @@ my $servers = YAML::LoadFile("src/${source}"); while (my($name,$server) = each %$servers) { $server->{name} = $name; - $server->{bandwidth} = $server->{bandwidth} * 1024 * 1024; + $server->{bandwidth_limit} = $server->{bandwidth} * 1024 * 1024; + $server->{bandwidth_used} = 0; if ($ENV{PINGDOM_USERNAME} && $ENV{PINGDOM_PASSWORD}) { @@ -106,28 +107,29 @@ foreach my $country ($countries->look_down("_tag" => "country")) # Discard the parsed country database $countries->delete; -# Loop over the mappings, trying to assign each country to the -# nearest server, but subject to the bandwidth limits; -foreach my $mapping (sort { $b->{priority} <=> $a->{priority} || $a->{distance} <=> $b->{distance} } @mappings) -{ - my $country = $mapping->{country}; - my $server = $mapping->{server}; +# Allocate each country to a server +allocate_servers(\@mappings); - if ($country->{bandwidth} <= $server->{bandwidth} && !exists($country->{server})) +# If we failed to allocate every country then loop, increasing +# the bandwidth for each server by a little and retrying until +# we manage to allocate everything +while (grep { !exists($_->{server}) } values %countries) +{ + # Clear any existing mappings of countries to servers + foreach my $country (values %countries) { - $country->{server} = $server; - $server->{bandwidth} = $server->{bandwidth} - $country->{bandwidth}; + delete $country->{server}; } -} -# Loop over the mappings again, assigning anything that is left -# as best we can, and allowing bandwidth limits to be exeeded -foreach my $mapping (sort { $b->{priority} <=> $a->{priority} || $a->{distance} <=> $b->{distance} } @mappings) -{ - my $country = $mapping->{country}; - my $server = $mapping->{server}; + # Reset bandwidth usage for servers and increase limits by 10% + foreach my $server (values %$servers) + { + $server->{bandwidth_used} = 0; + $server->{bandwidth_limit} = $server->{bandwidth_limit} * 1.1; + } - $country->{server} = $server unless exists($country->{server}); + # Try the allocate again + allocate_servers(\@mappings); } # Create JSON collection object @@ -155,6 +157,7 @@ foreach my $country (values %countries) $clon = $clon + 360; } + $zonefile->print("# $country->{name}\n"); $zonefile->print("C\L$country->{code}\E.${zone}:$server->{name}.${zone}:600\n"); push @json, { @@ -164,7 +167,9 @@ foreach my $country (values %countries) coordinates => [ [ $clon, $clat ], [ $slon, $slat ] ] }, properties => { - country => $country->{name} + country => $country->{name}, + server => $server->{name}, + colour => $server->{colour} } }; } @@ -288,3 +293,28 @@ sub distance return great_circle_distance($lon1, pip2 - $lat1, $lon2, pip2 - $lat2); } + +# +# Allocate each country to a server +# +sub allocate_servers +{ + my $mappings = shift; + + # Loop over the mappings, trying to assign each country to the + # nearest server, but subject to the bandwidth limits + foreach my $mapping (sort { $b->{priority} <=> $a->{priority} || $a->{distance} <=> $b->{distance} } @$mappings) + { + my $country = $mapping->{country}; + my $server = $mapping->{server}; + + if (!exists($country->{server}) && + $server->{bandwidth_used} + $country->{bandwidth} <= $server->{bandwidth_limit}) + { + $country->{server} = $server; + $server->{bandwidth_used} = $server->{bandwidth_used} + $country->{bandwidth}; + } + } + + return; +}