Skip to content

Commit df04aca

Browse files
authored
Merge pull request #4405 from cpuguy83/health_start_interval
Add support for health start interval
2 parents b8f51d9 + 125eeb7 commit df04aca

35 files changed

Lines changed: 217 additions & 201 deletions

cli/command/container/opts.go

Lines changed: 107 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -32,99 +32,100 @@ var deviceCgroupRuleRegexp = regexp.MustCompile(`^[acb] ([0-9]+|\*):([0-9]+|\*)
3232

3333
// containerOptions is a data object with all the options for creating a container
3434
type containerOptions struct {
35-
attach opts.ListOpts
36-
volumes opts.ListOpts
37-
tmpfs opts.ListOpts
38-
mounts opts.MountOpt
39-
blkioWeightDevice opts.WeightdeviceOpt
40-
deviceReadBps opts.ThrottledeviceOpt
41-
deviceWriteBps opts.ThrottledeviceOpt
42-
links opts.ListOpts
43-
aliases opts.ListOpts
44-
linkLocalIPs opts.ListOpts
45-
deviceReadIOps opts.ThrottledeviceOpt
46-
deviceWriteIOps opts.ThrottledeviceOpt
47-
env opts.ListOpts
48-
labels opts.ListOpts
49-
deviceCgroupRules opts.ListOpts
50-
devices opts.ListOpts
51-
gpus opts.GpuOpts
52-
ulimits *opts.UlimitOpt
53-
sysctls *opts.MapOpts
54-
publish opts.ListOpts
55-
expose opts.ListOpts
56-
dns opts.ListOpts
57-
dnsSearch opts.ListOpts
58-
dnsOptions opts.ListOpts
59-
extraHosts opts.ListOpts
60-
volumesFrom opts.ListOpts
61-
envFile opts.ListOpts
62-
capAdd opts.ListOpts
63-
capDrop opts.ListOpts
64-
groupAdd opts.ListOpts
65-
securityOpt opts.ListOpts
66-
storageOpt opts.ListOpts
67-
labelsFile opts.ListOpts
68-
loggingOpts opts.ListOpts
69-
privileged bool
70-
pidMode string
71-
utsMode string
72-
usernsMode string
73-
cgroupnsMode string
74-
publishAll bool
75-
stdin bool
76-
tty bool
77-
oomKillDisable bool
78-
oomScoreAdj int
79-
containerIDFile string
80-
entrypoint string
81-
hostname string
82-
domainname string
83-
memory opts.MemBytes
84-
memoryReservation opts.MemBytes
85-
memorySwap opts.MemSwapBytes
86-
kernelMemory opts.MemBytes
87-
user string
88-
workingDir string
89-
cpuCount int64
90-
cpuShares int64
91-
cpuPercent int64
92-
cpuPeriod int64
93-
cpuRealtimePeriod int64
94-
cpuRealtimeRuntime int64
95-
cpuQuota int64
96-
cpus opts.NanoCPUs
97-
cpusetCpus string
98-
cpusetMems string
99-
blkioWeight uint16
100-
ioMaxBandwidth opts.MemBytes
101-
ioMaxIOps uint64
102-
swappiness int64
103-
netMode opts.NetworkOpt
104-
macAddress string
105-
ipv4Address string
106-
ipv6Address string
107-
ipcMode string
108-
pidsLimit int64
109-
restartPolicy string
110-
readonlyRootfs bool
111-
loggingDriver string
112-
cgroupParent string
113-
volumeDriver string
114-
stopSignal string
115-
stopTimeout int
116-
isolation string
117-
shmSize opts.MemBytes
118-
noHealthcheck bool
119-
healthCmd string
120-
healthInterval time.Duration
121-
healthTimeout time.Duration
122-
healthStartPeriod time.Duration
123-
healthRetries int
124-
runtime string
125-
autoRemove bool
126-
init bool
127-
annotations *opts.MapOpts
35+
attach opts.ListOpts
36+
volumes opts.ListOpts
37+
tmpfs opts.ListOpts
38+
mounts opts.MountOpt
39+
blkioWeightDevice opts.WeightdeviceOpt
40+
deviceReadBps opts.ThrottledeviceOpt
41+
deviceWriteBps opts.ThrottledeviceOpt
42+
links opts.ListOpts
43+
aliases opts.ListOpts
44+
linkLocalIPs opts.ListOpts
45+
deviceReadIOps opts.ThrottledeviceOpt
46+
deviceWriteIOps opts.ThrottledeviceOpt
47+
env opts.ListOpts
48+
labels opts.ListOpts
49+
deviceCgroupRules opts.ListOpts
50+
devices opts.ListOpts
51+
gpus opts.GpuOpts
52+
ulimits *opts.UlimitOpt
53+
sysctls *opts.MapOpts
54+
publish opts.ListOpts
55+
expose opts.ListOpts
56+
dns opts.ListOpts
57+
dnsSearch opts.ListOpts
58+
dnsOptions opts.ListOpts
59+
extraHosts opts.ListOpts
60+
volumesFrom opts.ListOpts
61+
envFile opts.ListOpts
62+
capAdd opts.ListOpts
63+
capDrop opts.ListOpts
64+
groupAdd opts.ListOpts
65+
securityOpt opts.ListOpts
66+
storageOpt opts.ListOpts
67+
labelsFile opts.ListOpts
68+
loggingOpts opts.ListOpts
69+
privileged bool
70+
pidMode string
71+
utsMode string
72+
usernsMode string
73+
cgroupnsMode string
74+
publishAll bool
75+
stdin bool
76+
tty bool
77+
oomKillDisable bool
78+
oomScoreAdj int
79+
containerIDFile string
80+
entrypoint string
81+
hostname string
82+
domainname string
83+
memory opts.MemBytes
84+
memoryReservation opts.MemBytes
85+
memorySwap opts.MemSwapBytes
86+
kernelMemory opts.MemBytes
87+
user string
88+
workingDir string
89+
cpuCount int64
90+
cpuShares int64
91+
cpuPercent int64
92+
cpuPeriod int64
93+
cpuRealtimePeriod int64
94+
cpuRealtimeRuntime int64
95+
cpuQuota int64
96+
cpus opts.NanoCPUs
97+
cpusetCpus string
98+
cpusetMems string
99+
blkioWeight uint16
100+
ioMaxBandwidth opts.MemBytes
101+
ioMaxIOps uint64
102+
swappiness int64
103+
netMode opts.NetworkOpt
104+
macAddress string
105+
ipv4Address string
106+
ipv6Address string
107+
ipcMode string
108+
pidsLimit int64
109+
restartPolicy string
110+
readonlyRootfs bool
111+
loggingDriver string
112+
cgroupParent string
113+
volumeDriver string
114+
stopSignal string
115+
stopTimeout int
116+
isolation string
117+
shmSize opts.MemBytes
118+
noHealthcheck bool
119+
healthCmd string
120+
healthInterval time.Duration
121+
healthTimeout time.Duration
122+
healthStartPeriod time.Duration
123+
healthStartInterval time.Duration
124+
healthRetries int
125+
runtime string
126+
autoRemove bool
127+
init bool
128+
annotations *opts.MapOpts
128129

129130
Image string
130131
Args []string
@@ -251,6 +252,8 @@ func addFlags(flags *pflag.FlagSet) *containerOptions {
251252
flags.DurationVar(&copts.healthTimeout, "health-timeout", 0, "Maximum time to allow one check to run (ms|s|m|h) (default 0s)")
252253
flags.DurationVar(&copts.healthStartPeriod, "health-start-period", 0, "Start period for the container to initialize before starting health-retries countdown (ms|s|m|h) (default 0s)")
253254
flags.SetAnnotation("health-start-period", "version", []string{"1.29"})
255+
flags.DurationVar(&copts.healthStartInterval, "health-start-interval", 0, "Time between running the check during the start period (ms|s|m|h) (default 0s)")
256+
flags.SetAnnotation("health-start-interval", "version", []string{"1.44"})
254257
flags.BoolVar(&copts.noHealthcheck, "no-healthcheck", false, "Disable any container-specified HEALTHCHECK")
255258

256259
// Resource management
@@ -532,7 +535,8 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
532535
copts.healthInterval != 0 ||
533536
copts.healthTimeout != 0 ||
534537
copts.healthStartPeriod != 0 ||
535-
copts.healthRetries != 0
538+
copts.healthRetries != 0 ||
539+
copts.healthStartInterval != 0
536540
if copts.noHealthcheck {
537541
if haveHealthSettings {
538542
return nil, errors.Errorf("--no-healthcheck conflicts with --health-* options")
@@ -555,13 +559,17 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
555559
if copts.healthStartPeriod < 0 {
556560
return nil, fmt.Errorf("--health-start-period cannot be negative")
557561
}
562+
if copts.healthStartInterval < 0 {
563+
return nil, fmt.Errorf("--health-start-interval cannot be negative")
564+
}
558565

559566
healthConfig = &container.HealthConfig{
560-
Test: probe,
561-
Interval: copts.healthInterval,
562-
Timeout: copts.healthTimeout,
563-
StartPeriod: copts.healthStartPeriod,
564-
Retries: copts.healthRetries,
567+
Test: probe,
568+
Interval: copts.healthInterval,
569+
Timeout: copts.healthTimeout,
570+
StartPeriod: copts.healthStartPeriod,
571+
StartInterval: copts.healthStartInterval,
572+
Retries: copts.healthRetries,
565573
}
566574
}
567575

cli/command/container/opts_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -772,8 +772,8 @@ func TestParseHealth(t *testing.T) {
772772
checkError("--no-healthcheck conflicts with --health-* options",
773773
"--no-healthcheck", "--health-cmd=/check.sh -q", "img", "cmd")
774774

775-
health = checkOk("--health-timeout=2s", "--health-retries=3", "--health-interval=4.5s", "--health-start-period=5s", "img", "cmd")
776-
if health.Timeout != 2*time.Second || health.Retries != 3 || health.Interval != 4500*time.Millisecond || health.StartPeriod != 5*time.Second {
775+
health = checkOk("--health-timeout=2s", "--health-retries=3", "--health-interval=4.5s", "--health-start-period=5s", "--health-start-interval=1s", "img", "cmd")
776+
if health.Timeout != 2*time.Second || health.Retries != 3 || health.Interval != 4500*time.Millisecond || health.StartPeriod != 5*time.Second || health.StartInterval != 1*time.Second {
777777
t.Fatalf("--health-*: got %#v", health)
778778
}
779779
}

cli/command/service/opts.go

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,7 @@ type healthCheckOptions struct {
428428
timeout opts.PositiveDurationOpt
429429
retries int
430430
startPeriod opts.PositiveDurationOpt
431+
startInterval opts.PositiveDurationOpt
431432
noHealthcheck bool
432433
}
433434

@@ -436,6 +437,8 @@ func (opts *healthCheckOptions) toHealthConfig() (*container.HealthConfig, error
436437
haveHealthSettings := opts.cmd != "" ||
437438
opts.interval.Value() != nil ||
438439
opts.timeout.Value() != nil ||
440+
opts.startPeriod.Value() != nil ||
441+
opts.startInterval.Value() != nil ||
439442
opts.retries != 0
440443
if opts.noHealthcheck {
441444
if haveHealthSettings {
@@ -447,7 +450,7 @@ func (opts *healthCheckOptions) toHealthConfig() (*container.HealthConfig, error
447450
if opts.cmd != "" {
448451
test = []string{"CMD-SHELL", opts.cmd}
449452
}
450-
var interval, timeout, startPeriod time.Duration
453+
var interval, timeout, startPeriod, startInterval time.Duration
451454
if ptr := opts.interval.Value(); ptr != nil {
452455
interval = *ptr
453456
}
@@ -457,12 +460,16 @@ func (opts *healthCheckOptions) toHealthConfig() (*container.HealthConfig, error
457460
if ptr := opts.startPeriod.Value(); ptr != nil {
458461
startPeriod = *ptr
459462
}
463+
if ptr := opts.startInterval.Value(); ptr != nil {
464+
startInterval = *ptr
465+
}
460466
healthConfig = &container.HealthConfig{
461-
Test: test,
462-
Interval: interval,
463-
Timeout: timeout,
464-
Retries: opts.retries,
465-
StartPeriod: startPeriod,
467+
Test: test,
468+
Interval: interval,
469+
Timeout: timeout,
470+
Retries: opts.retries,
471+
StartPeriod: startPeriod,
472+
StartInterval: startInterval,
466473
}
467474
}
468475
return healthConfig, nil
@@ -906,6 +913,8 @@ func addServiceFlags(flags *pflag.FlagSet, opts *serviceOptions, defaultFlagValu
906913
flags.SetAnnotation(flagHealthRetries, "version", []string{"1.25"})
907914
flags.Var(&opts.healthcheck.startPeriod, flagHealthStartPeriod, "Start period for the container to initialize before counting retries towards unstable (ms|s|m|h)")
908915
flags.SetAnnotation(flagHealthStartPeriod, "version", []string{"1.29"})
916+
flags.Var(&opts.healthcheck.startInterval, flagHealthStartInterval, "Time between running the check during the start period (ms|s|m|h)")
917+
flags.SetAnnotation(flagHealthStartInterval, "version", []string{"1.44"})
909918
flags.BoolVar(&opts.healthcheck.noHealthcheck, flagNoHealthcheck, false, "Disable any container-specified HEALTHCHECK")
910919
flags.SetAnnotation(flagNoHealthcheck, "version", []string{"1.25"})
911920

@@ -1016,6 +1025,7 @@ const (
10161025
flagHealthRetries = "health-retries"
10171026
flagHealthTimeout = "health-timeout"
10181027
flagHealthStartPeriod = "health-start-period"
1028+
flagHealthStartInterval = "health-start-interval"
10191029
flagNoHealthcheck = "no-healthcheck"
10201030
flagSecret = "secret"
10211031
flagSecretAdd = "secret-add"

cli/command/service/opts_test.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -108,20 +108,22 @@ func TestUint64OptSetAndValue(t *testing.T) {
108108
func TestHealthCheckOptionsToHealthConfig(t *testing.T) {
109109
dur := time.Second
110110
opt := healthCheckOptions{
111-
cmd: "curl",
112-
interval: opts.PositiveDurationOpt{DurationOpt: *opts.NewDurationOpt(&dur)},
113-
timeout: opts.PositiveDurationOpt{DurationOpt: *opts.NewDurationOpt(&dur)},
114-
startPeriod: opts.PositiveDurationOpt{DurationOpt: *opts.NewDurationOpt(&dur)},
115-
retries: 10,
111+
cmd: "curl",
112+
interval: opts.PositiveDurationOpt{DurationOpt: *opts.NewDurationOpt(&dur)},
113+
timeout: opts.PositiveDurationOpt{DurationOpt: *opts.NewDurationOpt(&dur)},
114+
startPeriod: opts.PositiveDurationOpt{DurationOpt: *opts.NewDurationOpt(&dur)},
115+
startInterval: opts.PositiveDurationOpt{DurationOpt: *opts.NewDurationOpt(&dur)},
116+
retries: 10,
116117
}
117118
config, err := opt.toHealthConfig()
118119
assert.NilError(t, err)
119120
assert.Check(t, is.DeepEqual(&container.HealthConfig{
120-
Test: []string{"CMD-SHELL", "curl"},
121-
Interval: time.Second,
122-
Timeout: time.Second,
123-
StartPeriod: time.Second,
124-
Retries: 10,
121+
Test: []string{"CMD-SHELL", "curl"},
122+
Interval: time.Second,
123+
Timeout: time.Second,
124+
StartPeriod: time.Second,
125+
StartInterval: time.Second,
126+
Retries: 10,
125127
}, config))
126128
}
127129

docs/reference/commandline/container_create.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ Create a new container
5151
| `--health-cmd` | `string` | | Command to run to check health |
5252
| `--health-interval` | `duration` | `0s` | Time between running the check (ms\|s\|m\|h) (default 0s) |
5353
| `--health-retries` | `int` | `0` | Consecutive failures needed to report unhealthy |
54+
| `--health-start-interval` | `duration` | `0s` | Time between running the check during the start period (ms\|s\|m\|h) (default 0s) |
5455
| `--health-start-period` | `duration` | `0s` | Start period for the container to initialize before starting health-retries countdown (ms\|s\|m\|h) (default 0s) |
5556
| `--health-timeout` | `duration` | `0s` | Maximum time to allow one check to run (ms\|s\|m\|h) (default 0s) |
5657
| `--help` | | | Print usage |

docs/reference/commandline/container_run.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ Create and run a new container from an image
5353
| `--health-cmd` | `string` | | Command to run to check health |
5454
| `--health-interval` | `duration` | `0s` | Time between running the check (ms\|s\|m\|h) (default 0s) |
5555
| `--health-retries` | `int` | `0` | Consecutive failures needed to report unhealthy |
56+
| `--health-start-interval` | `duration` | `0s` | Time between running the check during the start period (ms\|s\|m\|h) (default 0s) |
5657
| `--health-start-period` | `duration` | `0s` | Start period for the container to initialize before starting health-retries countdown (ms\|s\|m\|h) (default 0s) |
5758
| `--health-timeout` | `duration` | `0s` | Maximum time to allow one check to run (ms\|s\|m\|h) (default 0s) |
5859
| `--help` | | | Print usage |

0 commit comments

Comments
 (0)