diff --git a/internal/plugin/manager.go b/internal/plugin/manager.go index edec00d63..36a10dda1 100644 --- a/internal/plugin/manager.go +++ b/internal/plugin/manager.go @@ -436,8 +436,9 @@ func (m *Manager) ListPlugins(typeNames ...string) ([]*core.NamedPlugin, error) } for _, p := range list { i := &core.NamedPlugin{ - Type: t.String(), - Name: p, + Type: t.String(), + Name: p, + Options: m.optionsForPlugin(t, p), } result = append(result, i) } @@ -728,3 +729,20 @@ func (m *Manager) loadParent(i *Instance) error { return nil } + +// optionsForPlugin fetches the options that were registered for a given +// plugin. the return type will be one of component.*Options. If the plugin is +// not found or has no options, returns nil. +func (m *Manager) optionsForPlugin(t component.Type, name string) interface{} { + for _, p := range m.Plugins { + if p.Name == name && p.HasType(t) { + return p.Options[t] + } + } + + if m.parent != nil { + return m.parent.optionsForPlugin(t, name) + } + + return nil +} diff --git a/lib/vagrant/machine/remote.rb b/lib/vagrant/machine/remote.rb index aefee0995..dedce8f73 100644 --- a/lib/vagrant/machine/remote.rb +++ b/lib/vagrant/machine/remote.rb @@ -44,7 +44,6 @@ module Vagrant @state_mutex = Mutex.new # TODO: get trigger config from go @triggers = Vagrant::Plugin::V2::Trigger.new(@env, @config.trigger, self, @ui) - @provider_options = {} # @config.vm.get_provider_overrides(@provider_name) # Keep track of where our UUID should be placed @index_uuid_file = nil @@ -154,7 +153,7 @@ module Vagrant end def provider_options - @provider_options + @provider_options ||= Vagrant.plugin("2").manager.provider[provider_name].last end def recover_machine(*_) diff --git a/lib/vagrant/plugin/remote/manager.rb b/lib/vagrant/plugin/remote/manager.rb index e0883fe3a..26b37637e 100644 --- a/lib/vagrant/plugin/remote/manager.rb +++ b/lib/vagrant/plugin/remote/manager.rb @@ -148,13 +148,6 @@ module Vagrant self.class.core_client end - # Synced folder plugins are registered with an integer priority, but in - # remote mode this is all captured by InternalService#get_plugins and - # handled on the Go sidw. Within the remote manager we return a stub - # value to ensure that any callers get the same shape of return value - # from the registry and don't blow up. - SYNCED_FOLDERS_STUB_PRIORITY = 123 - # This returns all synced folder implementations. # # @return [Registry] @@ -165,7 +158,12 @@ module Vagrant sf_class.plugin_name = plg[:name] sf_class.type = plg[:type] result.register(plg[:name].to_sym) do - [sf_class, SYNCED_FOLDERS_STUB_PRIORITY] + # The integer priority has already been captured on the Go side + # by InternalService#get_plugins. It's returned in the plugin + # options field, and we populate it into the same place for + # good measure, even though we expect that priority will be + # handled on the Go side now. + [sf_class, plg[:options]] end end end @@ -260,8 +258,7 @@ module Vagrant sf_class.plugin_name = plg[:name] sf_class.type = plg[:type] result.register(plg[:name].to_sym) do - # TODO: Options hash should be what? - [sf_class, {}] + [sf_class, plg[:options]] end end end diff --git a/lib/vagrant/protobufs/proto/vagrant_plugin_sdk/plugin_pb.rb b/lib/vagrant/protobufs/proto/vagrant_plugin_sdk/plugin_pb.rb index 006c5898a..49753288e 100644 --- a/lib/vagrant/protobufs/proto/vagrant_plugin_sdk/plugin_pb.rb +++ b/lib/vagrant/protobufs/proto/vagrant_plugin_sdk/plugin_pb.rb @@ -457,6 +457,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do optional :name, :string, 1 optional :type, :string, 2 optional :plugin, :message, 3, "google.protobuf.Any" + optional :options, :message, 4, "google.protobuf.Any" end add_message "hashicorp.vagrant.sdk.CorePluginManager" do end diff --git a/plugins/commands/serve/client/plugin_manager.rb b/plugins/commands/serve/client/plugin_manager.rb index 44970afe7..8aee31040 100644 --- a/plugins/commands/serve/client/plugin_manager.rb +++ b/plugins/commands/serve/client/plugin_manager.rb @@ -12,7 +12,8 @@ module VagrantPlugins Vagrant::Util::HashWithIndifferentAccess.new( name: plg.name, type: plg.type, - proto: plg.plugin + proto: plg.plugin, + options: _plugin_options_to_hash(plg.options), ) end end @@ -27,6 +28,25 @@ module VagrantPlugins ) mapper.map(resp.plugin, broker) end + + # Plugin options are an Any that contains one of the types defined in + # component.*Options in the SDK. + # + # On the Ruby side, plugin options are just a value that get stuffed in + # a tuple next to the plugin in the manager. Its type is context + # dependent so we need to unpack each kind of plugin options with its + # own logic. + def _plugin_options_to_hash(plg_opts) + opts = mapper.unany(plg_opts) + case opts + when Hashicorp::Vagrant::Sdk::PluginInfo::ProviderOptions + opts.to_h + when Hashicorp::Vagrant::Sdk::PluginInfo::SyncedFolderOptions + opts.priority + else + raise ArgumentError, "unexpected plugin options #{opts.inspect}" + end + end end end end diff --git a/plugins/kernel_v2/config/vm.rb b/plugins/kernel_v2/config/vm.rb index ff97b7a9c..a23c8a00b 100644 --- a/plugins/kernel_v2/config/vm.rb +++ b/plugins/kernel_v2/config/vm.rb @@ -761,12 +761,7 @@ module VagrantPlugins @allow_fstab_modification = true if @allow_fstab_modification == UNSET_VALUE end - # HACK(phinze): We cannot honor box_optional in gogo yet so we are - # temporarily hacking in a workaround which explicitly looks for docker - # instead of the option itself. Once plugin metadata is implemented - # this conditional should be reverted to the commented line below - # if !box && !clone && !machine.provider_options[:box_optional] - if !box && !clone && machine.provider_name != :docker + if !box && !clone && !machine.provider_options[:box_optional] errors << I18n.t("vagrant.config.vm.box_missing") end