api/types/container: define HealthStatus "pseudo" type

It currently is an alias for string, but may become a distinct type in future.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2025-04-26 15:25:24 +02:00
parent 890d48de19
commit 1e4bb14bcd
5 changed files with 37 additions and 27 deletions

View File

@@ -2,17 +2,22 @@ package container
import "time"
// HealthStatus is a string representation of the container's health.
//
// It currently is an alias for string, but may become a distinct type in future.
type HealthStatus = string
// Health states
const (
NoHealthcheck = "none" // Indicates there is no healthcheck
Starting = "starting" // Starting indicates that the container is not yet ready
Healthy = "healthy" // Healthy indicates that the container is running correctly
Unhealthy = "unhealthy" // Unhealthy indicates that the container has a problem
NoHealthcheck HealthStatus = "none" // Indicates there is no healthcheck
Starting HealthStatus = "starting" // Starting indicates that the container is not yet ready
Healthy HealthStatus = "healthy" // Healthy indicates that the container is running correctly
Unhealthy HealthStatus = "unhealthy" // Unhealthy indicates that the container has a problem
)
// Health stores information about the container's healthcheck results
type Health struct {
Status string // Status is one of [Starting], [Healthy] or [Unhealthy].
Status HealthStatus // Status is one of [Starting], [Healthy] or [Unhealthy].
FailingStreak int // FailingStreak is the number of consecutive failures
Log []*HealthcheckResult // Log contains the last few results (oldest first)
}

View File

@@ -30,7 +30,7 @@ func (s *Health) String() string {
// Status returns the current health status.
//
// Note that this takes a lock and the value may change after being read.
func (s *Health) Status() string {
func (s *Health) Status() container.HealthStatus {
s.mu.Lock()
defer s.mu.Unlock()
@@ -46,7 +46,7 @@ func (s *Health) Status() string {
// obeying the locking semantics.
//
// Status may be set directly if another lock is used.
func (s *Health) SetStatus(new string) {
func (s *Health) SetStatus(new container.HealthStatus) {
s.mu.Lock()
defer s.mu.Unlock()

View File

@@ -112,12 +112,15 @@ func (s *State) String() string {
return fmt.Sprintf("Exited (%d) %s ago", s.ExitCodeValue, units.HumanDuration(time.Now().UTC().Sub(s.FinishedAt)))
}
// IsValidHealthString checks if the provided string is a valid container health status or not.
func IsValidHealthString(s string) bool {
return s == container.Starting ||
s == container.Healthy ||
s == container.Unhealthy ||
s == container.NoHealthcheck
// 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
}
}
// StateString returns a single string to describe state

View File

@@ -10,22 +10,24 @@ import (
)
func TestIsValidHealthString(t *testing.T) {
contexts := []struct {
Health string
Expected bool
tests := []struct {
health container.HealthStatus
expected bool
}{
{container.Healthy, true},
{container.Unhealthy, true},
{container.Starting, true},
{container.NoHealthcheck, true},
{"fail", false},
{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 _, c := range contexts {
v := IsValidHealthString(c.Health)
if v != c.Expected {
t.Fatalf("Expected %t, but got %t", c.Expected, v)
}
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)
}
})
}
}

View File

@@ -188,7 +188,7 @@ func pollForHealthCheckLog(ctx context.Context, client client.APIClient, contain
}
}
func pollForHealthStatus(ctx context.Context, client client.APIClient, containerID string, healthStatus string) func(log poll.LogT) poll.Result {
func pollForHealthStatus(ctx context.Context, client client.APIClient, containerID string, healthStatus containertypes.HealthStatus) func(log poll.LogT) poll.Result {
return func(log poll.LogT) poll.Result {
inspect, err := client.ContainerInspect(ctx, containerID)