Skip to content

Instantly share code, notes, and snippets.

Created July 9, 2015 14:40
Show Gist options
  • Save anonymous/0f59066e41d7f2c645c8 to your computer and use it in GitHub Desktop.
Save anonymous/0f59066e41d7f2c645c8 to your computer and use it in GitHub Desktop.
#!/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 => "",
:green => "",
:yellow => "",
:cyan => "",
:bold => "",
:reset => ""}
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