Merge pull request #8722 from briancain/add-post-setup-proc-for-docker
Add post-install provisioner to docker provisioner
This commit is contained in:
commit
0225d63055
|
@ -4,9 +4,11 @@ module VagrantPlugins
|
||||||
module DockerProvisioner
|
module DockerProvisioner
|
||||||
class Config < Vagrant.plugin("2", :config)
|
class Config < Vagrant.plugin("2", :config)
|
||||||
attr_reader :images
|
attr_reader :images
|
||||||
|
attr_accessor :post_install_provisioner
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@images = Set.new
|
@images = Set.new
|
||||||
|
@post_install_provisioner = nil
|
||||||
|
|
||||||
@__build_images = []
|
@__build_images = []
|
||||||
@__containers = Hash.new { |h, k| h[k] = {} }
|
@__containers = Hash.new { |h, k| h[k] = {} }
|
||||||
|
@ -38,6 +40,15 @@ module VagrantPlugins
|
||||||
@images += images.map(&:to_s)
|
@images += images.map(&:to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def post_install_provision(name, **options, &block)
|
||||||
|
# Abort
|
||||||
|
raise DockerError, :wrong_provisioner if options[:type] == "docker"
|
||||||
|
|
||||||
|
proxy = VagrantPlugins::Kernel_V2::VMConfig.new
|
||||||
|
proxy.provision(name, **options, &block)
|
||||||
|
@post_install_provisioner = proxy.provisioners.first
|
||||||
|
end
|
||||||
|
|
||||||
def run(name, **options)
|
def run(name, **options)
|
||||||
@__containers[name.to_s] = options.dup
|
@__containers[name.to_s] = options.dup
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,10 +8,12 @@ module VagrantPlugins
|
||||||
# This handles verifying the Docker installation, installing it if it was
|
# This handles verifying the Docker installation, installing it if it was
|
||||||
# requested, and so on. This method will raise exceptions if things are
|
# requested, and so on. This method will raise exceptions if things are
|
||||||
# wrong.
|
# wrong.
|
||||||
|
# @return [Boolean] - false if docker cannot be detected on machine, else
|
||||||
|
# true if docker installs correctly or is installed
|
||||||
def ensure_installed
|
def ensure_installed
|
||||||
if !@machine.guest.capability?(:docker_installed)
|
if !@machine.guest.capability?(:docker_installed)
|
||||||
@machine.ui.warn(I18n.t("vagrant.docker_cant_detect"))
|
@machine.ui.warn(I18n.t("vagrant.docker_cant_detect"))
|
||||||
return
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
if !@machine.guest.capability(:docker_installed)
|
if !@machine.guest.capability(:docker_installed)
|
||||||
|
@ -26,6 +28,8 @@ module VagrantPlugins
|
||||||
if @machine.guest.capability?(:docker_configure_vagrant_user)
|
if @machine.guest.capability?(:docker_configure_vagrant_user)
|
||||||
@machine.guest.capability(:docker_configure_vagrant_user)
|
@machine.guest.capability(:docker_configure_vagrant_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,7 +19,16 @@ module VagrantPlugins
|
||||||
@logger = Log4r::Logger.new("vagrant::provisioners::docker")
|
@logger = Log4r::Logger.new("vagrant::provisioners::docker")
|
||||||
|
|
||||||
@logger.info("Checking for Docker installation...")
|
@logger.info("Checking for Docker installation...")
|
||||||
@installer.ensure_installed
|
if @installer.ensure_installed
|
||||||
|
if !config.post_install_provisioner.nil?
|
||||||
|
@logger.info("Running post setup provision script...")
|
||||||
|
env = {
|
||||||
|
callable: method(:run_provisioner),
|
||||||
|
provisioner: config.post_install_provisioner,
|
||||||
|
machine: machine}
|
||||||
|
machine.env.hook(:run_provisioner, env)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Attempt to start service if not running
|
# Attempt to start service if not running
|
||||||
@client.start_service
|
@client.start_service
|
||||||
|
@ -40,6 +49,14 @@ module VagrantPlugins
|
||||||
@client.run(config.containers)
|
@client.run(config.containers)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def run_provisioner(env)
|
||||||
|
klass = Vagrant.plugin("2").manager.provisioners[env[:provisioner].type]
|
||||||
|
result = klass.new(env[:machine], env[:provisioner].config)
|
||||||
|
result.config.finalize!
|
||||||
|
|
||||||
|
result.provision
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2361,6 +2361,9 @@ en:
|
||||||
Please check https://docs.ansible.com/intro_installation.html#control-machine-requirements
|
Please check https://docs.ansible.com/intro_installation.html#control-machine-requirements
|
||||||
|
|
||||||
docker:
|
docker:
|
||||||
|
wrong_provisioner: |-
|
||||||
|
The Docker post-install provisioner cannot also take a Docker post-install
|
||||||
|
provisioner
|
||||||
not_running: "Docker is not running on the guest VM."
|
not_running: "Docker is not running on the guest VM."
|
||||||
install_failed: "Docker installation failed."
|
install_failed: "Docker installation failed."
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
require File.expand_path("../../../../base", __FILE__)
|
require File.expand_path("../../../../base", __FILE__)
|
||||||
|
|
||||||
require Vagrant.source_root.join("plugins/provisioners/docker/config")
|
require Vagrant.source_root.join("plugins/provisioners/docker/config")
|
||||||
|
require Vagrant.source_root.join("plugins/kernel_v2/config/vm")
|
||||||
|
|
||||||
describe VagrantPlugins::DockerProvisioner::Config do
|
describe VagrantPlugins::DockerProvisioner::Config do
|
||||||
subject { described_class.new }
|
subject { described_class.new }
|
||||||
|
@ -137,4 +138,25 @@ describe VagrantPlugins::DockerProvisioner::Config do
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "#post_install_provision" do
|
||||||
|
it "raises an error if 'docker' provisioner was provided" do
|
||||||
|
expect {subject.post_install_provision("myprov", :type=>"docker", :inline=>"echo 'hello'")}
|
||||||
|
.to raise_error()
|
||||||
|
end
|
||||||
|
|
||||||
|
it "setups a basic provisioner" do
|
||||||
|
prov = double()
|
||||||
|
mock_provisioner = "mock"
|
||||||
|
mock_provisioners = [mock_provisioner]
|
||||||
|
|
||||||
|
allow(VagrantPlugins::Kernel_V2::VMConfig).to receive(:new).
|
||||||
|
and_return(prov)
|
||||||
|
allow(prov).to receive(:provision).and_return(mock_provisioners)
|
||||||
|
allow(prov).to receive(:provisioners).and_return(mock_provisioners)
|
||||||
|
|
||||||
|
subject.post_install_provision("myprov", :inline=>"echo 'hello'")
|
||||||
|
expect(subject.post_install_provisioner).to eq(mock_provisioner)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
require File.expand_path("../../../../base", __FILE__)
|
||||||
|
|
||||||
|
require Vagrant.source_root.join("plugins/provisioners/docker/provisioner")
|
||||||
|
|
||||||
|
describe VagrantPlugins::DockerProvisioner::Provisioner do
|
||||||
|
include_context "unit"
|
||||||
|
subject { described_class.new(machine, config, installer, client) }
|
||||||
|
|
||||||
|
let(:iso_env) do
|
||||||
|
# We have to create a Vagrantfile so there is a root path
|
||||||
|
env = isolated_environment
|
||||||
|
env.vagrantfile("")
|
||||||
|
env.create_vagrant_env
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:machine) { iso_env.machine(iso_env.machine_names[0], :dummy) }
|
||||||
|
let(:config) { double("config") }
|
||||||
|
let(:communicator) { double("comm") }
|
||||||
|
let(:guest) { double("guest") }
|
||||||
|
let(:client) { double("client") }
|
||||||
|
let(:installer) { double("installer") }
|
||||||
|
let(:hook) { double("hook") }
|
||||||
|
|
||||||
|
before do
|
||||||
|
machine.stub(communicate: communicator)
|
||||||
|
machine.stub(guest: guest)
|
||||||
|
|
||||||
|
communicator.stub(execute: true)
|
||||||
|
communicator.stub(upload: true)
|
||||||
|
|
||||||
|
guest.stub(capability?: false)
|
||||||
|
guest.stub(capability: false)
|
||||||
|
|
||||||
|
client.stub(start_service: true)
|
||||||
|
client.stub(daemon_running?: true)
|
||||||
|
|
||||||
|
config.stub(images: Set.new)
|
||||||
|
config.stub(build_images: Set.new)
|
||||||
|
config.stub(containers: Hash.new)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#provision" do
|
||||||
|
let(:provisioner) do
|
||||||
|
prov = VagrantPlugins::Kernel_V2::VagrantConfigProvisioner.new("spec-test", :shell)
|
||||||
|
prov.config = {}
|
||||||
|
prov
|
||||||
|
end
|
||||||
|
|
||||||
|
it "invokes a post_install_provisioner if defined and docker is installed" do
|
||||||
|
installer.stub(ensure_installed: true)
|
||||||
|
allow(config).to receive(:post_install_provisioner).and_return(provisioner)
|
||||||
|
allow(machine).to receive(:env).and_return(iso_env)
|
||||||
|
allow(machine.env).to receive(:hook).and_return(true)
|
||||||
|
|
||||||
|
expect(machine.env).to receive(:hook).with(:run_provisioner, anything)
|
||||||
|
subject.provision()
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not invoke post_install_provisioner if not defined" do
|
||||||
|
installer.stub(ensure_installed: true)
|
||||||
|
allow(config).to receive(:post_install_provisioner).and_return(nil)
|
||||||
|
allow(machine).to receive(:env).and_return(iso_env)
|
||||||
|
allow(machine.env).to receive(:hook).and_return(true)
|
||||||
|
|
||||||
|
expect(machine.env).not_to receive(:hook).with(:run_provisioner, anything)
|
||||||
|
subject.provision()
|
||||||
|
end
|
||||||
|
|
||||||
|
it "raises an error if docker daemon isn't running" do
|
||||||
|
allow(installer).to receive(:ensure_installed).and_return(false)
|
||||||
|
allow(client).to receive(:start_service).and_return(false)
|
||||||
|
allow(client).to receive(:daemon_running?).and_return(false)
|
||||||
|
|
||||||
|
expect { subject.provision() }.
|
||||||
|
to raise_error(VagrantPlugins::DockerProvisioner::DockerError)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -53,6 +53,9 @@ of these functions have examples in more detailed sections below.
|
||||||
|
|
||||||
* `pull_images` - Pull the given images. This does not start these images.
|
* `pull_images` - Pull the given images. This does not start these images.
|
||||||
|
|
||||||
|
* `post_install_provisioner` - A [provisioner block](/docs/provisioning) that runs post docker
|
||||||
|
installation.
|
||||||
|
|
||||||
* `run` - Run a container and configure it to start on boot. This can
|
* `run` - Run a container and configure it to start on boot. This can
|
||||||
only be specified once.
|
only be specified once.
|
||||||
|
|
||||||
|
@ -191,6 +194,15 @@ that are generally useful to know if you are using this provisioner.
|
||||||
|
|
||||||
### Customize `/etc/default/docker`
|
### Customize `/etc/default/docker`
|
||||||
|
|
||||||
To customize this file, use a shell provisioner before the Docker provisioner
|
To customize this file, use the `post_install_provisioner` shell provisioner.
|
||||||
that sets this file up. The Docker provisioner will not modify this file
|
|
||||||
in a destructive way.
|
```ruby
|
||||||
|
Vagrant.configure("2") do |config|
|
||||||
|
config.vm.provision "docker" do |d|
|
||||||
|
d.post_install_provision "shell", inline:"echo export http_proxy='http://127.0.0.1:3128/' >> /etc/default/docker"
|
||||||
|
d.run "ubuntu",
|
||||||
|
cmd: "bash -l",
|
||||||
|
args: "-v '/vagrant:/var/www'"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
Loading…
Reference in New Issue