class Luban::Deployment::Application::Dockerizer

Constants

DefaultRevisionSize

Attributes

build[R]

Public Instance Methods

build_application() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 87
def build_application
  if built?
    update_result "Skipped! ALREADY built #{build[:image_tag]}.", status: :skipped
    return
  end
  output = compose_application!

  if built?
    update_result "Successfully built #{build[:image_tag]}."
  else
    update_result "FAILED to build #{build[:image_tag]}: #{output}.", 
                  status: :failed, level: :error
  end
end
built?() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 83
def built?
  !(build[:image_id] = get_image_id).empty?
end
default_docker_tcp_port() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 17
def default_docker_tcp_port; docker_tls_verify? ? "2376" : "2375"; end
default_docker_templates_path() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 13
def default_docker_templates_path
  task.opts.default_docker_templates_path
end
distribute_application() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 106
def distribute_application
  if distributed?
    update_result "Skipped! ALREADY distributed #{build[:image_tag]}.", status: :skipped
    return
  end
  output = distribute_application!

  if distributed?
    update_result "Successfully distributed #{build[:image_tag]}."
  else
    update_result "FAILED to distribute #{build[:image_tag]}: #{output}", 
                  status: :failed, level: :error
  end
end
distributed?() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 102
def distributed?
  build[:image_id] == get_image_id(docker_options)
end
docker_ca_cert_path() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 23
def docker_ca_cert_path; docker_cert_path.join("ca.pem"); end
docker_client_cert_path() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 24
def docker_client_cert_path; docker_cert_path.join("cert.pem"); end
docker_host() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 32
def docker_host
  unix_socket = host[:docker_unix_socket] || docker_unix_socket
  if unix_socket.nil?
    tcp_port = host[:docker_tcp_port] || docker_tcp_port || default_docker_tcp_port
    "tcp://#{hostname}:#{tcp_port}"
  else
    "unix://#{unix_socket}"
  end
end
docker_options() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 42
def docker_options
  @docker_options ||= ["-H #{docker_host}"].concat(docker_tls_verify? ? tls_options : [])
end
docker_templates_path() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 9
def docker_templates_path
  task.opts.docker_templates_path
end
docker_tls_verify?() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 19
def docker_tls_verify?; 
  host[:docker_tls_verify].nil? ? docker_tls_verify : host[:docker_tls_verify]
end
dockerize_application() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 65
def dockerize_application
  rmdir(build[:path]) if force?
  dockerize_application!
  case build[:status]
  when :succeeded
    update_result "Successfully dockerized #{build[:image_tag]}."
  when :skipped
    update_result "Skipped! ALREADY dockerized #{build[:image_tag]}.", status: :skipped
  else
    update_result "FAILED to dockerize #{build[:image_tag]}.", status: :failed, level: :error
  end
  update_result build: build
end
get_image_id(docker_options = []) click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 79
def get_image_id(docker_options = [])
  capture(:docker, docker_options.join(' '), :images, "-q", build[:image_tag])
end
init_docker() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 50
def init_docker
  puts "  Initializing #{application_name} docker profile"
  docker_templates.each do |path|
    print "    - #{path}"
    src_path = default_docker_templates_path.join(path)
    dst_path = docker_templates_path.join(path)
    if file?(dst_path)
      puts "  [skipped]"
    else
      upload!(src_path, dst_path)
      puts "  [created]"
    end
  end
end
revision_size() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 46
def revision_size
  task.opts.revision_size || DefaultRevisionSize
end
tls_key_path() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 25
def tls_key_path; docker_cert_path.join("key.pem"); end
tls_options() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 27
def tls_options
  ["--tlsverify", "--tlscacert #{docker_ca_cert_path}",
   "--tlscert #{docker_client_cert_path}", "--tlskey #{tls_key_path}"]
end

Protected Instance Methods

archive_file_extname() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 182
def archive_file_extname; "tar.xz"; end
archive_file_name(name) click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 178
def archive_file_name(name)
  "#{project}-#{application}-#{name}.#{archive_file_extname}"
end
archive_file_path(name) click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 184
def archive_file_path(name)
  build[:context].join(archive_file_name(name))
end
build_path() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 188
def build_path; docker_path.join("build-#{stage}-#{build_tag}"); end
cleanup_archive!(name) click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 244
def cleanup_archive!(name)
  cleanup_files(archive_file_path("#{name.to_s.gsub(/-\h+$/, '')}-*"))
end
compose_application!() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 278
def compose_application!
  within build[:path] { capture(:"docker-compose", :build, "2>&1") }
end
compose_env_file() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 193
def compose_env_file; build[:path].join(".env"); end
compose_file() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 192
def compose_file; build[:path].join("docker-compose.yml"); end
compose_revision() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 165
def compose_revision
  require 'digest/md5'
  revisions = build[:sources].inject('') { |r, (_, src)| r += src[:md5] }
  Digest::MD5.hexdigest(revisions)[0, revision_size]
end
context_path() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 189
def context_path; build_path.join('context'); end
distribute_application!() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 282
def distribute_application!
  capture(:docker, :save, build[:image_tag], "|", 
          :docker, docker_options.join(' '), "load", "2>&1")
end
docker_templates(format: "erb") click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 291
def docker_templates(format: "erb")
  @docker_templates ||= 
    if default_docker_templates_path.directory?
      Dir.chdir(default_docker_templates_path) { Dir["**/*.#{format}"] }
    else
      []
    end
end
dockerfile() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 191
def dockerfile; build[:context].join("Dockerfile"); end
dockerize_application!() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 213
def dockerize_application!
  assure_dirs(build[:context])
  package_application!
  render_dockerfile
  render_compose_env_file
  render_compose_file
  build[:status] = status
end
get_packages() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 201
def get_packages
  packages.inject({}) do |pkgs, (name, package)|
    pkgs[name] = package.class.required_packages_for(package.current_version).inject(
                  { versions: package.installable_versions.join(', '),
                    current_version: package.current_version }) do |pkg, (type, deps)|
                  deps.each { |d| pkg["#{type}.#{d.name}".to_sym] = d.version }
                  pkg
                end
    pkgs
  end
end
get_releases(path, type:) click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 195
def get_releases(path, type:)
  capture(:ls, '-xtd', path.join('*')).split.
    collect { |p| File.basename(p) }.
    inject({}) { |r, t| r["#{type}.#{t}".to_sym] = path.join(t); r }
end
image_tag(revision) click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 190
def image_tag(revision); "#{project}-#{application}-#{stage}:#{build_tag}-#{revision}"; end
init() click to toggle source
Calls superclass method
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 123
def init
  super
  @build = task.opts.build || init_build
end
init_build() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 128
def init_build
  (@build = {}).tap do |b|
    b[:path] = build_path
    b[:context] = context_path
    b[:dockerfile] = dockerfile
    b[:compose_file] = compose_file
    b[:compose_env_file] = compose_env_file
    b[:sources] = init_build_sources
    b[:archives] = init_build_archives
    b[:revision] = compose_revision
    b[:image_tag] = image_tag(b[:revision])
  end
end
init_build_archives() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 171
def init_build_archives
  build[:sources].each_key.inject(build[:archives] = {}) do |archives, name|
    archives[name] = { path: archive_file_path("#{name}-#{build[:sources][name][:tag]}") }
    archives
  end
end
init_build_sources() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 142
def init_build_sources
  # Init packages
  sources = { packages: packages_path }
  # Init releases
  releases = get_releases(releases_path, type: 'app')
  if releases.has_key?(:"app.bundler")
    sources[:"app.bundler"] = releases.delete(:"app.bundler")
  end
  sources.merge!(releases)
  # Init profile
  profile_path = releases_path.dirname.join('profile')
  profile = directory?(profile_path) ? get_releases(profile_path, type: 'profile') : {}
  sources.merge!(profile)
  # Init environment
  sources["env.#{stage}".to_sym] = app_path

  sources.inject({}) do |srcs, (name, path)|
    md5 = md5_for_dir(path)
    srcs[name] = { path: path, md5: md5, tag: md5[0, revision_size] }
    srcs
  end
end
package_application!() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 222
def package_application!
  changed = false
  env_archive = "env.#{stage}".to_sym
  build[:archives].each_key do |name|
    changed = true if name != env_archive and package_archive!(name) == :succeeded
  end
  package_archive!(env_archive, force: changed)
end
package_archive!(name, force: false) click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 231
def package_archive!(name, force: false)
  source = build[:sources][name]
  archive = build[:archives][name]
  archive[:status] = 
    if !force and file?(archive[:path]) and archive[:path].basename.to_s =~ /#{source[:tag]}/
      :skipped
    else
      execute(:tar, "-cJf", archive[:path], source[:path]) ? :succeeded : :failed
    end.tap do |status| 
      cleanup_archive!(name) unless status == :failed
    end
end
remove_image!(docker_options = [], image_id) click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 287
def remove_image!(docker_options = [], image_id)
  execute(:docker, docker_options.join(' '), :rmi, image_id, "2>/dev/null")
end
render_compose_env_file() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 254
def render_compose_env_file
  upload_by_template(file_to_upload: build[:compose_env_file],
                     template_file: find_template_file('docker-compose-env.erb'),
                     auto_revision: true)
end
render_compose_file() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 260
def render_compose_file
  upload_by_template(file_to_upload: build[:compose_file],
                     template_file: find_template_file('docker-compose.yml.erb'),
                     auto_revision: true)
end
render_dockerfile() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 248
def render_dockerfile
  upload_by_template(file_to_upload: build[:dockerfile],
                     template_file: find_template_file("Dockerfile.#{base_os}.erb"),
                     auto_revision: true)
end
status() click to toggle source
# File lib/luban/deployment/cli/application/docker/dockerizer.rb, line 266
def status
  build[:archives].each_value.inject(:skipped) do |status, archive|
    if archive[:status] == :failed
      status = :failed; break
    end
    if archive[:status] == :succeeded
      status = :succeeded 
    end
    status
  end
end