@@ -2,6 +2,8 @@ package cluster
22
33import (
44 "encoding/json"
5+ "errors"
6+ "fmt"
57 "strings"
68
79 "github.com/samalba/dockerclient"
@@ -63,10 +65,10 @@ func consolidateResourceFields(c *dockerclient.ContainerConfig) {
6365// BuildContainerConfig creates a cluster.ContainerConfig from a dockerclient.ContainerConfig
6466func BuildContainerConfig (c dockerclient.ContainerConfig ) * ContainerConfig {
6567 var (
66- affinities []string
67- constraints []string
68- reschedulePolicy string
69- env []string
68+ affinities []string
69+ constraints []string
70+ reschedulePolicies [] string
71+ env []string
7072 )
7173
7274 // only for tests
@@ -84,9 +86,9 @@ func BuildContainerConfig(c dockerclient.ContainerConfig) *ContainerConfig {
8486 json .Unmarshal ([]byte (labels ), & constraints )
8587 }
8688
87- // parse reschedule policy from labels (ex. docker run --label 'com.docker.swarm.reschedule-policy =on-node-failure')
88- if label , ok := c .Labels [SwarmLabelNamespace + ".reschedule-policy " ]; ok {
89- reschedulePolicy = label
89+ // parse reschedule policy from labels (ex. docker run --label 'com.docker.swarm.reschedule-policies =on-node-failure')
90+ if labels , ok := c .Labels [SwarmLabelNamespace + ".reschedule-policies " ]; ok {
91+ json . Unmarshal ([] byte ( labels ), & reschedulePolicies )
9092 }
9193
9294 // parse affinities/constraints/reschedule policies from env (ex. docker run -e affinity:container==redis -e affinity:image==nginx -e constraint:region==us-east -e constraint:storage==ssd -e reschedule:off)
@@ -96,12 +98,7 @@ func BuildContainerConfig(c dockerclient.ContainerConfig) *ContainerConfig {
9698 } else if ok && key == "constraint" {
9799 constraints = append (constraints , value )
98100 } else if ok && key == "reschedule" {
99- if reschedulePolicy == "" {
100- reschedulePolicy = value
101- } else if reschedulePolicy != value {
102- // for off on conflict
103- reschedulePolicy = "off"
104- }
101+ reschedulePolicies = append (reschedulePolicies , value )
105102 } else {
106103 env = append (env , e )
107104 }
@@ -124,9 +121,11 @@ func BuildContainerConfig(c dockerclient.ContainerConfig) *ContainerConfig {
124121 }
125122 }
126123
127- // store reschedule policy in labels
128- if reschedulePolicy != "" {
129- c .Labels [SwarmLabelNamespace + ".reschedule-policy" ] = reschedulePolicy
124+ // store reschedule policies in labels
125+ if len (reschedulePolicies ) > 0 {
126+ if labels , err := json .Marshal (reschedulePolicies ); err == nil {
127+ c .Labels [SwarmLabelNamespace + ".reschedule-policies" ] = string (labels )
128+ }
130129 }
131130
132131 consolidateResourceFields (& c )
@@ -205,11 +204,32 @@ func (c *ContainerConfig) HaveNodeConstraint() bool {
205204 return false
206205}
207206
208- // ReschedulePolicy returns the current rescheduling policy
209- func (c * ContainerConfig ) ReschedulePolicy () string {
210- policy , ok := c .Labels [SwarmLabelNamespace + ".reschedule-policy" ]
211- if ! ok {
212- return "off"
207+ // HasReschedulePolicy returns true if the specified policy is part of the config
208+ func (c * ContainerConfig ) HasReschedulePolicy (p string ) bool {
209+ for _ , reschedulePolicy := range c .extractExprs ("reschedule-policies" ) {
210+ if reschedulePolicy == p {
211+ return true
212+ }
213+ }
214+ return false
215+ }
216+
217+ // Validate returns an error if the config isn't valid
218+ func (c * ContainerConfig ) Validate () error {
219+ //TODO: add validation for affinities and constraints
220+ reschedulePolicies := c .extractExprs ("reschedule-policies" )
221+ if len (reschedulePolicies ) > 1 {
222+ return errors .New ("too many reschedule policies" )
223+ } else if len (reschedulePolicies ) == 1 {
224+ valid := false
225+ for _ , validReschedulePolicy := range []string {"off" , "on-node-failure" } {
226+ if reschedulePolicies [0 ] == validReschedulePolicy {
227+ valid = true
228+ }
229+ }
230+ if ! valid {
231+ return fmt .Errorf ("invalid reschedule policy: %s" , reschedulePolicies [0 ])
232+ }
213233 }
214- return policy
234+ return nil
215235}
0 commit comments