class Dockly::BuildCache::Docker

Attributes

image[RW]

Public Instance Methods

copy_output_dir(container) click to toggle source
# File lib/dockly/build_cache/docker.rb, line 71
def copy_output_dir(container)
  ensure_present! :output_dir
  file_path = File.join(tmp_dir,s3_object(hash_output))
  FileUtils.mkdir_p(File.dirname(file_path))
  file = File.open(file_path, 'w+b')
  container.wait(3600) # 1 hour max timeout
  debug 'Restarting the container to copy the cache\'s output'
  # Restart the container so we can copy its output
  container = container.commit.run('sleep 3600')
  container.archive_out(output_directory) { |chunk| file.write(chunk.to_s) }
  container.kill
  file.tap(&:rewind)
end
execute!() click to toggle source
Calls superclass method Dockly::BuildCache::Base#execute!
# File lib/dockly/build_cache/docker.rb, line 4
def execute!
  ensure_present! :image
  super
  image
end
hash_output() click to toggle source
# File lib/dockly/build_cache/docker.rb, line 85
def hash_output
  ensure_present! :image, :hash_command
  @hash_output ||= begin
    status, body, _ = run_command(hash_command)
    raise "Hash Command `#{hash_command}` failed to run" unless status.zero?
    body
  end
end
parameter_output(command) click to toggle source
# File lib/dockly/build_cache/docker.rb, line 94
def parameter_output(command)
  ensure_present! :image
  raise "Parameter Command tried to run but not found" unless parameter_commands.keys.include?(command)
  @parameter_commands[command] ||= begin
    status, body, _ = run_command(command)
    raise "Parameter Command `#{command}` failed to run" unless status.zero?
    body
  end
end
push_cache(version) click to toggle source
# File lib/dockly/build_cache/docker.rb, line 24
def push_cache(version)
  ensure_present! :output_dir
  if cache = pull_from_s3(version)
    debug "inserting to #{output_directory}"
    if safe_push_cache
      push_cache_safe(cache)
    else
      push_cache_with_volumes(cache)
    end
    debug "inserted cache into #{output_directory}"
    cache.close
  else
    info "could not find #{s3_object(version)}"
  end
end
push_cache_safe(cache) click to toggle source
# File lib/dockly/build_cache/docker.rb, line 40
def push_cache_safe(cache)
  container = image.run("mkdir -p #{File.dirname(output_directory)}")
  image_with_dir = container.tap(&:wait).commit
  self.image = image_with_dir.insert_local(
    'localPath' => cache.path,
    'outputPath' => File.dirname(output_directory)
  )
end
push_cache_with_volumes(cache) click to toggle source
# File lib/dockly/build_cache/docker.rb, line 49
def push_cache_with_volumes(cache)
  path = File.expand_path(cache.path)
  path_parent = File.dirname(path)
  tar_flags = keep_old_files ? '-xkf' : 'xf'
  container = ::Docker::Container.create(
    'Image' => image.id,
    'Cmd' => ['/bin/bash', '-c', [
        "mkdir -p #{File.dirname(output_directory)}",
        '&&',
        "tar #{tar_flags} #{File.join('/', 'host', path)} -C #{File.dirname(output_directory)}"
      ].join(' ')
    ],
    'Volumes' => {
      File.join('/', 'host', path_parent) => { path_parent => 'rw' }
    }
  )
  container.start('Binds' => ["#{path_parent}:#{File.join('/', 'host', path_parent)}"])
  result = container.wait['StatusCode']
  raise "Got bad status code when copying build cache: #{result}" unless result.zero?
  self.image = container.commit
end
run_build() click to toggle source
# File lib/dockly/build_cache/docker.rb, line 10
def run_build
  status, _, container = run_command(build_command)
  raise "Build Cache `#{build_command}` failed to run." unless status.zero?
  cache = copy_output_dir(container)
  debug "pushing #{output_directory} to s3"
  push_to_s3(cache)
  debug "pushed #{output_directory} to s3"
  cache.close
  debug "commiting the completed container with id: #{container.id}"
  image = self.image = container.commit
  debug "created image with id: #{image.id}"
  image
end
run_command(command) click to toggle source
# File lib/dockly/build_cache/docker.rb, line 104
def run_command(command)
  debug "running command `#{command}` on image #{image.id}"
  container = image.run(["/bin/bash", "-c", "cd #{command_directory} && #{command}"])
  debug "command running in container #{container.id}"
  status = container.wait(docker.timeout)['StatusCode']
  resp = container.streaming_logs(stdout: true, stderr: true)
  debug "`#{command}` returned the following output:"
  debug resp.strip
  debug "`#{command}` exited with status #{status}, resulting container id: #{container.id}"
  [status, resp.strip, container]
end