provisioners: Import Docker provisioner code from Vocker
This commit is contained in:
parent
cfb258a55b
commit
0536817e90
|
@ -0,0 +1,15 @@
|
|||
module VagrantPlugins
|
||||
module Docker
|
||||
module Cap
|
||||
module Debian
|
||||
module DockerConfigureAutoStart
|
||||
def self.docker_configure_auto_start(machine)
|
||||
if ! machine.communicate.test('grep -q \'\-r=true\' /etc/init/docker.conf')
|
||||
machine.communicate.sudo("sed -i.bak 's/docker -d/docker -d -r=true/' /etc/init/docker.conf ")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,13 @@
|
|||
module VagrantPlugins
|
||||
module Docker
|
||||
module Cap
|
||||
module Debian
|
||||
module DockerConfigureVagrantUser
|
||||
def self.docker_configure_vagrant_user(machine)
|
||||
machine.communicate.sudo("usermod -a -G docker #{machine.config.ssh.username || "vagrant"}")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
module VagrantPlugins
|
||||
module Docker
|
||||
module Cap
|
||||
module Debian
|
||||
module DockerInstall
|
||||
def self.docker_install(machine, version)
|
||||
package = 'lxc-docker'
|
||||
package << "-#{version}" if version != :latest
|
||||
|
||||
machine.communicate.tap do |comm|
|
||||
# TODO: Perform check on the host machine if aufs is installed and using LXC
|
||||
if machine.provider_name != :lxc
|
||||
comm.sudo("lsmod | grep aufs || modprobe aufs || apt-get install -y linux-image-extra-`uname -r`")
|
||||
end
|
||||
comm.sudo("apt-get install -y --force-yes -q curl")
|
||||
comm.sudo("curl http://get.docker.io/gpg | apt-key add -")
|
||||
comm.sudo("echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list")
|
||||
comm.sudo("apt-get update")
|
||||
comm.sudo("apt-get install -y --force-yes -q xz-utils #{package} -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold'")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,13 @@
|
|||
module VagrantPlugins
|
||||
module Docker
|
||||
module Cap
|
||||
module Debian
|
||||
module DockerStartService
|
||||
def self.docker_start_service(machine)
|
||||
machine.communicate.sudo("service docker start")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,13 @@
|
|||
module VagrantPlugins
|
||||
module Docker
|
||||
module Cap
|
||||
module Linux
|
||||
module DockerInstalled
|
||||
def self.docker_installed(machine)
|
||||
machine.communicate.test("test -f /usr/bin/docker", sudo: true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,44 @@
|
|||
require 'set'
|
||||
|
||||
module VagrantPlugins
|
||||
module Docker
|
||||
class Config < Vagrant.plugin("2", :config)
|
||||
attr_reader :images, :containers
|
||||
attr_accessor :version
|
||||
|
||||
def initialize
|
||||
@images = Set.new
|
||||
@containers = Hash.new
|
||||
@version = :latest
|
||||
end
|
||||
|
||||
def pull_images(*images)
|
||||
@images += images.map(&:to_s)
|
||||
end
|
||||
|
||||
def run(*args)
|
||||
container_name = args.shift
|
||||
params = {}
|
||||
|
||||
if args.empty?
|
||||
params[:image] = container_name
|
||||
elsif args.first.is_a?(String)
|
||||
params[:image] = args.shift
|
||||
params[:cmd] = container_name
|
||||
else
|
||||
params = args.shift
|
||||
params[:cmd] ||= container_name
|
||||
end
|
||||
|
||||
# TODO: Validate provided parameters before assignment
|
||||
@containers[container_name.to_s] = params
|
||||
end
|
||||
|
||||
def merge(other)
|
||||
super.tap do |result|
|
||||
result.pull_images *(other.images + self.images)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,102 @@
|
|||
require 'digest/sha1'
|
||||
|
||||
module VagrantPlugins
|
||||
module Docker
|
||||
class DockerClient
|
||||
def initialize(machine)
|
||||
@machine = machine
|
||||
end
|
||||
|
||||
def pull_images(*images)
|
||||
@machine.communicate.tap do |comm|
|
||||
images.each do |image|
|
||||
comm.sudo("docker images | grep -q #{image} || docker pull #{image}")
|
||||
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.communicate.test('test -f /var/run/docker.pid')
|
||||
end
|
||||
|
||||
def run(containers)
|
||||
containers.each do |name, config|
|
||||
cids_dir = "/var/lib/vocker/cids"
|
||||
config[:cidfile] ||= "#{cids_dir}/#{Digest::SHA1.hexdigest name}"
|
||||
|
||||
@machine.communicate.sudo("mkdir -p #{cids_dir}")
|
||||
run_container({name: name}.merge config)
|
||||
end
|
||||
end
|
||||
|
||||
def run_container(config)
|
||||
raise "Container's cidfile was not provided!" unless config[:cidfile]
|
||||
|
||||
id = "$(cat #{config[:cidfile]})"
|
||||
|
||||
if container_exist?(id)
|
||||
start_container(id)
|
||||
else
|
||||
create_container(config)
|
||||
end
|
||||
end
|
||||
|
||||
def container_exist?(id)
|
||||
@machine.communicate.test("sudo docker ps -a -q | grep -q #{id}")
|
||||
end
|
||||
|
||||
def start_container(id)
|
||||
unless container_running?(id)
|
||||
@machine.communicate.sudo("docker start #{id}")
|
||||
end
|
||||
end
|
||||
|
||||
def container_running?(id)
|
||||
@machine.communicate.test("sudo docker ps -q | grep #{id}")
|
||||
end
|
||||
|
||||
def create_container(config)
|
||||
# DISCUSS: Does this really belong here?
|
||||
ensure_bind_mounts_exist(config)
|
||||
|
||||
args = "-cidfile=#{config[:cidfile]} -d "
|
||||
args << prepare_run_arguments(config)
|
||||
@machine.communicate.sudo %[
|
||||
rm -f #{config[:cidfile]}
|
||||
docker run #{args} #{config[:image]} #{config[:cmd]}
|
||||
]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def ensure_bind_mounts_exist(config)
|
||||
Array(config[:volumes]).each do |volume|
|
||||
if volume =~ /(.+):.+/
|
||||
guest_vm_path = $1
|
||||
@machine.communicate.sudo "mkdir -p #{guest_vm_path}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def prepare_run_arguments(config)
|
||||
args = []
|
||||
|
||||
args << "-dns=#{config[:dns]}" if config[:dns]
|
||||
args << "-name=#{config[:name]}" if config[:name]
|
||||
args << "#{config[:additional_run_args]}" if config[:additional_run_args]
|
||||
|
||||
args += Array(config[:volumes]).map { |volume| "-v #{volume}" }
|
||||
args += Array(config[:ports]).map { |port| "-p #{port}" }
|
||||
args += Array(config[:links]).map { |link| "-link #{link}" }
|
||||
|
||||
args.compact.flatten.join ' '
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,41 @@
|
|||
require_relative "errors"
|
||||
|
||||
module VagrantPlugins
|
||||
module Docker
|
||||
class DockerInstaller
|
||||
def initialize(machine, version)
|
||||
@machine = machine
|
||||
@version = version
|
||||
end
|
||||
|
||||
# This handles verifying the Docker installation, installing it if it was
|
||||
# requested, and so on. This method will raise exceptions if things are
|
||||
# wrong.
|
||||
def ensure_installed
|
||||
if !@machine.guest.capability?(:docker_installed)
|
||||
@machine.ui.warn(I18n.t("vagrant.docker_cant_detect"))
|
||||
return
|
||||
end
|
||||
|
||||
if !@machine.guest.capability(:docker_installed)
|
||||
@machine.ui.info(I18n.t("vagrant.docker_installing"))
|
||||
@machine.guest.capability(:docker_install, @version)
|
||||
|
||||
if !@machine.guest.capability(:docker_installed)
|
||||
raise Errors::DockerInstallFailed
|
||||
end
|
||||
end
|
||||
|
||||
if @machine.guest.capability?(:docker_configure_auto_start)
|
||||
@machine.guest.capability(:docker_configure_auto_start)
|
||||
else
|
||||
@machine.env.ui.warn I18n.t('vagrant.docker_auto_start_not_available')
|
||||
end
|
||||
|
||||
if @machine.guest.capability?(:docker_configure_vagrant_user)
|
||||
@machine.guest.capability(:docker_configure_vagrant_user)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
module VagrantPlugins
|
||||
module Docker
|
||||
module Errors
|
||||
class DockerInstallFailed < ::Vagrant::Errors::VagrantError
|
||||
end
|
||||
|
||||
class DockerNotRunning < ::Vagrant::Errors::VagrantError
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,48 @@
|
|||
require "vagrant"
|
||||
|
||||
module VagrantPlugins
|
||||
module Docker
|
||||
class Plugin < Vagrant.plugin("2")
|
||||
name "docker"
|
||||
description <<-DESC
|
||||
Provides support for provisioning your virtual machines with
|
||||
Docker images and containers.
|
||||
DESC
|
||||
|
||||
config(:docker, :provisioner) do
|
||||
require_relative "config"
|
||||
Config
|
||||
end
|
||||
|
||||
guest_capability("debian", "docker_install") do
|
||||
require_relative "cap/debian/docker_install"
|
||||
Cap::Debian::DockerInstall
|
||||
end
|
||||
|
||||
guest_capability("debian", "docker_configure_auto_start") do
|
||||
require_relative "cap/debian/docker_configure_auto_start"
|
||||
Cap::Debian::DockerConfigureAutoStart
|
||||
end
|
||||
|
||||
guest_capability("debian", "docker_configure_vagrant_user") do
|
||||
require_relative "cap/debian/docker_configure_vagrant_user"
|
||||
Cap::Debian::DockerConfigureVagrantUser
|
||||
end
|
||||
|
||||
guest_capability("debian", "docker_start_service") do
|
||||
require_relative "cap/debian/docker_start_service"
|
||||
Cap::Debian::DockerStartService
|
||||
end
|
||||
|
||||
guest_capability("linux", "docker_installed") do
|
||||
require_relative "cap/linux/docker_installed"
|
||||
Cap::Linux::DockerInstalled
|
||||
end
|
||||
|
||||
provisioner(:docker) do
|
||||
require_relative "provisioner"
|
||||
Provisioner
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,41 @@
|
|||
require_relative "errors"
|
||||
require_relative "docker_client"
|
||||
require_relative "docker_installer"
|
||||
|
||||
module VagrantPlugins
|
||||
module Docker
|
||||
# TODO: Improve handling of vagrant-lxc specifics (like checking for apparmor
|
||||
# profile stuff + autocorrection)
|
||||
class Provisioner < Vagrant.plugin("2", :provisioner)
|
||||
def initialize(machine, config, installer = nil, client = nil)
|
||||
super(machine, config)
|
||||
# TODO: Rename to installer / client (drop docker suffix)
|
||||
@installer = installer || DockerInstaller.new(@machine, config.version)
|
||||
@client = client || DockerClient.new(@machine)
|
||||
end
|
||||
|
||||
def provision
|
||||
@logger = Log4r::Logger.new("vagrant::provisioners::vocker")
|
||||
|
||||
@logger.info("Checking for Docker installation...")
|
||||
@installer.ensure_installed
|
||||
|
||||
# Attempt to start service if not running
|
||||
@client.start_service
|
||||
unless @client.daemon_running?
|
||||
raise Errors::DockerNotRunning
|
||||
end
|
||||
|
||||
if config.images.any?
|
||||
@machine.ui.info(I18n.t("vagrant.docker_pulling_images"))
|
||||
@client.pull_images(*config.images)
|
||||
end
|
||||
|
||||
if config.containers.any?
|
||||
@machine.ui.info(I18n.t("vagrant.docker_starting_containers"))
|
||||
@client.run(config.containers)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue