Browse code

Merge pull request #24943 from aaronlehmann/rolling-updates

Add failure action for rolling updates

Tibor Vass authored on 2016/07/26 02:15:28
Showing 13 changed files
... ...
@@ -4,6 +4,7 @@ import (
4 4
 	"fmt"
5 5
 	"io"
6 6
 	"strings"
7
+	"time"
7 8
 
8 9
 	"golang.org/x/net/context"
9 10
 
... ...
@@ -101,6 +102,17 @@ func printService(out io.Writer, service swarm.Service) {
101 101
 			fmt.Fprintf(out, " Replicas:\t%d\n", *service.Spec.Mode.Replicated.Replicas)
102 102
 		}
103 103
 	}
104
+
105
+	if service.UpdateStatus.State != "" {
106
+		fmt.Fprintln(out, "Update status:")
107
+		fmt.Fprintf(out, " State:\t\t%s\n", service.UpdateStatus.State)
108
+		fmt.Fprintf(out, " Started:\t%s ago\n", strings.ToLower(units.HumanDuration(time.Since(service.UpdateStatus.StartedAt))))
109
+		if service.UpdateStatus.State == swarm.UpdateStateCompleted {
110
+			fmt.Fprintf(out, " Completed:\t%s ago\n", strings.ToLower(units.HumanDuration(time.Since(service.UpdateStatus.CompletedAt))))
111
+		}
112
+		fmt.Fprintf(out, " Message:\t%s\n", service.UpdateStatus.Message)
113
+	}
114
+
104 115
 	fmt.Fprintln(out, "Placement:")
105 116
 	if service.Spec.TaskTemplate.Placement != nil && len(service.Spec.TaskTemplate.Placement.Constraints) > 0 {
106 117
 		ioutils.FprintfIfNotEmpty(out, " Constraints\t: %s\n", strings.Join(service.Spec.TaskTemplate.Placement.Constraints, ", "))
... ...
@@ -110,6 +122,7 @@ func printService(out io.Writer, service swarm.Service) {
110 110
 	if service.Spec.UpdateConfig.Delay.Nanoseconds() > 0 {
111 111
 		fmt.Fprintf(out, " Delay:\t\t%s\n", service.Spec.UpdateConfig.Delay)
112 112
 	}
113
+	fmt.Fprintf(out, " On failure:\t%s\n", service.Spec.UpdateConfig.FailureAction)
113 114
 	fmt.Fprintf(out, "ContainerSpec:\n")
114 115
 	printContainerSpec(out, service.Spec.TaskTemplate.ContainerSpec)
115 116
 
... ...
@@ -274,6 +274,7 @@ func (m *MountOpt) Value() []swarm.Mount {
274 274
 type updateOptions struct {
275 275
 	parallelism uint64
276 276
 	delay       time.Duration
277
+	onFailure   string
277 278
 }
278 279
 
279 280
 type resourceOptions struct {
... ...
@@ -455,8 +456,9 @@ func (opts *serviceOptions) ToService() (swarm.ServiceSpec, error) {
455 455
 		},
456 456
 		Mode: swarm.ServiceMode{},
457 457
 		UpdateConfig: &swarm.UpdateConfig{
458
-			Parallelism: opts.update.parallelism,
459
-			Delay:       opts.update.delay,
458
+			Parallelism:   opts.update.parallelism,
459
+			Delay:         opts.update.delay,
460
+			FailureAction: opts.update.onFailure,
460 461
 		},
461 462
 		Networks:     convertNetworks(opts.networks),
462 463
 		EndpointSpec: opts.endpoint.ToEndpointSpec(),
... ...
@@ -503,6 +505,7 @@ func addServiceFlags(cmd *cobra.Command, opts *serviceOptions) {
503 503
 
504 504
 	flags.Uint64Var(&opts.update.parallelism, flagUpdateParallelism, 1, "Maximum number of tasks updated simultaneously (0 to update all at once)")
505 505
 	flags.DurationVar(&opts.update.delay, flagUpdateDelay, time.Duration(0), "Delay between updates")
506
+	flags.StringVar(&opts.update.onFailure, flagUpdateFailureAction, "pause", "Action on update failure (pause|continue)")
506 507
 
507 508
 	flags.StringVar(&opts.endpoint.mode, flagEndpointMode, "", "Endpoint mode (vip or dnsrr)")
508 509
 
... ...
@@ -513,41 +516,42 @@ func addServiceFlags(cmd *cobra.Command, opts *serviceOptions) {
513 513
 }
514 514
 
515 515
 const (
516
-	flagConstraint         = "constraint"
517
-	flagConstraintRemove   = "constraint-rm"
518
-	flagConstraintAdd      = "constraint-add"
519
-	flagEndpointMode       = "endpoint-mode"
520
-	flagEnv                = "env"
521
-	flagEnvRemove          = "env-rm"
522
-	flagEnvAdd             = "env-add"
523
-	flagLabel              = "label"
524
-	flagLabelRemove        = "label-rm"
525
-	flagLabelAdd           = "label-add"
526
-	flagLimitCPU           = "limit-cpu"
527
-	flagLimitMemory        = "limit-memory"
528
-	flagMode               = "mode"
529
-	flagMount              = "mount"
530
-	flagMountRemove        = "mount-rm"
531
-	flagMountAdd           = "mount-add"
532
-	flagName               = "name"
533
-	flagNetwork            = "network"
534
-	flagNetworkRemove      = "network-rm"
535
-	flagNetworkAdd         = "network-add"
536
-	flagPublish            = "publish"
537
-	flagPublishRemove      = "publish-rm"
538
-	flagPublishAdd         = "publish-add"
539
-	flagReplicas           = "replicas"
540
-	flagReserveCPU         = "reserve-cpu"
541
-	flagReserveMemory      = "reserve-memory"
542
-	flagRestartCondition   = "restart-condition"
543
-	flagRestartDelay       = "restart-delay"
544
-	flagRestartMaxAttempts = "restart-max-attempts"
545
-	flagRestartWindow      = "restart-window"
546
-	flagStopGracePeriod    = "stop-grace-period"
547
-	flagUpdateDelay        = "update-delay"
548
-	flagUpdateParallelism  = "update-parallelism"
549
-	flagUser               = "user"
550
-	flagRegistryAuth       = "with-registry-auth"
551
-	flagLogDriver          = "log-driver"
552
-	flagLogOpt             = "log-opt"
516
+	flagConstraint          = "constraint"
517
+	flagConstraintRemove    = "constraint-rm"
518
+	flagConstraintAdd       = "constraint-add"
519
+	flagEndpointMode        = "endpoint-mode"
520
+	flagEnv                 = "env"
521
+	flagEnvRemove           = "env-rm"
522
+	flagEnvAdd              = "env-add"
523
+	flagLabel               = "label"
524
+	flagLabelRemove         = "label-rm"
525
+	flagLabelAdd            = "label-add"
526
+	flagLimitCPU            = "limit-cpu"
527
+	flagLimitMemory         = "limit-memory"
528
+	flagMode                = "mode"
529
+	flagMount               = "mount"
530
+	flagMountRemove         = "mount-rm"
531
+	flagMountAdd            = "mount-add"
532
+	flagName                = "name"
533
+	flagNetwork             = "network"
534
+	flagNetworkRemove       = "network-rm"
535
+	flagNetworkAdd          = "network-add"
536
+	flagPublish             = "publish"
537
+	flagPublishRemove       = "publish-rm"
538
+	flagPublishAdd          = "publish-add"
539
+	flagReplicas            = "replicas"
540
+	flagReserveCPU          = "reserve-cpu"
541
+	flagReserveMemory       = "reserve-memory"
542
+	flagRestartCondition    = "restart-condition"
543
+	flagRestartDelay        = "restart-delay"
544
+	flagRestartMaxAttempts  = "restart-max-attempts"
545
+	flagRestartWindow       = "restart-window"
546
+	flagStopGracePeriod     = "stop-grace-period"
547
+	flagUpdateDelay         = "update-delay"
548
+	flagUpdateFailureAction = "update-failure-action"
549
+	flagUpdateParallelism   = "update-parallelism"
550
+	flagUser                = "user"
551
+	flagRegistryAuth        = "with-registry-auth"
552
+	flagLogDriver           = "log-driver"
553
+	flagLogOpt              = "log-opt"
553 554
 )
... ...
@@ -191,12 +191,13 @@ func updateService(flags *pflag.FlagSet, spec *swarm.ServiceSpec) error {
191 191
 		return err
192 192
 	}
193 193
 
194
-	if anyChanged(flags, flagUpdateParallelism, flagUpdateDelay) {
194
+	if anyChanged(flags, flagUpdateParallelism, flagUpdateDelay, flagUpdateFailureAction) {
195 195
 		if spec.UpdateConfig == nil {
196 196
 			spec.UpdateConfig = &swarm.UpdateConfig{}
197 197
 		}
198 198
 		updateUint64(flagUpdateParallelism, &spec.UpdateConfig.Parallelism)
199 199
 		updateDuration(flagUpdateDelay, &spec.UpdateConfig.Delay)
200
+		updateString(flagUpdateFailureAction, &spec.UpdateConfig.FailureAction)
200 201
 	}
201 202
 
202 203
 	updateNetworks(flags, &spec.Networks)
... ...
@@ -1726,6 +1726,7 @@ _docker_service_update() {
1726 1726
 		--restart-window
1727 1727
 		--stop-grace-period
1728 1728
 		--update-delay
1729
+		--update-failure-action
1729 1730
 		--update-parallelism
1730 1731
 		--user -u
1731 1732
 		--workdir -w
... ...
@@ -1094,6 +1094,7 @@ __docker_service_subcommand() {
1094 1094
         "($help)--restart-window=[Window used to evaluate the restart policy]:window: "
1095 1095
         "($help)--stop-grace-period=[Time to wait before force killing a container]:grace period: "
1096 1096
         "($help)--update-delay=[Delay between updates]:delay: "
1097
+        "($help)--update-failure-action=[Action on update failure]:mode:(pause continue)"
1097 1098
         "($help)--update-parallelism=[Maximum number of tasks updated simultaneously]:number: "
1098 1099
         "($help -u --user)"{-u=,--user=}"[Username or UID]:user:_users"
1099 1100
         "($help)--with-registry-auth[Send registry authentication details to swarm agents]"
... ...
@@ -53,9 +53,16 @@ func ServiceFromGRPC(s swarmapi.Service) types.Service {
53 53
 		}
54 54
 
55 55
 		service.Spec.UpdateConfig.Delay, _ = ptypes.Duration(&s.Spec.Update.Delay)
56
+
57
+		switch s.Spec.Update.FailureAction {
58
+		case swarmapi.UpdateConfig_PAUSE:
59
+			service.Spec.UpdateConfig.FailureAction = types.UpdateFailureActionPause
60
+		case swarmapi.UpdateConfig_CONTINUE:
61
+			service.Spec.UpdateConfig.FailureAction = types.UpdateFailureActionContinue
62
+		}
56 63
 	}
57 64
 
58
-	//Mode
65
+	// Mode
59 66
 	switch t := s.Spec.GetMode().(type) {
60 67
 	case *swarmapi.ServiceSpec_Global:
61 68
 		service.Spec.Mode.Global = &types.GlobalService{}
... ...
@@ -65,6 +72,23 @@ func ServiceFromGRPC(s swarmapi.Service) types.Service {
65 65
 		}
66 66
 	}
67 67
 
68
+	// UpdateStatus
69
+	service.UpdateStatus = types.UpdateStatus{}
70
+	if s.UpdateStatus != nil {
71
+		switch s.UpdateStatus.State {
72
+		case swarmapi.UpdateStatus_UPDATING:
73
+			service.UpdateStatus.State = types.UpdateStateUpdating
74
+		case swarmapi.UpdateStatus_PAUSED:
75
+			service.UpdateStatus.State = types.UpdateStatePaused
76
+		case swarmapi.UpdateStatus_COMPLETED:
77
+			service.UpdateStatus.State = types.UpdateStateCompleted
78
+		}
79
+
80
+		service.UpdateStatus.StartedAt, _ = ptypes.Timestamp(s.UpdateStatus.StartedAt)
81
+		service.UpdateStatus.CompletedAt, _ = ptypes.Timestamp(s.UpdateStatus.CompletedAt)
82
+		service.UpdateStatus.Message = s.UpdateStatus.Message
83
+	}
84
+
68 85
 	return service
69 86
 }
70 87
 
... ...
@@ -111,9 +135,19 @@ func ServiceSpecToGRPC(s types.ServiceSpec) (swarmapi.ServiceSpec, error) {
111 111
 	}
112 112
 
113 113
 	if s.UpdateConfig != nil {
114
+		var failureAction swarmapi.UpdateConfig_FailureAction
115
+		switch s.UpdateConfig.FailureAction {
116
+		case types.UpdateFailureActionPause, "":
117
+			failureAction = swarmapi.UpdateConfig_PAUSE
118
+		case types.UpdateFailureActionContinue:
119
+			failureAction = swarmapi.UpdateConfig_CONTINUE
120
+		default:
121
+			return swarmapi.ServiceSpec{}, fmt.Errorf("unrecongized update failure action %s", s.UpdateConfig.FailureAction)
122
+		}
114 123
 		spec.Update = &swarmapi.UpdateConfig{
115
-			Parallelism: s.UpdateConfig.Parallelism,
116
-			Delay:       *ptypes.DurationProto(s.UpdateConfig.Delay),
124
+			Parallelism:   s.UpdateConfig.Parallelism,
125
+			Delay:         *ptypes.DurationProto(s.UpdateConfig.Delay),
126
+			FailureAction: failureAction,
117 127
 		}
118 128
 	}
119 129
 
... ...
@@ -3966,7 +3966,8 @@ Create a service
3966 3966
       },
3967 3967
       "UpdateConfig": {
3968 3968
         "Delay": 30000000000.0,
3969
-        "Parallelism": 2
3969
+        "Parallelism": 2,
3970
+        "FailureAction": "pause"
3970 3971
       },
3971 3972
       "EndpointSpec": {
3972 3973
         "Ports": [
... ...
@@ -4056,6 +4057,8 @@ JSON Parameters:
4056 4056
     - **Parallelism** – Maximum number of tasks to be updated in one iteration (0 means unlimited
4057 4057
       parallelism).
4058 4058
     - **Delay** – Amount of time between updates.
4059
+    - **FailureAction** - Action to take if an updated task fails to run, or stops running during the
4060
+      update. Values are `continue` and `pause`.
4059 4061
 - **Networks** – Array of network names or IDs to attach the service to.
4060 4062
 - **Endpoint** – Properties that can be configured to access and load balance a service.
4061 4063
     - **Spec** –
... ...
@@ -3967,7 +3967,8 @@ Create a service
3967 3967
       },
3968 3968
       "UpdateConfig": {
3969 3969
         "Delay": 30000000000.0,
3970
-        "Parallelism": 2
3970
+        "Parallelism": 2,
3971
+        "FailureAction": "pause"
3971 3972
       },
3972 3973
       "EndpointSpec": {
3973 3974
         "Ports": [
... ...
@@ -4057,6 +4058,8 @@ JSON Parameters:
4057 4057
     - **Parallelism** – Maximum number of tasks to be updated in one iteration (0 means unlimited
4058 4058
       parallelism).
4059 4059
     - **Delay** – Amount of time between updates.
4060
+    - **FailureAction** - Action to take if an updated task fails to run, or stops running during the
4061
+      update. Values are `continue` and `pause`.
4060 4062
 - **Networks** – Array of network names or IDs to attach the service to.
4061 4063
 - **Endpoint** – Properties that can be configured to access and load balance a service.
4062 4064
     - **Spec** –
... ...
@@ -17,33 +17,34 @@ Usage:  docker service create [OPTIONS] IMAGE [COMMAND] [ARG...]
17 17
 Create a new service
18 18
 
19 19
 Options:
20
-      --constraint value             Placement constraints (default [])
21
-      --endpoint-mode string         Endpoint mode (vip or dnsrr)
22
-  -e, --env value                    Set environment variables (default [])
23
-      --help                         Print usage
24
-  -l, --label value                  Service labels (default [])
25
-      --limit-cpu value              Limit CPUs (default 0.000)
26
-      --limit-memory value           Limit Memory (default 0 B)
27
-      --log-driver string            Logging driver for service
28
-      --log-opt value                Logging driver options (default [])
29
-      --mode string                  Service mode (replicated or global) (default "replicated")
30
-      --mount value                  Attach a mount to the service
31
-      --name string                  Service name
32
-      --network value                Network attachments (default [])
33
-  -p, --publish value                Publish a port as a node port (default [])
34
-      --replicas value               Number of tasks (default none)
35
-      --reserve-cpu value            Reserve CPUs (default 0.000)
36
-      --reserve-memory value         Reserve Memory (default 0 B)
37
-      --restart-condition string     Restart when condition is met (none, on-failure, or any)
38
-      --restart-delay value          Delay between restart attempts (default none)
39
-      --restart-max-attempts value   Maximum number of restarts before giving up (default none)
40
-      --restart-window value         Window used to evaluate the restart policy (default none)
41
-      --stop-grace-period value      Time to wait before force killing a container (default none)
42
-      --update-delay duration        Delay between updates
43
-      --update-parallelism uint      Maximum number of tasks updated simultaneously (0 to update all at once) (default 1)
44
-  -u, --user string                  Username or UID
45
-      --with-registry-auth           Send registry authentication details to Swarm agents
46
-  -w, --workdir string               Working directory inside the container
20
+      --constraint value               Placement constraints (default [])
21
+      --endpoint-mode string           Endpoint mode (vip or dnsrr)
22
+  -e, --env value                      Set environment variables (default [])
23
+      --help                           Print usage
24
+  -l, --label value                    Service labels (default [])
25
+      --limit-cpu value                Limit CPUs (default 0.000)
26
+      --limit-memory value             Limit Memory (default 0 B)
27
+      --log-driver string              Logging driver for service
28
+      --log-opt value                  Logging driver options (default [])
29
+      --mode string                    Service mode (replicated or global) (default "replicated")
30
+      --mount value                    Attach a mount to the service
31
+      --name string                    Service name
32
+      --network value                  Network attachments (default [])
33
+  -p, --publish value                  Publish a port as a node port (default [])
34
+      --replicas value                 Number of tasks (default none)
35
+      --reserve-cpu value              Reserve CPUs (default 0.000)
36
+      --reserve-memory value           Reserve Memory (default 0 B)
37
+      --restart-condition string       Restart when condition is met (none, on-failure, or any)
38
+      --restart-delay value            Delay between restart attempts (default none)
39
+      --restart-max-attempts value     Maximum number of restarts before giving up (default none)
40
+      --restart-window value           Window used to evaluate the restart policy (default none)
41
+      --stop-grace-period value        Time to wait before force killing a container (default none)
42
+      --update-delay duration          Delay between updates
43
+      --update-failure-action string   Action on update failure (pause|continue) (default "pause")
44
+      --update-parallelism uint        Maximum number of tasks updated simultaneously (0 to update all at once) (default 1)
45
+  -u, --user string                    Username or UID
46
+      --with-registry-auth             Send registry authentication details to Swarm agents
47
+  -w, --workdir string                 Working directory inside the container
47 48
 ```
48 49
 
49 50
 Creates a service as described by the specified parameters. This command has to
... ...
@@ -17,40 +17,41 @@ Usage:  docker service update [OPTIONS] SERVICE
17 17
 Update a service
18 18
 
19 19
 Options:
20
-      --args string                  Service command args
21
-      --constraint-add value         Add or update placement constraints (default [])
22
-      --constraint-rm value          Remove a constraint (default [])
23
-      --endpoint-mode string         Endpoint mode (vip or dnsrr)
24
-      --env-add value                Add or update environment variables (default [])
25
-      --env-rm value                 Remove an environment variable (default [])
26
-      --help                         Print usage
27
-      --image string                 Service image tag
28
-      --label-add value              Add or update service labels (default [])
29
-      --label-rm value               Remove a label by its key (default [])
30
-      --limit-cpu value              Limit CPUs (default 0.000)
31
-      --limit-memory value           Limit Memory (default 0 B)
32
-      --log-driver string            Logging driver for service
33
-      --log-opt value                Logging driver options (default [])
34
-      --mount-add value              Add or update a mount on a service
35
-      --mount-rm value               Remove a mount by its target path (default [])
36
-      --name string                  Service name
37
-      --network-add value            Add or update network attachments (default [])
38
-      --network-rm value             Remove a network by name (default [])
39
-      --publish-add value            Add or update a published port (default [])
40
-      --publish-rm value             Remove a published port by its target port (default [])
41
-      --replicas value               Number of tasks (default none)
42
-      --reserve-cpu value            Reserve CPUs (default 0.000)
43
-      --reserve-memory value         Reserve Memory (default 0 B)
44
-      --restart-condition string     Restart when condition is met (none, on-failure, or any)
45
-      --restart-delay value          Delay between restart attempts (default none)
46
-      --restart-max-attempts value   Maximum number of restarts before giving up (default none)
47
-      --restart-window value         Window used to evaluate the restart policy (default none)
48
-      --stop-grace-period value      Time to wait before force killing a container (default none)
49
-      --update-delay duration        Delay between updates
50
-      --update-parallelism uint      Maximum number of tasks updated simultaneously (0 to update all at once) (default 1)
51
-  -u, --user string                  Username or UID
52
-      --with-registry-auth           Send registry authentication details to Swarm agents
53
-  -w, --workdir string               Working directory inside the container
20
+      --args string                    Service command args
21
+      --constraint-add value           Add or update placement constraints (default [])
22
+      --constraint-rm value            Remove a constraint (default [])
23
+      --endpoint-mode string           Endpoint mode (vip or dnsrr)
24
+      --env-add value                  Add or update environment variables (default [])
25
+      --env-rm value                   Remove an environment variable (default [])
26
+      --help                           Print usage
27
+      --image string                   Service image tag
28
+      --label-add value                Add or update service labels (default [])
29
+      --label-rm value                 Remove a label by its key (default [])
30
+      --limit-cpu value                Limit CPUs (default 0.000)
31
+      --limit-memory value             Limit Memory (default 0 B)
32
+      --log-driver string              Logging driver for service
33
+      --log-opt value                  Logging driver options (default [])
34
+      --mount-add value                Add or update a mount on a service
35
+      --mount-rm value                 Remove a mount by its target path (default [])
36
+      --name string                    Service name
37
+      --network-add value              Add or update network attachments (default [])
38
+      --network-rm value               Remove a network by name (default [])
39
+      --publish-add value              Add or update a published port (default [])
40
+      --publish-rm value               Remove a published port by its target port (default [])
41
+      --replicas value                 Number of tasks (default none)
42
+      --reserve-cpu value              Reserve CPUs (default 0.000)
43
+      --reserve-memory value           Reserve Memory (default 0 B)
44
+      --restart-condition string       Restart when condition is met (none, on-failure, or any)
45
+      --restart-delay value            Delay between restart attempts (default none)
46
+      --restart-max-attempts value     Maximum number of restarts before giving up (default none)
47
+      --restart-window value           Window used to evaluate the restart policy (default none)
48
+      --stop-grace-period value        Time to wait before force killing a container (default none)
49
+      --update-delay duration          Delay between updates
50
+      --update-failure-action string   Action on update failure (pause|continue) (default "pause")
51
+      --update-parallelism uint        Maximum number of tasks updated simultaneously (0 to update all at once) (default 1)
52
+  -u, --user string                    Username or UID
53
+      --with-registry-auth             Send registry authentication details to Swarm agents
54
+  -w, --workdir string                 Working directory inside the container
54 55
 ```
55 56
 
56 57
 Updates a service as described by the specified parameters. This command has to be run targeting a manager node.
... ...
@@ -60,7 +60,7 @@ clone git golang.org/x/net 2beffdc2e92c8a3027590f898fe88f69af48a3f8 https://gith
60 60
 clone git golang.org/x/sys eb2c74142fd19a79b3f237334c7384d5167b1b46 https://github.com/golang/sys.git
61 61
 clone git github.com/docker/go-units 651fc226e7441360384da338d0fd37f2440ffbe3
62 62
 clone git github.com/docker/go-connections fa2850ff103453a9ad190da0df0af134f0314b3d
63
-clone git github.com/docker/engine-api ebb728a1346926edc2ad9418f9b6045901810b20
63
+clone git github.com/docker/engine-api 53b6b19ee622c8584c28fdde0e3893383b290da3
64 64
 clone git github.com/RackSec/srslog 259aed10dfa74ea2961eddd1d9847619f6e98837
65 65
 clone git github.com/imdario/mergo 0.2.1
66 66
 
... ...
@@ -791,8 +791,9 @@ func serviceForUpdate(s *swarm.Service) {
791 791
 			},
792 792
 		},
793 793
 		UpdateConfig: &swarm.UpdateConfig{
794
-			Parallelism: 2,
795
-			Delay:       8 * time.Second,
794
+			Parallelism:   2,
795
+			Delay:         8 * time.Second,
796
+			FailureAction: swarm.UpdateFailureActionContinue,
796 797
 		},
797 798
 	}
798 799
 	s.Spec.Name = "updatetest"
... ...
@@ -6,8 +6,9 @@ import "time"
6 6
 type Service struct {
7 7
 	ID string
8 8
 	Meta
9
-	Spec     ServiceSpec `json:",omitempty"`
10
-	Endpoint Endpoint    `json:",omitempty"`
9
+	Spec         ServiceSpec  `json:",omitempty"`
10
+	Endpoint     Endpoint     `json:",omitempty"`
11
+	UpdateStatus UpdateStatus `json:",omitempty"`
11 12
 }
12 13
 
13 14
 // ServiceSpec represents the spec of a service.
... ...
@@ -29,6 +30,26 @@ type ServiceMode struct {
29 29
 	Global     *GlobalService     `json:",omitempty"`
30 30
 }
31 31
 
32
+// UpdateState is the state of a service update.
33
+type UpdateState string
34
+
35
+const (
36
+	// UpdateStateUpdating is the updating state.
37
+	UpdateStateUpdating UpdateState = "updating"
38
+	// UpdateStatePaused is the paused state.
39
+	UpdateStatePaused UpdateState = "paused"
40
+	// UpdateStateCompleted is the completed state.
41
+	UpdateStateCompleted UpdateState = "completed"
42
+)
43
+
44
+// UpdateStatus reports the status of a service update.
45
+type UpdateStatus struct {
46
+	State       UpdateState `json:",omitempty"`
47
+	StartedAt   time.Time   `json:",omitempty"`
48
+	CompletedAt time.Time   `json:",omitempty"`
49
+	Message     string      `json:",omitempty"`
50
+}
51
+
32 52
 // ReplicatedService is a kind of ServiceMode.
33 53
 type ReplicatedService struct {
34 54
 	Replicas *uint64 `json:",omitempty"`
... ...
@@ -37,8 +58,16 @@ type ReplicatedService struct {
37 37
 // GlobalService is a kind of ServiceMode.
38 38
 type GlobalService struct{}
39 39
 
40
+const (
41
+	// UpdateFailureActionPause PAUSE
42
+	UpdateFailureActionPause = "pause"
43
+	// UpdateFailureActionContinue CONTINUE
44
+	UpdateFailureActionContinue = "continue"
45
+)
46
+
40 47
 // UpdateConfig represents the update configuration.
41 48
 type UpdateConfig struct {
42
-	Parallelism uint64        `json:",omitempty"`
43
-	Delay       time.Duration `json:",omitempty"`
49
+	Parallelism   uint64        `json:",omitempty"`
50
+	Delay         time.Duration `json:",omitempty"`
51
+	FailureAction string        `json:",omitempty"`
44 52
 }