vagrant/plugins/provisioners/docker/client.rb

134 lines
3.9 KiB
Ruby
Raw Normal View History

require 'digest/sha1'
module VagrantPlugins
module DockerProvisioner
class Client
def initialize(machine)
@machine = machine
end
def build_images(images)
@machine.communicate.tap do |comm|
images.each do |path, opts|
@machine.ui.info(I18n.t("vagrant.docker_building_single", path: path))
comm.sudo("docker build #{opts[:args]} #{path}") do |type, data|
handle_comm(type, data)
end
end
end
end
def pull_images(*images)
@machine.communicate.tap do |comm|
images.each do |image|
@machine.ui.info(I18n.t("vagrant.docker_pulling_single", name: image))
comm.sudo("docker pull #{image}") do |type, data|
handle_comm(type, data)
end
end
end
end
def start_service
if !daemon_running? && @machine.guest.capability?(:docker_start_service)
@machine.guest.capability(:docker_start_service)
end
end
def daemon_running?
@machine.guest.capability(:docker_daemon_running)
end
def run(containers)
containers.each do |name, config|
cids_dir = "/var/lib/vagrant/cids"
config[:cidfile] ||= "#{cids_dir}/#{Digest::SHA1.hexdigest name}"
@machine.ui.info(I18n.t("vagrant.docker_running", name: name))
@machine.communicate.sudo("mkdir -p #{cids_dir}")
run_container({
name: name,
original_name: name,
}.merge(config))
end
end
def run_container(config)
2013-12-03 22:36:14 +00:00
raise "Container's cidfile was not provided!" if !config[:cidfile]
id = "$(cat #{config[:cidfile]})"
if container_exists?(id)
start_container(id)
else
create_container(config)
end
end
def container_exists?(id)
lookup_container(id, true)
end
def start_container(id)
2013-12-03 22:36:14 +00:00
if !container_running?(id)
@machine.communicate.sudo("docker start #{id}")
end
end
def container_running?(id)
lookup_container(id)
end
def create_container(config)
name = config[:name]
# If the name is the automatically assigned name, then
# replace the "/" with "-" because "/" is not a valid
# character for a docker container name.
name = name.gsub("/", "-") if name == config[:original_name]
2014-03-30 05:49:52 +00:00
args = "--cidfile=#{config[:cidfile]} "
args << "-d " if config[:daemonize]
args << "--name #{name} " if name && config[:auto_assign_name]
args << config[:args] if config[:args]
@machine.communicate.sudo %[
rm -f #{config[:cidfile]}
2014-03-03 15:30:42 +00:00
docker run #{args} #{config[:image]} #{config[:cmd]}
]
end
def lookup_container(id, list_all = false)
docker_ps = "sudo docker ps -q"
docker_ps << " -a" if list_all
@machine.communicate.tap do |comm|
# Docker < 0.7.0 stores container IDs using its short version while
# recent versions use the full container ID
# See https://github.com/dotcloud/docker/pull/2140 for more information
return comm.test("#{docker_ps} | grep -wFq #{id}") ||
comm.test("#{docker_ps} -notrunc | grep -wFq #{id}")
end
end
protected
# This handles outputting the communication data back to the UI
def handle_comm(type, data)
if [:stderr, :stdout].include?(type)
# Output the data with the proper color based on the stream.
color = type == :stdout ? :green : :red
# Clear out the newline since we add one
data = data.chomp
return if data.empty?
options = {}
#options[:color] = color if !config.keep_color
@machine.ui.info(data.chomp, options)
end
end
end
end
end