diff --git a/manage.go b/manage.go index 90074f9c5c..2139bc9132 100644 --- a/manage.go +++ b/manage.go @@ -75,7 +75,11 @@ func manage(c *cli.Context) { s := scheduler.NewScheduler( cluster, &strategy.BinPackingPlacementStrategy{OvercommitRatio: 0.05}, - []filter.Filter{&filter.LabelFilter{}, &filter.PortFilter{}}, + []filter.Filter{ + &filter.HealthFilter{}, + &filter.LabelFilter{}, + &filter.PortFilter{}, + }, ) log.Fatal(api.ListenAndServe(cluster, s, c.String("addr"), c.App.Version)) diff --git a/scheduler/filter/health.go b/scheduler/filter/health.go new file mode 100644 index 0000000000..e05ba3a356 --- /dev/null +++ b/scheduler/filter/health.go @@ -0,0 +1,31 @@ +package filter + +import ( + "errors" + + "github.com/docker/swarm/cluster" + "github.com/samalba/dockerclient" +) + +var ( + ErrNoHealthyNodeAvailable = errors.New("No healthy node available in the cluster") +) + +// HealthFilter only schedules containers on healthy nodes. +type HealthFilter struct { +} + +func (f *HealthFilter) Filter(config *dockerclient.ContainerConfig, nodes []*cluster.Node) ([]*cluster.Node, error) { + result := []*cluster.Node{} + for _, node := range nodes { + if node.IsHealthy() { + result = append(result, node) + } + } + + if len(result) == 0 { + return nil, ErrNoHealthyNodeAvailable + } + + return result, nil +}