class Linecook::Baker::Docker
FIXME - refactor into a base class with an interface
Constants
- RETAIN_IMAGES
Attributes
config[R]
Public Class Methods
new(image, config)
click to toggle source
# File lib/linecook-gem/baker/docker.rb, line 20 def initialize(image, config) @image = image @config = config munge_config end
Public Instance Methods
converge()
click to toggle source
# File lib/linecook-gem/baker/docker.rb, line 43 def converge if @inherited begin instance.create rescue puts "Disabling docker cache" # Disable the cache and retry if we ran into a problem driver_config = instance.driver.send(:config) driver_config[:use_cache] = false with_retries(5) do instance.create end end end instance.converge ensure unlock("create_#{@inherited.id}") if @inherited end
destroy()
click to toggle source
# File lib/linecook-gem/baker/docker.rb, line 63 def destroy container.delete(force: true) instance.destroy rescue ::Docker::Error::NotFoundError => e puts e.message end
exec(command)
click to toggle source
# File lib/linecook-gem/baker/docker.rb, line 70 def exec(command) command = ['/bin/bash', '-c', command] container.exec(command, tty: true) end
inherit(image)
click to toggle source
# File lib/linecook-gem/baker/docker.rb, line 75 def inherit(image) puts "Inheriting from #{image.id}..." import(image) unless image_exists?(image) @inherited = image end
instance()
click to toggle source
# File lib/linecook-gem/baker/docker.rb, line 39 def instance @instance ||= @config.instances.find {|x| @image.name == x.suite.name } end
save()
click to toggle source
# File lib/linecook-gem/baker/docker.rb, line 27 def save FileUtils.mkdir_p(File.dirname(@image.path)) with_retries(5) do # You might be wondering "wtf is this"? And how! # tl;dr, we want to take the bitwise OR of the return codes for everything in the pipe. # so, if any command in the pipe fails, treat the whole pipe to have failed. # otherwise, we could end up with xz compressing an invalid export, and treating it as OK. status = system("/bin/bash -c 'docker export #{@image.id} | xz -T 0 -0 > #{@image.path}; exit $((${PIPESTATUS[0]} | ${PIPESTATUS[1]}))'") fail "Export failed" unless status end end
Private Instance Methods
container()
click to toggle source
# File lib/linecook-gem/baker/docker.rb, line 83 def container @container ||= ::Docker::Container::get(@image.id) end
image_exists?(image)
click to toggle source
# File lib/linecook-gem/baker/docker.rb, line 87 def image_exists?(image) images=`docker images --format "{{.Repository}}:{{.Tag}}"`.lines.map(&:strip) images.include?("#{image.group}:#{image.tag}") end
import(image)
click to toggle source
# File lib/linecook-gem/baker/docker.rb, line 92 def import(image) lock("import_#{image.id}") if image_exists?(image) puts "Image #{image.id} has already been imported" else puts "Importing #{image.id}..." image.fetch open(image.path) do |io| ::Docker::Image.import_stream(repo: image.group, tag: image.tag, changes: ['CMD ["/sbin/init"]']) do io.read(Excon.defaults[:chunk_size] * 10 ) || "" end end end ensure unlock("import_#{image.id}") end
munge_config()
click to toggle source
May the gods forgive us for all the rules this breaks
# File lib/linecook-gem/baker/docker.rb, line 111 def munge_config @data = @config.send(:data).instance_variable_get(:@data) @data[:driver][:instance_name] = @image.id suite = @data[:suites].find{ |n| n[:name] == @image.name } if suite && suite[:inherit] inherited = Linecook::Image.new(suite[:inherit][:name], suite[:inherit][:group], suite[:inherit][:tag]) inherit(inherited) @data[:driver][:image] = "#{inherited.group}:#{inherited.tag}" @data[:driver][:provision_command] ||= [] @data[:driver][:provision_command] << 'sed -i \'s/\(PasswordAuthentication no\)/#\1/g\' /etc/ssh/sshd_config' end end