125 lines
2.7 KiB
Go
125 lines
2.7 KiB
Go
package core
|
|
|
|
import (
|
|
"context"
|
|
// "fmt"
|
|
|
|
"github.com/hashicorp/go-argmapper"
|
|
|
|
"github.com/hashicorp/vagrant-plugin-sdk/component"
|
|
"github.com/hashicorp/vagrant/internal/config"
|
|
"github.com/hashicorp/vagrant/internal/plugin"
|
|
"github.com/hashicorp/vagrant/internal/server/proto/vagrant_server"
|
|
)
|
|
|
|
type Component struct {
|
|
Value interface{}
|
|
Info *vagrant_server.Component
|
|
|
|
// These fields can be accessed internally
|
|
hooks map[string][]*config.Hook
|
|
labels map[string]string
|
|
mappers []*argmapper.Func
|
|
|
|
// These are private, please do not access them ever except as an
|
|
// internal Component implementation detail.
|
|
closed bool
|
|
plugin *plugin.Instance
|
|
}
|
|
|
|
// Close cleans up any resources associated with the Component. Close should
|
|
// always be called when the component is done being used.
|
|
func (c *Component) Close() error {
|
|
if c == nil {
|
|
return nil
|
|
}
|
|
|
|
// If we closed already do nothing.
|
|
if c.closed {
|
|
return nil
|
|
}
|
|
|
|
c.closed = true
|
|
if c.plugin != nil {
|
|
c.plugin.Close()
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// componentCreator represents the configuration to initialize the component
|
|
// for a given application.
|
|
type componentCreator struct {
|
|
Type component.Type
|
|
}
|
|
|
|
// componentCreatorMap contains all the components that can be initialized
|
|
// for an app.
|
|
var componentCreatorMap = map[component.Type]*componentCreator{
|
|
component.CommandType: {
|
|
Type: component.CommandType,
|
|
},
|
|
component.ProviderType: {
|
|
Type: component.ProviderType,
|
|
},
|
|
component.HostType: {
|
|
Type: component.HostType,
|
|
},
|
|
}
|
|
|
|
// Create creates the component of the given type.
|
|
func (cc *componentCreator) Create(
|
|
ctx context.Context,
|
|
scope interface{},
|
|
pluginName string,
|
|
) (*Component, error) {
|
|
s, ok := scope.(interface {
|
|
startPlugin(context.Context, component.Type, string) (*plugin.Instance, error)
|
|
})
|
|
if !ok {
|
|
panic("the scope provided is invalid")
|
|
}
|
|
|
|
// Start the plugin
|
|
pinst, err := s.startPlugin(
|
|
ctx,
|
|
cc.Type,
|
|
pluginName,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// TODO: configure
|
|
// If we have a config, configure
|
|
// Configure the component. This will handle all the cases where no
|
|
// config is given but required, vice versa, and everything in between.
|
|
// diag := component.Configure(pinst.Component, opCfg.Use.Body, hclCtx)
|
|
// if diag.HasErrors() {
|
|
// pinst.Close()
|
|
// return nil, diag
|
|
// }
|
|
|
|
// TODO: Setup hooks
|
|
hooks := map[string][]*config.Hook{}
|
|
// for _, h := range opCfg.Hooks {
|
|
// hooks[h.When] = append(hooks[h.When], h)
|
|
// }
|
|
|
|
return &Component{
|
|
Value: pinst.Component,
|
|
Info: &vagrant_server.Component{
|
|
Type: vagrant_server.Component_Type(cc.Type),
|
|
Name: pluginName,
|
|
},
|
|
|
|
hooks: hooks,
|
|
mappers: pinst.Mappers,
|
|
plugin: pinst,
|
|
}, nil
|
|
}
|
|
|
|
type pluginer interface {
|
|
startPlugin(context.Context, component.Type, string) (*plugin.Instance, error)
|
|
}
|