mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Add support for rollback flags
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
This commit is contained in:
parent
cc9d04647a
commit
3a88a24d23
10 changed files with 422 additions and 238 deletions
|
@ -2265,6 +2265,32 @@ definitions:
|
|||
description: "The fraction of tasks that may fail during an update before the failure action is invoked, specified as a floating point number between 0 and 1."
|
||||
type: "number"
|
||||
default: 0
|
||||
RollbackConfig:
|
||||
description: "Specification for the rollback strategy of the service."
|
||||
type: "object"
|
||||
properties:
|
||||
Parallelism:
|
||||
description: "Maximum number of tasks to be rolled back in one iteration (0 means unlimited parallelism)."
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
Delay:
|
||||
description: "Amount of time between rollback iterations, in nanoseconds."
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
FailureAction:
|
||||
description: "Action to take if an rolled back task fails to run, or stops running during the rollback."
|
||||
type: "string"
|
||||
enum:
|
||||
- "continue"
|
||||
- "pause"
|
||||
Monitor:
|
||||
description: "Amount of time to monitor each rolled back task for failures, in nanoseconds."
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
MaxFailureRatio:
|
||||
description: "The fraction of tasks that may fail during a rollback before the failure action is invoked, specified as a floating point number between 0 and 1."
|
||||
type: "number"
|
||||
default: 0
|
||||
Networks:
|
||||
description: "Array of network names or IDs to attach the service to."
|
||||
type: "array"
|
||||
|
@ -2387,6 +2413,13 @@ definitions:
|
|||
Replicas: 1
|
||||
UpdateConfig:
|
||||
Parallelism: 1
|
||||
Delay: 1000000000
|
||||
FailureAction: "pause"
|
||||
Monitor: 15000000000
|
||||
MaxFailureRatio: 0.15
|
||||
RollbackConfig:
|
||||
Parallelism: 1
|
||||
Delay: 1000000000
|
||||
FailureAction: "pause"
|
||||
Monitor: 15000000000
|
||||
MaxFailureRatio: 0.15
|
||||
|
@ -7436,9 +7469,17 @@ paths:
|
|||
Replicated:
|
||||
Replicas: 4
|
||||
UpdateConfig:
|
||||
Delay: 30000000000
|
||||
Parallelism: 2
|
||||
Delay: 1000000000
|
||||
FailureAction: "pause"
|
||||
Monitor: 15000000000
|
||||
MaxFailureRatio: 0.15
|
||||
RollbackConfig:
|
||||
Parallelism: 1
|
||||
Delay: 1000000000
|
||||
FailureAction: "pause"
|
||||
Monitor: 15000000000
|
||||
MaxFailureRatio: 0.15
|
||||
EndpointSpec:
|
||||
Ports:
|
||||
-
|
||||
|
@ -7564,7 +7605,15 @@ paths:
|
|||
Replicated:
|
||||
Replicas: 1
|
||||
UpdateConfig:
|
||||
Parallelism: 2
|
||||
Delay: 1000000000
|
||||
FailureAction: "pause"
|
||||
Monitor: 15000000000
|
||||
MaxFailureRatio: 0.15
|
||||
RollbackConfig:
|
||||
Parallelism: 1
|
||||
Delay: 1000000000
|
||||
FailureAction: "pause"
|
||||
Monitor: 15000000000
|
||||
MaxFailureRatio: 0.15
|
||||
EndpointSpec:
|
||||
|
|
|
@ -21,6 +21,7 @@ type ServiceSpec struct {
|
|||
TaskTemplate TaskSpec `json:",omitempty"`
|
||||
Mode ServiceMode `json:",omitempty"`
|
||||
UpdateConfig *UpdateConfig `json:",omitempty"`
|
||||
RollbackConfig *UpdateConfig `json:",omitempty"`
|
||||
|
||||
// Networks field in ServiceSpec is deprecated. The
|
||||
// same field in TaskSpec should be used instead.
|
||||
|
|
|
@ -57,6 +57,18 @@ UpdateConfig:
|
|||
{{- end }}
|
||||
Max failure ratio: {{ .UpdateMaxFailureRatio }}
|
||||
{{- end }}
|
||||
{{- if .HasRollbackConfig }}
|
||||
RollbackConfig:
|
||||
Parallelism: {{ .RollbackParallelism }}
|
||||
{{- if .HasRollbackDelay}}
|
||||
Delay: {{ .RollbackDelay }}
|
||||
{{- end }}
|
||||
On failure: {{ .RollbackOnFailure }}
|
||||
{{- if .HasRollbackMonitor}}
|
||||
Monitoring Period: {{ .RollbackMonitor }}
|
||||
{{- end }}
|
||||
Max failure ratio: {{ .RollbackMaxFailureRatio }}
|
||||
{{- end }}
|
||||
ContainerSpec:
|
||||
Image: {{ .ContainerImage }}
|
||||
{{- if .ContainerArgs }}
|
||||
|
@ -259,6 +271,38 @@ func (ctx *serviceInspectContext) UpdateMaxFailureRatio() float32 {
|
|||
return ctx.Service.Spec.UpdateConfig.MaxFailureRatio
|
||||
}
|
||||
|
||||
func (ctx *serviceInspectContext) HasRollbackConfig() bool {
|
||||
return ctx.Service.Spec.RollbackConfig != nil
|
||||
}
|
||||
|
||||
func (ctx *serviceInspectContext) RollbackParallelism() uint64 {
|
||||
return ctx.Service.Spec.RollbackConfig.Parallelism
|
||||
}
|
||||
|
||||
func (ctx *serviceInspectContext) HasRollbackDelay() bool {
|
||||
return ctx.Service.Spec.RollbackConfig.Delay.Nanoseconds() > 0
|
||||
}
|
||||
|
||||
func (ctx *serviceInspectContext) RollbackDelay() time.Duration {
|
||||
return ctx.Service.Spec.RollbackConfig.Delay
|
||||
}
|
||||
|
||||
func (ctx *serviceInspectContext) RollbackOnFailure() string {
|
||||
return ctx.Service.Spec.RollbackConfig.FailureAction
|
||||
}
|
||||
|
||||
func (ctx *serviceInspectContext) HasRollbackMonitor() bool {
|
||||
return ctx.Service.Spec.RollbackConfig.Monitor.Nanoseconds() > 0
|
||||
}
|
||||
|
||||
func (ctx *serviceInspectContext) RollbackMonitor() time.Duration {
|
||||
return ctx.Service.Spec.RollbackConfig.Monitor
|
||||
}
|
||||
|
||||
func (ctx *serviceInspectContext) RollbackMaxFailureRatio() float32 {
|
||||
return ctx.Service.Spec.RollbackConfig.MaxFailureRatio
|
||||
}
|
||||
|
||||
func (ctx *serviceInspectContext) ContainerImage() string {
|
||||
return ctx.Service.Spec.TaskTemplate.ContainerSpec.Image
|
||||
}
|
||||
|
|
|
@ -49,7 +49,6 @@ func formatServiceInspect(t *testing.T, format formatter.Format, now time.Time)
|
|||
Replicas: &two,
|
||||
},
|
||||
},
|
||||
UpdateConfig: nil,
|
||||
Networks: []swarm.NetworkAttachmentConfig{
|
||||
{
|
||||
Target: "5vpyomhb6ievnk0i0o60gcnei",
|
||||
|
|
|
@ -165,6 +165,16 @@ type updateOptions struct {
|
|||
maxFailureRatio floatValue
|
||||
}
|
||||
|
||||
func (opts updateOptions) config() *swarm.UpdateConfig {
|
||||
return &swarm.UpdateConfig{
|
||||
Parallelism: opts.parallelism,
|
||||
Delay: opts.delay,
|
||||
Monitor: opts.monitor,
|
||||
FailureAction: opts.onFailure,
|
||||
MaxFailureRatio: opts.maxFailureRatio.Value(),
|
||||
}
|
||||
}
|
||||
|
||||
type resourceOptions struct {
|
||||
limitCPU opts.NanoCPUs
|
||||
limitMemBytes opts.MemBytes
|
||||
|
@ -328,6 +338,7 @@ type serviceOptions struct {
|
|||
constraints opts.ListOpts
|
||||
placementPrefs placementPrefOpts
|
||||
update updateOptions
|
||||
rollback updateOptions
|
||||
networks opts.ListOpts
|
||||
endpoint endpointOptions
|
||||
|
||||
|
@ -447,13 +458,8 @@ func (opts *serviceOptions) ToService() (swarm.ServiceSpec, error) {
|
|||
},
|
||||
Networks: convertNetworks(opts.networks.GetAll()),
|
||||
Mode: serviceMode,
|
||||
UpdateConfig: &swarm.UpdateConfig{
|
||||
Parallelism: opts.update.parallelism,
|
||||
Delay: opts.update.delay,
|
||||
Monitor: opts.update.monitor,
|
||||
FailureAction: opts.update.onFailure,
|
||||
MaxFailureRatio: opts.update.maxFailureRatio.Value(),
|
||||
},
|
||||
UpdateConfig: opts.update.config(),
|
||||
RollbackConfig: opts.rollback.config(),
|
||||
EndpointSpec: opts.endpoint.ToEndpointSpec(),
|
||||
}
|
||||
|
||||
|
@ -491,6 +497,17 @@ func addServiceFlags(cmd *cobra.Command, opts *serviceOptions) {
|
|||
flags.Var(&opts.update.maxFailureRatio, flagUpdateMaxFailureRatio, "Failure rate to tolerate during an update")
|
||||
flags.SetAnnotation(flagUpdateMaxFailureRatio, "version", []string{"1.25"})
|
||||
|
||||
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.27"})
|
||||
flags.DurationVar(&opts.rollback.delay, flagRollbackDelay, time.Duration(0), "Delay between task rollbacks (ns|us|ms|s|m|h) (default 0s)")
|
||||
flags.SetAnnotation(flagRollbackDelay, "version", []string{"1.27"})
|
||||
flags.DurationVar(&opts.rollback.monitor, flagRollbackMonitor, time.Duration(0), "Duration after each task rollback to monitor for failure (ns|us|ms|s|m|h) (default 0s)")
|
||||
flags.SetAnnotation(flagRollbackMonitor, "version", []string{"1.27"})
|
||||
flags.StringVar(&opts.rollback.onFailure, flagRollbackFailureAction, "pause", `Action on rollback failure ("pause"|"continue")`)
|
||||
flags.SetAnnotation(flagRollbackFailureAction, "version", []string{"1.27"})
|
||||
flags.Var(&opts.rollback.maxFailureRatio, flagRollbackMaxFailureRatio, "Failure rate to tolerate during a rollback")
|
||||
flags.SetAnnotation(flagRollbackMaxFailureRatio, "version", []string{"1.27"})
|
||||
|
||||
flags.StringVar(&opts.endpoint.mode, flagEndpointMode, "vip", "Endpoint mode (vip or dnsrr)")
|
||||
|
||||
flags.BoolVar(&opts.registryAuth, flagRegistryAuth, false, "Send registry authentication details to swarm agents")
|
||||
|
@ -572,6 +589,11 @@ const (
|
|||
flagRestartDelay = "restart-delay"
|
||||
flagRestartMaxAttempts = "restart-max-attempts"
|
||||
flagRestartWindow = "restart-window"
|
||||
flagRollbackDelay = "rollback-delay"
|
||||
flagRollbackFailureAction = "rollback-failure-action"
|
||||
flagRollbackMaxFailureRatio = "rollback-max-failure-ratio"
|
||||
flagRollbackMonitor = "rollback-monitor"
|
||||
flagRollbackParallelism = "rollback-parallelism"
|
||||
flagStopGracePeriod = "stop-grace-period"
|
||||
flagStopSignal = "stop-signal"
|
||||
flagTTY = "tty"
|
||||
|
|
|
@ -289,6 +289,17 @@ func updateService(flags *pflag.FlagSet, spec *swarm.ServiceSpec) error {
|
|||
updateFloatValue(flagUpdateMaxFailureRatio, &spec.UpdateConfig.MaxFailureRatio)
|
||||
}
|
||||
|
||||
if anyChanged(flags, flagRollbackParallelism, flagRollbackDelay, flagRollbackMonitor, flagRollbackFailureAction, flagRollbackMaxFailureRatio) {
|
||||
if spec.RollbackConfig == nil {
|
||||
spec.RollbackConfig = &swarm.UpdateConfig{}
|
||||
}
|
||||
updateUint64(flagRollbackParallelism, &spec.RollbackConfig.Parallelism)
|
||||
updateDuration(flagRollbackDelay, &spec.RollbackConfig.Delay)
|
||||
updateDuration(flagRollbackMonitor, &spec.RollbackConfig.Monitor)
|
||||
updateString(flagRollbackFailureAction, &spec.RollbackConfig.FailureAction)
|
||||
updateFloatValue(flagRollbackMaxFailureRatio, &spec.RollbackConfig.MaxFailureRatio)
|
||||
}
|
||||
|
||||
if flags.Changed(flagEndpointMode) {
|
||||
value, _ := flags.GetString(flagEndpointMode)
|
||||
if spec.EndpointSpec == nil {
|
||||
|
|
|
@ -92,26 +92,8 @@ func serviceSpecFromGRPC(spec *swarmapi.ServiceSpec) *types.ServiceSpec {
|
|||
}
|
||||
|
||||
// UpdateConfig
|
||||
if spec.Update != nil {
|
||||
convertedSpec.UpdateConfig = &types.UpdateConfig{
|
||||
Parallelism: spec.Update.Parallelism,
|
||||
MaxFailureRatio: spec.Update.MaxFailureRatio,
|
||||
}
|
||||
|
||||
convertedSpec.UpdateConfig.Delay = spec.Update.Delay
|
||||
if spec.Update.Monitor != nil {
|
||||
convertedSpec.UpdateConfig.Monitor, _ = gogotypes.DurationFromProto(spec.Update.Monitor)
|
||||
}
|
||||
|
||||
switch spec.Update.FailureAction {
|
||||
case swarmapi.UpdateConfig_PAUSE:
|
||||
convertedSpec.UpdateConfig.FailureAction = types.UpdateFailureActionPause
|
||||
case swarmapi.UpdateConfig_CONTINUE:
|
||||
convertedSpec.UpdateConfig.FailureAction = types.UpdateFailureActionContinue
|
||||
case swarmapi.UpdateConfig_ROLLBACK:
|
||||
convertedSpec.UpdateConfig.FailureAction = types.UpdateFailureActionRollback
|
||||
}
|
||||
}
|
||||
convertedSpec.UpdateConfig = updateConfigFromGRPC(spec.Update)
|
||||
convertedSpec.RollbackConfig = updateConfigFromGRPC(spec.Rollback)
|
||||
|
||||
// Mode
|
||||
switch t := spec.GetMode().(type) {
|
||||
|
@ -188,27 +170,13 @@ func ServiceSpecToGRPC(s types.ServiceSpec) (swarmapi.ServiceSpec, error) {
|
|||
}
|
||||
}
|
||||
|
||||
if s.UpdateConfig != nil {
|
||||
var failureAction swarmapi.UpdateConfig_FailureAction
|
||||
switch s.UpdateConfig.FailureAction {
|
||||
case types.UpdateFailureActionPause, "":
|
||||
failureAction = swarmapi.UpdateConfig_PAUSE
|
||||
case types.UpdateFailureActionContinue:
|
||||
failureAction = swarmapi.UpdateConfig_CONTINUE
|
||||
case types.UpdateFailureActionRollback:
|
||||
failureAction = swarmapi.UpdateConfig_ROLLBACK
|
||||
default:
|
||||
return swarmapi.ServiceSpec{}, fmt.Errorf("unrecognized update failure action %s", s.UpdateConfig.FailureAction)
|
||||
}
|
||||
spec.Update = &swarmapi.UpdateConfig{
|
||||
Parallelism: s.UpdateConfig.Parallelism,
|
||||
Delay: s.UpdateConfig.Delay,
|
||||
FailureAction: failureAction,
|
||||
MaxFailureRatio: s.UpdateConfig.MaxFailureRatio,
|
||||
}
|
||||
if s.UpdateConfig.Monitor != 0 {
|
||||
spec.Update.Monitor = gogotypes.DurationProto(s.UpdateConfig.Monitor)
|
||||
spec.Update, err = updateConfigToGRPC(s.UpdateConfig)
|
||||
if err != nil {
|
||||
return swarmapi.ServiceSpec{}, err
|
||||
}
|
||||
spec.Rollback, err = updateConfigToGRPC(s.RollbackConfig)
|
||||
if err != nil {
|
||||
return swarmapi.Servicepec{}, err
|
||||
}
|
||||
|
||||
if s.EndpointSpec != nil {
|
||||
|
@ -415,3 +383,58 @@ func driverToGRPC(p *types.Driver) *swarmapi.Driver {
|
|||
Options: p.Options,
|
||||
}
|
||||
}
|
||||
|
||||
func updateConfigFromGRPC(updateConfig *swarmapi.UpdateConfig) *types.UpdateConfig {
|
||||
if updateConfig == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
converted := &types.UpdateConfig{
|
||||
Parallelism: updateConfig.Parallelism,
|
||||
MaxFailureRatio: updateConfig.MaxFailureRatio,
|
||||
}
|
||||
|
||||
converted.Delay = updateConfig.Delay
|
||||
if updateConfig.Monitor != nil {
|
||||
converted.Monitor, _ = gogotypes.DurationFromProto(updateConfig.Monitor)
|
||||
}
|
||||
|
||||
switch updateConfig.FailureAction {
|
||||
case swarmapi.UpdateConfig_PAUSE:
|
||||
converted.FailureAction = types.UpdateFailureActionPause
|
||||
case swarmapi.UpdateConfig_CONTINUE:
|
||||
converted.FailureAction = types.UpdateFailureActionContinue
|
||||
case swarmapi.UpdateConfig_ROLLBACK:
|
||||
converted.FailureAction = types.UpdateFailureActionRollback
|
||||
}
|
||||
|
||||
return converted
|
||||
}
|
||||
|
||||
func updateConfigToGRPC(updateConfig *types.UpdateConfig) (*swarmapi.UpdateConfig, error) {
|
||||
if updateConfig == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
converted := &swarmapi.UpdateConfig{
|
||||
Parallelism: updateConfig.Parallelism,
|
||||
Delay: updateConfig.Delay,
|
||||
MaxFailureRatio: updateConfig.MaxFailureRatio,
|
||||
}
|
||||
|
||||
switch updateConfig.FailureAction {
|
||||
case types.UpdateFailureActionPause, "":
|
||||
converted.FailureAction = swarmapi.UpdateConfig_PAUSE
|
||||
case types.UpdateFailureActionContinue:
|
||||
converted.FailureAction = swarmapi.UpdateConfig_CONTINUE
|
||||
case types.UpdateFailureActionRollback:
|
||||
converted.FailureAction = swarmapi.UpdateConfig_ROLLBACK
|
||||
default:
|
||||
return nil, fmt.Errorf("unrecongized update failure action %s", updateConfig.FailureAction)
|
||||
}
|
||||
if updateConfig.Monitor != 0 {
|
||||
converted.Monitor = gogotypes.DurationProto(updateConfig.Monitor)
|
||||
}
|
||||
|
||||
return converted, nil
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ keywords: "API, Docker, rcli, REST, documentation"
|
|||
* `POST /services/create` and `POST /services/(id or name)/update` now accept the `ReadOnly` parameter, which mounts the container's root filesystem as read only.
|
||||
* `POST /build` now accepts `extrahosts` parameter to specify a host to ip mapping to use during the build.
|
||||
* `POST /services/create` and `POST /services/(id or name)/update` now accept a `rollback` value for `FailureAction`.
|
||||
* `POST /services/create` and `POST /services/(id or name)/update` now accept an optional `RollbackConfig` object which specifies rollback options.
|
||||
|
||||
## v1.26 API changes
|
||||
|
||||
|
|
|
@ -57,6 +57,13 @@ Options:
|
|||
--restart-delay duration Delay between restart attempts (ns|us|ms|s|m|h)
|
||||
--restart-max-attempts uint Maximum number of restarts before giving up
|
||||
--restart-window duration Window used to evaluate the restart policy (ns|us|ms|s|m|h)
|
||||
--rollback-delay duration Delay between task rollbacks (ns|us|ms|s|m|h) (default 0s)
|
||||
--rollback-failure-action string Action on rollback failure ("pause"|"continue") (default "pause")
|
||||
--rollback-max-failure-ratio float Failure rate to tolerate during a rollback
|
||||
--rollback-monitor duration Duration after each task rollback to monitor for failure
|
||||
(ns|us|ms|s|m|h) (default 0s)
|
||||
--rollback-parallelism uint Maximum number of tasks rolled back simultaneously (0 to roll
|
||||
back all at once) (default 1)
|
||||
--secret secret Specify secrets to expose to the service
|
||||
--stop-grace-period duration Time to wait before force killing a container (ns|us|ms|s|m|h)
|
||||
--stop-signal string Signal to stop the container
|
||||
|
|
|
@ -69,6 +69,13 @@ Options:
|
|||
--restart-max-attempts uint Maximum number of restarts before giving up
|
||||
--restart-window duration Window used to evaluate the restart policy (ns|us|ms|s|m|h)
|
||||
--rollback Rollback to previous specification
|
||||
--rollback-delay duration Delay between task rollbacks (ns|us|ms|s|m|h) (default 0s)
|
||||
--rollback-failure-action string Action on rollback failure ("pause"|"continue") (default "pause")
|
||||
--rollback-max-failure-ratio float Failure rate to tolerate during a rollback
|
||||
--rollback-monitor duration Duration after each task rollback to monitor for failure
|
||||
(ns|us|ms|s|m|h) (default 0s)
|
||||
--rollback-parallelism uint Maximum number of tasks rolled back simultaneously (0 to roll
|
||||
back all at once) (default 1)
|
||||
--secret-add secret Add or update a secret on a service
|
||||
--secret-rm list Remove a secret (default [])
|
||||
--stop-grace-period duration Time to wait before force killing a container (ns|us|ms|s|m|h)
|
||||
|
@ -202,6 +209,26 @@ web
|
|||
|
||||
```
|
||||
|
||||
Services can also be set up to roll back to the previous version automatically
|
||||
when an update fails. To set up a service for automatic rollback, use
|
||||
`--update-failure-action=rollback`. A rollback will be triggered if the fraction
|
||||
of the tasks which failed to update successfully exceeds the value given with
|
||||
`--update-max-failure-ratio`.
|
||||
|
||||
The rate, parallelism, and other parameters of a rollback operation are
|
||||
determined by the values passed with the following flags:
|
||||
|
||||
- `--rollback-delay`
|
||||
- `--rollback-failure-action`
|
||||
- `--rollback-max-failure-ratio`
|
||||
- `--rollback-monitor`
|
||||
- `--rollback-parallelism`
|
||||
|
||||
For example, a service set up with `--update-parallelism 1 --rollback-parallelism 3`
|
||||
will update one task at a time during a normal update, but during a rollback, 3
|
||||
tasks at a time will get rolled back. These rollback parameters are respected both
|
||||
during automatic rollbacks and for rollbacks initiated manually using `--rollback`.
|
||||
|
||||
### Add or remove secrets
|
||||
|
||||
Use the `--secret-add` or `--secret-rm` options add or remove a service's
|
||||
|
|
Loading…
Add table
Reference in a new issue