class Specinfra::Backend::Docker
Public Class Methods
new(config = {})
click to toggle source
Calls superclass method
# File lib/specinfra/backend/docker.rb, line 4 def initialize(config = {}) super begin require 'docker' unless defined?(::Docker) rescue LoadError fail "Docker client library is not available. Try installing `docker-api' gem." end ::Docker.url = get_config(:docker_url) if image = get_config(:docker_image) @images = [] @base_image = get_or_pull_image(image) create_and_start_container ObjectSpace.define_finalizer(self, proc { cleanup_container }) elsif container = get_config(:docker_container) @container = ::Docker::Container.get(container) else fail 'Please specify docker_image or docker_container.' end end
Public Instance Methods
commit_container()
click to toggle source
# File lib/specinfra/backend/docker.rb, line 48 def commit_container @container.commit end
run_command(cmd, opts={})
click to toggle source
# File lib/specinfra/backend/docker.rb, line 28 def run_command(cmd, opts={}) cmd = build_command(cmd) run_pre_command(opts) docker_run!(cmd, opts) end
send_file(from, to)
click to toggle source
# File lib/specinfra/backend/docker.rb, line 34 def send_file(from, to) if @base_image @images << commit_container if @container @images << current_image.insert_local('localPath' => from, 'outputPath' => to) cleanup_container create_and_start_container elsif @container # This needs Docker >= 1.8 @container.archive_in(from, to) else fail 'Cannot call send_file without docker_image or docker_container.' end end
Private Instance Methods
cleanup_container()
click to toggle source
# File lib/specinfra/backend/docker.rb, line 79 def cleanup_container @container.stop @container.delete end
create_and_start_container()
click to toggle source
# File lib/specinfra/backend/docker.rb, line 54 def create_and_start_container opts = { 'Image' => current_image.id } if current_image.json["Config"]["Cmd"].nil? && current_image.json["Config"]["Entrypoint"].nil? opts.merge!({'Cmd' => ['/bin/sh']}) end opts.merge!({'OpenStdin' => true}) if path = get_config(:path) (opts['Env'] ||= []) << "PATH=#{path}" end env = get_config(:env).to_a.map { |v| v.join('=') } opts['Env'] = opts['Env'].to_a.concat(env) opts.merge!(get_config(:docker_container_create_options) || {}) @container = ::Docker::Container.create(opts) @container.start while @container.json['State'].key?('Health') && @container.json['State']['Health']['Status'] == "starting" do sleep 0.5 end end
current_image()
click to toggle source
# File lib/specinfra/backend/docker.rb, line 84 def current_image @images.last || @base_image end
docker_run!(cmd, opts={})
click to toggle source
# File lib/specinfra/backend/docker.rb, line 88 def docker_run!(cmd, opts={}) opts.merge!(get_config(:docker_container_exec_options) || {}) stdout, stderr, status = @container.exec(cmd.shellsplit, opts) CommandResult.new :stdout => stdout.join, :stderr => stderr.join, :exit_status => status rescue ::Docker::Error::DockerError => e raise rescue => e @container.kill err = stderr.nil? ? ([e.message] + e.backtrace) : stderr CommandResult.new :stdout => [stdout].join, :stderr => err.join, :exit_status => (status || 1) end
get_or_pull_image(name)
click to toggle source
# File lib/specinfra/backend/docker.rb, line 103 def get_or_pull_image(name) begin ::Docker::Image.get(name) rescue ::Docker::Error::NotFoundError ::Docker::Image.create('fromImage' => name) end end
run_pre_command(opts)
click to toggle source
# File lib/specinfra/backend/docker.rb, line 111 def run_pre_command(opts) if get_config(:pre_command) cmd = build_command(get_config(:pre_command)) docker_run!(cmd, opts) end end