Some commands like `vagrant init` and `vagrant box` should be able to run successfully without a full Project available in VAGRANT_CWD (in other words, they don't require that a valid Vagrantfile be available.) Thus far we've been assuming that a Project is available when dispatching commands, which mean that commands of this nature weren't working. Here we make the Basis available to serve as an alternative client to Vagrant::Environment::Remote such that it can be instantiated and passed through to commands. This required some changes to Environment::Remote to make its interactions with the client more defensive, but we manage to avoid needing to make any changes to the normal legacy codepaths.
142 lines
4.4 KiB
Ruby
142 lines
4.4 KiB
Ruby
require 'vagrant/machine_index/remote'
|
|
|
|
module Vagrant
|
|
class Environment
|
|
module Remote
|
|
|
|
def self.prepended(klass)
|
|
klass.class_eval do
|
|
attr_reader :client
|
|
end
|
|
end
|
|
|
|
# Client can be either a Project or a Basis
|
|
def initialize(opts={})
|
|
@client = opts[:client]
|
|
if @client.nil?
|
|
raise ArgumentError,
|
|
"Remote client is required for `#{self.class.name}'"
|
|
end
|
|
|
|
@logger = Log4r::Logger.new("vagrant::environment")
|
|
|
|
# Set the default ui class
|
|
opts[:ui_class] ||= UI::Remote
|
|
|
|
@cwd = Pathname.new(@client.cwd)
|
|
@home_path = @client.respond_to?(:home) && Pathname.new(@client.home)
|
|
@vagrantfile_name = @client.respond_to?(:vagrantfile_name) && [@client.vagrantfile_name]
|
|
@ui = opts.fetch(:ui, opts[:ui_class].new(@client.ui))
|
|
@local_data_path = Pathname.new(@client.local_data)
|
|
@boxes_path = @home_path && @home_path.join("boxes")
|
|
@data_dir = Pathname.new(@client.data_dir)
|
|
@gems_path = Vagrant::Bundler.instance.plugin_gem_path
|
|
@tmp_path = Pathname.new(@client.temp_dir)
|
|
|
|
# This is the batch lock, that enforces that only one {BatchAction}
|
|
# runs at a time from {#batch}.
|
|
@batch_lock = Mutex.new
|
|
@locks = {}
|
|
|
|
@logger.info("Environment initialized (#{self})")
|
|
@logger.info(" - cwd: #{cwd}")
|
|
@logger.info(" - home path: #{home_path}")
|
|
|
|
# TODO: aliases
|
|
@aliases_path = Pathname.new(ENV["VAGRANT_ALIAS_FILE"]).expand_path if ENV.key?("VAGRANT_ALIAS_FILE")
|
|
@aliases_path ||= @home_path && @home_path.join("aliases")
|
|
|
|
@default_private_key_path = Pathname.new(@client.default_private_key)
|
|
copy_insecure_private_key
|
|
|
|
# Initialize localized plugins
|
|
plugins = Vagrant::Plugin::Manager.instance.localize!(self)
|
|
# Load any environment local plugins
|
|
Vagrant::Plugin::Manager.instance.load_plugins(plugins)
|
|
|
|
# Initialize globalize plugins
|
|
plugins = Vagrant::Plugin::Manager.instance.globalize!
|
|
# Load any global plugins
|
|
Vagrant::Plugin::Manager.instance.load_plugins(plugins)
|
|
|
|
plugins = process_configured_plugins
|
|
|
|
# Call the hooks that does not require configurations to be loaded
|
|
# by using a "clean" action runner
|
|
hook(:environment_plugins_loaded, runner: Action::Runner.new(env: self))
|
|
|
|
# Call the environment load hooks
|
|
hook(:environment_load, runner: Action::Runner.new(env: self))
|
|
end
|
|
|
|
# Returns the collection of boxes for the environment.
|
|
#
|
|
# @return [BoxCollection]
|
|
def boxes
|
|
box_colletion_client = client.boxes
|
|
@_boxes ||= BoxCollection.new(nil, client: box_colletion_client)
|
|
end
|
|
|
|
# Returns the host object associated with this environment.
|
|
#
|
|
# @return [Class]
|
|
def host
|
|
if !@host
|
|
h = @client.host
|
|
@host = Vagrant::Host.new(h, nil, nil, self)
|
|
end
|
|
@host
|
|
end
|
|
|
|
# Gets a target (machine) by name
|
|
#
|
|
# @param [String] machine name
|
|
# return [VagrantPlugins::CommandServe::Client::Machine]
|
|
def get_target(name)
|
|
client.target(name)
|
|
end
|
|
|
|
def setup_home_path
|
|
# no-op
|
|
# Don't setup a home path in ruby
|
|
end
|
|
|
|
def setup_local_data_path(force=false)
|
|
# no-op
|
|
# Don't setup a home path in ruby
|
|
end
|
|
|
|
# The {MachineIndex} to store information about the machines.
|
|
#
|
|
# @return [MachineIndex]
|
|
def machine_index
|
|
@machine_index ||= Vagrant::MachineIndex.new(client: client.target_index)
|
|
end
|
|
|
|
def config_loader
|
|
return @config_loader if @config_loader
|
|
|
|
root_vagrantfile = nil
|
|
if client.respond_to?(:vagrantfile_path) && client.respond_to?(:vagrantfile_name)
|
|
path = client.vagrantfile_path
|
|
name = client.vagrantfile_name
|
|
root_vagrantfile = path.join(name).to_s
|
|
end
|
|
@config_loader = Config::Loader.new(
|
|
Config::VERSIONS, Config::VERSIONS_ORDER)
|
|
@config_loader.set(:root, root_vagrantfile) if root_vagrantfile
|
|
@config_loader
|
|
end
|
|
|
|
def vagrantfile
|
|
# When in remote mode we don't load the "home" vagrantfile
|
|
@vagrantfile ||= Vagrant::Vagrantfile.new(config_loader, [:root])
|
|
end
|
|
|
|
def to_proto
|
|
client.proto
|
|
end
|
|
end
|
|
end
|
|
end
|