Skip to content
This repository was archived by the owner on Jan 21, 2020. It is now read-only.

Enrollment controller #678

Merged
merged 15 commits into from
Sep 10, 2017
Merged
1 change: 1 addition & 0 deletions cmd/infrakit/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (

// Supported "kinds"
_ "github.com/docker/infrakit/pkg/run/v0/aws"
_ "github.com/docker/infrakit/pkg/run/v0/enrollment"
_ "github.com/docker/infrakit/pkg/run/v0/file"
_ "github.com/docker/infrakit/pkg/run/v0/group"
_ "github.com/docker/infrakit/pkg/run/v0/hyperkit"
Expand Down
79 changes: 79 additions & 0 deletions docs/controller/enrollment/example.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#
#
# Example for enrollment controller
#
# Enrollment controller makes sure the instances in the source group (specified
# by the List field) are in sync with entries in the downstream instance plugin
# specified by Instance field.
#
# This example uses swarm as backend. So be sure your swarm on the same host
# is a leader via `docker swarm init`.
#
#
# 1. Start up all the plugins:
# INFRAKIT_MANAGER_BACKEND=swarm build/infrakit plugin start manager group \
# enrollment:nfs \
# simulator:nfs-auth simulator:simulator vanilla
#
# This starts up the group at 'us-east', one simulator at 'nfs' and another at 'simulator'
#
# 2. Commit the group to create the groups -- see the group.yml included.
#
# infrakit group controller commit -y docs/controller/enrollment/group.yml
#
# Verify the group has workers:
#
# infrakit group/workers describe
#
# 3. Commit this file to create the enrollments
#
# infrakit nfs controller commit -y docs/controller/enrollment/example.yml
#
# 4. Verify that entries are in sync: check the group describe and nfs-auth/disk (that's
# the Plugin specified in the Instance section of this config.
#
# infrakit group/workers describe # returns the list of nodes in the group
# infrakit infrakit nfs-auth/disk describe # returns the list of corresponding enrollments
#
# For each member of the group workers you should see a corresponding entry in the enrollments.
# Note that the instance ID of an enrollment (in nfs-auth/disk) will be different from the instance
# ID of a member in group/workers; however, the ID of a member of group/workers should show up as
# a label in the instance of nfs-auth/disk (as infrakit.enrollment.sourceID).
#
# 5. Try scale up the workers group
#
# infrakit group/workers scale 10
#
# After a while, verify enrollment:
#
# infrakit nfs-auth/disk describe


kind: enrollment
metadata:
name: nfs/workers # socket file = nfs and the name of control loop is 'workers'
properties:
List: group/workers # socket file = group and group id is 'workers'
Instance:

# the name of a plugin that has disk as subtype.
Plugin: nfs-auth/disk

# the entire Properties block here will be rendered and included as the downstream
# instance plugin's instance.Spec when Provision() is called.
Properties:

# You can include template expressions in this block; however, you need to
# escape the braces.
host: \{\{.ID\}\}
iops: 10
options:
# This expression is a template used to select the key from each source entry
# of instance.Description. Note here we escape the template tags
# so that template expressions don't get clobbered by infrakit template when
# using that as a preprocessor prior to committing.
SourceKeySelector: \{\{.ID\}\}

# How often to run the sync. The string value here is in the format of Go's time.Duration.
# For example, 1m means 1 minute.
SyncInterval: 5s # seconds
30 changes: 30 additions & 0 deletions docs/controller/enrollment/group.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#
# A group of workers
#
# Start up -- plugin start should include manager, vanilla, simulator, and group
# Then commit
#
# infrakit group controller commit -y docs/controller/enrollment/group.yml
#
kind: group
metadata:
name: workers
properties:
Allocation:
Size: 5
Flavor:
Plugin: vanilla
Properties:
Attachments:
- ID: attachid
Type: attachtype
Init:
- docker pull nginx:alpine
- docker run -d -p 80:80 nginx-alpine
Tags:
project: infrakit
tier: web
Instance:
Plugin: simulator/compute
Properties:
Note: custom field
3 changes: 2 additions & 1 deletion docs/plugins/instance.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Instance plugin API

<!-- SOURCE-CHECKSUM pkg/spi/instance/* 9117db2da2ea1073a6f94b241e6c6a9a0a9048d452c44631323150dfeffdfde2b8c5ba85e274fabe -->
<!-- SOURCE-CHECKSUM pkg/spi/instance/* 6b3c98bed4470312a41376f651cee99a9e35ffb09117db2da2ea1073a6f94b241e6c6a9a0a9048d452c44631323150dfeffdfde2b8c5ba85e274fabe -->


## API

Expand Down
8 changes: 3 additions & 5 deletions pkg/cli/v0/group/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,14 @@ var log = logutil.New("module", "cli/v1/group")
func init() {
cli.Register(group.InterfaceSpec,
[]cli.CmdBuilder{
//Group,
// Group,
Ls,
Inspect,
Describe,
Commit,
Free,
Destroy,
Size,
SetSize,
Scale,
DestroyInstances,
})
}
Expand All @@ -42,8 +41,7 @@ func Group(name string, services *cli.Services) *cobra.Command {
Commit(name, services),
Free(name, services),
Destroy(name, services),
Size(name, services),
SetSize(name, services),
Scale(name, services),
DestroyInstances(name, services),
)

Expand Down
91 changes: 91 additions & 0 deletions pkg/cli/v0/group/scale.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package group

import (
"fmt"
"os"
"strconv"

"github.com/docker/infrakit/pkg/cli"
"github.com/docker/infrakit/pkg/plugin"
"github.com/docker/infrakit/pkg/spi/group"
"github.com/spf13/cobra"
)

// Scale returns the scale command
func Scale(name string, services *cli.Services) *cobra.Command {

scale := &cobra.Command{
Use: "scale <groupID> [new-target]",
Short: "Returns size of the group if no args provided. Otherwise set the target size.",
RunE: func(cmd *cobra.Command, args []string) error {

pluginName := plugin.Name(name)
_, gid := pluginName.GetLookupAndType()

size := -1

if gid == "" {
// if gid is not known, then we need it to be provided
switch len(args) {

case 0:
cmd.Usage()
os.Exit(1)
case 1:
gid = args[0]
case 2:
gid = args[0]
sz, err := strconv.Atoi(args[1])
if err != nil {
return err
}
size = sz
default:
cmd.Usage()
os.Exit(1)
}
} else {
// if gid is not known, then we need it to be provided
switch len(args) {

case 0:
size = -1
case 1:
sz, err := strconv.Atoi(args[0])
if err != nil {
return err
}
size = sz
default:
cmd.Usage()
os.Exit(1)
}
}

groupPlugin, err := LoadPlugin(services.Plugins(), name)
if err != nil {
return nil
}
cli.MustNotNil(groupPlugin, "group plugin not found", "name", name)

groupID := group.ID(gid)
target, err := groupPlugin.Size(groupID)
if err != nil {
return err
}
fmt.Printf("Group %v at %d instances", groupID, target)

if size > -1 {
err = groupPlugin.SetSize(groupID, size)
if err != nil {
return err
}
fmt.Printf(", scale to %d", size)
}

fmt.Println()
return nil
},
}
return scale
}
57 changes: 57 additions & 0 deletions pkg/controller/enrollment/controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package enrollment

import (
"github.com/docker/infrakit/pkg/controller"
enrollment "github.com/docker/infrakit/pkg/controller/enrollment/types"
"github.com/docker/infrakit/pkg/controller/internal"
"github.com/docker/infrakit/pkg/discovery"
logutil "github.com/docker/infrakit/pkg/log"
"github.com/docker/infrakit/pkg/manager"
"github.com/docker/infrakit/pkg/types"
)

var (
log = logutil.New("module", "controller/enrollment")
debugV = logutil.V(200)
)

// NewController returns a controller implementation
func NewController(plugins func() discovery.Plugins, leader manager.Leadership,
options enrollment.Options) controller.Controller {
return internal.NewController(
leader,
// the constructor
func(spec types.Spec) (internal.Managed, error) {
return newEnroller(plugins, leader, options), nil
},
// the key function
func(metadata types.Metadata) string {
return metadata.Name
},
)
}

// NewTypedControllers return typed controllers
func NewTypedControllers(plugins func() discovery.Plugins, leader manager.Leadership,
options enrollment.Options) func() (map[string]controller.Controller, error) {

return (internal.NewController(
leader,
// the constructor
func(spec types.Spec) (internal.Managed, error) {
log.Debug("Creating managed object", "spec", spec)
return newEnroller(plugins, leader, options), nil
},
// the key function
func(metadata types.Metadata) string {
return metadata.Name
},
)).ManagedObjects
}

func (l *enroller) started() bool {
l.lock.RLock()
defer l.lock.RUnlock()

return l.running
}
Loading