Created
July 9, 2015 14:40
-
-
Save anonymous/0f59066e41d7f2c645c8 to your computer and use it in GitHub Desktop.
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/ruby | |
require 'optparse' | |
require 'time' | |
require 'json' | |
OPTIONS = {:action => nil, :inspect => false, :save_state => nil, :metadata => nil} | |
METHODS = %w{START UPDATE VALIDATE} | |
ENVVARS = %w{BUILD_CAUSE BUILD_TIME BUILD_MONTH BUILD_WEEK BUILD_DAY BUILD_HASH BUILD_TAG} | |
opt = OptionParser.new | |
opt.banner = "Start, stop and validate containers" | |
opt.separator "" | |
["START", "UPDATE", "VALIDATE"].each do |method| | |
option = "--%s" % method.downcase | |
help = "Perform the %s action based on %s_METHOD" % [method.downcase, method] | |
opt.on(option, help) do | |
OPTIONS[:action] = method | |
end | |
end | |
opt.on("--inspect", "Show image metadata") do | |
OPTIONS[:inspect] = true | |
end | |
opt.on("--metadata", "Show JSON metadata for image") do | |
OPTIONS[:metadata] = true | |
end | |
opt.parse! | |
def self.color(code) | |
colors = {:red => "[31m", | |
:green => "[32m", | |
:yellow => "[33m", | |
:cyan => "[36m", | |
:bold => "[1m", | |
:reset => "[0m"} | |
if STDOUT.tty? | |
return colors[code] || "" | |
else | |
return "" | |
end | |
end | |
def self.colorize(code, msg) | |
"%s%s%s" % [ color(code), msg, color(:reset) ] | |
end | |
def valid_method?(method) | |
METHODS.include?(method) | |
end | |
def key_for_method(method) | |
"%s_METHOD" % method.upcase | |
end | |
def validate_method_script(method) | |
return unless script_for(method) | |
File.exist?(script_for(method)) && File.executable?(script_for(method)) | |
end | |
def script_for(method) | |
key = key_for_method(method) | |
image_metadata[key.downcase] || ENV[key] | |
end | |
def method_supported?(method) | |
key = key_for_method(method) | |
image_metadata[key.downcase] || ENV[key] | |
end | |
def images_metadata | |
Dir.entries("/").grep(/^\.image_metadata/).map do |metadata| | |
if metadata =~ /^\.image_metadata_(.+)/ | |
[$1, JSON.parse(File.read(File.join("/", metadata)))] | |
else | |
[nil, {}] | |
end | |
end.sort_by{|_, m| m["build_time_stamp"]}.map {|i, m| [i, m]} | |
end | |
def image_metadata | |
images_metadata.last[1] | |
end | |
def inspect_container | |
if ENV["CONTAINER_FIRST_START"] | |
puts "Container first started at %s (%s)" % [colorize(:bold, Time.at(Integer(ENV["CONTAINER_FIRST_START"]))), ENV["CONTAINER_FIRST_START"]] | |
puts | |
end | |
puts "Container management methods:" | |
puts | |
METHODS.each do |method| | |
if script = script_for(method) | |
if File.exist?(script) && File.executable?(script) | |
puts colorize(:green, " Container supports %s method using command %s" % [method, script]) | |
else | |
puts colorize(:red, " Container supports %s method but %s does not exist or is not executable" % [method, script]) | |
end | |
else | |
puts colorize(:yellow, " Container does not support the %s method" % method) | |
end | |
end | |
images_metadata.each do |image, metadata| | |
next unless image | |
puts | |
puts "Metadata for image %s" % colorize(:bold, image) | |
puts | |
puts " Names:" | |
puts " Project Name: %s " % metadata["project"] | |
puts " Image Name: %s " % metadata["image_name"] | |
puts " Image Tag Names: %s " % metadata["image_tag_names"].join(", ") | |
puts | |
puts " Build Info:" | |
puts " CI Run: %s " % metadata["ci"] | |
puts " Git Hash: %s " % metadata["gitref"] | |
puts " Build Cause: %s " % metadata["build_cause"] | |
puts " Build Time: %s (%s) " % [metadata["build_time"], metadata["build_time_stamp"]] | |
puts " Build Tag: %s " % metadata["build_tag"] | |
puts | |
puts " Actions:" | |
puts " START: %s " % [metadata["start_method"] || colorize(:yellow, "not set")] | |
puts " UPDATE: %s " % [metadata["update_method"] || colorize(:yellow, "not set")] | |
puts " VALIDATE: %s " % [metadata["validate_method"] || colorize(:yellow, "not set")] | |
end | |
end | |
def set_environment_for(method) | |
ENV["CONTAINER_RUN_MODE"] = method | |
end | |
def run_method(method) | |
abort("Unknown method %s" % method) unless valid_method?(method) | |
abort("This container does not support the %s method" % method) unless method_supported?(method) | |
abort("The script %s does not exist or is not executable" % script_for(method)) unless validate_method_script(method) | |
if script = script_for(OPTIONS[:action]) | |
puts "%s: Performing %s action via %s" % [Time.now, colorize(:bold, method), colorize(:bold, script)] | |
set_environment_for(method) | |
exec(script) | |
else | |
abort("%s environment variable is not set, cannot perform %s action" % [key_for_method(method), method]) | |
end | |
end | |
def metadata | |
puts image_metadata.to_json | |
end | |
if OPTIONS[:inspect] | |
inspect_container | |
elsif OPTIONS[:metadata] | |
metadata | |
elsif OPTIONS[:action] | |
run_method(OPTIONS[:action]) | |
else | |
puts opt | |
exit 1 | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment