When starting up, and before any loading, find our current
specification and activate all the internal dependencies
while also collecting the activated specifications. Store
these for later use when doing plugin resolutions. We bypass
the builtin list when running in bundler since they will
still show up as not activated, but we use the entire list
regardless.
264 lines
8.0 KiB
Ruby
Executable File
264 lines
8.0 KiB
Ruby
Executable File
#!/usr/bin/env ruby
|
|
|
|
# Trap interrupts to quit cleanly. This will be overridden at some point
|
|
# by Vagrant. This is made to catch any interrupts while Vagrant is
|
|
# initializing which have historically resulted in stack traces.
|
|
Signal.trap("INT") { abort }
|
|
|
|
# Disable exception reporting by default if available
|
|
if Thread.respond_to?(:report_on_exception=)
|
|
Thread.report_on_exception = false
|
|
end
|
|
|
|
# Split arguments by "--" if its there, we'll recombine them later
|
|
argv = ARGV.dup
|
|
argv_extra = []
|
|
|
|
# These will be the options that are passed to initialize the Vagrant
|
|
# environment.
|
|
opts = {}
|
|
|
|
if idx = argv.index("--")
|
|
argv_extra = argv.slice(idx+1, argv.length-2)
|
|
argv = argv.slice(0, idx)
|
|
end
|
|
|
|
require_relative "../lib/vagrant/version"
|
|
# Fast path the version of Vagrant
|
|
if argv.include?("-v") || argv.include?("--version")
|
|
puts "Vagrant #{Vagrant::VERSION}"
|
|
exit 0
|
|
end
|
|
|
|
# Disable plugin loading for commands where plugins are not required. This will
|
|
# also disable loading of the Vagrantfile if it available as the environment
|
|
# is not required for these commands
|
|
argv.each_index do |i|
|
|
arg = argv[i]
|
|
|
|
if !arg.start_with?("-")
|
|
if arg == "box" && argv[i+1] == "list"
|
|
opts[:vagrantfile_name] = ""
|
|
ENV['VAGRANT_NO_PLUGINS'] = "1"
|
|
end
|
|
|
|
# Do not load plugins when performing plugin operations
|
|
if arg == "plugin"
|
|
if argv.none?{|a| a == "--local" } && !ENV["VAGRANT_LOCAL_PLUGINS_LOAD"]
|
|
opts[:vagrantfile_name] = ""
|
|
end
|
|
ENV['VAGRANT_NO_PLUGINS'] = "1"
|
|
# Only initialize plugins when listing installed plugins
|
|
if argv[i+1] != "list"
|
|
ENV['VAGRANT_DISABLE_PLUGIN_INIT'] = "1"
|
|
end
|
|
end
|
|
|
|
break
|
|
end
|
|
end
|
|
|
|
# Set logging level to `debug`. This is done before loading 'vagrant', as it
|
|
# sets up the logging system.
|
|
if argv.include?("--debug")
|
|
argv.delete("--debug")
|
|
ENV["VAGRANT_LOG"] = "debug"
|
|
end
|
|
|
|
# Enable log timestamps if requested
|
|
if argv.include?("--timestamp")
|
|
argv.delete("--timestamp")
|
|
ENV["VAGRANT_LOG_TIMESTAMP"] = "1"
|
|
end
|
|
|
|
# Convenience flag to enable debug with timestamps
|
|
if argv.include?("--debug-timestamp")
|
|
argv.delete("--debug-timestamp")
|
|
ENV["VAGRANT_LOG"] = "debug"
|
|
ENV["VAGRANT_LOG_TIMESTAMP"] = "1"
|
|
end
|
|
|
|
# Stdout/stderr should not buffer output
|
|
$stdout.sync = true
|
|
$stderr.sync = true
|
|
|
|
# Before we start activate all our dependencies
|
|
# so we can provide correct resolutions later
|
|
builtin_specs = []
|
|
|
|
vagrant_spec = Gem::Specification.find_all_by_name("vagrant").detect do |spec|
|
|
spec.version == Gem::Version.new(Vagrant::VERSION)
|
|
end
|
|
|
|
dep_activator = proc do |spec|
|
|
spec.runtime_dependencies.each do |dep|
|
|
gem(dep.name, *dep.requirement.as_list)
|
|
dep_spec = Gem::Specification.find_all_by_name(dep.name).detect(&:activated?)
|
|
if dep_spec
|
|
builtin_specs << dep_spec
|
|
dep_activator.call(dep_spec)
|
|
end
|
|
end
|
|
end
|
|
|
|
if vagrant_spec
|
|
dep_activator.call(vagrant_spec)
|
|
end
|
|
|
|
env = nil
|
|
begin
|
|
require 'log4r'
|
|
require 'vagrant'
|
|
require 'vagrant/bundler'
|
|
require 'vagrant/cli'
|
|
require 'vagrant/util/platform'
|
|
require 'vagrant/util/experimental'
|
|
|
|
# Set our list of builtin specs
|
|
Vagrant::Bundler.instance.builtin_specs = builtin_specs
|
|
|
|
# Schedule the cleanup of things
|
|
at_exit(&Vagrant::Bundler.instance.method(:deinit))
|
|
|
|
# If this is not a pre-release disable verbose output
|
|
if !Vagrant.prerelease?
|
|
$VERBOSE = nil
|
|
end
|
|
|
|
# Add any option flags defined within this file here
|
|
# so they are automatically propagated to all commands
|
|
Vagrant.add_default_cli_options(proc { |o|
|
|
o.on("--[no-]color", "Enable or disable color output")
|
|
o.on("--machine-readable", "Enable machine readable output")
|
|
o.on("-v", "--version", "Display Vagrant version")
|
|
o.on("--debug", "Enable debug output")
|
|
o.on("--timestamp", "Enable timestamps on log output")
|
|
o.on("--debug-timestamp", "Enable debug output with timestamps")
|
|
o.on("--no-tty", "Enable non-interactive output")
|
|
})
|
|
|
|
# Create a logger right away
|
|
logger = Log4r::Logger.new("vagrant::bin::vagrant")
|
|
logger.info("`vagrant` invoked: #{ARGV.inspect}")
|
|
|
|
# Disable color in a few cases:
|
|
#
|
|
# * --no-color is anywhere in our arguments
|
|
# * STDOUT is not a TTY
|
|
# * The terminal doesn't support colors (Windows)
|
|
#
|
|
if argv.include?("--no-color") || ENV["VAGRANT_NO_COLOR"]
|
|
# Delete the argument from the list so that it doesn't
|
|
# cause any invalid arguments down the road.
|
|
argv.delete("--no-color")
|
|
|
|
opts[:ui_class] = Vagrant::UI::Basic
|
|
elsif !Vagrant::Util::Platform.terminal_supports_colors?
|
|
opts[:ui_class] = Vagrant::UI::Basic
|
|
elsif !$stdout.tty? && !Vagrant::Util::Platform.cygwin?
|
|
# Cygwin always reports STDOUT is not a TTY, so we only disable
|
|
# colors if its not a TTY AND its not Cygwin.
|
|
opts[:ui_class] = Vagrant::UI::Basic
|
|
end
|
|
|
|
# Also allow users to force colors.
|
|
if argv.include?("--color") || ENV["VAGRANT_FORCE_COLOR"]
|
|
argv.delete("--color")
|
|
opts[:ui_class] = Vagrant::UI::Colored
|
|
end
|
|
|
|
# Highest precedence is if we have enabled machine-readable output
|
|
if argv.include?("--machine-readable")
|
|
argv.delete("--machine-readable")
|
|
opts[:ui_class] = Vagrant::UI::MachineReadable
|
|
end
|
|
|
|
# Setting to enable/disable showing progress bars
|
|
if argv.include?("--no-tty")
|
|
argv.delete("--no-tty")
|
|
opts[:ui_class] = Vagrant::UI::NonInteractive
|
|
end
|
|
|
|
# Default to colored output
|
|
opts[:ui_class] ||= Vagrant::UI::Colored
|
|
|
|
# Recombine the arguments
|
|
if !argv_extra.empty?
|
|
argv << "--"
|
|
argv += argv_extra
|
|
end
|
|
|
|
# Create the environment, which is the cwd of wherever the
|
|
# `vagrant` command was invoked from
|
|
logger.debug("Creating Vagrant environment")
|
|
env = Vagrant::Environment.new(opts)
|
|
|
|
# If we are running with the Windows Subsystem for Linux do
|
|
# some extra setup to allow access to Vagrant managed machines
|
|
# outside the subsystem
|
|
if Vagrant::Util::Platform.wsl?
|
|
recreate_env = Vagrant::Util::Platform.wsl_init(env, logger)
|
|
if recreate_env
|
|
logger.info("Re-creating Vagrant environment due to WSL modifications.")
|
|
env = Vagrant::Environment.new(opts)
|
|
end
|
|
end
|
|
|
|
if !Vagrant.in_installer? && !Vagrant.very_quiet?
|
|
# If we're not in the installer, warn.
|
|
env.ui.warn(I18n.t("vagrant.general.not_in_installer") + "\n", prefix: false)
|
|
end
|
|
|
|
# Acceptable experimental flag values include:
|
|
#
|
|
# Unset - Disables experimental features
|
|
# 0 - Disables experimental features
|
|
# 1 - Enables all features
|
|
# String - Enables one or more features, separated by commas
|
|
if Vagrant::Util::Experimental.enabled?
|
|
experimental = Vagrant::Util::Experimental.features_requested
|
|
ui = Vagrant::UI::Prefixed.new(env.ui, "vagrant")
|
|
logger.debug("Experimental flag is enabled")
|
|
if Vagrant::Util::Experimental.global_enabled?
|
|
ui.warn(I18n.t("vagrant.general.experimental.all"), bold: true, prefix: true, channel: :error)
|
|
else
|
|
ui.warn(I18n.t("vagrant.general.experimental.features", features: experimental.join(", ")), bold: true, prefix: true, channel: :error)
|
|
end
|
|
end
|
|
|
|
begin
|
|
# Execute the CLI interface, and exit with the proper error code
|
|
exit_status = env.cli(argv)
|
|
ensure
|
|
# Unload the environment so cleanup can be done
|
|
env.unload
|
|
end
|
|
|
|
# Exit with the exit status from our CLI command
|
|
exit(exit_status)
|
|
rescue Exception => e
|
|
# It is possible for errors to happen in Vagrant's initialization. In
|
|
# this case, we don't have access to this class yet, so we check for it.
|
|
raise if !defined?(Vagrant) || !defined?(Vagrant::Errors)
|
|
raise if !e.is_a?(Vagrant::Errors::VagrantError)
|
|
|
|
require 'log4r'
|
|
logger = Log4r::Logger.new("vagrant::bin::vagrant")
|
|
logger.error("Vagrant experienced an error! Details:")
|
|
logger.error(e.inspect)
|
|
logger.error(e.message)
|
|
logger.error(e.backtrace.join("\n"))
|
|
|
|
if env
|
|
opts = { prefix: false }
|
|
env.ui.error e.message, opts if e.message
|
|
env.ui.machine("error-exit", e.class.to_s, e.message.to_s)
|
|
else
|
|
$stderr.puts "Vagrant failed to initialize at a very early stage:\n\n"
|
|
$stderr.puts e.message
|
|
end
|
|
|
|
exit e.status_code if e.respond_to?(:status_code)
|
|
exit 255 # An error occurred with no status code defined
|
|
end
|