infrakit: Move the hyperkit instance plugin into the source directory

- The tools directory ideally should not contain source code
- Removes double vendoring of packagages
- Makes it easer to hook the build into the top-level Makefile

Eventually, the plugin should be moved to the infrakit repo.

Signed-off-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
This commit is contained in:
Rolf Neugebauer
2017-03-25 12:41:22 +01:00
parent 30c39863c1
commit 48845bcfd9
418 changed files with 23393 additions and 2389 deletions

View File

@@ -0,0 +1,75 @@
package instance
import (
"github.com/docker/infrakit/pkg/plugin"
rpc_client "github.com/docker/infrakit/pkg/rpc/client"
"github.com/docker/infrakit/pkg/spi/instance"
"github.com/docker/infrakit/pkg/types"
)
// NewClient returns a plugin interface implementation connected to a plugin
func NewClient(name plugin.Name, socketPath string) (instance.Plugin, error) {
rpcClient, err := rpc_client.New(socketPath, instance.InterfaceSpec)
if err != nil {
return nil, err
}
return &client{name: name, client: rpcClient}, nil
}
type client struct {
name plugin.Name
client rpc_client.Client
}
// Validate performs local validation on a provision request.
func (c client) Validate(properties *types.Any) error {
_, instanceType := c.name.GetLookupAndType()
req := ValidateRequest{Properties: properties, Type: instanceType}
resp := ValidateResponse{}
return c.client.Call("Instance.Validate", req, &resp)
}
// Provision creates a new instance based on the spec.
func (c client) Provision(spec instance.Spec) (*instance.ID, error) {
_, instanceType := c.name.GetLookupAndType()
req := ProvisionRequest{Spec: spec, Type: instanceType}
resp := ProvisionResponse{}
if err := c.client.Call("Instance.Provision", req, &resp); err != nil {
return nil, err
}
return resp.ID, nil
}
// Label labels the instance
func (c client) Label(instance instance.ID, labels map[string]string) error {
_, instanceType := c.name.GetLookupAndType()
req := LabelRequest{Type: instanceType, Instance: instance, Labels: labels}
resp := LabelResponse{}
return c.client.Call("Instance.Label", req, &resp)
}
// Destroy terminates an existing instance.
func (c client) Destroy(instance instance.ID) error {
_, instanceType := c.name.GetLookupAndType()
req := DestroyRequest{Instance: instance, Type: instanceType}
resp := DestroyResponse{}
return c.client.Call("Instance.Destroy", req, &resp)
}
// DescribeInstances returns descriptions of all instances matching all of the provided tags.
func (c client) DescribeInstances(tags map[string]string) ([]instance.Description, error) {
_, instanceType := c.name.GetLookupAndType()
req := DescribeInstancesRequest{Tags: tags, Type: instanceType}
resp := DescribeInstancesResponse{}
err := c.client.Call("Instance.DescribeInstances", req, &resp)
if err != nil {
return nil, err
}
return resp.Descriptions, nil
}

View File

@@ -0,0 +1,154 @@
package instance
import (
"fmt"
"net/http"
"github.com/docker/infrakit/pkg/spi"
"github.com/docker/infrakit/pkg/spi/instance"
)
// PluginServer returns a RPCService that conforms to the net/rpc rpc call convention.
func PluginServer(p instance.Plugin) *Instance {
return &Instance{plugin: p, typedPlugins: map[string]instance.Plugin{}}
}
// PluginServerWithTypes which supports multiple types of instance plugins. The de-multiplexing
// is done by the server's RPC method implementations.
func PluginServerWithTypes(typed map[string]instance.Plugin) *Instance {
return &Instance{typedPlugins: typed}
}
// Instance is the JSON RPC service representing the Instance Plugin. It must be exported in order to be
// registered by the rpc server package.
type Instance struct {
plugin instance.Plugin // the default plugin
typedPlugins map[string]instance.Plugin // by type, as qualified in the name of the plugin
}
// VendorInfo returns a metadata object about the plugin, if the plugin implements it.
func (p *Instance) VendorInfo() *spi.VendorInfo {
// TODO(chungers) - support typed plugins
if p.plugin == nil {
return nil
}
if m, is := p.plugin.(spi.Vendor); is {
return m.VendorInfo()
}
return nil
}
// SetExampleProperties sets the rpc request with any example properties/ custom type
func (p *Instance) SetExampleProperties(request interface{}) {
// TODO(chungers) - support typed plugins
if p.plugin == nil {
return
}
i, is := p.plugin.(spi.InputExample)
if !is {
return
}
example := i.ExampleProperties()
if example == nil {
return
}
switch request := request.(type) {
case *ValidateRequest:
request.Properties = example
case *ProvisionRequest:
request.Spec.Properties = example
}
}
// ImplementedInterface returns the interface implemented by this RPC service.
func (p *Instance) ImplementedInterface() spi.InterfaceSpec {
return instance.InterfaceSpec
}
func (p *Instance) getPlugin(instanceType string) instance.Plugin {
if instanceType == "" {
return p.plugin
}
if p, has := p.typedPlugins[instanceType]; has {
return p
}
return nil
}
// Validate performs local validation on a provision request.
func (p *Instance) Validate(_ *http.Request, req *ValidateRequest, resp *ValidateResponse) error {
c := p.getPlugin(req.Type)
if c == nil {
return fmt.Errorf("no-plugin:%s", req.Type)
}
resp.Type = req.Type
err := c.Validate(req.Properties)
if err != nil {
return err
}
resp.OK = true
return nil
}
// Provision creates a new instance based on the spec.
func (p *Instance) Provision(_ *http.Request, req *ProvisionRequest, resp *ProvisionResponse) error {
resp.Type = req.Type
c := p.getPlugin(req.Type)
if c == nil {
return fmt.Errorf("no-plugin:%s", req.Type)
}
id, err := c.Provision(req.Spec)
if err != nil {
return err
}
resp.ID = id
return nil
}
// Label labels the instance
func (p *Instance) Label(_ *http.Request, req *LabelRequest, resp *LabelResponse) error {
resp.Type = req.Type
c := p.getPlugin(req.Type)
if c == nil {
return fmt.Errorf("no-plugin:%s", req.Type)
}
err := c.Label(req.Instance, req.Labels)
if err != nil {
return err
}
resp.OK = true
return nil
}
// Destroy terminates an existing instance.
func (p *Instance) Destroy(_ *http.Request, req *DestroyRequest, resp *DestroyResponse) error {
resp.Type = req.Type
c := p.getPlugin(req.Type)
if c == nil {
return fmt.Errorf("no-plugin:%s", req.Type)
}
err := c.Destroy(req.Instance)
if err != nil {
return err
}
resp.OK = true
return nil
}
// DescribeInstances returns descriptions of all instances matching all of the provided tags.
func (p *Instance) DescribeInstances(_ *http.Request, req *DescribeInstancesRequest, resp *DescribeInstancesResponse) error {
resp.Type = req.Type
c := p.getPlugin(req.Type)
if c == nil {
return fmt.Errorf("no-plugin:%s", req.Type)
}
desc, err := c.DescribeInstances(req.Tags)
if err != nil {
return err
}
resp.Descriptions = desc
return nil
}

View File

@@ -0,0 +1,67 @@
package instance
import (
"github.com/docker/infrakit/pkg/spi/instance"
"github.com/docker/infrakit/pkg/types"
)
// ValidateRequest is the rpc wrapper for the Validate method args
type ValidateRequest struct {
Type string
Properties *types.Any
}
// ValidateResponse is the rpc wrapper for the Validate response values
type ValidateResponse struct {
Type string
OK bool
}
// ProvisionRequest is the rpc wrapper for Provision request
type ProvisionRequest struct {
Type string
Spec instance.Spec
}
// ProvisionResponse is the rpc wrapper for Provision response
type ProvisionResponse struct {
Type string
ID *instance.ID
}
// LabelRequest is the rpc wrapper for Label request
type LabelRequest struct {
Type string
Instance instance.ID
Labels map[string]string
}
// LabelResponse is the rpc wrapper for Label response
type LabelResponse struct {
Type string
OK bool
}
// DestroyRequest is the rpc wrapper for Destroy request
type DestroyRequest struct {
Type string
Instance instance.ID
}
// DestroyResponse is the rpc wrapper for Destroy response
type DestroyResponse struct {
Type string
OK bool
}
// DescribeInstancesRequest is the rpc wrapper for DescribeInstances request
type DescribeInstancesRequest struct {
Type string
Tags map[string]string
}
// DescribeInstancesResponse is the rpc wrapper for the DescribeInstances response
type DescribeInstancesResponse struct {
Type string
Descriptions []instance.Description
}