Skip to content

Instantly share code, notes, and snippets.

@trinitronx
Last active December 17, 2015 10:18
Show Gist options
  • Save trinitronx/5593423 to your computer and use it in GitHub Desktop.
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
#!/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