Add flags to container/service for health start interval

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
This commit is contained in:
Brian Goff 2023-07-06 19:05:34 +00:00
parent 9bfaa6ff79
commit 986879c071
4 changed files with 137 additions and 117 deletions

View File

@ -31,99 +31,100 @@ var deviceCgroupRuleRegexp = regexp.MustCompile(`^[acb] ([0-9]+|\*):([0-9]+|\*)
// containerOptions is a data object with all the options for creating a container
type containerOptions struct {
attach opts.ListOpts
volumes opts.ListOpts
tmpfs opts.ListOpts
mounts opts.MountOpt
blkioWeightDevice opts.WeightdeviceOpt
deviceReadBps opts.ThrottledeviceOpt
deviceWriteBps opts.ThrottledeviceOpt
links opts.ListOpts
aliases opts.ListOpts
linkLocalIPs opts.ListOpts
deviceReadIOps opts.ThrottledeviceOpt
deviceWriteIOps opts.ThrottledeviceOpt
env opts.ListOpts
labels opts.ListOpts
deviceCgroupRules opts.ListOpts
devices opts.ListOpts
gpus opts.GpuOpts
ulimits *opts.UlimitOpt
sysctls *opts.MapOpts
publish opts.ListOpts
expose opts.ListOpts
dns opts.ListOpts
dnsSearch opts.ListOpts
dnsOptions opts.ListOpts
extraHosts opts.ListOpts
volumesFrom opts.ListOpts
envFile opts.ListOpts
capAdd opts.ListOpts
capDrop opts.ListOpts
groupAdd opts.ListOpts
securityOpt opts.ListOpts
storageOpt opts.ListOpts
labelsFile opts.ListOpts
loggingOpts opts.ListOpts
privileged bool
pidMode string
utsMode string
usernsMode string
cgroupnsMode string
publishAll bool
stdin bool
tty bool
oomKillDisable bool
oomScoreAdj int
containerIDFile string
entrypoint string
hostname string
domainname string
memory opts.MemBytes
memoryReservation opts.MemBytes
memorySwap opts.MemSwapBytes
kernelMemory opts.MemBytes
user string
workingDir string
cpuCount int64
cpuShares int64
cpuPercent int64
cpuPeriod int64
cpuRealtimePeriod int64
cpuRealtimeRuntime int64
cpuQuota int64
cpus opts.NanoCPUs
cpusetCpus string
cpusetMems string
blkioWeight uint16
ioMaxBandwidth opts.MemBytes
ioMaxIOps uint64
swappiness int64
netMode opts.NetworkOpt
macAddress string
ipv4Address string
ipv6Address string
ipcMode string
pidsLimit int64
restartPolicy string
readonlyRootfs bool
loggingDriver string
cgroupParent string
volumeDriver string
stopSignal string
stopTimeout int
isolation string
shmSize opts.MemBytes
noHealthcheck bool
healthCmd string
healthInterval time.Duration
healthTimeout time.Duration
healthStartPeriod time.Duration
healthRetries int
runtime string
autoRemove bool
init bool
annotations *opts.MapOpts
attach opts.ListOpts
volumes opts.ListOpts
tmpfs opts.ListOpts
mounts opts.MountOpt
blkioWeightDevice opts.WeightdeviceOpt
deviceReadBps opts.ThrottledeviceOpt
deviceWriteBps opts.ThrottledeviceOpt
links opts.ListOpts
aliases opts.ListOpts
linkLocalIPs opts.ListOpts
deviceReadIOps opts.ThrottledeviceOpt
deviceWriteIOps opts.ThrottledeviceOpt
env opts.ListOpts
labels opts.ListOpts
deviceCgroupRules opts.ListOpts
devices opts.ListOpts
gpus opts.GpuOpts
ulimits *opts.UlimitOpt
sysctls *opts.MapOpts
publish opts.ListOpts
expose opts.ListOpts
dns opts.ListOpts
dnsSearch opts.ListOpts
dnsOptions opts.ListOpts
extraHosts opts.ListOpts
volumesFrom opts.ListOpts
envFile opts.ListOpts
capAdd opts.ListOpts
capDrop opts.ListOpts
groupAdd opts.ListOpts
securityOpt opts.ListOpts
storageOpt opts.ListOpts
labelsFile opts.ListOpts
loggingOpts opts.ListOpts
privileged bool
pidMode string
utsMode string
usernsMode string
cgroupnsMode string
publishAll bool
stdin bool
tty bool
oomKillDisable bool
oomScoreAdj int
containerIDFile string
entrypoint string
hostname string
domainname string
memory opts.MemBytes
memoryReservation opts.MemBytes
memorySwap opts.MemSwapBytes
kernelMemory opts.MemBytes
user string
workingDir string
cpuCount int64
cpuShares int64
cpuPercent int64
cpuPeriod int64
cpuRealtimePeriod int64
cpuRealtimeRuntime int64
cpuQuota int64
cpus opts.NanoCPUs
cpusetCpus string
cpusetMems string
blkioWeight uint16
ioMaxBandwidth opts.MemBytes
ioMaxIOps uint64
swappiness int64
netMode opts.NetworkOpt
macAddress string
ipv4Address string
ipv6Address string
ipcMode string
pidsLimit int64
restartPolicy string
readonlyRootfs bool
loggingDriver string
cgroupParent string
volumeDriver string
stopSignal string
stopTimeout int
isolation string
shmSize opts.MemBytes
noHealthcheck bool
healthCmd string
healthInterval time.Duration
healthTimeout time.Duration
healthStartPeriod time.Duration
healthStartInterval time.Duration
healthRetries int
runtime string
autoRemove bool
init bool
annotations *opts.MapOpts
Image string
Args []string
@ -250,6 +251,8 @@ func addFlags(flags *pflag.FlagSet) *containerOptions {
flags.DurationVar(&copts.healthTimeout, "health-timeout", 0, "Maximum time to allow one check to run (ms|s|m|h) (default 0s)")
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)")
flags.SetAnnotation("health-start-period", "version", []string{"1.29"})
flags.DurationVar(&copts.healthStartInterval, "health-start-interval", 0, "Time between running the check during the start period (ms|s|m|h) (default 0s)")
flags.SetAnnotation("health-start-interval", "version", []string{"1.44"})
flags.BoolVar(&copts.noHealthcheck, "no-healthcheck", false, "Disable any container-specified HEALTHCHECK")
// Resource management
@ -526,7 +529,8 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
copts.healthInterval != 0 ||
copts.healthTimeout != 0 ||
copts.healthStartPeriod != 0 ||
copts.healthRetries != 0
copts.healthRetries != 0 ||
copts.healthStartInterval != 0
if copts.noHealthcheck {
if haveHealthSettings {
return nil, errors.Errorf("--no-healthcheck conflicts with --health-* options")
@ -549,13 +553,17 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
if copts.healthStartPeriod < 0 {
return nil, fmt.Errorf("--health-start-period cannot be negative")
}
if copts.healthStartInterval < 0 {
return nil, fmt.Errorf("--health-start-interval cannot be negative")
}
healthConfig = &container.HealthConfig{
Test: probe,
Interval: copts.healthInterval,
Timeout: copts.healthTimeout,
StartPeriod: copts.healthStartPeriod,
Retries: copts.healthRetries,
Test: probe,
Interval: copts.healthInterval,
Timeout: copts.healthTimeout,
StartPeriod: copts.healthStartPeriod,
StartInterval: copts.healthStartInterval,
Retries: copts.healthRetries,
}
}

View File

@ -720,8 +720,8 @@ func TestParseHealth(t *testing.T) {
checkError("--no-healthcheck conflicts with --health-* options",
"--no-healthcheck", "--health-cmd=/check.sh -q", "img", "cmd")
health = checkOk("--health-timeout=2s", "--health-retries=3", "--health-interval=4.5s", "--health-start-period=5s", "img", "cmd")
if health.Timeout != 2*time.Second || health.Retries != 3 || health.Interval != 4500*time.Millisecond || health.StartPeriod != 5*time.Second {
health = checkOk("--health-timeout=2s", "--health-retries=3", "--health-interval=4.5s", "--health-start-period=5s", "--health-start-interval=1s", "img", "cmd")
if health.Timeout != 2*time.Second || health.Retries != 3 || health.Interval != 4500*time.Millisecond || health.StartPeriod != 5*time.Second || health.StartInterval != 1*time.Second {
t.Fatalf("--health-*: got %#v", health)
}
}

View File

@ -428,6 +428,7 @@ type healthCheckOptions struct {
timeout opts.PositiveDurationOpt
retries int
startPeriod opts.PositiveDurationOpt
startInterval opts.PositiveDurationOpt
noHealthcheck bool
}
@ -436,6 +437,8 @@ func (opts *healthCheckOptions) toHealthConfig() (*container.HealthConfig, error
haveHealthSettings := opts.cmd != "" ||
opts.interval.Value() != nil ||
opts.timeout.Value() != nil ||
opts.startPeriod.Value() != nil ||
opts.startInterval.Value() != nil ||
opts.retries != 0
if opts.noHealthcheck {
if haveHealthSettings {
@ -447,7 +450,7 @@ func (opts *healthCheckOptions) toHealthConfig() (*container.HealthConfig, error
if opts.cmd != "" {
test = []string{"CMD-SHELL", opts.cmd}
}
var interval, timeout, startPeriod time.Duration
var interval, timeout, startPeriod, startInterval time.Duration
if ptr := opts.interval.Value(); ptr != nil {
interval = *ptr
}
@ -457,12 +460,16 @@ func (opts *healthCheckOptions) toHealthConfig() (*container.HealthConfig, error
if ptr := opts.startPeriod.Value(); ptr != nil {
startPeriod = *ptr
}
if ptr := opts.startInterval.Value(); ptr != nil {
startInterval = *ptr
}
healthConfig = &container.HealthConfig{
Test: test,
Interval: interval,
Timeout: timeout,
Retries: opts.retries,
StartPeriod: startPeriod,
Test: test,
Interval: interval,
Timeout: timeout,
Retries: opts.retries,
StartPeriod: startPeriod,
StartInterval: startInterval,
}
}
return healthConfig, nil
@ -906,6 +913,8 @@ func addServiceFlags(flags *pflag.FlagSet, opts *serviceOptions, defaultFlagValu
flags.SetAnnotation(flagHealthRetries, "version", []string{"1.25"})
flags.Var(&opts.healthcheck.startPeriod, flagHealthStartPeriod, "Start period for the container to initialize before counting retries towards unstable (ms|s|m|h)")
flags.SetAnnotation(flagHealthStartPeriod, "version", []string{"1.29"})
flags.Var(&opts.healthcheck.startInterval, flagHealthStartInterval, "Time between running the check during the start period (ms|s|m|h)")
flags.SetAnnotation(flagHealthStartInterval, "version", []string{"1.44"})
flags.BoolVar(&opts.healthcheck.noHealthcheck, flagNoHealthcheck, false, "Disable any container-specified HEALTHCHECK")
flags.SetAnnotation(flagNoHealthcheck, "version", []string{"1.25"})
@ -1016,6 +1025,7 @@ const (
flagHealthRetries = "health-retries"
flagHealthTimeout = "health-timeout"
flagHealthStartPeriod = "health-start-period"
flagHealthStartInterval = "health-start-interval"
flagNoHealthcheck = "no-healthcheck"
flagSecret = "secret"
flagSecretAdd = "secret-add"

View File

@ -108,20 +108,22 @@ func TestUint64OptSetAndValue(t *testing.T) {
func TestHealthCheckOptionsToHealthConfig(t *testing.T) {
dur := time.Second
opt := healthCheckOptions{
cmd: "curl",
interval: opts.PositiveDurationOpt{DurationOpt: *opts.NewDurationOpt(&dur)},
timeout: opts.PositiveDurationOpt{DurationOpt: *opts.NewDurationOpt(&dur)},
startPeriod: opts.PositiveDurationOpt{DurationOpt: *opts.NewDurationOpt(&dur)},
retries: 10,
cmd: "curl",
interval: opts.PositiveDurationOpt{DurationOpt: *opts.NewDurationOpt(&dur)},
timeout: opts.PositiveDurationOpt{DurationOpt: *opts.NewDurationOpt(&dur)},
startPeriod: opts.PositiveDurationOpt{DurationOpt: *opts.NewDurationOpt(&dur)},
startInterval: opts.PositiveDurationOpt{DurationOpt: *opts.NewDurationOpt(&dur)},
retries: 10,
}
config, err := opt.toHealthConfig()
assert.NilError(t, err)
assert.Check(t, is.DeepEqual(&container.HealthConfig{
Test: []string{"CMD-SHELL", "curl"},
Interval: time.Second,
Timeout: time.Second,
StartPeriod: time.Second,
Retries: 10,
Test: []string{"CMD-SHELL", "curl"},
Interval: time.Second,
Timeout: time.Second,
StartPeriod: time.Second,
StartInterval: time.Second,
Retries: 10,
}, config))
}