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

@ -119,6 +119,7 @@ type containerOptions struct {
healthInterval time.Duration healthInterval time.Duration
healthTimeout time.Duration healthTimeout time.Duration
healthStartPeriod time.Duration healthStartPeriod time.Duration
healthStartInterval time.Duration
healthRetries int healthRetries int
runtime string runtime string
autoRemove bool autoRemove bool
@ -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.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.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.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") flags.BoolVar(&copts.noHealthcheck, "no-healthcheck", false, "Disable any container-specified HEALTHCHECK")
// Resource management // Resource management
@ -526,7 +529,8 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
copts.healthInterval != 0 || copts.healthInterval != 0 ||
copts.healthTimeout != 0 || copts.healthTimeout != 0 ||
copts.healthStartPeriod != 0 || copts.healthStartPeriod != 0 ||
copts.healthRetries != 0 copts.healthRetries != 0 ||
copts.healthStartInterval != 0
if copts.noHealthcheck { if copts.noHealthcheck {
if haveHealthSettings { if haveHealthSettings {
return nil, errors.Errorf("--no-healthcheck conflicts with --health-* options") return nil, errors.Errorf("--no-healthcheck conflicts with --health-* options")
@ -549,12 +553,16 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
if copts.healthStartPeriod < 0 { if copts.healthStartPeriod < 0 {
return nil, fmt.Errorf("--health-start-period cannot be negative") 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{ healthConfig = &container.HealthConfig{
Test: probe, Test: probe,
Interval: copts.healthInterval, Interval: copts.healthInterval,
Timeout: copts.healthTimeout, Timeout: copts.healthTimeout,
StartPeriod: copts.healthStartPeriod, StartPeriod: copts.healthStartPeriod,
StartInterval: copts.healthStartInterval,
Retries: copts.healthRetries, Retries: copts.healthRetries,
} }
} }

View File

@ -720,8 +720,8 @@ func TestParseHealth(t *testing.T) {
checkError("--no-healthcheck conflicts with --health-* options", checkError("--no-healthcheck conflicts with --health-* options",
"--no-healthcheck", "--health-cmd=/check.sh -q", "img", "cmd") "--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") 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 { 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) t.Fatalf("--health-*: got %#v", health)
} }
} }

View File

@ -428,6 +428,7 @@ type healthCheckOptions struct {
timeout opts.PositiveDurationOpt timeout opts.PositiveDurationOpt
retries int retries int
startPeriod opts.PositiveDurationOpt startPeriod opts.PositiveDurationOpt
startInterval opts.PositiveDurationOpt
noHealthcheck bool noHealthcheck bool
} }
@ -436,6 +437,8 @@ func (opts *healthCheckOptions) toHealthConfig() (*container.HealthConfig, error
haveHealthSettings := opts.cmd != "" || haveHealthSettings := opts.cmd != "" ||
opts.interval.Value() != nil || opts.interval.Value() != nil ||
opts.timeout.Value() != nil || opts.timeout.Value() != nil ||
opts.startPeriod.Value() != nil ||
opts.startInterval.Value() != nil ||
opts.retries != 0 opts.retries != 0
if opts.noHealthcheck { if opts.noHealthcheck {
if haveHealthSettings { if haveHealthSettings {
@ -447,7 +450,7 @@ func (opts *healthCheckOptions) toHealthConfig() (*container.HealthConfig, error
if opts.cmd != "" { if opts.cmd != "" {
test = []string{"CMD-SHELL", 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 { if ptr := opts.interval.Value(); ptr != nil {
interval = *ptr interval = *ptr
} }
@ -457,12 +460,16 @@ func (opts *healthCheckOptions) toHealthConfig() (*container.HealthConfig, error
if ptr := opts.startPeriod.Value(); ptr != nil { if ptr := opts.startPeriod.Value(); ptr != nil {
startPeriod = *ptr startPeriod = *ptr
} }
if ptr := opts.startInterval.Value(); ptr != nil {
startInterval = *ptr
}
healthConfig = &container.HealthConfig{ healthConfig = &container.HealthConfig{
Test: test, Test: test,
Interval: interval, Interval: interval,
Timeout: timeout, Timeout: timeout,
Retries: opts.retries, Retries: opts.retries,
StartPeriod: startPeriod, StartPeriod: startPeriod,
StartInterval: startInterval,
} }
} }
return healthConfig, nil return healthConfig, nil
@ -906,6 +913,8 @@ func addServiceFlags(flags *pflag.FlagSet, opts *serviceOptions, defaultFlagValu
flags.SetAnnotation(flagHealthRetries, "version", []string{"1.25"}) 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.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.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.BoolVar(&opts.healthcheck.noHealthcheck, flagNoHealthcheck, false, "Disable any container-specified HEALTHCHECK")
flags.SetAnnotation(flagNoHealthcheck, "version", []string{"1.25"}) flags.SetAnnotation(flagNoHealthcheck, "version", []string{"1.25"})
@ -1016,6 +1025,7 @@ const (
flagHealthRetries = "health-retries" flagHealthRetries = "health-retries"
flagHealthTimeout = "health-timeout" flagHealthTimeout = "health-timeout"
flagHealthStartPeriod = "health-start-period" flagHealthStartPeriod = "health-start-period"
flagHealthStartInterval = "health-start-interval"
flagNoHealthcheck = "no-healthcheck" flagNoHealthcheck = "no-healthcheck"
flagSecret = "secret" flagSecret = "secret"
flagSecretAdd = "secret-add" flagSecretAdd = "secret-add"

View File

@ -112,6 +112,7 @@ func TestHealthCheckOptionsToHealthConfig(t *testing.T) {
interval: opts.PositiveDurationOpt{DurationOpt: *opts.NewDurationOpt(&dur)}, interval: opts.PositiveDurationOpt{DurationOpt: *opts.NewDurationOpt(&dur)},
timeout: opts.PositiveDurationOpt{DurationOpt: *opts.NewDurationOpt(&dur)}, timeout: opts.PositiveDurationOpt{DurationOpt: *opts.NewDurationOpt(&dur)},
startPeriod: opts.PositiveDurationOpt{DurationOpt: *opts.NewDurationOpt(&dur)}, startPeriod: opts.PositiveDurationOpt{DurationOpt: *opts.NewDurationOpt(&dur)},
startInterval: opts.PositiveDurationOpt{DurationOpt: *opts.NewDurationOpt(&dur)},
retries: 10, retries: 10,
} }
config, err := opt.toHealthConfig() config, err := opt.toHealthConfig()
@ -121,6 +122,7 @@ func TestHealthCheckOptionsToHealthConfig(t *testing.T) {
Interval: time.Second, Interval: time.Second,
Timeout: time.Second, Timeout: time.Second,
StartPeriod: time.Second, StartPeriod: time.Second,
StartInterval: time.Second,
Retries: 10, Retries: 10,
}, config)) }, config))
} }