Add support for update order

This parameter controls the order of operations when rolling out an
update task. Either the old task is stopped before starting the new one,
or the new task is started first, and the running tasks will briefly
overlap.

This commit adds Rollout to the API, and --update-order / --rollback-order
flags to the CLI.

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
This commit is contained in:
Aaron Lehmann 2017-01-18 11:38:19 -08:00
parent 12702bdc81
commit 2805c2e929
3 changed files with 22 additions and 2 deletions

View File

@ -57,6 +57,7 @@ UpdateConfig:
Monitoring Period: {{ .UpdateMonitor }} Monitoring Period: {{ .UpdateMonitor }}
{{- end }} {{- end }}
Max failure ratio: {{ .UpdateMaxFailureRatio }} Max failure ratio: {{ .UpdateMaxFailureRatio }}
Update order: {{ .UpdateOrder }}
{{- end }} {{- end }}
{{- if .HasRollbackConfig }} {{- if .HasRollbackConfig }}
RollbackConfig: RollbackConfig:
@ -69,6 +70,7 @@ RollbackConfig:
Monitoring Period: {{ .RollbackMonitor }} Monitoring Period: {{ .RollbackMonitor }}
{{- end }} {{- end }}
Max failure ratio: {{ .RollbackMaxFailureRatio }} Max failure ratio: {{ .RollbackMaxFailureRatio }}
Rollback order: {{ .RollbackOrder }}
{{- end }} {{- end }}
ContainerSpec: ContainerSpec:
Image: {{ .ContainerImage }} Image: {{ .ContainerImage }}
@ -260,6 +262,10 @@ func (ctx *serviceInspectContext) UpdateOnFailure() string {
return ctx.Service.Spec.UpdateConfig.FailureAction return ctx.Service.Spec.UpdateConfig.FailureAction
} }
func (ctx *serviceInspectContext) UpdateOrder() string {
return ctx.Service.Spec.UpdateConfig.Order
}
func (ctx *serviceInspectContext) HasUpdateMonitor() bool { func (ctx *serviceInspectContext) HasUpdateMonitor() bool {
return ctx.Service.Spec.UpdateConfig.Monitor.Nanoseconds() > 0 return ctx.Service.Spec.UpdateConfig.Monitor.Nanoseconds() > 0
} }
@ -304,6 +310,10 @@ func (ctx *serviceInspectContext) RollbackMaxFailureRatio() float32 {
return ctx.Service.Spec.RollbackConfig.MaxFailureRatio return ctx.Service.Spec.RollbackConfig.MaxFailureRatio
} }
func (ctx *serviceInspectContext) RollbackOrder() string {
return ctx.Service.Spec.RollbackConfig.Order
}
func (ctx *serviceInspectContext) ContainerImage() string { func (ctx *serviceInspectContext) ContainerImage() string {
return ctx.Service.Spec.TaskTemplate.ContainerSpec.Image return ctx.Service.Spec.TaskTemplate.ContainerSpec.Image
} }

View File

@ -188,6 +188,7 @@ type updateOptions struct {
monitor time.Duration monitor time.Duration
onFailure string onFailure string
maxFailureRatio floatValue maxFailureRatio floatValue
order string
} }
func (opts updateOptions) config() *swarm.UpdateConfig { func (opts updateOptions) config() *swarm.UpdateConfig {
@ -197,6 +198,7 @@ func (opts updateOptions) config() *swarm.UpdateConfig {
Monitor: opts.monitor, Monitor: opts.monitor,
FailureAction: opts.onFailure, FailureAction: opts.onFailure,
MaxFailureRatio: opts.maxFailureRatio.Value(), MaxFailureRatio: opts.maxFailureRatio.Value(),
Order: opts.order,
} }
} }
@ -533,6 +535,8 @@ func addServiceFlags(flags *pflag.FlagSet, opts *serviceOptions) {
flags.StringVar(&opts.update.onFailure, flagUpdateFailureAction, "pause", `Action on update failure ("pause"|"continue"|"rollback")`) flags.StringVar(&opts.update.onFailure, flagUpdateFailureAction, "pause", `Action on update failure ("pause"|"continue"|"rollback")`)
flags.Var(&opts.update.maxFailureRatio, flagUpdateMaxFailureRatio, "Failure rate to tolerate during an update") flags.Var(&opts.update.maxFailureRatio, flagUpdateMaxFailureRatio, "Failure rate to tolerate during an update")
flags.SetAnnotation(flagUpdateMaxFailureRatio, "version", []string{"1.25"}) flags.SetAnnotation(flagUpdateMaxFailureRatio, "version", []string{"1.25"})
flags.StringVar(&opts.update.order, flagUpdateOrder, "stop-first", `Update order ("start-first"|"stop-first")`)
flags.SetAnnotation(flagUpdateOrder, "version", []string{"1.29"})
flags.Uint64Var(&opts.rollback.parallelism, flagRollbackParallelism, 1, "Maximum number of tasks rolled back simultaneously (0 to roll back all at once)") flags.Uint64Var(&opts.rollback.parallelism, flagRollbackParallelism, 1, "Maximum number of tasks rolled back simultaneously (0 to roll back all at once)")
flags.SetAnnotation(flagRollbackParallelism, "version", []string{"1.28"}) flags.SetAnnotation(flagRollbackParallelism, "version", []string{"1.28"})
@ -544,6 +548,8 @@ func addServiceFlags(flags *pflag.FlagSet, opts *serviceOptions) {
flags.SetAnnotation(flagRollbackFailureAction, "version", []string{"1.28"}) flags.SetAnnotation(flagRollbackFailureAction, "version", []string{"1.28"})
flags.Var(&opts.rollback.maxFailureRatio, flagRollbackMaxFailureRatio, "Failure rate to tolerate during a rollback") flags.Var(&opts.rollback.maxFailureRatio, flagRollbackMaxFailureRatio, "Failure rate to tolerate during a rollback")
flags.SetAnnotation(flagRollbackMaxFailureRatio, "version", []string{"1.28"}) flags.SetAnnotation(flagRollbackMaxFailureRatio, "version", []string{"1.28"})
flags.StringVar(&opts.rollback.order, flagRollbackOrder, "stop-first", `Rollback order ("start-first"|"stop-first")`)
flags.SetAnnotation(flagRollbackOrder, "version", []string{"1.29"})
flags.StringVar(&opts.endpoint.mode, flagEndpointMode, "vip", "Endpoint mode (vip or dnsrr)") flags.StringVar(&opts.endpoint.mode, flagEndpointMode, "vip", "Endpoint mode (vip or dnsrr)")
@ -633,6 +639,7 @@ const (
flagRollbackFailureAction = "rollback-failure-action" flagRollbackFailureAction = "rollback-failure-action"
flagRollbackMaxFailureRatio = "rollback-max-failure-ratio" flagRollbackMaxFailureRatio = "rollback-max-failure-ratio"
flagRollbackMonitor = "rollback-monitor" flagRollbackMonitor = "rollback-monitor"
flagRollbackOrder = "rollback-order"
flagRollbackParallelism = "rollback-parallelism" flagRollbackParallelism = "rollback-parallelism"
flagStopGracePeriod = "stop-grace-period" flagStopGracePeriod = "stop-grace-period"
flagStopSignal = "stop-signal" flagStopSignal = "stop-signal"
@ -641,6 +648,7 @@ const (
flagUpdateFailureAction = "update-failure-action" flagUpdateFailureAction = "update-failure-action"
flagUpdateMaxFailureRatio = "update-max-failure-ratio" flagUpdateMaxFailureRatio = "update-max-failure-ratio"
flagUpdateMonitor = "update-monitor" flagUpdateMonitor = "update-monitor"
flagUpdateOrder = "update-order"
flagUpdateParallelism = "update-parallelism" flagUpdateParallelism = "update-parallelism"
flagUser = "user" flagUser = "user"
flagWorkdir = "workdir" flagWorkdir = "workdir"

View File

@ -320,7 +320,7 @@ func updateService(flags *pflag.FlagSet, spec *swarm.ServiceSpec) error {
return err return err
} }
if anyChanged(flags, flagUpdateParallelism, flagUpdateDelay, flagUpdateMonitor, flagUpdateFailureAction, flagUpdateMaxFailureRatio) { if anyChanged(flags, flagUpdateParallelism, flagUpdateDelay, flagUpdateMonitor, flagUpdateFailureAction, flagUpdateMaxFailureRatio, flagUpdateOrder) {
if spec.UpdateConfig == nil { if spec.UpdateConfig == nil {
spec.UpdateConfig = &swarm.UpdateConfig{} spec.UpdateConfig = &swarm.UpdateConfig{}
} }
@ -329,9 +329,10 @@ func updateService(flags *pflag.FlagSet, spec *swarm.ServiceSpec) error {
updateDuration(flagUpdateMonitor, &spec.UpdateConfig.Monitor) updateDuration(flagUpdateMonitor, &spec.UpdateConfig.Monitor)
updateString(flagUpdateFailureAction, &spec.UpdateConfig.FailureAction) updateString(flagUpdateFailureAction, &spec.UpdateConfig.FailureAction)
updateFloatValue(flagUpdateMaxFailureRatio, &spec.UpdateConfig.MaxFailureRatio) updateFloatValue(flagUpdateMaxFailureRatio, &spec.UpdateConfig.MaxFailureRatio)
updateString(flagUpdateOrder, &spec.UpdateConfig.Order)
} }
if anyChanged(flags, flagRollbackParallelism, flagRollbackDelay, flagRollbackMonitor, flagRollbackFailureAction, flagRollbackMaxFailureRatio) { if anyChanged(flags, flagRollbackParallelism, flagRollbackDelay, flagRollbackMonitor, flagRollbackFailureAction, flagRollbackMaxFailureRatio, flagRollbackOrder) {
if spec.RollbackConfig == nil { if spec.RollbackConfig == nil {
spec.RollbackConfig = &swarm.UpdateConfig{} spec.RollbackConfig = &swarm.UpdateConfig{}
} }
@ -340,6 +341,7 @@ func updateService(flags *pflag.FlagSet, spec *swarm.ServiceSpec) error {
updateDuration(flagRollbackMonitor, &spec.RollbackConfig.Monitor) updateDuration(flagRollbackMonitor, &spec.RollbackConfig.Monitor)
updateString(flagRollbackFailureAction, &spec.RollbackConfig.FailureAction) updateString(flagRollbackFailureAction, &spec.RollbackConfig.FailureAction)
updateFloatValue(flagRollbackMaxFailureRatio, &spec.RollbackConfig.MaxFailureRatio) updateFloatValue(flagRollbackMaxFailureRatio, &spec.RollbackConfig.MaxFailureRatio)
updateString(flagRollbackOrder, &spec.RollbackConfig.Order)
} }
if flags.Changed(flagEndpointMode) { if flags.Changed(flagEndpointMode) {