class DockerRunner
Attributes
code[RW]
deployment_id[RW]
docker_host[RW]
docker_host_secure[RW]
host[RW]
image_name[RW]
instance_index[RW]
interact[RW]
registry[RW]
remote_address[RW]
run_untagged[RW]
secure_docker_api[RW]
use_extension[RW]
user[RW]
version[RW]
Public Class Methods
new(config)
click to toggle source
# File lib/support/docker_runner.rb, line 12 def initialize(config) @config = config @run_config = config['run'] @build_config = config['build'] @run_untagged = false @image_name = @run_config['image_name'] if (!@image_name) if (@build_config) @image_name = @build_config['name'] raise "Build config does not have 'name'" if (@image_name == nil) else raise "Can't find an image name. Either specify 'name' in build config or 'image_name' in run config." end end @registry = @config['registry'] @instance_index = 0 @use_extension = false @interact = false @remote_address = nil @api_container = nil @version = nil @secure_docker_api = true @build_args = nil end
Public Instance Methods
find_machine_apis()
click to toggle source
# File lib/support/docker_runner.rb, line 40 def find_machine_apis @run_on_apis = [] @all_docker_apis_in_cluster = [] if (@deploy_config != nil) && (@deploy_config[:hosts] != nil) @deploy_config[:hosts].each do |host_key| host = Hosts::HOSTS[host_key] address = "tcp://#{host[:address]}:#{host[:docker_port]}" docker_api = DockerApi.new(address, host[:ssl]) @all_docker_apis_in_cluster << docker_api @run_on_apis << docker_api if (address == @remote_address) || ( @deploy_config[:targets][run_name] == :all) end else # Config not given, we need to create api from remote address and ssl setting. This is the only api for this class. @docker_host = @docker_host || ENV['DOCKER_HOST'] @docker_host_secure = @docker_host_secure || (ENV['DOCKER_TLS_VERIFY'].to_s == '1') docker_api = DockerApi.new(@docker_host, @docker_host_secure) @all_docker_apis_in_cluster << docker_api @run_on_apis << docker_api end end
image_version()
click to toggle source
# File lib/support/docker_runner.rb, line 66 def image_version return @version if (@version != nil) the_version = 'latest' the_version = @build_config['version'] if (@build_config) && (@build_config['version'] != nil) return the_version end
kill_all(name_prefix)
click to toggle source
# File lib/support/docker_runner.rb, line 73 def kill_all(name_prefix) find_machine_apis @all_docker_apis_in_cluster.each do |api| #options = {filters: {status: [:running, :exited, :paused, :restarting]}} options = {} containers = Docker::Container.all(options.to_json, api.connection) containers.each do |container| if (container.json["Name"].start_with?("/#{name_prefix}")) pp "Killing and removing: #{container.json["Name"]}" container.kill() if (container.json["State"]["Running"]) container.remove() if (container != nil) else pp " * Container didn't match: #{container.json["Name"]}" end end end end
run()
click to toggle source
# File lib/support/docker_runner.rb, line 92 def run find_machine_apis raise "No run on apis" if (@run_on_apis.count == 0) code = @code instance_index = 1 if (@instance_index == :next) options = {filters: {status: [:running]}} @active_container_names = [] containers = Docker::Container.all(options.to_json, @run_on_apis.first.connection) containers.each do |container| container_json = container.json container_name = container_json["Name"] @active_container_names << container_name end instance_index = 1 container_name_taken = true while (true) instance_ext = "_#{instance_index}" instance_name = "/#{run_name}#{instance_ext}" if (!@active_container_names.include? instance_name) @instance_index = instance_index break else instance_index += 1 end end end instance_ext = "" instance_ext = "_#{@instance_index}" if (@use_extension) instance_name = "#{run_name}#{instance_ext}" @all_docker_apis_in_cluster.each do |docker_api| kill_previous_containers_in_cluster(docker_api, instance_name) end image_name = image_name_with_registry() @run_on_apis.each do |docker_api| if (!@run_untagged) pull_image_to_host(docker_api, registry) end run_container(docker_api, instance_name) end end
run_name()
click to toggle source
# File lib/support/docker_runner.rb, line 62 def run_name return @run_config['name'] end
Private Instance Methods
container_state()
click to toggle source
# File lib/support/docker_runner.rb, line 249 def container_state return @api_container.json['State'] end
image_name_with_registry()
click to toggle source
# File lib/support/docker_runner.rb, line 240 def image_name_with_registry image_name = @image_name if (registry != nil) && (!@run_untagged) registry_without_protocol = registry.split("://").last image_name = "#{registry_without_protocol}/#{@image_name}" end return image_name end
kill_previous_containers_in_cluster(docker_api, instance_name)
click to toggle source
# File lib/support/docker_runner.rb, line 218 def kill_previous_containers_in_cluster(docker_api, instance_name) pp "Killing and removing containers with same name: #{instance_name}" @api_container = nil begin @api_container = Docker::Container.get(instance_name, {}, docker_api.connection) puts "Killing and removing container: #{instance_name} in #{docker_api.connection}" @api_container.kill() rescue Docker::Error::NotFoundError => not_found_error puts "No container with name \"#{instance_name}\" running. No need to kill." end if (@api_container) begin pp "Removing container: #{instance_name}" @api_container.remove() if (@api_container != nil) rescue Docker::Error::NotFoundError => remove_error puts "Didn't find image to remove: #{instance_name}" end end end
pull_image_to_host(docker_api, registry)
click to toggle source
# File lib/support/docker_runner.rb, line 142 def pull_image_to_host(docker_api, registry) return if (registry == nil) || (@run_untagged) Excon.defaults[:write_timeout] = 500 Excon.defaults[:read_timeout] = 500 options = {} options[:repo] = registry options[:fromImage] = "#{image_name_with_registry}:#{image_version}" pp "See if Host needs to pull image (#{options[:fromImage]}). Host: #{docker_api.connection}" image = Docker::Image.create(options, nil, docker_api.connection) end
run_container(docker_api, instance_name)
click to toggle source
# File lib/support/docker_runner.rb, line 154 def run_container(docker_api, instance_name) create_options = @run_config['options'] || {} if (!image_name_with_registry.include? ":") create_options['Image'] = "#{image_name_with_registry}:#{image_version}" else create_options['Image'] = image_name_with_registry end create_options['name'] = instance_name create_options['Labels'] = { deployer: @user, deploy_id: @deployment_id } create_options['Tty'] = true if (@interact == true) create_options['Entrypoint'] = ["/bin/bash"] if (@interact == true) pp "Running container: #{instance_name}\nOptions: #{create_options}" cli_command = "docker run --name #{instance_name}" if (create_options['Env'] != nil) create_options['Env'].each do |env| cli_command += " -e #{env}" end end if (create_options['HostConfig'] != nil) host_config = create_options['HostConfig'] binds = host_config['Binds'] if (binds != nil) binds.each do |bind| cli_command += " -v #{bind}" end end links = host_config['Links'] if (links != nil) links.each do |link| cli_command += " --link #{link}" end end ports = host_config['PortBindings'] ports.keys.each do |port| container_port = port.split("/").first host_port = container_port port_binds = ports[port] port_binds.each do |bind| host_port = bind['HostPort'] if (bind['HostPort'] != nil) cli_command += " -p #{host_port}:#{container_port}" end if (port_binds.length == 0) cli_command += " -p #{host_port}:#{container_port}" end end end cli_command += " -d" cli_command += " #{create_options['Image']}" cli_command += " #{create_options['Entrypoint']}" if (create_options['Entrypoint'] != nil) puts "CLI Command: #{cli_command}" @api_container = Docker::Container.create(create_options, docker_api.connection) puts @api_container.start if (@interact) pp "==================================================================" pp "CONTAINER STARTED FOR INTERACTION - ENTRYPOINT NOT CALLED" pp "To attach: docker exec -it '#{instance_name}' bash" pp "==================================================================" end end
wait_for_completion()
click to toggle source
# File lib/support/docker_runner.rb, line 253 def wait_for_completion while (container_state()["Running"] == true) sleep 1 puts "Waiting for container #{run_name} to finish." end exit_code = container_state()['ExitCode'] raise "Container failed (#{image_name_with_registry()}) Exit code: #{exit_code}" if (exit_code != 0) end