diff --git a/plugins/providers/docker/action/login.rb b/plugins/providers/docker/action/login.rb index a63c0fdc6..56f3b7e2c 100644 --- a/plugins/providers/docker/action/login.rb +++ b/plugins/providers/docker/action/login.rb @@ -9,6 +9,21 @@ module VagrantPlugins @logger = Log4r::Logger.new("vagrant::docker::login") end + def login(env, config, driver) + # Login! + env[:ui].output(I18n.t("docker_provider.logging_in")) + driver.login( + config.email, config.username, + config.password, config.auth_server) + + # Continue, so that the auth is protected + # from meddling. + @app.call(env) + + # Log out + driver.logout(config.auth_server) + end + def call(env) config = env[:machine].provider_config driver = env[:machine].provider.driver @@ -16,21 +31,15 @@ module VagrantPlugins # If we don't have a password set, don't auth return @app.call(env) if config.password == "" - # Grab a host VM lock to do the login so that we only login - # once per container for the rest of this process. - env[:machine].provider.host_vm_lock do - # Login! - env[:ui].output(I18n.t("docker_provider.logging_in")) - driver.login( - config.email, config.username, - config.password, config.auth_server) - - # Continue, within the lock, so that the auth is protected - # from meddling. - @app.call(env) - - # Log out - driver.logout(config.auth_server) + if !env[:machine].provider.host_vm? + # no host vm in use, using docker directly + login(env, config, driver) + else + # Grab a host VM lock to do the login so that we only login + # once per container for the rest of this process. + env[:machine].provider.host_vm_lock do + login(env, config, driver) + end end end end diff --git a/test/unit/plugins/providers/docker/action/login_test.rb b/test/unit/plugins/providers/docker/action/login_test.rb new file mode 100644 index 000000000..85b68897b --- /dev/null +++ b/test/unit/plugins/providers/docker/action/login_test.rb @@ -0,0 +1,96 @@ +require_relative "../../../../base" +require_relative "../../../../../../plugins/providers/docker/action/login" + + +describe VagrantPlugins::DockerProvider::Action::Login do + include_context "unit" + include_context "virtualbox" + + 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(:provider_config) { double("provider_config", username: "docker", password: "") } + + let(:machine) do + iso_env.machine(iso_env.machine_names[0], :docker).tap do |m| + allow(m).to receive(:id).and_return("12345") + allow(m).to receive(:provider_config).and_return(provider_config) + allow(m.provider).to receive(:driver).and_return(driver) + allow(m.provider).to receive(:host_vm?).and_return(false) + end + end + + let(:env) {{ machine: machine, ui: machine.ui, root_path: Pathname.new(".") }} + let(:app) { lambda { |*args| }} + let(:driver) { double("driver", create: "abcd1234") } + + + subject { described_class.new(app, env) } + + after do + sandbox.close + end + + describe "#call" do + it "calls the next action in the chain" do + allow(driver).to receive(:host_vm?).and_return(false) + + called = false + app = ->(*args) { called = true } + + action = described_class.new(app, env) + + action.call(env) + + expect(called).to eq(true) + end + + it "uses a host vm lock if host_vm is true and password is set" do + allow(driver).to receive(:host_vm?).and_return(true) + allow(driver).to receive(:login).and_return(true) + allow(driver).to receive(:logout).and_return(true) + + allow(machine.provider).to receive(:host_vm?).and_return(true) + allow(machine.provider).to receive(:host_vm_lock) { |&block| block.call } + + allow(provider_config).to receive(:password).and_return("docker") + allow(provider_config).to receive(:email).and_return("docker") + allow(provider_config).to receive(:auth_server).and_return("docker") + + called = false + app = ->(*args) { called = true } + + action = described_class.new(app, env) + + action.call(env) + + expect(called).to eq(true) + end + + it "doesn't use the host vm if not set" do + allow(driver).to receive(:host_vm?).and_return(false) + allow(driver).to receive(:login).and_return(true) + allow(driver).to receive(:logout).and_return(true) + + allow(machine.provider).to receive(:host_vm?).and_return(false) + + allow(provider_config).to receive(:password).and_return("docker") + allow(provider_config).to receive(:email).and_return("docker") + allow(provider_config).to receive(:auth_server).and_return("docker") + + called = false + app = ->(*args) { called = true } + + action = described_class.new(app, env) + + action.call(env) + + expect(called).to eq(true) + end + end +end