diff --git a/internal/core/basis.go b/internal/core/basis.go index ed7e1b95b..dd92612e6 100644 --- a/internal/core/basis.go +++ b/internal/core/basis.go @@ -16,6 +16,7 @@ import ( "github.com/hashicorp/vagrant-plugin-sdk/core" "github.com/hashicorp/vagrant-plugin-sdk/datadir" "github.com/hashicorp/vagrant-plugin-sdk/helper/path" + "github.com/hashicorp/vagrant-plugin-sdk/helper/paths" "github.com/hashicorp/vagrant-plugin-sdk/internal-shared/cacher" "github.com/hashicorp/vagrant-plugin-sdk/internal-shared/dynamic" "github.com/hashicorp/vagrant-plugin-sdk/internal-shared/protomappers" @@ -201,6 +202,14 @@ func (b *Basis) Config() *vagrant_plugin_sdk.Vagrantfile_Vagrantfile { return b.basis.Configuration } +func (p *Basis) CWD() (path string, err error) { + cwd, err := paths.VagrantCwd() + if err != nil { + return "", err + } + return cwd.String(), nil +} + // Basis UI is the "default" UI with no prefix modifications func (b *Basis) UI() (terminal.UI, error) { return b.ui, nil @@ -211,6 +220,12 @@ func (b *Basis) DataDir() (*datadir.Basis, error) { return b.dir, nil } +// DefaultPrivateKey implements core.Basis +func (b *Basis) DefaultPrivateKey() (path string, err error) { + defaultPrivateKeyPath := b.dir.DataDir().Join("insecure_private_key") + return defaultPrivateKeyPath.String(), nil +} + // Implements core.Basis // Returns all the registered plugins of the types specified func (b *Basis) Plugins(types ...string) (plugins []*core.NamedPlugin, err error) { @@ -275,7 +290,7 @@ func (b *Basis) State() *StateBag { return b.statebag.(*StateBag) } -func (b *Basis) Boxes() (bc *BoxCollection, err error) { +func (b *Basis) Boxes() (bc core.BoxCollection, err error) { if b.boxCollection == nil { b.boxCollection = &BoxCollection{ basis: b, diff --git a/internal/core/project.go b/internal/core/project.go index cf01f768b..182d820a1 100644 --- a/internal/core/project.go +++ b/internal/core/project.go @@ -110,8 +110,7 @@ func (p *Project) Tmp() (path string, err error) { // DefaultPrivateKey implements core.Project func (p *Project) DefaultPrivateKey() (path string, err error) { - defaultPrivateKeyPath := p.dir.DataDir().Join("insecure_private_key") - return defaultPrivateKeyPath.String(), nil + return p.basis.DefaultPrivateKey() } // Host implements core.Project diff --git a/lib/vagrant/environment/remote.rb b/lib/vagrant/environment/remote.rb index cbea55e42..43d0bf16b 100644 --- a/lib/vagrant/environment/remote.rb +++ b/lib/vagrant/environment/remote.rb @@ -10,6 +10,7 @@ module Vagrant end end + # Client can be either a Project or a Basis def initialize(opts={}) @client = opts[:client] if @client.nil? @@ -23,11 +24,11 @@ module Vagrant opts[:ui_class] ||= UI::Remote @cwd = Pathname.new(@client.cwd) - @home_path = Pathname.new(@client.home) - @vagrantfile_name = [@client.vagrantfile_name] + @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.join("boxes") + @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) @@ -43,7 +44,7 @@ module Vagrant # TODO: aliases @aliases_path = Pathname.new(ENV["VAGRANT_ALIAS_FILE"]).expand_path if ENV.key?("VAGRANT_ALIAS_FILE") - @aliases_path ||= @home_path.join("aliases") + @aliases_path ||= @home_path && @home_path.join("aliases") @default_private_key_path = Pathname.new(@client.default_private_key) copy_insecure_private_key @@ -112,20 +113,26 @@ module Vagrant @machine_index ||= Vagrant::MachineIndex.new(client: client.target_index) end - def vagrantfile - if @vagrantfile.nil? + 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 - full_path = path.join(name).to_s - - config_loader = Vagrant::Config::Loader.new( - Vagrant::Config::VERSIONS, Vagrant::Config::VERSIONS_ORDER) - config_loader.set(:root, full_path) - @vagrantfile = Vagrant::Vagrantfile.new(config_loader, [:root]) + root_vagrantfile = path.join(name).to_s end - @vagrantfile + @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 diff --git a/lib/vagrant/protobufs/proto/vagrant_plugin_sdk/plugin_services_pb.rb b/lib/vagrant/protobufs/proto/vagrant_plugin_sdk/plugin_services_pb.rb index 929a2eacb..09c3bc78c 100644 --- a/lib/vagrant/protobufs/proto/vagrant_plugin_sdk/plugin_services_pb.rb +++ b/lib/vagrant/protobufs/proto/vagrant_plugin_sdk/plugin_services_pb.rb @@ -350,9 +350,15 @@ module Hashicorp self.unmarshal_class_method = :decode self.service_name = 'hashicorp.vagrant.sdk.BasisService' + rpc :CWD, ::Google::Protobuf::Empty, ::Hashicorp::Vagrant::Sdk::Args::Path rpc :DataDir, ::Google::Protobuf::Empty, ::Hashicorp::Vagrant::Sdk::Args::DataDir::Basis + rpc :DefaultPrivateKey, ::Google::Protobuf::Empty, ::Hashicorp::Vagrant::Sdk::Args::Path rpc :UI, ::Google::Protobuf::Empty, ::Hashicorp::Vagrant::Sdk::Args::TerminalUI rpc :Host, ::Google::Protobuf::Empty, ::Hashicorp::Vagrant::Sdk::Args::Host + rpc :Boxes, ::Google::Protobuf::Empty, ::Hashicorp::Vagrant::Sdk::Args::BoxCollection + rpc :TargetIndex, ::Google::Protobuf::Empty, ::Hashicorp::Vagrant::Sdk::Args::TargetIndex + rpc :Seed, ::Hashicorp::Vagrant::Sdk::Args::Seeds, ::Google::Protobuf::Empty + rpc :Seeds, ::Google::Protobuf::Empty, ::Hashicorp::Vagrant::Sdk::Args::Seeds end Stub = Service.rpc_stub_class diff --git a/plugins/commands/serve/client/basis.rb b/plugins/commands/serve/client/basis.rb index bea0620eb..221171397 100644 --- a/plugins/commands/serve/client/basis.rb +++ b/plugins/commands/serve/client/basis.rb @@ -2,6 +2,18 @@ module VagrantPlugins module CommandServe class Client class Basis < Client + def boxes + BoxCollection.load( + client.boxes(Empty.new), + broker: broker + ) + end + + def cwd + resp = client.cwd(Empty.new) + resp.path + end + # return [Sdk::Args::DataDir::Basis] def data_dirs resp = client.data_dir(Empty.new) @@ -13,6 +25,18 @@ module VagrantPlugins data_dirs.data_dir end + def default_private_key + resp = client.default_private_key(Empty.new) + resp.path + end + + def target_index + TargetIndex.load( + client.target_index(Empty.new), + broker: broker + ) + end + # @return [Terminal] def ui begin @@ -21,7 +45,7 @@ module VagrantPlugins broker: @broker, ) rescue => err - raise "Failed to load terminal via project: #{err}" + raise "Failed to load terminal via basis: #{err}" end end @@ -45,6 +69,14 @@ module VagrantPlugins end plugins end + + def local_data + data_dirs.data_dir + end + + def temp_dir + data_dirs.temp_dir + end end end end diff --git a/plugins/commands/serve/service/command_service.rb b/plugins/commands/serve/service/command_service.rb index 53224d1ca..f21180109 100644 --- a/plugins/commands/serve/service/command_service.rb +++ b/plugins/commands/serve/service/command_service.rb @@ -21,7 +21,7 @@ module VagrantPlugins funcspec( args: [ SDK::Args::TerminalUI, - SDK::Args::Project, + SDK::Args::Basis, SDK::Command::Arguments, ], result: SDK::Command::ExecuteResp, @@ -32,15 +32,29 @@ module VagrantPlugins with_info(ctx, broker: broker) do |info| plugin_name = info.plugin_name - _, env, arguments = mapper.funcspec_map( + ui, basis, arguments = mapper.funcspec_map( req.spec, expect: [ Vagrant::UI::Remote, - Vagrant::Environment, + SDK::Args::Basis, Type::CommandArguments ] ) + # We need a Vagrant::Environment to pass to the command. If we got a + # Project from seeds we can use that to get an environment. + # Otherwise we can initialize a barebones environment from the + # Basis we received directly from the funcspec args above. + if @seeds && @seeds.named["project"] + logger.debug("loading a full environment from project found in seeds") + project = mapper.unany(@seeds.named["project"]) + env = mapper.generate(project, type: Vagrant::Environment) + else + logger.debug("loading a minimal environment from basis provided in args") + client = Client::Basis.load(basis, broker: broker) + env = Vagrant::Environment.new(ui: ui, client: client) + end + plugin = Vagrant.plugin("2").local_manager.commands[plugin_name.to_sym].to_a.first if !plugin raise "Failed to locate command plugin for: #{plugin_name}"