add --strategy to choose the strategy to use

Signed-off-by: Victor Vieux <vieux@docker.com>
This commit is contained in:
Victor Vieux 2014-12-12 23:57:27 +00:00
parent c85b0a9c39
commit b1e80ce157
6 changed files with 106 additions and 50 deletions

52
flags.go Normal file
View File

@ -0,0 +1,52 @@
package main
import "github.com/codegangsta/cli"
var (
flDiscovery = cli.StringFlag{
Name: "discovery",
Value: "",
Usage: "DiscoveryService to use [token://<token>, etcd://<ip1>,<ip2>/<path>, file://path/to/file]",
EnvVar: "SWARM_DISCOVERY",
}
flAddr = cli.StringFlag{
Name: "addr",
Value: "127.0.0.1:4243",
Usage: "ip to advertise",
EnvVar: "SWARM_ADDR",
}
flHeartBeat = cli.IntFlag{
Name: "heartbeat, hb",
Value: 25,
Usage: "time in second between each heartbeat",
}
flEnableCors = cli.BoolFlag{
Name: "api-enable-cors, cors",
Usage: "enable CORS headers in the remote API",
}
flTls = cli.BoolFlag{
Name: "tls",
Usage: "Use TLS; implied by --tlsverify=true",
}
flTlsCaCert = cli.StringFlag{
Name: "tlscacert",
Usage: "Trust only remotes providing a certificate signed by the CA given here",
}
flTlsCert = cli.StringFlag{
Name: "tlscert",
Usage: "Path to TLS certificate file",
}
flTlsKey = cli.StringFlag{
Name: "tlskey",
Usage: "Path to TLS key file",
}
flTlsVerify = cli.BoolFlag{
Name: "tlsverify",
Usage: "Use TLS and verify the remote",
}
flStrategy = cli.StringFlag{
Name: "strategy",
Usage: "PlacementStrategy to use [binpacking, random]",
Value: "binpacking:0.05",
}
)

44
main.go
View File

@ -36,49 +36,6 @@ func main() {
return nil
}
// flags
flDiscovery := cli.StringFlag{
Name: "discovery",
Value: "",
Usage: "token://<token>, file://path/to/file",
EnvVar: "SWARM_DISCOVERY",
}
flAddr := cli.StringFlag{
Name: "addr",
Value: "127.0.0.1:4243",
Usage: "ip to advertise",
EnvVar: "SWARM_ADDR",
}
flHeartBeat := cli.IntFlag{
Name: "heartbeat, hb",
Value: 25,
Usage: "time in second between each heartbeat",
}
flEnableCors := cli.BoolFlag{
Name: "api-enable-cors, cors",
Usage: "enable CORS headers in the remote API",
}
flTls := cli.BoolFlag{
Name: "tls",
Usage: "Use TLS; implied by --tlsverify=true",
}
flTlsCaCert := cli.StringFlag{
Name: "tlscacert",
Usage: "Trust only remotes providing a certificate signed by the CA given here",
}
flTlsCert := cli.StringFlag{
Name: "tlscert",
Usage: "Path to TLS certificate file",
}
flTlsKey := cli.StringFlag{
Name: "tlskey",
Usage: "Path to TLS key file",
}
flTlsVerify := cli.BoolFlag{
Name: "tlsverify",
Usage: "Use TLS and verify the remote",
}
app.Commands = []cli.Command{
{
Name: "create",
@ -121,6 +78,7 @@ func main() {
ShortName: "m",
Usage: "manage a docker cluster",
Flags: []cli.Flag{
flStrategy,
flDiscovery, flAddr, flHeartBeat,
flTls, flTlsCaCert, flTlsCert, flTlsKey, flTlsVerify,
flEnableCors},

View File

@ -123,9 +123,13 @@ func manage(c *cli.Context) {
}
}()
s := scheduler.NewScheduler(
s, err := strategy.New(c.String("strategy"))
if err != nil {
log.Fatal(err)
}
sched := scheduler.NewScheduler(
cluster,
&strategy.BinPackingPlacementStrategy{OvercommitRatio: 0.05},
s,
[]filter.Filter{
&filter.HealthFilter{},
&filter.LabelFilter{},
@ -133,5 +137,5 @@ func manage(c *cli.Context) {
},
)
log.Fatal(api.ListenAndServe(cluster, s, c.String("addr"), c.App.Version, c.Bool("cors"), tlsConfig))
log.Fatal(api.ListenAndServe(cluster, sched, c.String("addr"), c.App.Version, c.Bool("cors"), tlsConfig))
}

View File

@ -3,6 +3,7 @@ package strategy
import (
"errors"
"sort"
"strconv"
"github.com/docker/swarm/cluster"
"github.com/samalba/dockerclient"
@ -16,6 +17,11 @@ type BinPackingPlacementStrategy struct {
OvercommitRatio float64
}
func (p *BinPackingPlacementStrategy) Initialize(opts string) (err error) {
p.OvercommitRatio, err = strconv.ParseFloat(opts, 64)
return err
}
func (p *BinPackingPlacementStrategy) PlaceContainer(config *dockerclient.ContainerConfig, nodes []*cluster.Node) (*cluster.Node, error) {
scores := scores{}

View File

@ -9,14 +9,15 @@ import (
"github.com/samalba/dockerclient"
)
func init() {
rand.Seed(time.Now().UTC().UnixNano())
}
// Randomly place the container into the cluster.
type RandomPlacementStrategy struct {
}
func (p *RandomPlacementStrategy) Initialize(_ string) error {
rand.Seed(time.Now().UTC().UnixNano())
return nil
}
func (p *RandomPlacementStrategy) PlaceContainer(config *dockerclient.ContainerConfig, nodes []*cluster.Node) (*cluster.Node, error) {
if size := len(nodes); size > 0 {
n := rand.Intn(len(nodes))

View File

@ -1,12 +1,47 @@
package strategy
import (
"errors"
"strings"
log "github.com/Sirupsen/logrus"
"github.com/docker/swarm/cluster"
"github.com/samalba/dockerclient"
)
type PlacementStrategy interface {
Initialize(string) error
// Given a container configuration and a set of nodes, select the target
// node where the container should be scheduled.
PlaceContainer(config *dockerclient.ContainerConfig, nodes []*cluster.Node) (*cluster.Node, error)
}
var (
strategies map[string]PlacementStrategy
ErrNotSupported = errors.New("strategy not supported")
)
func init() {
strategies = make(map[string]PlacementStrategy)
strategies["binpacking"] = &BinPackingPlacementStrategy{}
strategies["random"] = &RandomPlacementStrategy{}
}
func New(nameAndOpts string) (PlacementStrategy, error) {
var (
parts = strings.SplitN(nameAndOpts, ":", 2)
name = parts[0]
opts string
)
if len(parts) == 2 {
opts = parts[1]
}
if strategy, exists := strategies[name]; exists {
log.Debugf("Initialising %q strategy with %q", name, opts)
err := strategy.Initialize(opts)
return strategy, err
}
return nil, ErrNotSupported
}