Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
#!/usr/bin/env ruby
begin
require 'multi_json'
require 'rexml/document'
require 'terminal-table'
rescue LoadError => e
abort "Unable to load library: #{e.message}"
end
require 'net/http'
require 'open-uri'
class Release
CACHE = File.expand_path('~/.ubuntu-cloud-images.json')
TABLE = 'http://cloud-images.ubuntu.com/locator/ec2/releasesTable'
attr_accessor :region, :suite, :version, :arch, :type, :date, :ami, :aki, :launch
def initialize(data)
data.each do |k,v|
send("#{k}=", v) if respond_to?("#{k}=")
end
end
def to_a
self.class.row_format.map {|x| send(x)}
end
def =~(filters)
filters.all? {|key, value| send(key) == value}
end
def self.row_format
# ['region', 'suite', 'version', 'arch', 'type', 'date', 'ami', 'aki', launch']
['region', 'suite', 'arch', 'type', 'date', 'ami', 'launch']
end
def self.by_attributes(filters = {})
all.select {|x| x =~ filters}
end
def self.all
get_releases
MultiJson.load(File.read(CACHE)).map {|release| new(Hash[self.row_format.zip(release)])}
end
def self.get_releases
return if cache_up_to_date?
releases = open(TABLE).read
releases[releases.rindex(',')] = ''
keypair = ENV['EC2_KEYPAIR_NAME'] || 'EC2_KEYPAIR_NAME'
data = MultiJson.load(releases)['aaData']
data.each do |row|
row[6] = REXML::Document.new(row[6]).elements.first.text
row.push("ec2-run-instances -k #{keypair} #{row[6]}")
row.delete_at(7)
row.delete_at(2)
end
File.open(CACHE, 'w') {|f| f.write(MultiJson.dump(data))}
end
def self.cache_up_to_date?
File.exists?(CACHE) && (File.mtime(CACHE).to_date > releases_last_modified)
end
def self.releases_last_modified
response = nil
uri = URI(TABLE)
Net::HTTP.start(uri.host, 80) {|http| response = http.head(uri.path)}
DateTime.parse(response['last-modified'])
end
end
if __FILE__ == $0
filters = {}
ARGV.each do |arg|
k,v = arg.split(':')
filters[k] = v
end
if filters.empty? || filters.values.any? {|x| x.nil?}
abort "Usage: #{__FILE__} field:value [ field:value [ field:value [...]]]"
end
STDOUT.puts(Terminal::Table.new :headings => Release.row_format, :rows => Release.by_attributes(filters).map(&:to_a))
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment