vagrant/plugins/commands/validate/command.rb
Brian Cain 68dda8f853
Fixes #10224: Clear our registered providers when validating configs with no provider
Prior to this commit, if you went to validate your Vagrantfile and
wanted to ignore the provider, Vagrant would still fail as it checks if
there are any registered providers that are installed and usable. This
commit mocks out all registered providers to bypass that for the
validate command so that Vagrant can just validate the config and ignore
any provider config blocks.
2018-11-30 10:54:16 -08:00

100 lines
2.9 KiB
Ruby

require 'optparse'
module VagrantPlugins
module CommandValidate
class Command < Vagrant.plugin("2", :command)
def self.synopsis
"validates the Vagrantfile"
end
def execute
options = {}
opts = OptionParser.new do |o|
o.banner = "Usage: vagrant validate [options]"
o.separator ""
o.separator "Validates a Vagrantfile config"
o.separator ""
o.separator "Options:"
o.separator ""
o.on("-p", "--ignore-provider", "Ignores provider config options") do |p|
options[:ignore_provider] = p
end
end
# Parse the options
argv = parse_options(opts)
return if !argv
action_env = {}
if options[:ignore_provider]
action_env[:ignore_provider] = true
mockup_providers!
end
# Validate the configuration of all machines
with_target_vms() do |machine|
machine.action_raw(:config_validate, Vagrant::Action::Builtin::ConfigValidate, action_env)
end
@env.ui.info(I18n.t("vagrant.commands.validate.success"))
# Success, exit status 0
0
end
protected
# This method is required to bypass some of the provider checks that would
# otherwise raise exceptions before Vagrant could load and validate a config.
# It essentially ignores that there are no installed or usable prodivers so
# that Vagrant can go along and validate the rest of the Vagrantfile and ignore
# any provider blocks.
def mockup_providers!
require 'log4r'
logger = Log4r::Logger.new("vagrant::validate")
logger.debug("Overriding all registered provider classes for validate")
# Without setting up a tmp Environment, Vagrant will completely
# erase the local data dotfile and you can lose state after the
# validate command completes.
tmp_data_dir = Dir.mktmpdir("vagrant-validate-")
@env = Vagrant::Environment.new(
cwd: @env.cwd,
home_path: @env.home_path,
ui_class: @env.ui_class,
vagrantfile_name: @env.vagrantfile_name,
local_data_path: tmp_data_dir,
data_dir: tmp_data_dir
)
Vagrant.plugin("2").manager.providers.each do |key, data|
data[0].class_eval do
def initialize(machine)
@machine = machine
end
def machine_id_changed
end
def self.installed?
true
end
def self.usable?(raise_error=false)
true
end
def state
state_id = Vagrant::MachineState::NOT_CREATED_ID
short = :not_created
long = :not_created
Vagrant::MachineState.new(state_id, short, long)
end
end
end
end
end
end
end