commands/up: automatically install providers

This commit is contained in:
Mitchell Hashimoto 2015-11-05 13:58:15 -08:00
parent 69d9bc0fe8
commit baea923e9c
4 changed files with 87 additions and 16 deletions

View File

@ -309,6 +309,7 @@ module Vagrant
def default_provider(**opts) def default_provider(**opts)
opts[:exclude] = Set.new(opts[:exclude]) if opts[:exclude] opts[:exclude] = Set.new(opts[:exclude]) if opts[:exclude]
opts[:force_default] = true if !opts.key?(:force_default) opts[:force_default] = true if !opts.key?(:force_default)
opts[:check_usable] = true if !opts.key?(:check_usable)
default = ENV["VAGRANT_DEFAULT_PROVIDER"] default = ENV["VAGRANT_DEFAULT_PROVIDER"]
default = nil if default == "" default = nil if default == ""
@ -376,6 +377,7 @@ module Vagrant
# Find the matching implementation # Find the matching implementation
ordered.each do |_, key, impl, _| ordered.each do |_, key, impl, _|
return key if !opts[:check_usable]
return key if impl.usable?(false) return key if impl.usable?(false)
end end

View File

@ -1,4 +1,5 @@
require 'optparse' require 'optparse'
require 'set'
require "vagrant" require "vagrant"
@ -16,6 +17,7 @@ module VagrantPlugins
def execute def execute
options = {} options = {}
options[:destroy_on_error] = true options[:destroy_on_error] = true
options[:install_provider] = true
options[:parallel] = true options[:parallel] = true
options[:provision_ignore_sentinel] = false options[:provision_ignore_sentinel] = false
@ -41,6 +43,11 @@ module VagrantPlugins
"Back the machine with a specific provider") do |provider| "Back the machine with a specific provider") do |provider|
options[:provider] = provider options[:provider] = provider
end end
o.on("--[no-]install-provider",
"If possible, install the provider if it isn't installed") do |p|
options[:install_provider] = p
end
end end
# Parse the options # Parse the options
@ -53,24 +60,32 @@ module VagrantPlugins
# Go over each VM and bring it up # Go over each VM and bring it up
@logger.debug("'Up' each target VM...") @logger.debug("'Up' each target VM...")
# Build up the batch job of what we'll do # Get the names of the machines we want to bring up
machines = [] names = argv
@env.batch(options[:parallel]) do |batch| if names.empty?
names = argv autostart = false
if names.empty? @env.vagrantfile.machine_names_and_options.each do |n, o|
autostart = false autostart = true if o.key?(:autostart)
@env.vagrantfile.machine_names_and_options.each do |n, o| o[:autostart] = true if !o.key?(:autostart)
autostart = true if o.key?(:autostart) names << n.to_s if o[:autostart]
o[:autostart] = true if !o.key?(:autostart)
names << n.to_s if o[:autostart]
end
# If we have an autostart key but no names, it means that
# all machines are autostart: false and we don't start anything.
names = nil if autostart && names.empty?
end end
if names # If we have an autostart key but no names, it means that
# all machines are autostart: false and we don't start anything.
names = nil if autostart && names.empty?
end
# Build up the batch job of what we'll do
machines = []
if names
# If we're installing providers, then do that. We don't
# parallelize this step because it is likely the same provider
# anyways.
if options[:install_provider]
install_providers(names)
end
@env.batch(options[:parallel]) do |batch|
with_target_vms(names, provider: options[:provider]) do |machine| with_target_vms(names, provider: options[:provider]) do |machine|
@env.ui.info(I18n.t( @env.ui.info(I18n.t(
"vagrant.commands.up.upping", "vagrant.commands.up.upping",
@ -106,6 +121,44 @@ module VagrantPlugins
# Success, exit status 0 # Success, exit status 0
0 0
end end
protected
def install_providers(names)
# First create a set of all the providers we need to check for.
# Most likely this will be a set of one.
providers = Set.new
names.each do |name|
providers.add(@env.default_provider(machine: name.to_sym, check_usable: false))
end
# Go through and determine if we can install the providers
providers.delete_if do |name|
!@env.can_install_provider?(name)
end
# Install the providers if we have to
providers.each do |name|
# Find the provider. Ignore if we can't find it, this error
# will pop up later in the process.
parts = Vagrant.plugin("2").manager.providers[name]
next if !parts
# If the provider is already installed, then our work here is done
cls = parts[0]
next if cls.installed?
# Some human-friendly output
ui = Vagrant::UI::Prefixed.new(@env.ui, "")
ui.output(I18n.t(
"vagrant.installing_provider",
provider: name.to_s))
ui.detail(I18n.t("vagrant.installing_provider_detail"))
# Install the provider
@env.install_provider(name)
end
end
end end
end end
end end

View File

@ -5,6 +5,15 @@ module VagrantPlugins
class Provider < Vagrant.plugin("2", :provider) class Provider < Vagrant.plugin("2", :provider)
attr_reader :driver attr_reader :driver
def self.installed?
Driver::Meta.new
true
rescue Vagrant::Errors::VirtualBoxInvalidVersion
return false
rescue Vagrant::Errors::VirtualBoxNotDetected
return false
end
def self.usable?(raise_error=false) def self.usable?(raise_error=false)
# Instantiate the driver, which will determine the VirtualBox # Instantiate the driver, which will determine the VirtualBox
# version and all that, which checks for VirtualBox being present # version and all that, which checks for VirtualBox being present

View File

@ -154,6 +154,13 @@ en:
Inserting generated public key within guest... Inserting generated public key within guest...
inserting_remove_key: |- inserting_remove_key: |-
Removing insecure key from the guest if it's present... Removing insecure key from the guest if it's present...
installing_provider: |-
Provider '%{provider}' not found. We'll automatically install it now...
installing_provider_detail: |-
The installation process will start below. Human interaction may be
required at some points. If you're uncomfortable with automatically
installing this provider, you can safely Ctrl-C this process and install
it manually.
list_commands: |- list_commands: |-
Below is a listing of all available Vagrant commands and a brief Below is a listing of all available Vagrant commands and a brief
description of what they do. description of what they do.