From 66a3b58c088420b3a9e742e47f5a9e5847f2dd03 Mon Sep 17 00:00:00 2001 From: sophia Date: Mon, 18 May 2020 14:10:42 -0400 Subject: [PATCH] Add provider capaiblity :has_communicator --- lib/vagrant/action.rb | 1 + lib/vagrant/action/builtin/has_provisioner.rb | 36 ++++++++++ plugins/kernel_v2/config/vm_provisioner.rb | 2 +- plugins/providers/docker/action.rb | 14 ---- .../docker/action/has_provisioner.rb | 26 -------- .../providers/docker/cap/has_communicator.rb | 11 ++++ plugins/providers/docker/plugin.rb | 5 ++ .../docker/action/has_provisioner_test.rb | 62 ----------------- .../action/builtin/has_provisioner_test.rb | 66 +++++++++++++++++++ 9 files changed, 120 insertions(+), 103 deletions(-) create mode 100644 lib/vagrant/action/builtin/has_provisioner.rb delete mode 100644 plugins/providers/docker/action/has_provisioner.rb create mode 100644 plugins/providers/docker/cap/has_communicator.rb delete mode 100644 test/unit/plugins/providers/docker/action/has_provisioner_test.rb create mode 100644 test/unit/vagrant/action/builtin/has_provisioner_test.rb diff --git a/lib/vagrant/action.rb b/lib/vagrant/action.rb index 31a910c04..77bc47cd9 100644 --- a/lib/vagrant/action.rb +++ b/lib/vagrant/action.rb @@ -24,6 +24,7 @@ module Vagrant autoload :HandleBox, "vagrant/action/builtin/handle_box" autoload :HandleBoxUrl, "vagrant/action/builtin/handle_box_url" autoload :HandleForwardedPortCollisions, "vagrant/action/builtin/handle_forwarded_port_collisions" + autoload :HasProvisioner, "vagrant/action/builtin/has_provisioner" autoload :IsEnvSet, "vagrant/action/builtin/is_env_set" autoload :IsState, "vagrant/action/builtin/is_state" autoload :Lock, "vagrant/action/builtin/lock" diff --git a/lib/vagrant/action/builtin/has_provisioner.rb b/lib/vagrant/action/builtin/has_provisioner.rb new file mode 100644 index 000000000..c58abe9b4 --- /dev/null +++ b/lib/vagrant/action/builtin/has_provisioner.rb @@ -0,0 +1,36 @@ +module Vagrant + module Action + module Builtin + # This middleware is used with Call to test if this machine + # has available provisioners + class HasProvisioner + def initialize(app, env) + @app = app + @logger = Log4r::Logger.new("vagrant::action::builtin::has_provisioner") + end + + def call(env) + machine = env[:machine] + + if machine.provider.capability?(:has_communicator) + has_communicator = machine.provider.capability(:has_communicator) + else + has_communicator = true + end + + env[:skip] = [] + if !has_communicator + machine.config.vm.provisioners.each do |p| + if p.communicator_required + env[:skip].push(p) + @logger.info("Skipping running provisioner #{p.name || 'no name'}, type: #{p.type}") + p.run = :never + end + end + end + @app.call(env) + end + end + end + end +end diff --git a/plugins/kernel_v2/config/vm_provisioner.rb b/plugins/kernel_v2/config/vm_provisioner.rb index b49280261..a99e143d0 100644 --- a/plugins/kernel_v2/config/vm_provisioner.rb +++ b/plugins/kernel_v2/config/vm_provisioner.rb @@ -75,7 +75,7 @@ module VagrantPlugins @type = type @before = options[:before] @after = options[:after] - @communicator_required = options[:communicator_required] || true + @communicator_required = options.fetch(:communicator_required, true) # Attempt to find the provisioner... if !Vagrant.plugin("2").manager.provisioners[type] diff --git a/plugins/providers/docker/action.rb b/plugins/providers/docker/action.rb index f9180afd8..2705439f4 100644 --- a/plugins/providers/docker/action.rb +++ b/plugins/providers/docker/action.rb @@ -67,9 +67,6 @@ module VagrantPlugins end b3.use Call, HasProvisioner do |env3, b4| - if env3[:skip].length > 0 - b4.use Message, I18n.t("docker_provider.messages.not_provisioning", provisioiners: check_skipped_provisioners(env3[:skip])) - end b4.use Provision end end @@ -214,9 +211,6 @@ module VagrantPlugins b.use Call, IsState, :running do |env, b2| if env[:machine_action] != :run_command b2.use Call, HasProvisioner do |env2, b3| - if env2[:skip].length > 0 - b3.use Message, I18n.t("docker_provider.messages.not_provisioning", provisioiners: check_skipped_provisioners(env2[:skip])) - end b3.use Provision end end @@ -298,7 +292,6 @@ module VagrantPlugins autoload :DestroyNetwork, action_root.join("destroy_network") autoload :ForwardedPorts, action_root.join("forwarded_ports") autoload :HasSSH, action_root.join("has_ssh") - autoload :HasProvisioner, action_root.join("has_provisioner") autoload :HostMachine, action_root.join("host_machine") autoload :HostMachineBuildDir, action_root.join("host_machine_build_dir") autoload :HostMachinePortChecker, action_root.join("host_machine_port_checker") @@ -319,13 +312,6 @@ module VagrantPlugins autoload :Start, action_root.join("start") autoload :Stop, action_root.join("stop") autoload :WaitForRunning, action_root.join("wait_for_running") - - private - - def self.check_skipped_provisioners(provisioners) - skipped_provisioners = provisioners.map { |p| "#{p.name || 'no name'}, type: #{p.type}" } - skipped_provisioners.join("\n- ") - end end end end diff --git a/plugins/providers/docker/action/has_provisioner.rb b/plugins/providers/docker/action/has_provisioner.rb deleted file mode 100644 index fdf324ce5..000000000 --- a/plugins/providers/docker/action/has_provisioner.rb +++ /dev/null @@ -1,26 +0,0 @@ -module VagrantPlugins - module DockerProvider - module Action - # This middleware is used with Call to test if this machine - # has available provisioners - class HasProvisioner - def initialize(app, env) - @app = app - end - - def call(env) - env[:skip] = [] - if !env[:machine].provider_config.has_ssh - env[:machine].config.vm.provisioners.each do |p| - if p.communicator_required - env[:skip].push(p) - p.run = :never - end - end - end - @app.call(env) - end - end - end - end -end diff --git a/plugins/providers/docker/cap/has_communicator.rb b/plugins/providers/docker/cap/has_communicator.rb new file mode 100644 index 000000000..42ef6c763 --- /dev/null +++ b/plugins/providers/docker/cap/has_communicator.rb @@ -0,0 +1,11 @@ +module VagrantPlugins + module DockerProvider + module Cap + module HasCommunicator + def self.has_communicator(machine) + return machine.provider_config.has_ssh + end + end + end + end +end diff --git a/plugins/providers/docker/plugin.rb b/plugins/providers/docker/plugin.rb index d5f7c7bd4..b297016ec 100644 --- a/plugins/providers/docker/plugin.rb +++ b/plugins/providers/docker/plugin.rb @@ -67,6 +67,11 @@ module VagrantPlugins Cap::ProxyMachine end + provider_capability("docker", "has_communicator") do + require_relative "cap/has_communicator" + Cap::HasCommunicator + end + protected def self.init! diff --git a/test/unit/plugins/providers/docker/action/has_provisioner_test.rb b/test/unit/plugins/providers/docker/action/has_provisioner_test.rb deleted file mode 100644 index dd8aa1360..000000000 --- a/test/unit/plugins/providers/docker/action/has_provisioner_test.rb +++ /dev/null @@ -1,62 +0,0 @@ -require_relative "../../../../base" -require_relative "../../../../../../plugins/providers/docker/action/has_provisioner" - - -describe VagrantPlugins::DockerProvider::Action::HasProvisioner do - include_context "unit" - - let(:sandbox) { isolated_environment } - - let(:iso_env) do - # We have to create a Vagrantfile so there is a root path - sandbox.vagrantfile("") - sandbox.create_vagrant_env - end - - let(:provisioner_one) { double("provisioner_one") } - let(:provisioner_two) { double("provisioner_two") } - let(:provisioners) { [provisioner_one, provisioner_two] } - - let(:machine) do - iso_env.machine(iso_env.machine_names[0], :docker).tap do |m| - allow(m).to receive_message_chain(:config, :vm, :provisioners).and_return(provisioners) - end - end - - let(:env) {{ machine: machine, ui: machine.ui, root_path: Pathname.new(".") }} - let(:app) { lambda { |*args| }} - - subject { described_class.new(app, env) } - - after do - sandbox.close - end - - describe "#call" do - - before do - allow(provisioner_one).to receive(:communicator_required).and_return(true) - allow(provisioner_two).to receive(:communicator_required).and_return(false) - end - - it "does not skip any provisioners if provider has ssh" do - env[:machine].provider_config.has_ssh = true - expect(provisioner_one).to_not receive(:communicator_required) - expect(provisioner_two).to_not receive(:communicator_required) - - subject.call(env) - expect(env[:skip]).to eq([]) - end - - it "skips provisioners that require a communicator if provider does not have ssh" do - env[:machine].provider_config.has_ssh = false - expect(provisioner_one).to receive(:communicator_required) - expect(provisioner_two).to receive(:communicator_required) - expect(provisioner_one).to receive(:run=).with(:never) - - subject.call(env) - expect(env[:skip]).to eq([provisioner_one]) - end - - end -end diff --git a/test/unit/vagrant/action/builtin/has_provisioner_test.rb b/test/unit/vagrant/action/builtin/has_provisioner_test.rb new file mode 100644 index 000000000..474b8d60b --- /dev/null +++ b/test/unit/vagrant/action/builtin/has_provisioner_test.rb @@ -0,0 +1,66 @@ +require File.expand_path("../../../../base", __FILE__) + + +describe Vagrant::Action::Builtin::HasProvisioner do + include_context "unit" + + let(:provisioner_one) { double("provisioner_one") } + let(:provisioner_two) { double("provisioner_two") } + let(:provisioners) { [provisioner_one, provisioner_two] } + let(:machine) { double("machine") } + let(:ui) {double("ui") } + let(:env) {{ machine: machine, ui: ui, root_path: Pathname.new(".") }} + let(:app) { lambda { |*args| }} + + subject { described_class.new(app, env) } + + describe "#call" do + before do + allow(provisioner_one).to receive(:communicator_required).and_return(true) + allow(provisioner_one).to receive(:name) + allow(provisioner_one).to receive(:type) + allow(provisioner_two).to receive(:communicator_required).and_return(false) + allow(provisioner_two).to receive(:name) + allow(provisioner_two).to receive(:type) + allow(machine).to receive_message_chain(:config, :vm, :provisioners).and_return(provisioners) + end + + context "provider has capability :has_communicator" do + before do + allow(machine).to receive_message_chain(:provider, :capability?).with(:has_communicator).and_return(true) + end + + it "does not skip any provisioners if provider has ssh" do + allow(machine).to receive_message_chain(:provider, :capability).with(:has_communicator).and_return(true) + expect(provisioner_one).to_not receive(:communicator_required) + expect(provisioner_two).to_not receive(:communicator_required) + + subject.call(env) + expect(env[:skip]).to eq([]) + end + + it "skips provisioners that require a communicator if provider does not have ssh" do + allow(machine).to receive_message_chain(:provider, :capability).with(:has_communicator).and_return(false) + expect(provisioner_one).to receive(:communicator_required) + expect(provisioner_two).to receive(:communicator_required) + expect(provisioner_one).to receive(:run=).with(:never) + + subject.call(env) + expect(env[:skip]).to eq([provisioner_one]) + end + end + + context "provider does not have capability :has_communicator" do + before do + allow(machine).to receive_message_chain(:provider, :capability?).with(:has_communicator).and_return(false) + end + + it "does not skip any provisioners" do + expect(provisioner_one).to_not receive(:communicator_required) + expect(provisioner_two).to_not receive(:communicator_required) + subject.call(env) + expect(env[:skip]).to eq([]) + end + end + end +end