diff --git a/plugins/commands/serve/service/communicator_service.rb b/plugins/commands/serve/service/communicator_service.rb index 02da19a40..373abe7b2 100644 --- a/plugins/commands/serve/service/communicator_service.rb +++ b/plugins/commands/serve/service/communicator_service.rb @@ -15,14 +15,12 @@ module VagrantPlugins end def ready(req, ctx) - with_info(ctx, broker: broker) do |info| - plugin_name = info.plugin_name + with_plugin(ctx, :communicators, broker: broker) do |plugin| machine = mapper.funcspec_map( req, mapper, broker, expect: [Vagrant::Machine] ) - plugin = Vagrant.plugin("2").manager.communicators[plugin_name.to_s.to_sym] - communicator = plugin.new(machine) + communicator = load_communicator(plugin, machine) ready = communicator.ready? SDK::Communicator::ReadyResp.new( ready: ready @@ -41,16 +39,15 @@ module VagrantPlugins end def wait_for_ready(req, ctx) - with_info(ctx, broker: broker) do |info| - plugin_name = info.plugin_name + with_plugin(ctx, :communicators, broker: broker) do |plugin| machine, wait_duration = mapper.funcspec_map( req, mapper, broker, expect: [Vagrant::Machine, SDK::Args::TimeDuration] ) - plugin = Vagrant.plugin("2").manager.communicators[plugin_name.to_s.to_sym] + communicator = load_communicator(plugin, machine) begin - ready = plugin.new(machine).wait_for_ready(wait_duration.duration) + ready = communicator.wait_for_ready(wait_duration.duration) rescue => err logger.error(err) logger.debug("#{err.class}: #{err}\n#{err.backtrace.join("\n")}") @@ -77,8 +74,7 @@ module VagrantPlugins def download(req, ctx) logger.debug("Downloading") - with_info(ctx, broker: broker) do |info| - plugin_name = info.plugin_name + with_plugin(ctx, :communicators, broker: broker) do |plugin| dest_proto = req.args.select{ |a| a.name == "destination" }.first to = mapper.map(dest_proto.value, to: Pathname).to_s source_proto = req.args.select{ |a| a.name == "source" }.first @@ -89,8 +85,7 @@ module VagrantPlugins expect: [Vagrant::Machine] ) - plugin = Vagrant.plugin("2").manager.communicators[plugin_name.to_s.to_sym] - communicator = plugin.new(machine) + communicator = load_communicator(plugin, machine) communicator.download(from, to) Empty.new end @@ -110,8 +105,7 @@ module VagrantPlugins def upload(req, ctx) logger.debug("Uploading") - with_info(ctx, broker: broker) do |info| - plugin_name = info.plugin_name + with_plugin(ctx, :communicators, broker: broker) do |plugin| dest_proto = req.args.select{ |a| a.name == "destination" }.first to = mapper.map(dest_proto.value, to: Pathname).to_s source_proto = req.args.select{ |a| a.name == "source" }.first @@ -122,8 +116,7 @@ module VagrantPlugins expect: [Vagrant::Machine] ) - plugin = Vagrant.plugin("2").manager.communicators[plugin_name.to_s.to_sym] - communicator = plugin.new(machine) + communicator = load_communicator(plugin, machine) communicator.upload(from, to) Empty.new end @@ -141,16 +134,14 @@ module VagrantPlugins end def execute(req, ctx) - with_info(ctx, broker: broker) do |info| - plugin_name = info.plugin_name + with_plugin(ctx, :communicators, broker: broker) do |plugin| logger.debug("got req: #{req}") machine, cmd, opts = mapper.funcspec_map( req, mapper, broker, expect: [Vagrant::Machine, SDK::Communicator::Command, Type::Options] ) - plugin = Vagrant.plugin("2").manager.communicators[plugin_name.to_s.to_sym] - communicator = plugin.new(machine) + communicator = load_communicator(plugin, machine) output = {stdout: '', stderr: ''} exit_code = communicator.execute(cmd.command, opts.value) { |type, data| output[type] << data if output[type] @@ -176,15 +167,13 @@ module VagrantPlugins end def privileged_execute(req, ctx) - with_info(ctx, broker: broker) do |info| - plugin_name = info.plugin_name + with_plugin(ctx, :communicators, broker: broker) do |plugin| machine, cmd, opts = mapper.funcspec_map( req, mapper, broker, expect: [Vagrant::Machine, SDK::Communicator::Command, Type::Options] ) - plugin = Vagrant.plugin("2").manager.communicators[plugin_name.to_s.to_sym] - communicator = plugin.new(machine) + communicator = load_communicator(plugin, machine) output = {stdout: '', stderr: ''} exit_code = communicator.sudo(cmd.command, opts.value) { |type, data| output[type] << data if output[type] @@ -210,15 +199,13 @@ module VagrantPlugins end def test(req, ctx) - with_info(ctx, broker: broker) do |info| - plugin_name = info.plugin_name + with_plugin(ctx, :communicators, broker: broker) do |plugin| machine, cmd, opts = mapper.funcspec_map( req, mapper, broker, expect: [Vagrant::Machine, SDK::Communicator::Command, Type::Options] ) - plugin = Vagrant.plugin("2").manager.communicators[plugin_name.to_s.to_sym] - communicator = plugin.new(machine) + communicator = load_communicator(plugin, machine) valid = communicator.test(cmd.command, opts.value) logger.debug("command is valid?: #{valid}") @@ -237,19 +224,25 @@ module VagrantPlugins end def reset(req, ctx) - with_info(ctx, broker: broker) do |info| - plugin_name = info.plugin_name + with_plugin(ctx, :communicators, broker: broker) do |plugin| machine = mapper.funcspec_map( req, mapper, broker, expect: [Vagrant::Machine] ) - plugin = Vagrant.plugin("2").manager.communicators[plugin_name.to_s.to_sym] - communicator = plugin.new(machine) + communicator = load_communicator(plugin, machine) communicator.reset Empty.new end end + + def load_communicator(klass, machine) + key = cache.key(klass, machine) + return cache.get(key) if cache.registered?(key) + klass.new(machine).tap do |i| + cache.register(key, i) + end + end end end end diff --git a/plugins/commands/serve/service/guest_service.rb b/plugins/commands/serve/service/guest_service.rb index 139307c30..ded12103b 100644 --- a/plugins/commands/serve/service/guest_service.rb +++ b/plugins/commands/serve/service/guest_service.rb @@ -24,22 +24,16 @@ module VagrantPlugins end def detect(req, ctx) - with_info(ctx, broker: broker) do |info| - plugin_name = info.plugin_name + with_plugin(ctx, :guests, broker: broker) do |plugin, info| machine = mapper.funcspec_map(req, expect: Vagrant::Machine) - plugin = Vagrant.plugin("2").local_manager.guests[plugin_name.to_s.to_sym].to_a.first - if !plugin - logger.debug("Failed to locate guest plugin for: #{plugin_name}") - raise "Failed to locate guest plugin for: #{plugin_name.inspect}" - end - guest = plugin.new + guest = load_guest(plugin) begin detected = guest.detect?(machine) rescue => err logger.debug("error encountered detecting guest: #{err.class} - #{err}") detected = false end - logger.debug("detected #{detected} for guest #{plugin_name}") + logger.debug("detected #{detected} for guest #{info.plugin_name}") SDK::Platform::DetectResp.new( detected: detected, ) @@ -53,13 +47,13 @@ module VagrantPlugins def parent(req, ctx) with_info(ctx, broker: broker) do |info| plugin_name = info.plugin_name - guest_hash = Vagrant.plugin("2").local_manager.guests[plugin_name.to_s.to_sym].to_a - plugin = guest_hash.first - if !plugin + guest_info = Array(Vagrant.plugin("2").local_manager.guests[plugin_name]) + if !guest_info.first raise "Failed to locate guest plugin for: #{plugin_name.inspect}" end + # TODO: shouldn't this be checking length? SDK::Platform::ParentResp.new( - parent: guest_hash.last + parent: guest_info.last ) end end @@ -73,6 +67,14 @@ module VagrantPlugins nargs end + + def load_guest(klass) + key = cache.key(klass) + return cache.get(key) if cache.registered?(key) + klass.new.tap do |i| + cache.register(key, i) + end + end end end end diff --git a/plugins/commands/serve/service/host_service.rb b/plugins/commands/serve/service/host_service.rb index bb6146826..86e7fbb42 100644 --- a/plugins/commands/serve/service/host_service.rb +++ b/plugins/commands/serve/service/host_service.rb @@ -26,21 +26,16 @@ module VagrantPlugins end def detect(req, ctx) - with_info(ctx, broker: broker) do |info| - plugin_name = info.plugin_name + with_plugin(ctx, :hosts, broker: broker) do |plugin, info| statebag = mapper.funcspec_map(req, expect: Client::StateBag) - plugin = Vagrant.plugin("2").local_manager.hosts[plugin_name.to_s.to_sym].to_a.first - if !plugin - raise "Failed to locate host plugin for: #{plugin_name.inspect}" - end - host = plugin.new + host = load_host(plugin) begin detected = host.detect?(statebag) rescue => err logger.debug("error encountered detecting host: #{err.class} - #{err}") detected = false end - logger.debug("detected #{detected} for host #{plugin_name}") + logger.debug("detected #{detected} for host #{info.plugin_name}") SDK::Platform::DetectResp.new( detected: detected, ) @@ -56,16 +51,24 @@ module VagrantPlugins def parent(req, ctx) with_info(ctx, broker: broker) do |info| plugin_name = info.plugin_name - host_hash = Vagrant.plugin("2").local_manager.hosts[plugin_name.to_s.to_sym].to_a - plugin = host_hash.first - if !plugin + host_info = Array(Vagrant.plugin("2").local_manager.hosts[plugin_name]) + if !host_info.first raise "Failed to locate host plugin for: #{plugin_name.inspect}" end + # TODO: shouldn't this be checking length? SDK::Platform::ParentResp.new( - parent: host_hash.last + parent: host_info.last ) end end + + def load_host(klass) + key = cache.key(klass) + return cache.get(key) if cache.registered?(key) + klass.new.tap do |i| + cache.register(key, i) + end + end end end end diff --git a/plugins/commands/serve/service/provider_service.rb b/plugins/commands/serve/service/provider_service.rb index 4f1ad3c15..02e206a7a 100644 --- a/plugins/commands/serve/service/provider_service.rb +++ b/plugins/commands/serve/service/provider_service.rb @@ -82,7 +82,7 @@ module VagrantPlugins def machine_id_changed(req, ctx) with_plugin(ctx, :providers, broker: broker) do |plugin| machine = mapper.funcspec_map(req, expect: [Vagrant::Machine]) - provider = plugin.new(machine) + provider = load_provider(plugin, machine) provider.machine_id_changed end Empty.new @@ -100,7 +100,7 @@ module VagrantPlugins def ssh_info(req, ctx) with_plugin(ctx, :providers, broker: broker) do |plugin| machine = mapper.funcspec_map(req, expect: [Vagrant::Machine]) - provider = plugin.new(machine) + provider = load_provider(plugin, machine) info = provider.ssh_info info[:port] = info[:port].to_s if info.key?(:port) return SDK::Args::Connection::SSHInfo.new(**info) @@ -119,7 +119,7 @@ module VagrantPlugins def state(req, ctx) with_plugin(ctx, :providers, broker: broker) do |plugin| machine = mapper.funcspec_map(req, expect: [Vagrant::Machine]) - provider = plugin.new(machine) + provider = load_provider(plugin, machine) machine_state = provider.state return mapper.map(machine_state, to: SDK::Args::Target::Machine::State) end @@ -138,6 +138,14 @@ module VagrantPlugins ) machine.env.action_runner.run(callable, env) end + + def load_provider(klass, machine) + key = cache.key(klass, machine) + return cache.get(key) if cache.registered?(key) + klass.new(machine).tap do |i| + cache.register(key, i) + end + end end end end diff --git a/plugins/commands/serve/service/synced_folder_service.rb b/plugins/commands/serve/service/synced_folder_service.rb index fb5204763..34ecf0598 100644 --- a/plugins/commands/serve/service/synced_folder_service.rb +++ b/plugins/commands/serve/service/synced_folder_service.rb @@ -28,7 +28,7 @@ module VagrantPlugins machine = mapper.funcspec_map( req, expect: [Vagrant::Machine] ) - sf = plugin.new + sf = load_synced_folder(plugin) usable = sf.usable?(machine) SDK::SyncedFolder::UsableResp.new( usable: usable, @@ -56,7 +56,7 @@ module VagrantPlugins # change the top level folders hash key to a string folders = folders.value folders.transform_keys!(&:to_s) - sf = plugin.new + sf = load_synced_folder(plugin) sf.prepare(machine, folders, opts.value) Empty.new end @@ -81,7 +81,7 @@ module VagrantPlugins # change the top level folders hash key to a string folders = folders.value folders.transform_keys!(&:to_s) - sf = plugin.new + sf = load_synced_folder(plugin) sf.enable(machine, folders, opts.value) Empty.new end @@ -106,7 +106,7 @@ module VagrantPlugins # change the top level folders hash key to a string folders = folders.value folders.transform_keys!(&:to_s) - sf = plugin.new + sf = load_synced_folder(plugin) sf.disable(machine, folders, opts.value) Empty.new end @@ -128,11 +128,19 @@ module VagrantPlugins expect: [Vagrant::Machine, Type::Options] ) - sf = plugin.new + sf = load_synced_folder(plugin) sf.cleanup(machine, opts.value) Empty.new end end + + def load_synced_folder(klass) + key = cache.key(klass) + return cache.get(key) if cache.registered?(key) + klass.new.tap do |i| + cache.register(key, i) + end + end end end end