Last active
December 17, 2015 10:18
-
-
Save trinitronx/5593423 to your computer and use it in GitHub Desktop.
A simple script to find the fastest mirrors from ubuntu's mirrors.txt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# encoding: utf-8 | |
require 'rubygems' | |
require 'net/http' | |
require 'net/ping/tcp' | |
# This script grabs the master mirror list file from mirrors.ubuntu.com | |
# And then attempts to find the fastest subset of them and writes it out to a file | |
# This is intended to be used with the apt mirrors method in order to get the fastest | |
# updates to our vagrant VM | |
# Reference: http://mvogt.wordpress.com/2011/03/21/the-apt-mirror-method/ | |
# Change this to output to a different file | |
OUTPUT_FILE='/var/www/nginx-default/mirrors.txt' | |
mirrorlist_host = 'mirrors.ubuntu.com' | |
min_num_servers=5 # Minimum number of servers to require in server list | |
timeout=0.05 # start with 50ms limit | |
max_tries=3 # Number of times to try to get min_num_servers servers with <timeout ping | |
timeout_delta=0.01 # timeout increment to use for retry | |
uri_list = [] | |
# The technique used here is: | |
# 1. loop through each mirror | |
# 2. Trim list by performing TCP ping on port 80 for each (with a timeout limit) | |
# 3. If we end up with less than min_num_servers, and tries is < max_tries then retry with same timeout | |
# Else increase timeout by timeout_delta and retry | |
# Define ShortServerListException so we can catch it and retry | |
class ShortServerListException < Exception | |
end | |
Net::HTTP.start(mirrorlist_host) do |http| | |
resp = http.get("/mirrors.txt") | |
resp.body.each_line do |line| | |
uri_list.push( URI(line) ) | |
end | |
end | |
puts "Total Mirrors Found: #{uri_list.length}" | |
all_uris = uri_list.clone | |
File.open(OUTPUT_FILE, 'wt') do |f| | |
try_count=0 | |
# Remove hosts with > timeout ping (in ms) | |
begin | |
uri_list.delete_if do |uri| | |
# puts "LENGTH: #{uri_list.length}" | |
# puts uri_list | |
if Net::Ping::TCP.new('mirror.vcu.edu',80, timeout).ping | |
printf "%40s\t%s\n", uri.host, "\033[1;32m✓\033[0m" | |
f.write(uri.to_s + "\n") | |
false | |
else | |
printf "%40s\t%s\n", uri.host, "\033[1;31m✗\033[0m" | |
# puts "Removing index: #{uri_list.find_index(uri)}" | |
true | |
end | |
end | |
try_count += 1 | |
# puts "FINAL LIST:" | |
# puts uri_list | |
if uri_list.length.zero? || uri_list.length < min_num_servers | |
f.truncate(0) | |
msg = "Not enough mirror URIs failed to pass ping test!\nA minimum of #{min_num_servers} passing servers is required" | |
puts msg | |
raise ShortServerListException, msg | |
end | |
rescue ShortServerListException | |
# restart with full list | |
uri_list = all_uris.clone | |
puts "Retrying with full url list" | |
puts "TRIES: #{try_count}" | |
puts "LEN : #{uri_list.length}" | |
puts "ZERO?: #{uri_list.length.zero?}" | |
if try_count < max_tries | |
retry | |
else | |
timeout += timeout_delta | |
puts "Increasing timeout: #{timeout}" | |
retry | |
end | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment