class Dockage::Docker::Shell

Constants

DOCKER_DEFAULT_HOST

Public Class Methods

new() click to toggle source
# File lib/dockage/docker/shell.rb, line 7
def initialize
  @env = "export DOCKER_HOST=#{Dockage.settings[:docker_host] || DOCKER_DEFAULT_HOST}"
end

Public Instance Methods

build() click to toggle source
# File lib/dockage/docker/shell.rb, line 51
def build
  invoke('build', attach_std: true)
end
container_exists?(name) click to toggle source
# File lib/dockage/docker/shell.rb, line 114
def container_exists?(name)
  ps(name, true).any?
end
container_running?(name) click to toggle source
# File lib/dockage/docker/shell.rb, line 110
def container_running?(name)
  ps(name).any?
end
destroy(name) click to toggle source
# File lib/dockage/docker/shell.rb, line 32
def destroy(name)
  unless container_exists?(name)
    Dockage.logger("Container #{name.bold.yellow} not found")
    return
  end
  Dockage.logger("Destroying container #{name.bold.yellow}")
  invoke("rm #{name}", catch_errors: false)
end
provide(container) click to toggle source
# File lib/dockage/docker/shell.rb, line 41
def provide(container)
  raise SSHOptionsError unless container[:ssh]
  unless container_running?(container[:name])
    Dockage.error("Container #{container[:name].bold.yellow} is not running")
  end
  container[:provision].each do |provision|
    SSH.execute(provision, container[:ssh])
  end
end
ps(name = nil, all = false) click to toggle source
# File lib/dockage/docker/shell.rb, line 55
def ps(name = nil, all = false)
  ps_output = invoke("ps --no-trunc #{all && '-a '}", attach_std: false).split(/\n/)
  containers = Parse.parse_docker_ps(ps_output)
  containers.reject! { |con| con[:name] != name } if name
  containers
end
pull(image) click to toggle source
# File lib/dockage/docker/shell.rb, line 11
def pull(image)
  invoke("pull #{image}", attach_std: true)
end
reload(container) click to toggle source
# File lib/dockage/docker/shell.rb, line 74
def reload(container)
  return unless dependences_satisfied?(container)
  stop(container[:name]) if container_running?(container[:name])
  destroy(container[:name]) if container_exists?(container[:name])
  up(container)
end
run(image, opts = {}) click to toggle source
# File lib/dockage/docker/shell.rb, line 118
def run(image, opts = {})
  command = "run" \
    "#{opts[:detach]  == false || ' -d'}" \
    "#{opts[:links]   && opts[:links].map { |link| " --link #{link}" }.join}" \
    "#{opts[:volumes] && opts[:volumes].map { |volume| " -v #{volume}" }.join}" \
    "#{opts[:ports]   && opts[:ports].map { |port| " -p #{port}" }.join}" \
    "#{opts[:name]    && " --name #{opts[:name]}"}" \
    " #{image}" \
    "#{opts[:cmd]     && " /bin/sh -c '#{opts[:cmd]}'"}"
  invoke(command)
end
shellinit() click to toggle source
# File lib/dockage/docker/shell.rb, line 106
def shellinit
  "export #{@env}"
end
start(name) click to toggle source
# File lib/dockage/docker/shell.rb, line 15
def start(name)
  if container_running?(name)
    Dockage.logger("Container #{name.bold.yellow} is already running")
    return
  end
  invoke("start #{name}", catch_errors: true)
end
status(name = nil) click to toggle source
# File lib/dockage/docker/shell.rb, line 81
def status(name = nil)
  output = ''

  containers = Dockage.settings[:containers]
  containers = containers.select { |con| con[:name] == name } if name

  active_containers = ps(name, true)
  containers.each do |container|
    output += "#{container[:name].to_s.bold.yellow} is "
    docker_container = active_containers.select { |con| con[:name] == container[:name] }.first
    if docker_container
      output += docker_container[:running] ? 'running'.green : 'not running'.red
    else
      output += 'not exists'.red
    end
    output += "\n"
  end

  output
end
stop(name) click to toggle source
# File lib/dockage/docker/shell.rb, line 23
def stop(name)
  unless container_running?(name)
    Dockage.logger("Container #{name.bold.yellow} is not running. Nothing to do")
    return
  end
  Dockage.logger("Stopping container #{name.bold.yellow}")
  invoke("stop #{name}", catch_errors: true)
end
up(container) click to toggle source
# File lib/dockage/docker/shell.rb, line 62
def up(container)
  Dockage.logger("Bringing up #{container[:name].yellow.bold}")
  return reload(container) if should_be_reload?(container)
  if container_running?(container[:name])
    Dockage.logger("Container #{container[:name].bold} is already up. Nothing to do")
    return
  end
  return start(container[:name]) if container_exists?(container[:name])
  pull(container[:image]) if container[:keep_fresh]
  run(container[:image], container)
end
version() click to toggle source
# File lib/dockage/docker/shell.rb, line 102
def version
  invoke('version')
end

Private Instance Methods

dependences_satisfied?(container) click to toggle source
# File lib/dockage/docker/shell.rb, line 132
def dependences_satisfied?(container)
  return true unless container[:links] && container[:links].any?
  active_containers = ps
  container[:links].each do |link|
    dependency_name = link.split(':').first
    next if active_containers.select { |con| con[:name] == dependency_name }.any?
    dependency_container = Dockage.settings.containers.select { |con| con[:name] == dependency_name }.first
    unless dependency_container
      Dockage.error("#{dependency_name.bold} is required for " \
                   "#{container[:name]} but does not specified " \
                   "in config file")
    end
    up(dependency_container)
  end
end
invoke(cmd, opts = {}) click to toggle source
# File lib/dockage/docker/shell.rb, line 163
def invoke(cmd, opts = {})
  command = "#{@env} && docker #{cmd}"
  Dockage.verbose(command)
  if opts[:attach_std]
    output = sys_exec(command, opts[:catch_errors])
  else
    output = `#{command}`
  end
  Dockage.debug(output)
  output
end
should_be_reload?(container) click to toggle source
# File lib/dockage/docker/shell.rb, line 148
def should_be_reload?(container)
  return false unless container[:links]
  containers = ps(nil, true)
  return false unless containers.select { |con| con[:name] == container[:name] }.any?
  links = container[:links].map { |link| link.split(':').first }
  dependency_containers = containers.select { |con| links.include?(con[:name]) }
  dependency_containers.each do |dep_con|
    unless dep_con[:linked_with].include?(container[:name])
      Dockage.logger("Container #{container[:name].bold} has missing links and should be reloaded")
      return true
    end
  end
  false
end
sys_exec(cmd, catch_errors = true) click to toggle source
# File lib/dockage/docker/shell.rb, line 175
def sys_exec(cmd, catch_errors = true)
  Open3.popen3(cmd.to_s) do |stdin, stdout, stderr|
    @in, @out, @err = stdin, stdout.gets, stderr.gets
    @in.close
    Dockage.verbose(@out.strip) if @out && !@out.empty?
    if @err && !@err.strip.empty?
      puts @err.strip.red
      @ruined = true
    end
  end
  exit 1 if catch_errors && @ruined
end