Update runner to load plugins via plugin manager
This commit is contained in:
parent
e10cd26407
commit
4c8dc9a01c
@ -5,19 +5,15 @@ import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/hashicorp/go-argmapper"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"github.com/hashicorp/vagrant-plugin-sdk/component"
|
||||
"github.com/hashicorp/vagrant-plugin-sdk/internal-shared/dynamic"
|
||||
"github.com/hashicorp/vagrant-plugin-sdk/proto/vagrant_plugin_sdk"
|
||||
"github.com/hashicorp/vagrant-plugin-sdk/terminal"
|
||||
configpkg "github.com/hashicorp/vagrant/internal/config"
|
||||
"github.com/hashicorp/vagrant/internal/core"
|
||||
"github.com/hashicorp/vagrant/internal/factory"
|
||||
"github.com/hashicorp/vagrant/internal/plugin"
|
||||
"github.com/hashicorp/vagrant/internal/server/proto/vagrant_server"
|
||||
)
|
||||
@ -30,40 +26,60 @@ func (r *Runner) LoadPlugins(cfg *configpkg.Config) error {
|
||||
}
|
||||
|
||||
for _, p := range plugins {
|
||||
r.logger.Info("loading ruby plugin", "name", p.Name, "type", p.Type)
|
||||
cfg.TrackRubyPlugin(p.Name, []interface{}{p.Type})
|
||||
r.logger.Info("loading ruby plugin",
|
||||
"name", p.Name,
|
||||
"type", p.Type)
|
||||
|
||||
err = r.plugins.Register(
|
||||
plugin.RubyFactory(r.vagrantRubyRuntime, p.Name, component.Type(p.Type)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Now lets load builtin plugins
|
||||
for name, options := range plugin.Builtins {
|
||||
r.logger.Info("loading builtin plugin " + name)
|
||||
f := plugin.BuiltinFactory(name, component.PluginInfoType)
|
||||
bp, err := dynamic.CallFunc(f, (**plugin.Instance)(nil), []*argmapper.Func{},
|
||||
argmapper.Typed(r.logger))
|
||||
for name, _ := range plugin.Builtins {
|
||||
r.logger.Info("loading builtin plugin",
|
||||
"name", name)
|
||||
|
||||
err = r.plugins.Register(
|
||||
plugin.BuiltinFactory(name))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
defer bp.(*plugin.Instance).Close()
|
||||
p, ok := bp.(*plugin.Instance).Component.(component.PluginInfo)
|
||||
if !ok {
|
||||
panic("failed to convert instance to plugin info component")
|
||||
}
|
||||
typs := p.ComponentTypes()
|
||||
r.logger.Info("valid component types for builtin plugin", "name", name, "types", typs)
|
||||
cmps := []interface{}{}
|
||||
for _, t := range typs {
|
||||
cmps = append(cmps, t)
|
||||
}
|
||||
|
||||
if plugin.IN_PROCESS_PLUGINS {
|
||||
if err := r.builtinPlugins.Add(name, options...); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
cfg.TrackBuiltinPlugin(name, cmps)
|
||||
}
|
||||
|
||||
// NOTE: basis/project plugins loaded in core
|
||||
|
||||
// for name, options := range plugin.Builtins {
|
||||
// r.logger.Info("loading builtin plugin " + name)
|
||||
// f := plugin.BuiltinFactory(name, component.PluginInfoType)
|
||||
// bp, err := dynamic.CallFunc(f, (**plugin.Instance)(nil), []*argmapper.Func{},
|
||||
// argmapper.Typed(r.logger))
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
// defer bp.(*plugin.Instance).Close()
|
||||
// p, ok := bp.(*plugin.Instance).Component.(component.PluginInfo)
|
||||
// if !ok {
|
||||
// panic("failed to convert instance to plugin info component")
|
||||
// }
|
||||
// typs := p.ComponentTypes()
|
||||
// r.logger.Info("valid component types for builtin plugin", "name", name, "types", typs)
|
||||
// cmps := []interface{}{}
|
||||
// for _, t := range typs {
|
||||
// cmps = append(cmps, t)
|
||||
// }
|
||||
|
||||
// if plugin.IN_PROCESS_PLUGINS {
|
||||
// if err := r.builtinPlugins.Add(name, options...); err != nil {
|
||||
// return err
|
||||
// }
|
||||
// }
|
||||
|
||||
// cfg.TrackBuiltinPlugin(name, cmps)
|
||||
// }
|
||||
|
||||
// TODO(spox): fix this loading
|
||||
// if err == nil {
|
||||
// cfg.TrackPlugin("custom-host", []interface{}{component.HostType})
|
||||
@ -120,7 +136,7 @@ func (r *Runner) executeJob(
|
||||
opts := []core.BasisOption{
|
||||
core.WithLogger(log),
|
||||
core.WithUI(ui),
|
||||
core.WithComponents(r.factories),
|
||||
core.WithPluginManager(r.plugins),
|
||||
core.WithClient(r.client),
|
||||
core.WithJobInfo(jobInfo),
|
||||
}
|
||||
@ -206,112 +222,3 @@ func (r *Runner) executeJob(
|
||||
return nil, status.Errorf(codes.Aborted, "unknown operation %T", job.Operation)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Runner) pluginFactories(
|
||||
log hclog.Logger,
|
||||
plugins []*configpkg.Plugin,
|
||||
wd string,
|
||||
) (map[component.Type]*factory.Factory, error) {
|
||||
// Copy all our base factories first
|
||||
result := map[component.Type]*factory.Factory{}
|
||||
for k, f := range r.factories {
|
||||
result[k] = f.Copy()
|
||||
}
|
||||
|
||||
// Get our plugin search paths
|
||||
pluginPaths, err := plugin.DefaultPaths(wd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Debug("plugin search path", "path", pluginPaths)
|
||||
|
||||
// Search for all of our plugins
|
||||
var perr error
|
||||
for _, pluginCfg := range plugins {
|
||||
plog := log.With("plugin_name", pluginCfg.Name)
|
||||
|
||||
// If this is a ruby plugin, register it using the ruby factory
|
||||
if pluginCfg.Type.Ruby {
|
||||
for _, t := range pluginCfg.Types() {
|
||||
plog.Debug("registering ruby plugin", "name", pluginCfg.Name, "type", t)
|
||||
result[t].Register(
|
||||
pluginCfg.Name,
|
||||
plugin.BuiltinRubyFactory(
|
||||
r.vagrantRubyRuntime,
|
||||
pluginCfg.Name,
|
||||
t,
|
||||
),
|
||||
)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// If this a builtin plugin, register it using the builtin factory
|
||||
if pluginCfg.Type.Builtin {
|
||||
for _, t := range pluginCfg.Types() {
|
||||
plog.Debug("registering builtin plugin", "name", pluginCfg.Name, "type", t)
|
||||
if plugin.IN_PROCESS_PLUGINS {
|
||||
result[t].Register(
|
||||
pluginCfg.Name,
|
||||
r.builtinPlugins.Factory(
|
||||
pluginCfg.Name,
|
||||
t,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
result[t].Register(
|
||||
pluginCfg.Name,
|
||||
plugin.BuiltinFactory(
|
||||
pluginCfg.Name,
|
||||
t,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Now we can search for the plugin outside of vagrant
|
||||
plog.Debug("searching for plugin")
|
||||
|
||||
// Find our plugin.
|
||||
cmd, err := plugin.Discover(pluginCfg, pluginPaths)
|
||||
if err != nil {
|
||||
plog.Warn("error searching for plugin", "err", err)
|
||||
perr = multierror.Append(perr, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// If the plugin was not found, it is only an error if
|
||||
// we don't have it already registered.
|
||||
if cmd == nil {
|
||||
if _, ok := plugin.Builtins[pluginCfg.Name]; !ok {
|
||||
perr = multierror.Append(perr, fmt.Errorf(
|
||||
"plugin %q not found",
|
||||
pluginCfg.Name))
|
||||
plog.Warn("plugin not found")
|
||||
} else {
|
||||
plog.Debug("plugin found as builtin")
|
||||
for _, t := range pluginCfg.Types() {
|
||||
result[t].Register(
|
||||
pluginCfg.Name,
|
||||
plugin.BuiltinFactory(
|
||||
pluginCfg.Name,
|
||||
t,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// Register the command
|
||||
plog.Debug("plugin found as external binary", "path", cmd.Path)
|
||||
for _, t := range pluginCfg.Types() {
|
||||
result[t].Register(pluginCfg.Name, plugin.Factory(cmd, t))
|
||||
}
|
||||
}
|
||||
|
||||
return result, perr
|
||||
}
|
||||
|
||||
@ -11,10 +11,8 @@ import (
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"github.com/hashicorp/vagrant-plugin-sdk/component"
|
||||
"github.com/hashicorp/vagrant-plugin-sdk/terminal"
|
||||
intcfg "github.com/hashicorp/vagrant/internal/config"
|
||||
"github.com/hashicorp/vagrant/internal/factory"
|
||||
"github.com/hashicorp/vagrant/internal/plugin"
|
||||
|
||||
"github.com/hashicorp/vagrant/internal/server"
|
||||
@ -54,7 +52,6 @@ type Runner struct {
|
||||
ctx context.Context
|
||||
cleanupFunc func()
|
||||
runner *vagrant_server.Runner
|
||||
factories map[component.Type]*factory.Factory
|
||||
ui terminal.UI
|
||||
local bool
|
||||
tempDir string
|
||||
@ -62,6 +59,8 @@ type Runner struct {
|
||||
closedVal int32
|
||||
acceptWg sync.WaitGroup
|
||||
|
||||
plugins *plugin.Manager
|
||||
|
||||
// config is the current runner config.
|
||||
config *vagrant_server.RunnerConfig
|
||||
originalEnv []*vagrant_server.ConfigVar
|
||||
@ -89,12 +88,11 @@ func New(opts ...Option) (*Runner, error) {
|
||||
|
||||
// Our default runner
|
||||
runner := &Runner{
|
||||
id: id,
|
||||
logger: hclog.L(),
|
||||
ctx: context.Background(),
|
||||
runner: &vagrant_server.Runner{Id: id},
|
||||
opConfig: &intcfg.Config{},
|
||||
factories: plugin.BaseFactories,
|
||||
id: id,
|
||||
logger: hclog.L(),
|
||||
ctx: context.Background(),
|
||||
runner: &vagrant_server.Runner{Id: id},
|
||||
opConfig: &intcfg.Config{},
|
||||
}
|
||||
|
||||
// Build our config
|
||||
@ -107,13 +105,17 @@ func New(opts ...Option) (*Runner, error) {
|
||||
}
|
||||
|
||||
runner.logger = runner.logger.ResetNamed("vagrant.runner")
|
||||
runner.plugins = plugin.NewManager(runner.logger.Named("plugin-manager"))
|
||||
|
||||
// Setup our runner components list
|
||||
for t, f := range runner.factories {
|
||||
for _, n := range f.Registered() {
|
||||
runner.runner.Components = append(runner.runner.Components, &vagrant_server.Component{
|
||||
Type: vagrant_server.Component_Type(t),
|
||||
Name: n,
|
||||
})
|
||||
for _, p := range runner.plugins.Plugins {
|
||||
for _, t := range p.Types {
|
||||
runner.runner.Components = append(runner.runner.Components,
|
||||
&vagrant_server.Component{
|
||||
Type: vagrant_server.Component_Type(t),
|
||||
Name: t.String(),
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -173,26 +175,22 @@ func (r *Runner) Start() error {
|
||||
|
||||
log.Info("runner registered with server")
|
||||
|
||||
if plugin.IN_PROCESS_PLUGINS {
|
||||
r.builtinPlugins = plugin.NewBuiltins(context.Background(), log)
|
||||
}
|
||||
// if plugin.IN_PROCESS_PLUGINS {
|
||||
// r.builtinPlugins = plugin.NewBuiltins(context.Background(), log)
|
||||
// }
|
||||
|
||||
// track plugins
|
||||
err = r.LoadPlugins(r.opConfig)
|
||||
if err != nil {
|
||||
r.logger.Error("failed to load ruby runtime plugins", "error", err)
|
||||
r.logger.Error("unexpected failure while loading plugins",
|
||||
"error", err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
r.factories, err = r.pluginFactories(r.logger, r.opConfig.Plugins(), ".")
|
||||
if err != nil {
|
||||
r.logger.Error("failed to load plugin factories", "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if r.builtinPlugins != nil {
|
||||
r.builtinPlugins.Start()
|
||||
}
|
||||
// if r.builtinPlugins != nil {
|
||||
// r.builtinPlugins.Start()
|
||||
// }
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -255,15 +253,6 @@ func WithVagrantRubyRuntime(vrr plg.ClientProtocol) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// WithComponentFactory sets a factory for a component type. If this isn't set for
|
||||
// a component type, then the builtins will be used.
|
||||
func WithComponentFactory(t component.Type, f *factory.Factory) Option {
|
||||
return func(r *Runner, cfg *config) error {
|
||||
r.factories[t] = f
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithLogger sets the logger that the runner will use. If this isn't
|
||||
// set it uses hclog.L().
|
||||
func WithLogger(logger hclog.Logger) Option {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user