Class: Vagrant::Plugin::Remote::Manager

Inherits:
Object
  • Object
show all
Defined in:
lib/vagrant/plugin/remote/manager.rb

Overview

This class maintains a list of all the registered plugins as well as provides methods that allow querying all registered components of those plugins as a single unit.

Constant Summary collapse

WRAPPER_CLASS =

This wrapper class is used for encapsulating a remote plugin class. This block is the content for the anonymous subclass created for the remote plugin. Its job is to store the name and type of a plugin within the class context. When initialized it will use the remote plugin manager to load the proper client into the remote plugin instance. It also handles passing non-API method calls to the local instance of a plugin if the plugin exists within the Ruby runtime.

proc do |klass|
  class << klass
    # @return [String] name of the plugin (virtualbox, smb, shell, etc.)
    attr_accessor :plugin_name
    # @return [String] type of plugin (Provider, Provisioner, etc.)
    attr_accessor :type

    # @return [String]
    def name
      "Vagrant::Plugin::Remote::#{type.to_s.split(/-_/).map(&:capitalize).join}"
    end

    # @return [String]
    def to_s
      "<#{name} plugin_name=#{plugin_name}>"
    end

    # @return [String]
    def inspect
      "<#{name} plugin_name=#{plugin_name} type=#{type}>"
    end

    def inherited(klass) # :nodoc:

      klass.plugin_name = plugin_name
      klass.type = type
    end

    # @return [VagrantPlugins::Commands::Serve::Client] client for plugin
    def client
      return @client if @client
      @client = Manager.client.get_plugin(
        name: plugin_name,
        type: type
      )
    end
  end

  def initialize(*args, **kwargs, &block)
    @logger = Log4r::Logger.new(self.class.name.downcase)
    kwargs[:client] = self.class.client
    super(*args, **kwargs, &block)
    kwargs.delete(:client)
    @init = [args, kwargs, block]
  end

  # @return [String] name of plugin
  def name
    self.class.plugin_name
  end

  # @return [String]
  def inspect
    "<#{self.class.name}:#{object_id} plugin_name=#{name} type=#{self.class.type}>"
  end

  # @return [String]
  def to_s
    "<#{self.class.name}:#{object_id}>"
  end

  # If an unknown method is called on the plugin, this will check if the
  # actual plugin is local to the Ruby runtime. If it is not, a NoMethodError
  # will be generated. If it is, the local plugin will either be loaded
  # from the cache or instantiated and the method call will be executed
  # against the local plugin instance.
  def method_missing(*args, **kwargs, &block)
    klass = get_local_plugin
    return super if klass.nil?
    @logger.debug("found local plugin class #{self.class.name} -> #{klass.name}")
    c = VagrantPlugins::CommandServe.cache
    key = c.key(klass, *@init[0])
    if !c.registered?(key)
      @logger.debug("creating new local plugin instance of #{klass} with args: #{@init}")
      c.register(key, klass.new(*@init[0], **@init[1], &@init[2]))
    end
    @logger.debug("sending ##{args.first} result to local plugin #{klass}")
    c.get(key).send(*args, **kwargs, &block)
  end

  private

  # @return [Class, NilClass] class of the local plugin
  def get_local_plugin
    m = ["#{self.class.type.downcase}s",
      "#{self.class.type.downcase}es"].detect { |i|
      Vagrant.plugin("2").local_manager.respond_to?(i)
    }
    if m.nil?
      @logger.debug("failed to locate valid local plugin registry method for plugin type #{self.class.type}")
      return
    end
    klass = Array(Vagrant.plugin("2").local_manager.
      send(m)[self.class.plugin_name.to_sym]).first
    @logger.trace("local plugin lookup for #{self.class.name} / #{self.class.plugin_name} / #{self.class.type}: #{klass}")
    klass
  end
end

Class Attribute Summary collapse

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(manager) ⇒ Remote::Manager

Create a new remote plugin manager

Parameters:

  • manager (V2::Manger)


134
135
136
137
# File 'lib/vagrant/plugin/remote/manager.rb', line 134

def initialize(manager)
  @logger = Log4r::Logger.new(self.class.name.downcase)
  @real_manager = manager
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args, **kwargs, &block) ⇒ Object



139
140
141
142
# File 'lib/vagrant/plugin/remote/manager.rb', line 139

def method_missing(m, *args, **kwargs, &block)
  @logger.debug("method not defined, sending to real manager `#{m}'")
  @real_manager.send(m, *args, **kwargs, &block)
end

Class Attribute Details

.clientVagrantPlugins::Command::Serve::Client::PluginManager

Returns remote manager client.

Returns:

  • (VagrantPlugins::Command::Serve::Client::PluginManager)

    remote manager client



15
16
17
# File 'lib/vagrant/plugin/remote/manager.rb', line 15

def client
  @client
end

.core_clientVagrantPlugins::Command::Serve::Client::CorePluginManager

Returns remote manager client for core plugins.

Returns:

  • (VagrantPlugins::Command::Serve::Client::CorePluginManager)

    remote manager client for core plugins



18
19
20
# File 'lib/vagrant/plugin/remote/manager.rb', line 18

def core_client
  @core_client
end

Instance Attribute Details

#real_managerV2::Manager (readonly)

Returns:



128
129
130
# File 'lib/vagrant/plugin/remote/manager.rb', line 128

def real_manager
  @real_manager
end

Instance Method Details

#commandsRegistry

This returns all command implementations.

Returns:



178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/vagrant/plugin/remote/manager.rb', line 178

def commands
  Registry.new.tap do |result|
    plugin_manager.list_plugins(:command).each do |plg|
      sf_class = Class.new(Remote::Command, &WRAPPER_CLASS)
      sf_class.plugin_name = plg[:name]
      sf_class.type = plg[:type]
      result.register(plg[:name].to_sym) do
        [proc{sf_class}, plg[:options]]
      end
    end
  end
end

#communicatorsRegistry

This returns all communicator implementations.

Returns:



194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/vagrant/plugin/remote/manager.rb', line 194

def communicators
  Registry.new.tap do |result|
    plugin_manager.list_plugins(:communicator).each do |plg|
      sf_class = Class.new(Remote::Communicator, &WRAPPER_CLASS)
      sf_class.plugin_name = plg[:name]
      sf_class.type = plg[:type]
      result.register(plg[:name].to_sym) do
        proc{sf_class}
      end
    end
  end
end

#core_plugin_managerVagrantPlugins::Command::Serve::Client::CorePluginManager

Returns remote core manager client.

Returns:

  • (VagrantPlugins::Command::Serve::Client::CorePluginManager)

    remote core manager client



150
151
152
# File 'lib/vagrant/plugin/remote/manager.rb', line 150

def core_plugin_manager
  self.class.core_client
end

#guestsRegistry

This returns all guest implementations.

Returns:



225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/vagrant/plugin/remote/manager.rb', line 225

def guests
  Registry.new.tap do |result|
    plugin_manager.list_plugins(:guest).each do |plg|
      sf_class = Class.new(Remote::Guest, &WRAPPER_CLASS)
      sf_class.plugin_name = plg[:name]
      sf_class.type = plg[:type]
      result.register(plg[:name].to_sym) do
        proc{sf_class}
      end
    end
  end
end

#hostsRegistry

This returns all host implementations.

Returns:



241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/vagrant/plugin/remote/manager.rb', line 241

def hosts
  Registry.new.tap do |result|
    plugin_manager.list_plugins(:host).each do |plg|
      sf_class = Class.new(Remote::Host, &WRAPPER_CLASS)
      sf_class.plugin_name = plg[:name]
      sf_class.type = plg[:type]
      result.register(plg[:name].to_sym) do
        proc{sf_class}
      end
    end
  end
end

#plugin_managerVagrantPlugins::Command::Serve::Client::PluginManager

Returns remote manager client.

Returns:

  • (VagrantPlugins::Command::Serve::Client::PluginManager)

    remote manager client



145
146
147
# File 'lib/vagrant/plugin/remote/manager.rb', line 145

def plugin_manager
  self.class.client
end

#providersRegistry

This returns all provider implementations.

Returns:



257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/vagrant/plugin/remote/manager.rb', line 257

def providers
  Registry.new.tap do |result|
    plugin_manager.list_plugins(:provider).each do |plg|
      sf_class = Class.new(Remote::Provider, &WRAPPER_CLASS)
      sf_class.plugin_name = plg[:name]
      sf_class.type = plg[:type]
      result.register(plg[:name].to_sym) do
        [sf_class, plg[:options]]
      end
    end
  end
end

#provisionersObject



270
271
272
273
274
275
276
277
278
279
280
281
282
283
# File 'lib/vagrant/plugin/remote/manager.rb', line 270

def provisioners
  return real_manager.provisioners if plugin_manager.nil?

  Registry.new.tap do |result|
    plugin_manager.list_plugins(:provisioner).each do |plg|
      sf_class = Class.new(Remote::Provisioner, &WRAPPER_CLASS)
      sf_class.plugin_name = plg[:name]
      sf_class.type = plg[:type]
      result.register(plg[:name].to_sym) do
        sf_class
      end
    end
  end
end

#pushesRegistry

This returns all push implementations.

Returns:



288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/vagrant/plugin/remote/manager.rb', line 288

def pushes
  Registry.new.tap do |result|
    plugin_manager.list_plugins(:push).each do |plg|
      sf_class = Class.new(Remote::Push, &WRAPPER_CLASS)
      sf_class.plugin_name = plg[:name]
      sf_class.type = plg[:type]
      result.register(plg[:name].to_sym) do
        sf_class
      end
    end
  end
end

#synced_foldersRegistry

This returns all synced folder implementations.

Returns:



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/vagrant/plugin/remote/manager.rb', line 157

def synced_folders
  Registry.new.tap do |result|
    plugin_manager.list_plugins(:synced_folder).each do |plg|
      sf_class = Class.new(Remote::SyncedFolder, &WRAPPER_CLASS)
      sf_class.plugin_name = plg[:name]
      sf_class.type = plg[:type]
      result.register(plg[:name].to_sym) do
        # 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
end