Update plugin manager loading. Add ruby client.
This commit is contained in:
parent
a8fd255f5b
commit
1134a4e5ed
@ -27,6 +27,16 @@ func NewInternal(
|
||||
}
|
||||
}
|
||||
|
||||
func Internal(l hclog.Logger, m []*argmapper.Func) *internal {
|
||||
return &internal{
|
||||
broker: nil,
|
||||
cache: cacher.New(),
|
||||
cleanup: cleanup.New(),
|
||||
logger: l,
|
||||
mappers: m,
|
||||
}
|
||||
}
|
||||
|
||||
type internal struct {
|
||||
broker *plugin.GRPCBroker
|
||||
cache cacher.Cache
|
||||
|
||||
@ -41,6 +41,7 @@ var (
|
||||
|
||||
type PluginRegistration func(hclog.Logger) (*Plugin, error)
|
||||
type PluginConfigurator func(*Instance, hclog.Logger) error
|
||||
type PluginInitializer func(*Plugin, hclog.Logger) error
|
||||
|
||||
type componentCache map[string]componentEntry
|
||||
type componentEntry map[component.Type]*Instance
|
||||
@ -56,16 +57,22 @@ type Manager struct {
|
||||
discoveredPaths []path.Path // List of paths this manager has loaded
|
||||
dispenseFuncs []PluginConfigurator // Configuration functions applied to instances
|
||||
instances componentCache // Cache for prevlous generated components
|
||||
initFuncs []PluginInitializer // Initializer functions applied to plugins at creation
|
||||
legacyLoaded bool // Flag that legacy plugins have been loaded
|
||||
legacyBroker *plugin.GRPCBroker // Broker for legacy runtime
|
||||
logger hclog.Logger // Logger for the manager
|
||||
m sync.Mutex
|
||||
parent *Manager // Parent manager if this is a sub manager
|
||||
srv []byte // Marshalled proto message for plugin manager
|
||||
rubyC *serverclient.RubyVagrantClient // Client to the Ruby runtime
|
||||
parent *Manager // Parent manager if this is a sub manager
|
||||
srv []byte // Marshalled proto message for plugin manager
|
||||
}
|
||||
|
||||
// Create a new plugin manager
|
||||
func NewManager(ctx context.Context, l hclog.Logger) *Manager {
|
||||
func NewManager(
|
||||
ctx context.Context, // context for the manager
|
||||
r *serverclient.RubyVagrantClient, // client to the ruby runtime
|
||||
l hclog.Logger, // logger
|
||||
) *Manager {
|
||||
return &Manager{
|
||||
Plugins: []*Plugin{},
|
||||
builtins: NewBuiltins(ctx, l),
|
||||
@ -75,9 +82,18 @@ func NewManager(ctx context.Context, l hclog.Logger) *Manager {
|
||||
dispenseFuncs: []PluginConfigurator{},
|
||||
instances: make(componentCache),
|
||||
logger: l,
|
||||
rubyC: r,
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the client to the Ruby runtime
|
||||
func (m *Manager) RubyClient() *serverclient.RubyVagrantClient {
|
||||
if m.parent != nil {
|
||||
return m.parent.RubyClient()
|
||||
}
|
||||
return m.rubyC
|
||||
}
|
||||
|
||||
// Create a sub manager based off current manager
|
||||
func (m *Manager) Sub(name string) *Manager {
|
||||
if name == "" {
|
||||
@ -326,7 +342,13 @@ func (m *Manager) Configure(fn PluginConfigurator) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Find a specific plugin by name and component type
|
||||
// Add initializer to be applied to plugin when created
|
||||
func (m *Manager) Initializer(fn PluginInitializer) error {
|
||||
m.initFuncs = append(m.initFuncs, fn)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Find a component instance by plugin name and component type
|
||||
func (m *Manager) Find(
|
||||
n string, // Name of the plugin
|
||||
t component.Type, // component type of plugin
|
||||
@ -337,6 +359,24 @@ func (m *Manager) Find(
|
||||
return m.find(n, t)
|
||||
}
|
||||
|
||||
// Get a plugin by name
|
||||
func (m *Manager) Get(
|
||||
n string, // Name of the plugin
|
||||
t component.Type, // component type supported by plugin
|
||||
) (*Plugin, error) {
|
||||
for _, p := range m.Plugins {
|
||||
if p.Name == n && p.HasType(t) {
|
||||
return p, nil
|
||||
}
|
||||
}
|
||||
|
||||
if m.parent != nil {
|
||||
return m.parent.Get(n, t)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("failed to locate plugin %s implementing component %s", n, t.String())
|
||||
}
|
||||
|
||||
// Find all plugins which support a specific component type
|
||||
func (m *Manager) Typed(
|
||||
t component.Type, // Type of plugins
|
||||
@ -348,6 +388,10 @@ func (m *Manager) Typed(
|
||||
for _, p := range m.Plugins {
|
||||
if p.HasType(t) {
|
||||
result = append(result, p.Name)
|
||||
m.logger.Trace("found typed plugin match",
|
||||
"type", t.String(),
|
||||
"name", p.Name,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -524,6 +568,13 @@ func (m *Manager) register(
|
||||
}
|
||||
plg.manager = m
|
||||
|
||||
// Run initializers on new plugin
|
||||
for _, fn := range m.initFuncs {
|
||||
if err = fn(plg, m.logger); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
m.Plugins = append(m.Plugins, plg)
|
||||
return
|
||||
}
|
||||
@ -597,10 +648,6 @@ func (m *Manager) fetch(
|
||||
t component.Type, // type of component
|
||||
c []PluginConfigurator,
|
||||
) (i *Instance, err error) {
|
||||
m.logger.Info("configurators for use by fetch function",
|
||||
"passed-count", len(c),
|
||||
"local-count", len(m.dispenseFuncs),
|
||||
)
|
||||
var cfns []PluginConfigurator
|
||||
if len(c) > 0 {
|
||||
l := len(c) + len(m.dispenseFuncs)
|
||||
@ -615,7 +662,7 @@ func (m *Manager) fetch(
|
||||
// and generate the component instance
|
||||
for _, p := range m.Plugins {
|
||||
if p.Name == n && p.HasType(t) {
|
||||
return p.InstanceOf(t, cfns)
|
||||
return p.instanceOf(t, cfns)
|
||||
}
|
||||
}
|
||||
|
||||
@ -650,7 +697,7 @@ func (m *Manager) isCacheable(t component.Type) bool {
|
||||
func (m *Manager) loadParent(i *Instance) error {
|
||||
c, ok := i.Component.(HasParent)
|
||||
if !ok {
|
||||
m.logger.Debug("component component does not support parents",
|
||||
m.logger.Trace("component does not support parents",
|
||||
"type", i.Type.String(),
|
||||
"name", i.Name,
|
||||
)
|
||||
|
||||
@ -15,6 +15,7 @@ import (
|
||||
"github.com/hashicorp/vagrant-plugin-sdk/core"
|
||||
"github.com/hashicorp/vagrant-plugin-sdk/internal-shared/cacher"
|
||||
"github.com/hashicorp/vagrant-plugin-sdk/internal-shared/cleanup"
|
||||
"github.com/hashicorp/vagrant/builtin/configvagrant"
|
||||
"github.com/hashicorp/vagrant/builtin/httpdownloader"
|
||||
"github.com/hashicorp/vagrant/builtin/myplugin"
|
||||
"github.com/hashicorp/vagrant/builtin/otherplugin"
|
||||
@ -32,6 +33,7 @@ var (
|
||||
// Builtins is the map of all available builtin plugins and their
|
||||
// options for launching them.
|
||||
Builtins = map[string][]sdk.Option{
|
||||
"configvagrant": configvagrant.CommandOptions,
|
||||
"myplugin": myplugin.CommandOptions,
|
||||
"otherplugin": otherplugin.CommandOptions,
|
||||
"httpdownloader": httpdownloader.PluginOptions,
|
||||
@ -77,6 +79,23 @@ type HasParent interface {
|
||||
SetParentComponent(interface{})
|
||||
}
|
||||
|
||||
// Returns the plugin manager instance this plugin is attached
|
||||
func (p *Plugin) Manager() *Manager {
|
||||
return p.manager
|
||||
}
|
||||
|
||||
// Get a component from the plugin. This will load the component via
|
||||
// the configured plugin manager so all expected caching and configuration
|
||||
// will occur.
|
||||
func (p *Plugin) Component(t component.Type) (interface{}, error) {
|
||||
i, err := p.manager.Find(p.Name, t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return i.Component, nil
|
||||
}
|
||||
|
||||
// Check if plugin implements specific component type
|
||||
func (p *Plugin) HasType(
|
||||
t component.Type,
|
||||
@ -102,8 +121,11 @@ func (p *Plugin) Close() (err error) {
|
||||
return p.cleaner.Close()
|
||||
}
|
||||
|
||||
// Get specific component type from plugin
|
||||
func (p *Plugin) InstanceOf(
|
||||
// Get specific component type from plugin. This is not exported
|
||||
// as it should not be called directly. The plugin manager should
|
||||
// be used for loading component instances so all callbacks are
|
||||
// applied appropriately and caching will be respected
|
||||
func (p *Plugin) instanceOf(
|
||||
c component.Type,
|
||||
cfns []PluginConfigurator,
|
||||
) (i *Instance, err error) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user