diff --git a/api/types/container/health.go b/api/types/container/health.go index 59ff576998..96e91cc8d8 100644 --- a/api/types/container/health.go +++ b/api/types/container/health.go @@ -1,6 +1,10 @@ package container -import "time" +import ( + "fmt" + "strings" + "time" +) // HealthStatus is a string representation of the container's health. // @@ -29,3 +33,18 @@ type HealthcheckResult struct { ExitCode int // ExitCode meanings: 0=healthy, 1=unhealthy, 2=reserved (considered unhealthy), else=error running probe Output string // Output from last check } + +var validHealths = []string{ + NoHealthcheck, Starting, Healthy, Unhealthy, +} + +// ValidateHealthStatus checks if the provided string is a valid +// container [HealthStatus]. +func ValidateHealthStatus(s HealthStatus) error { + switch s { + case NoHealthcheck, Starting, Healthy, Unhealthy: + return nil + default: + return errInvalidParameter{error: fmt.Errorf("invalid value for health (%s): must be one of %s", s, strings.Join(validHealths, ", "))} + } +} diff --git a/api/types/container/health_test.go b/api/types/container/health_test.go new file mode 100644 index 0000000000..dbd1cb96b9 --- /dev/null +++ b/api/types/container/health_test.go @@ -0,0 +1,31 @@ +package container + +import ( + "testing" + + "gotest.tools/v3/assert" +) + +func TestValidateHealthStatus(t *testing.T) { + tests := []struct { + health HealthStatus + expectedErr string + }{ + {health: Healthy}, + {health: Unhealthy}, + {health: Starting}, + {health: NoHealthcheck}, + {health: "invalid-health-string", expectedErr: `invalid value for health (invalid-health-string): must be one of none, starting, healthy, unhealthy`}, + } + + for _, tc := range tests { + t.Run(tc.health, func(t *testing.T) { + err := ValidateHealthStatus(tc.health) + if tc.expectedErr == "" { + assert.NilError(t, err) + } else { + assert.Error(t, err, tc.expectedErr) + } + }) + } +} diff --git a/container/state.go b/container/state.go index 9493dfcf48..d2cc536e17 100644 --- a/container/state.go +++ b/container/state.go @@ -102,13 +102,10 @@ func (s *State) String() string { // IsValidHealthString checks if the provided string is a valid // [container.HealthStatus]. -func IsValidHealthString(s container.HealthStatus) bool { - switch s { - case container.NoHealthcheck, container.Starting, container.Healthy, container.Unhealthy: - return true - default: - return false - } +// +// Deprecated: use [container.ValidateHealthStatus] and check for nil-errors. +func IsValidHealthString(s string) bool { + return container.ValidateHealthStatus(s) == nil } // StateString returns a single string to describe state diff --git a/container/state_test.go b/container/state_test.go index e5d3515462..42825f68fd 100644 --- a/container/state_test.go +++ b/container/state_test.go @@ -9,28 +9,6 @@ import ( libcontainerdtypes "github.com/docker/docker/libcontainerd/types" ) -func TestIsValidHealthString(t *testing.T) { - tests := []struct { - health container.HealthStatus - expected bool - }{ - {health: container.Healthy, expected: true}, - {health: container.Unhealthy, expected: true}, - {health: container.Starting, expected: true}, - {health: container.NoHealthcheck, expected: true}, - {health: "fail", expected: false}, - } - - for _, tc := range tests { - t.Run(tc.health, func(t *testing.T) { - v := IsValidHealthString(tc.health) - if v != tc.expected { - t.Fatalf("Expected %t, but got %t", tc.expected, v) - } - }) - } -} - type mockTask struct { libcontainerdtypes.Task pid uint32 diff --git a/daemon/list.go b/daemon/list.go index 00373dd9aa..251c17b409 100644 --- a/daemon/list.go +++ b/daemon/list.go @@ -297,10 +297,9 @@ func (daemon *Daemon) foldFilter(ctx context.Context, view *container.View, conf } err = psFilters.WalkValues("health", func(value string) error { - if !container.IsValidHealthString(value) { - return errdefs.InvalidParameter(fmt.Errorf("unrecognized filter value for health: %s", value)) + if err := containertypes.ValidateHealthStatus(value); err != nil { + return errdefs.InvalidParameter(fmt.Errorf("invalid filter 'health=%s': %w", value, err)) } - return nil }) if err != nil {