From 69d9bc0fe85e65ec21ff6ee8d19b9b77da1ef7e9 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 5 Nov 2015 11:50:10 -0800 Subject: [PATCH] Environment can_install_provider and install_provider --- lib/vagrant/environment.rb | 26 ++++++++++++ lib/vagrant/plugin/v2/provider.rb | 15 +++++++ test/unit/vagrant/environment_test.rb | 42 ++++++++++++++++++++ test/unit/vagrant/plugin/v2/provider_test.rb | 4 ++ 4 files changed, 87 insertions(+) diff --git a/lib/vagrant/environment.rb b/lib/vagrant/environment.rb index 015e4b95f..034d71163 100644 --- a/lib/vagrant/environment.rb +++ b/lib/vagrant/environment.rb @@ -383,6 +383,26 @@ module Vagrant raise Errors::NoDefaultProvider end + # Returns whether or not we know how to install the provider with + # the given name. + # + # @return [Boolean] + def can_install_provider?(name) + host.capability?(provider_install_key(name)) + end + + # Installs the provider with the given name. + # + # This will raise an exception if we don't know how to install the + # provider with the given name. You should guard this call with + # `can_install_provider?` for added safety. + # + # An exception will be raised if there are any failures installing + # the provider. + def install_provider(name) + host.capability(provider_install_key(name)) + end + # Returns the collection of boxes for the environment. # # @return [BoxCollection] @@ -883,6 +903,12 @@ module Vagrant nil end + # Returns the key used for the host capability for provider installs + # of the given name. + def provider_install_key(name) + "provider_install_#{name}".to_sym + end + # This upgrades a home directory that was in the v1.1 format to the # v1.5 format. It will raise exceptions if anything fails. def upgrade_home_path_v1_1 diff --git a/lib/vagrant/plugin/v2/provider.rb b/lib/vagrant/plugin/v2/provider.rb index 0ea7a1f13..3e96d86e1 100644 --- a/lib/vagrant/plugin/v2/provider.rb +++ b/lib/vagrant/plugin/v2/provider.rb @@ -24,6 +24,21 @@ module Vagrant true end + # This is called early, before a machine is instantiated, to check + # if this provider is installed. This should return true or false. + # + # If the provider is not installed and Vagrant determines it is + # able to install this provider, then it will do so. Installation + # is done by calling Environment.install_provider. + # + # If Environment.can_install_provider? returns false, then an error + # will be shown to the user. + def self.installed? + # By default return true for backwards compat so all providers + # continue to work. + true + end + # Initialize the provider to represent the given machine. # # @param [Vagrant::Machine] machine The machine that this provider diff --git a/test/unit/vagrant/environment_test.rb b/test/unit/vagrant/environment_test.rb index c5cf8370d..6a595fb57 100644 --- a/test/unit/vagrant/environment_test.rb +++ b/test/unit/vagrant/environment_test.rb @@ -25,6 +25,48 @@ describe Vagrant::Environment do let(:instance) { env.create_vagrant_env } subject { instance } + describe "#can_install_provider?" do + let(:plugin_hosts) { {} } + let(:plugin_host_caps) { {} } + + before do + m = Vagrant.plugin("2").manager + m.stub(hosts: plugin_hosts) + m.stub(host_capabilities: plugin_host_caps) + + # Detect the host + env.vagrantfile <<-VF + Vagrant.configure("2") do |config| + config.vagrant.host = nil + end + VF + + # Setup the foo host by default + plugin_hosts[:foo] = [detect_class(true), nil] + end + + it "should return whether it can install or not" do + plugin_host_caps[:foo] = { provider_install_foo: Class } + + expect(subject.can_install_provider?(:foo)).to be_true + expect(subject.can_install_provider?(:bar)).to be_false + end + end + + describe "#install_provider" do + let(:host) { double(:host) } + + before do + allow(subject).to receive(:host).and_return(host) + end + + it "should install the correct provider" do + expect(host).to receive(:capability).with(:provider_install_foo) + + subject.install_provider(:foo) + end + end + describe "#home_path" do it "is set to the home path given" do Dir.mktmpdir do |dir| diff --git a/test/unit/vagrant/plugin/v2/provider_test.rb b/test/unit/vagrant/plugin/v2/provider_test.rb index c27274db1..634b311c6 100644 --- a/test/unit/vagrant/plugin/v2/provider_test.rb +++ b/test/unit/vagrant/plugin/v2/provider_test.rb @@ -12,6 +12,10 @@ describe Vagrant::Plugin::V2::Provider do expect(described_class).to be_usable end + it "should be installed by default" do + expect(described_class).to be_installed + end + it "should return nil by default for actions" do expect(instance.action(:whatever)).to be_nil end