Also move the validation function to live with the type definition,
which allows it to be used outside of the daemon as well.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
| ... | ... |
@@ -1,6 +1,7 @@ |
| 1 | 1 |
package container // import "github.com/docker/docker/api/types/container" |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "fmt" |
|
| 4 | 5 |
"strings" |
| 5 | 6 |
|
| 6 | 7 |
"github.com/docker/docker/api/types/blkiodev" |
| ... | ... |
@@ -271,33 +272,42 @@ type DeviceMapping struct {
|
| 271 | 271 |
|
| 272 | 272 |
// RestartPolicy represents the restart policies of the container. |
| 273 | 273 |
type RestartPolicy struct {
|
| 274 |
- Name string |
|
| 274 |
+ Name RestartPolicyMode |
|
| 275 | 275 |
MaximumRetryCount int |
| 276 | 276 |
} |
| 277 | 277 |
|
| 278 |
+type RestartPolicyMode string |
|
| 279 |
+ |
|
| 280 |
+const ( |
|
| 281 |
+ RestartPolicyDisabled RestartPolicyMode = "no" |
|
| 282 |
+ RestartPolicyAlways RestartPolicyMode = "always" |
|
| 283 |
+ RestartPolicyOnFailure RestartPolicyMode = "on-failure" |
|
| 284 |
+ RestartPolicyUnlessStopped RestartPolicyMode = "unless-stopped" |
|
| 285 |
+) |
|
| 286 |
+ |
|
| 278 | 287 |
// IsNone indicates whether the container has the "no" restart policy. |
| 279 | 288 |
// This means the container will not automatically restart when exiting. |
| 280 | 289 |
func (rp *RestartPolicy) IsNone() bool {
|
| 281 |
- return rp.Name == "no" || rp.Name == "" |
|
| 290 |
+ return rp.Name == RestartPolicyDisabled || rp.Name == "" |
|
| 282 | 291 |
} |
| 283 | 292 |
|
| 284 | 293 |
// IsAlways indicates whether the container has the "always" restart policy. |
| 285 | 294 |
// This means the container will automatically restart regardless of the exit status. |
| 286 | 295 |
func (rp *RestartPolicy) IsAlways() bool {
|
| 287 |
- return rp.Name == "always" |
|
| 296 |
+ return rp.Name == RestartPolicyAlways |
|
| 288 | 297 |
} |
| 289 | 298 |
|
| 290 | 299 |
// IsOnFailure indicates whether the container has the "on-failure" restart policy. |
| 291 | 300 |
// This means the container will automatically restart of exiting with a non-zero exit status. |
| 292 | 301 |
func (rp *RestartPolicy) IsOnFailure() bool {
|
| 293 |
- return rp.Name == "on-failure" |
|
| 302 |
+ return rp.Name == RestartPolicyOnFailure |
|
| 294 | 303 |
} |
| 295 | 304 |
|
| 296 | 305 |
// IsUnlessStopped indicates whether the container has the |
| 297 | 306 |
// "unless-stopped" restart policy. This means the container will |
| 298 | 307 |
// automatically restart unless user has put it to stopped state. |
| 299 | 308 |
func (rp *RestartPolicy) IsUnlessStopped() bool {
|
| 300 |
- return rp.Name == "unless-stopped" |
|
| 309 |
+ return rp.Name == RestartPolicyUnlessStopped |
|
| 301 | 310 |
} |
| 302 | 311 |
|
| 303 | 312 |
// IsSame compares two RestartPolicy to see if they are the same |
| ... | ... |
@@ -305,6 +315,29 @@ func (rp *RestartPolicy) IsSame(tp *RestartPolicy) bool {
|
| 305 | 305 |
return rp.Name == tp.Name && rp.MaximumRetryCount == tp.MaximumRetryCount |
| 306 | 306 |
} |
| 307 | 307 |
|
| 308 |
+// ValidateRestartPolicy validates the given RestartPolicy. |
|
| 309 |
+func ValidateRestartPolicy(policy RestartPolicy) error {
|
|
| 310 |
+ switch policy.Name {
|
|
| 311 |
+ case RestartPolicyAlways, RestartPolicyUnlessStopped, RestartPolicyDisabled: |
|
| 312 |
+ if policy.MaximumRetryCount != 0 {
|
|
| 313 |
+ return &errInvalidParameter{fmt.Errorf("invalid restart policy: maximum retry count cannot be used with restart policy '%s'", policy.Name)}
|
|
| 314 |
+ } |
|
| 315 |
+ return nil |
|
| 316 |
+ case RestartPolicyOnFailure: |
|
| 317 |
+ if policy.MaximumRetryCount < 0 {
|
|
| 318 |
+ return &errInvalidParameter{fmt.Errorf("invalid restart policy: maximum retry count cannot be negative")}
|
|
| 319 |
+ } |
|
| 320 |
+ return nil |
|
| 321 |
+ case "": |
|
| 322 |
+ // Versions before v25.0.0 created an empty restart-policy "name" as |
|
| 323 |
+ // default. Allow an empty name with "any" MaximumRetryCount for |
|
| 324 |
+ // backward-compatibility. |
|
| 325 |
+ return nil |
|
| 326 |
+ default: |
|
| 327 |
+ return &errInvalidParameter{fmt.Errorf("invalid restart policy: '%s'", policy.Name)}
|
|
| 328 |
+ } |
|
| 329 |
+} |
|
| 330 |
+ |
|
| 308 | 331 |
// LogMode is a type to define the available modes for logging |
| 309 | 332 |
// These modes affect how logs are handled when log messages start piling up. |
| 310 | 333 |
type LogMode string |
| 311 | 334 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,105 @@ |
| 0 |
+package container |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "testing" |
|
| 4 |
+ |
|
| 5 |
+ "github.com/docker/docker/errdefs" |
|
| 6 |
+ "gotest.tools/v3/assert" |
|
| 7 |
+ is "gotest.tools/v3/assert/cmp" |
|
| 8 |
+) |
|
| 9 |
+ |
|
| 10 |
+func TestValidateRestartPolicy(t *testing.T) {
|
|
| 11 |
+ tests := []struct {
|
|
| 12 |
+ name string |
|
| 13 |
+ input RestartPolicy |
|
| 14 |
+ expectedErr string |
|
| 15 |
+ }{
|
|
| 16 |
+ {
|
|
| 17 |
+ name: "empty", |
|
| 18 |
+ input: RestartPolicy{},
|
|
| 19 |
+ }, |
|
| 20 |
+ {
|
|
| 21 |
+ name: "empty with invalid MaxRestartCount (for backward compatibility)", |
|
| 22 |
+ input: RestartPolicy{MaximumRetryCount: 123},
|
|
| 23 |
+ expectedErr: "", // Allowed for backward compatibility |
|
| 24 |
+ }, |
|
| 25 |
+ {
|
|
| 26 |
+ name: "empty with negative MaxRestartCount)", |
|
| 27 |
+ input: RestartPolicy{MaximumRetryCount: -123},
|
|
| 28 |
+ expectedErr: "", // Allowed for backward compatibility |
|
| 29 |
+ }, |
|
| 30 |
+ {
|
|
| 31 |
+ name: "always", |
|
| 32 |
+ input: RestartPolicy{Name: RestartPolicyAlways},
|
|
| 33 |
+ }, |
|
| 34 |
+ {
|
|
| 35 |
+ name: "always with MaxRestartCount", |
|
| 36 |
+ input: RestartPolicy{Name: RestartPolicyAlways, MaximumRetryCount: 123},
|
|
| 37 |
+ expectedErr: "invalid restart policy: maximum retry count cannot be used with restart policy 'always'", |
|
| 38 |
+ }, |
|
| 39 |
+ {
|
|
| 40 |
+ name: "always with negative MaxRestartCount", |
|
| 41 |
+ input: RestartPolicy{Name: RestartPolicyAlways, MaximumRetryCount: -123},
|
|
| 42 |
+ expectedErr: "invalid restart policy: maximum retry count cannot be used with restart policy 'always'", |
|
| 43 |
+ }, |
|
| 44 |
+ {
|
|
| 45 |
+ name: "unless-stopped", |
|
| 46 |
+ input: RestartPolicy{Name: RestartPolicyUnlessStopped},
|
|
| 47 |
+ }, |
|
| 48 |
+ {
|
|
| 49 |
+ name: "unless-stopped with MaxRestartCount", |
|
| 50 |
+ input: RestartPolicy{Name: RestartPolicyUnlessStopped, MaximumRetryCount: 123},
|
|
| 51 |
+ expectedErr: "invalid restart policy: maximum retry count cannot be used with restart policy 'unless-stopped'", |
|
| 52 |
+ }, |
|
| 53 |
+ {
|
|
| 54 |
+ name: "unless-stopped with negative MaxRestartCount", |
|
| 55 |
+ input: RestartPolicy{Name: RestartPolicyUnlessStopped, MaximumRetryCount: -123},
|
|
| 56 |
+ expectedErr: "invalid restart policy: maximum retry count cannot be used with restart policy 'unless-stopped'", |
|
| 57 |
+ }, |
|
| 58 |
+ {
|
|
| 59 |
+ name: "disabled", |
|
| 60 |
+ input: RestartPolicy{Name: RestartPolicyDisabled},
|
|
| 61 |
+ }, |
|
| 62 |
+ {
|
|
| 63 |
+ name: "disabled with MaxRestartCount", |
|
| 64 |
+ input: RestartPolicy{Name: RestartPolicyDisabled, MaximumRetryCount: 123},
|
|
| 65 |
+ expectedErr: "invalid restart policy: maximum retry count cannot be used with restart policy 'no'", |
|
| 66 |
+ }, |
|
| 67 |
+ {
|
|
| 68 |
+ name: "disabled with negative MaxRestartCount", |
|
| 69 |
+ input: RestartPolicy{Name: RestartPolicyDisabled, MaximumRetryCount: -123},
|
|
| 70 |
+ expectedErr: "invalid restart policy: maximum retry count cannot be used with restart policy 'no'", |
|
| 71 |
+ }, |
|
| 72 |
+ {
|
|
| 73 |
+ name: "on-failure", |
|
| 74 |
+ input: RestartPolicy{Name: RestartPolicyOnFailure},
|
|
| 75 |
+ }, |
|
| 76 |
+ {
|
|
| 77 |
+ name: "on-failure with MaxRestartCount", |
|
| 78 |
+ input: RestartPolicy{Name: RestartPolicyOnFailure, MaximumRetryCount: 123},
|
|
| 79 |
+ }, |
|
| 80 |
+ {
|
|
| 81 |
+ name: "on-failure with negative MaxRestartCount", |
|
| 82 |
+ input: RestartPolicy{Name: RestartPolicyOnFailure, MaximumRetryCount: -123},
|
|
| 83 |
+ expectedErr: "invalid restart policy: maximum retry count cannot be negative", |
|
| 84 |
+ }, |
|
| 85 |
+ {
|
|
| 86 |
+ name: "unknown policy", |
|
| 87 |
+ input: RestartPolicy{Name: "I do not exist"},
|
|
| 88 |
+ expectedErr: "invalid restart policy: 'I do not exist'", |
|
| 89 |
+ }, |
|
| 90 |
+ } |
|
| 91 |
+ |
|
| 92 |
+ for _, tc := range tests {
|
|
| 93 |
+ tc := tc |
|
| 94 |
+ t.Run(tc.name, func(t *testing.T) {
|
|
| 95 |
+ err := ValidateRestartPolicy(tc.input) |
|
| 96 |
+ if tc.expectedErr == "" {
|
|
| 97 |
+ assert.Check(t, err) |
|
| 98 |
+ } else {
|
|
| 99 |
+ assert.Check(t, is.ErrorType(err, errdefs.IsInvalidParameter)) |
|
| 100 |
+ assert.Check(t, is.Error(err, tc.expectedErr)) |
|
| 101 |
+ } |
|
| 102 |
+ }) |
|
| 103 |
+ } |
|
| 104 |
+} |
| ... | ... |
@@ -221,7 +221,7 @@ func TestRestartPolicy(t *testing.T) {
|
| 221 | 221 |
{Name: "on-failure", MaximumRetryCount: 0}: {none: false, always: false, onFailure: true},
|
| 222 | 222 |
} |
| 223 | 223 |
for policy, expected := range policies {
|
| 224 |
- t.Run("policy="+policy.Name, func(t *testing.T) {
|
|
| 224 |
+ t.Run("policy="+string(policy.Name), func(t *testing.T) {
|
|
| 225 | 225 |
assert.Check(t, is.Equal(policy.IsNone(), expected.none)) |
| 226 | 226 |
assert.Check(t, is.Equal(policy.IsAlways(), expected.always)) |
| 227 | 227 |
assert.Check(t, is.Equal(policy.IsOnFailure(), expected.onFailure)) |
| ... | ... |
@@ -298,7 +298,7 @@ func validateHostConfig(hostConfig *containertypes.HostConfig) error {
|
| 298 | 298 |
if err := validatePortBindings(hostConfig.PortBindings); err != nil {
|
| 299 | 299 |
return err |
| 300 | 300 |
} |
| 301 |
- if err := validateRestartPolicy(hostConfig.RestartPolicy); err != nil {
|
|
| 301 |
+ if err := containertypes.ValidateRestartPolicy(hostConfig.RestartPolicy); err != nil {
|
|
| 302 | 302 |
return err |
| 303 | 303 |
} |
| 304 | 304 |
if err := validateCapabilities(hostConfig); err != nil {
|
| ... | ... |
@@ -362,25 +362,6 @@ func validatePortBindings(ports nat.PortMap) error {
|
| 362 | 362 |
return nil |
| 363 | 363 |
} |
| 364 | 364 |
|
| 365 |
-func validateRestartPolicy(policy containertypes.RestartPolicy) error {
|
|
| 366 |
- switch policy.Name {
|
|
| 367 |
- case "always", "unless-stopped", "no": |
|
| 368 |
- if policy.MaximumRetryCount != 0 {
|
|
| 369 |
- return errors.Errorf("maximum retry count cannot be used with restart policy '%s'", policy.Name)
|
|
| 370 |
- } |
|
| 371 |
- case "on-failure": |
|
| 372 |
- if policy.MaximumRetryCount < 0 {
|
|
| 373 |
- return errors.Errorf("maximum retry count cannot be negative")
|
|
| 374 |
- } |
|
| 375 |
- case "": |
|
| 376 |
- // do nothing |
|
| 377 |
- return nil |
|
| 378 |
- default: |
|
| 379 |
- return errors.Errorf("invalid restart policy '%s'", policy.Name)
|
|
| 380 |
- } |
|
| 381 |
- return nil |
|
| 382 |
-} |
|
| 383 |
- |
|
| 384 | 365 |
// translateWorkingDir translates the working-dir for the target platform, |
| 385 | 366 |
// and returns an error if the given path is not an absolute path. |
| 386 | 367 |
func translateWorkingDir(config *containertypes.Config) error {
|
| ... | ... |
@@ -63,6 +63,16 @@ func (daemon *Daemon) containerCreate(ctx context.Context, daemonCfg *configStor |
| 63 | 63 |
return containertypes.CreateResponse{}, errdefs.InvalidParameter(errors.New("Config cannot be empty in order to create a container"))
|
| 64 | 64 |
} |
| 65 | 65 |
|
| 66 |
+ // Normalize some defaults. Doing this "ad-hoc" here for now, as there's |
|
| 67 |
+ // only one field to migrate, but we should consider having a better |
|
| 68 |
+ // location for this (and decide where in the flow would be most appropriate). |
|
| 69 |
+ // |
|
| 70 |
+ // TODO(thaJeztah): we should have a more visible, more canonical location for this. |
|
| 71 |
+ if opts.params.HostConfig != nil && opts.params.HostConfig.RestartPolicy.Name == "" {
|
|
| 72 |
+ // Set the default restart-policy ("none") if no restart-policy was set.
|
|
| 73 |
+ opts.params.HostConfig.RestartPolicy.Name = containertypes.RestartPolicyDisabled |
|
| 74 |
+ } |
|
| 75 |
+ |
|
| 66 | 76 |
warnings, err := daemon.verifyContainerSettings(daemonCfg, opts.params.HostConfig, opts.params.Config, false) |
| 67 | 77 |
if err != nil {
|
| 68 | 78 |
return containertypes.CreateResponse{Warnings: warnings}, errdefs.InvalidParameter(err)
|
| ... | ... |
@@ -338,8 +338,21 @@ func (daemon *Daemon) restore(cfg *configStore) error {
|
| 338 | 338 |
|
| 339 | 339 |
baseLogger := log.G(context.TODO()).WithField("container", c.ID)
|
| 340 | 340 |
|
| 341 |
+ // Migrate containers that don't have the default ("no") restart-policy set.
|
|
| 342 |
+ // The RestartPolicy.Name field may be empty for containers that were |
|
| 343 |
+ // created with versions before v25.0.0. |
|
| 344 |
+ // |
|
| 345 |
+ // We also need to set the MaximumRetryCount to 0, to prevent |
|
| 346 |
+ // validation from failing (MaximumRetryCount is not allowed if |
|
| 347 |
+ // no restart-policy ("none") is set).
|
|
| 348 |
+ if c.HostConfig != nil && c.HostConfig.RestartPolicy.Name == "" {
|
|
| 349 |
+ baseLogger.WithError(err).Debug("migrated restart-policy")
|
|
| 350 |
+ c.HostConfig.RestartPolicy.Name = containertypes.RestartPolicyDisabled |
|
| 351 |
+ c.HostConfig.RestartPolicy.MaximumRetryCount = 0 |
|
| 352 |
+ } |
|
| 353 |
+ |
|
| 341 | 354 |
if err := daemon.checkpointAndSave(c); err != nil {
|
| 342 |
- baseLogger.WithError(err).Error("error saving backported mountspec to disk")
|
|
| 355 |
+ baseLogger.WithError(err).Error("failed to save migrated container config to disk")
|
|
| 343 | 356 |
} |
| 344 | 357 |
|
| 345 | 358 |
daemon.setStateCounter(c) |
| ... | ... |
@@ -10,7 +10,7 @@ import ( |
| 10 | 10 |
"time" |
| 11 | 11 |
|
| 12 | 12 |
"github.com/docker/docker/api/types" |
| 13 |
- containerapi "github.com/docker/docker/api/types/container" |
|
| 13 |
+ containertypes "github.com/docker/docker/api/types/container" |
|
| 14 | 14 |
realcontainer "github.com/docker/docker/container" |
| 15 | 15 |
"github.com/docker/docker/integration/internal/container" |
| 16 | 16 |
"github.com/docker/docker/testutil/daemon" |
| ... | ... |
@@ -101,7 +101,7 @@ func TestDaemonRestartIpcMode(t *testing.T) {
|
| 101 | 101 |
// check the container is created with private ipc mode as per daemon default |
| 102 | 102 |
cID := container.Run(ctx, t, c, |
| 103 | 103 |
container.WithCmd("top"),
|
| 104 |
- container.WithRestartPolicy("always"),
|
|
| 104 |
+ container.WithRestartPolicy(containertypes.RestartPolicyAlways), |
|
| 105 | 105 |
) |
| 106 | 106 |
defer c.ContainerRemove(ctx, cID, types.ContainerRemoveOptions{Force: true})
|
| 107 | 107 |
|
| ... | ... |
@@ -199,7 +199,7 @@ func TestRestartDaemonWithRestartingContainer(t *testing.T) {
|
| 199 | 199 |
// Just create the container, no need to start it to be started. |
| 200 | 200 |
// We really want to make sure there is no process running when docker starts back up. |
| 201 | 201 |
// We will manipulate the on disk state later |
| 202 |
- id := container.Create(ctx, t, apiClient, container.WithRestartPolicy("always"), container.WithCmd("/bin/sh", "-c", "exit 1"))
|
|
| 202 |
+ id := container.Create(ctx, t, apiClient, container.WithRestartPolicy(containertypes.RestartPolicyAlways), container.WithCmd("/bin/sh", "-c", "exit 1"))
|
|
| 203 | 203 |
|
| 204 | 204 |
d.Stop(t) |
| 205 | 205 |
|
| ... | ... |
@@ -212,7 +212,7 @@ func TestRestartDaemonWithRestartingContainer(t *testing.T) {
|
| 212 | 212 |
|
| 213 | 213 |
ctxTimeout, cancel := context.WithTimeout(ctx, 30*time.Second) |
| 214 | 214 |
defer cancel() |
| 215 |
- chOk, chErr := apiClient.ContainerWait(ctxTimeout, id, containerapi.WaitConditionNextExit) |
|
| 215 |
+ chOk, chErr := apiClient.ContainerWait(ctxTimeout, id, containertypes.WaitConditionNextExit) |
|
| 216 | 216 |
select {
|
| 217 | 217 |
case <-chOk: |
| 218 | 218 |
case err := <-chErr: |
| ... | ... |
@@ -284,6 +284,6 @@ func TestHardRestartWhenContainerIsRunning(t *testing.T) {
|
| 284 | 284 |
} |
| 285 | 285 |
|
| 286 | 286 |
stopTimeout := 0 |
| 287 |
- assert.Assert(t, apiClient.ContainerStop(ctx, onFailure, containerapi.StopOptions{Timeout: &stopTimeout}))
|
|
| 287 |
+ assert.Assert(t, apiClient.ContainerStop(ctx, onFailure, containertypes.StopOptions{Timeout: &stopTimeout}))
|
|
| 288 | 288 |
}) |
| 289 | 289 |
} |
| ... | ... |
@@ -6,6 +6,7 @@ import ( |
| 6 | 6 |
"testing" |
| 7 | 7 |
"time" |
| 8 | 8 |
|
| 9 |
+ containertypes "github.com/docker/docker/api/types/container" |
|
| 9 | 10 |
"github.com/docker/docker/client" |
| 10 | 11 |
"github.com/docker/docker/integration/internal/container" |
| 11 | 12 |
"github.com/docker/docker/testutil/request" |
| ... | ... |
@@ -112,7 +113,7 @@ func TestKillWithStopSignalAndRestartPolicies(t *testing.T) {
|
| 112 | 112 |
t.Run(tc.doc, func(t *testing.T) {
|
| 113 | 113 |
ctx := context.Background() |
| 114 | 114 |
id := container.Run(ctx, t, apiClient, |
| 115 |
- container.WithRestartPolicy("always"),
|
|
| 115 |
+ container.WithRestartPolicy(containertypes.RestartPolicyAlways), |
|
| 116 | 116 |
func(c *container.TestContainerConfig) {
|
| 117 | 117 |
c.Config.StopSignal = tc.stopsignal |
| 118 | 118 |
}) |
| ... | ... |
@@ -24,7 +24,7 @@ func TestStopContainerWithRestartPolicyAlways(t *testing.T) {
|
| 24 | 24 |
container.Run(ctx, t, apiClient, |
| 25 | 25 |
container.WithName(name), |
| 26 | 26 |
container.WithCmd("false"),
|
| 27 |
- container.WithRestartPolicy("always"),
|
|
| 27 |
+ container.WithRestartPolicy(containertypes.RestartPolicyAlways), |
|
| 28 | 28 |
) |
| 29 | 29 |
} |
| 30 | 30 |
|
| ... | ... |
@@ -13,6 +13,7 @@ import ( |
| 13 | 13 |
"testing" |
| 14 | 14 |
|
| 15 | 15 |
"github.com/docker/docker/api/types" |
| 16 |
+ containertypes "github.com/docker/docker/api/types/container" |
|
| 16 | 17 |
"github.com/docker/docker/api/types/mount" |
| 17 | 18 |
"github.com/docker/docker/api/types/volume" |
| 18 | 19 |
"github.com/docker/docker/daemon/config" |
| ... | ... |
@@ -380,9 +381,9 @@ func testLiveRestoreVolumeReferences(t *testing.T) {
|
| 380 | 380 |
c := d.NewClientT(t) |
| 381 | 381 |
ctx := context.Background() |
| 382 | 382 |
|
| 383 |
- runTest := func(t *testing.T, policy string) {
|
|
| 384 |
- t.Run(policy, func(t *testing.T) {
|
|
| 385 |
- volName := "test-live-restore-volume-references-" + policy |
|
| 383 |
+ runTest := func(t *testing.T, policy containertypes.RestartPolicyMode) {
|
|
| 384 |
+ t.Run(string(policy), func(t *testing.T) {
|
|
| 385 |
+ volName := "test-live-restore-volume-references-" + string(policy) |
|
| 386 | 386 |
_, err := c.VolumeCreate(ctx, volume.CreateOptions{Name: volName})
|
| 387 | 387 |
assert.NilError(t, err) |
| 388 | 388 |
|
| ... | ... |
@@ -408,10 +409,10 @@ func testLiveRestoreVolumeReferences(t *testing.T) {
|
| 408 | 408 |
} |
| 409 | 409 |
|
| 410 | 410 |
t.Run("restartPolicy", func(t *testing.T) {
|
| 411 |
- runTest(t, "always") |
|
| 412 |
- runTest(t, "unless-stopped") |
|
| 413 |
- runTest(t, "on-failure") |
|
| 414 |
- runTest(t, "no") |
|
| 411 |
+ runTest(t, containertypes.RestartPolicyAlways) |
|
| 412 |
+ runTest(t, containertypes.RestartPolicyUnlessStopped) |
|
| 413 |
+ runTest(t, containertypes.RestartPolicyOnFailure) |
|
| 414 |
+ runTest(t, containertypes.RestartPolicyDisabled) |
|
| 415 | 415 |
}) |
| 416 | 416 |
|
| 417 | 417 |
// Make sure that the local volume driver's mount ref count is restored |
| ... | ... |
@@ -169,7 +169,7 @@ func WithPidsLimit(limit *int64) func(*TestContainerConfig) {
|
| 169 | 169 |
} |
| 170 | 170 |
|
| 171 | 171 |
// WithRestartPolicy sets container's restart policy |
| 172 |
-func WithRestartPolicy(policy string) func(c *TestContainerConfig) {
|
|
| 172 |
+func WithRestartPolicy(policy container.RestartPolicyMode) func(c *TestContainerConfig) {
|
|
| 173 | 173 |
return func(c *TestContainerConfig) {
|
| 174 | 174 |
c.HostConfig.RestartPolicy.Name = policy |
| 175 | 175 |
} |