diff options
author | 2016-01-04 02:18:48 +0100 | |
---|---|---|
committer | 2016-01-04 02:18:48 +0100 | |
commit | fd7fa9102a50dedb2f1cbad4993fa2c7427407aa (patch) | |
tree | 7ca0f15a86f6a84599f076e01e8a27a8e22ec8d2 /lib/mirror_toolkit.rb | |
download | mirror-toolkit-fd7fa9102a50dedb2f1cbad4993fa2c7427407aa.tar.gz mirror-toolkit-fd7fa9102a50dedb2f1cbad4993fa2c7427407aa.tar.bz2 mirror-toolkit-fd7fa9102a50dedb2f1cbad4993fa2c7427407aa.zip |
Add initial set of tools
- rsync-cat: rsync-to-stdout utility
- gm-lag: displays the current lag of a mirror
Diffstat (limited to 'lib/mirror_toolkit.rb')
-rw-r--r-- | lib/mirror_toolkit.rb | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/lib/mirror_toolkit.rb b/lib/mirror_toolkit.rb new file mode 100644 index 0000000..cc53090 --- /dev/null +++ b/lib/mirror_toolkit.rb @@ -0,0 +1,89 @@ +require 'open3' +require 'time' +require 'net/http' + +# Mirror toolkit functionality and other shared stuff +module MirrorToolkit + RSYNC_TIMESTAMP_FILE = '/gentoo-portage/metadata/timestamp' + DISTFILES_TIMESTAMP_FILE = '/distfiles/timestamp.mirmon' + + TYPE_RSYNC = 1 + TYPE_DISTFILES = 2 + + module_function + + # Calls `rsync_cat` to fetch a file from rsync + def rsync_cat(uri) + rsync_cat = File.join(File.dirname(__FILE__), '..', 'bin', 'rsync-cat') + stdin, stdout, stderr, wait_thr = Open3.popen3(rsync_cat, uri) + stdin.close + + if wait_thr.value == 0 + return stdout.gets + else + fail "Rsync call unsuccessful: '#{stderr.gets.chomp}'" + end + end + + # Fetches a URI from any of the Gentoo mirror types + def remote_fetch(url) + case url.scheme + when 'rsync' + rsync_cat(url.to_s) + when 'http', 'https', 'ftp' + Net::HTTP.get(url) + else + fail 'Unknown URI scheme.' + end + end + + # Tries to return a Time object for every kind of timestamp used on Gentoo mirrors + def parse_timestamp(ts) + if ts.numeric? + Time.at(ts.to_i).utc + else + Time.parse(ts).utc + end + end + + # Returns a URI object where to find the timestamp for the given url and mirror type. + def get_timestamp_url(url, type) + mirror = URI(url) + + case mirror.scheme + when 'rsync' + if type == TYPE_RSYNC + mirror.path = MirrorToolkit::RSYNC_TIMESTAMP_FILE + elsif type == TYPE_DISTFILES + mirror.path += MirrorToolkit::DISTFILES_TIMESTAMP_FILE + end + when 'http', 'https', 'ftp' + mirror.path = MirrorToolkit::DISTFILES_TIMESTAMP_FILE + end + + mirror + end + + # Returns the number of seconds a mirror is lagging behind, or nil if it cannot be determined. + def get_lag(url, type) + Time.now.utc - parse_timestamp(remote_fetch(get_timestamp_url(url, type))) + rescue + nil + end + + # Renders seconds as a nice human-printable string + def humanize_seconds(secs) + [[60, :seconds], [60, :minutes], [24, :hours], [1000, :days]].map do |count, name| + if secs > 0 + secs, n = secs.divmod(count) + "#{n.to_i} #{name}" + end + end.compact.reverse.join(' ') + end +end + +class String + def numeric? + true if Float(self) rescue false + end +end |