Skip to content

Commit c130ce1

Browse files
committed
api/types: move container Health types to api/types/container
This moves the `Health` and `HealthcheckResult` types to the container package, as well as the related `NoHealthcheck`, `Starting`, `Healthy`, and `Unhealthy` consts. Signed-off-by: Sebastiaan van Stijn <[email protected]>
1 parent df22a51 commit c130ce1

14 files changed

Lines changed: 93 additions & 76 deletions

File tree

api/types/container/health.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package container
2+
3+
import "time"
4+
5+
// Health states
6+
const (
7+
NoHealthcheck = "none" // Indicates there is no healthcheck
8+
Starting = "starting" // Starting indicates that the container is not yet ready
9+
Healthy = "healthy" // Healthy indicates that the container is running correctly
10+
Unhealthy = "unhealthy" // Unhealthy indicates that the container has a problem
11+
)
12+
13+
// Health stores information about the container's healthcheck results
14+
type Health struct {
15+
Status string // Status is one of [Starting], [Healthy] or [Unhealthy].
16+
FailingStreak int // FailingStreak is the number of consecutive failures
17+
Log []*HealthcheckResult // Log contains the last few results (oldest first)
18+
}
19+
20+
// HealthcheckResult stores information about a single run of a healthcheck probe
21+
type HealthcheckResult struct {
22+
Start time.Time // Start is the time this check started
23+
End time.Time // End is the time this check ended
24+
ExitCode int // ExitCode meanings: 0=healthy, 1=unhealthy, 2=reserved (considered unhealthy), else=error running probe
25+
Output string // Output from last check
26+
}

api/types/types.go

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -203,29 +203,6 @@ type Version struct {
203203
BuildTime string `json:",omitempty"`
204204
}
205205

206-
// HealthcheckResult stores information about a single run of a healthcheck probe
207-
type HealthcheckResult struct {
208-
Start time.Time // Start is the time this check started
209-
End time.Time // End is the time this check ended
210-
ExitCode int // ExitCode meanings: 0=healthy, 1=unhealthy, 2=reserved (considered unhealthy), else=error running probe
211-
Output string // Output from last check
212-
}
213-
214-
// Health states
215-
const (
216-
NoHealthcheck = "none" // Indicates there is no healthcheck
217-
Starting = "starting" // Starting indicates that the container is not yet ready
218-
Healthy = "healthy" // Healthy indicates that the container is running correctly
219-
Unhealthy = "unhealthy" // Unhealthy indicates that the container has a problem
220-
)
221-
222-
// Health stores information about the container's healthcheck results
223-
type Health struct {
224-
Status string // Status is one of Starting, Healthy or Unhealthy
225-
FailingStreak int // FailingStreak is the number of consecutive failures
226-
Log []*HealthcheckResult // Log contains the last few results (oldest first)
227-
}
228-
229206
// ContainerState stores container's running state
230207
// it's part of ContainerJSONBase and will return by "inspect" command
231208
type ContainerState struct {
@@ -240,7 +217,7 @@ type ContainerState struct {
240217
Error string
241218
StartedAt string
242219
FinishedAt string
243-
Health *Health `json:",omitempty"`
220+
Health *container.Health `json:",omitempty"`
244221
}
245222

246223
// ContainerJSONBase contains response of Engine API:

api/types/types_deprecated.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,3 +231,21 @@ type DefaultNetworkSettings = container.DefaultNetworkSettings
231231
//
232232
// Deprecated: use [container.NetworkSettingsSummary].
233233
type SummaryNetworkSettings = container.NetworkSettingsSummary
234+
235+
// Health states
236+
const (
237+
NoHealthcheck = container.NoHealthcheck // Deprecated: use [container.NoHealthcheck].
238+
Starting = container.Starting // Deprecated: use [container.Starting].
239+
Healthy = container.Healthy // Deprecated: use [container.Healthy].
240+
Unhealthy = container.Unhealthy // Deprecated: use [container.Unhealthy].
241+
)
242+
243+
// Health stores information about the container's healthcheck results.
244+
//
245+
// Deprecated: use [container.Health].
246+
type Health = container.Health
247+
248+
// HealthcheckResult stores information about a single run of a healthcheck probe.
249+
//
250+
// Deprecated: use [container.HealthcheckResult].
251+
type HealthcheckResult = container.HealthcheckResult

container/health.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ import (
55
"sync"
66

77
"github.com/containerd/log"
8-
"github.com/docker/docker/api/types"
8+
"github.com/docker/docker/api/types/container"
99
)
1010

1111
// Health holds the current container health-check state
1212
type Health struct {
13-
types.Health
13+
container.Health
1414
stop chan struct{} // Write struct{} to stop the monitor
1515
mu sync.Mutex
1616
}
@@ -20,7 +20,7 @@ func (s *Health) String() string {
2020
status := s.Status()
2121

2222
switch status {
23-
case types.Starting:
23+
case container.Starting:
2424
return "health: starting"
2525
default: // Healthy and Unhealthy are clear on their own
2626
return status
@@ -36,7 +36,7 @@ func (s *Health) Status() string {
3636

3737
// This happens when the monitor has yet to be setup.
3838
if s.Health.Status == "" {
39-
return types.Unhealthy
39+
return container.Unhealthy
4040
}
4141

4242
return s.Health.Status
@@ -77,7 +77,7 @@ func (s *Health) CloseMonitorChannel() {
7777
close(s.stop)
7878
s.stop = nil
7979
// unhealthy when the monitor has stopped for compatibility reasons
80-
s.Health.Status = types.Unhealthy
80+
s.Health.Status = container.Unhealthy
8181
log.G(context.TODO()).Debug("CloseMonitorChannel done")
8282
}
8383
}

container/state.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"sync"
88
"time"
99

10-
"github.com/docker/docker/api/types"
10+
"github.com/docker/docker/api/types/container"
1111
libcontainerdtypes "github.com/docker/docker/libcontainerd/types"
1212
units "github.com/docker/go-units"
1313
)
@@ -110,10 +110,10 @@ func (s *State) String() string {
110110

111111
// IsValidHealthString checks if the provided string is a valid container health status or not.
112112
func IsValidHealthString(s string) bool {
113-
return s == types.Starting ||
114-
s == types.Healthy ||
115-
s == types.Unhealthy ||
116-
s == types.NoHealthcheck
113+
return s == container.Starting ||
114+
s == container.Healthy ||
115+
s == container.Unhealthy ||
116+
s == container.NoHealthcheck
117117
}
118118

119119
// StateString returns a single string to describe state

container/state_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"testing"
66
"time"
77

8-
"github.com/docker/docker/api/types"
8+
"github.com/docker/docker/api/types/container"
99
libcontainerdtypes "github.com/docker/docker/libcontainerd/types"
1010
)
1111

@@ -14,10 +14,10 @@ func TestIsValidHealthString(t *testing.T) {
1414
Health string
1515
Expected bool
1616
}{
17-
{types.Healthy, true},
18-
{types.Unhealthy, true},
19-
{types.Starting, true},
20-
{types.NoHealthcheck, true},
17+
{container.Healthy, true},
18+
{container.Unhealthy, true},
19+
{container.Starting, true},
20+
{container.NoHealthcheck, true},
2121
{"fail", false},
2222
}
2323

container/view.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ func (v *View) GetAllNames() map[string][]string {
301301
// transform maps a (deep) copied Container object to what queries need.
302302
// A lock on the Container is not held because these are immutable deep copies.
303303
func (v *View) transform(ctr *Container) *Snapshot {
304-
health := types.NoHealthcheck
304+
health := container.NoHealthcheck
305305
if ctr.Health != nil {
306306
health = ctr.Health.Status()
307307
}

container/view_test.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import (
77
"path/filepath"
88
"testing"
99

10-
"github.com/docker/docker/api/types"
11-
containertypes "github.com/docker/docker/api/types/container"
10+
"github.com/docker/docker/api/types/container"
1211
"github.com/docker/docker/pkg/stringid"
1312
"github.com/google/uuid"
1413
"gotest.tools/v3/assert"
@@ -37,7 +36,7 @@ func newContainer(t *testing.T) *Container {
3736
t.Fatal(err)
3837
}
3938
c := NewBaseContainer(id, cRoot)
40-
c.HostConfig = &containertypes.HostConfig{}
39+
c.HostConfig = &container.HostConfig{}
4140
return c
4241
}
4342

@@ -171,7 +170,7 @@ func TestViewWithHealthCheck(t *testing.T) {
171170
one = newContainer(t)
172171
)
173172
one.Health = &Health{
174-
Health: types.Health{
173+
Health: container.Health{
175174
Status: "starting",
176175
},
177176
}

daemon/health.go

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import (
1010
"time"
1111

1212
"github.com/containerd/log"
13-
"github.com/docker/docker/api/types"
1413
"github.com/docker/docker/api/types/backend"
14+
containertypes "github.com/docker/docker/api/types/container"
1515
"github.com/docker/docker/api/types/events"
1616
"github.com/docker/docker/api/types/strslice"
1717
"github.com/docker/docker/container"
@@ -55,7 +55,7 @@ const (
5555
type probe interface {
5656
// Perform one run of the check. Returns the exit code and an optional
5757
// short diagnostic string.
58-
run(context.Context, *Daemon, *container.Container) (*types.HealthcheckResult, error)
58+
run(context.Context, *Daemon, *container.Container) (*containertypes.HealthcheckResult, error)
5959
}
6060

6161
// cmdProbe implements the "CMD" probe type.
@@ -66,7 +66,7 @@ type cmdProbe struct {
6666

6767
// exec the healthcheck command in the container.
6868
// Returns the exit code and probe output (if any)
69-
func (p *cmdProbe) run(ctx context.Context, d *Daemon, cntr *container.Container) (*types.HealthcheckResult, error) {
69+
func (p *cmdProbe) run(ctx context.Context, d *Daemon, cntr *container.Container) (*containertypes.HealthcheckResult, error) {
7070
startTime := time.Now()
7171
cmdSlice := strslice.StrSlice(cntr.Config.Healthcheck.Test)[1:]
7272
if p.shell {
@@ -145,7 +145,7 @@ func (p *cmdProbe) run(ctx context.Context, d *Daemon, cntr *container.Container
145145
} else {
146146
msg = fmt.Sprintf("Health check exceeded timeout (%v)", probeTimeout)
147147
}
148-
return &types.HealthcheckResult{
148+
return &containertypes.HealthcheckResult{
149149
ExitCode: -1,
150150
Output: msg,
151151
End: time.Now(),
@@ -173,15 +173,15 @@ func (p *cmdProbe) run(ctx context.Context, d *Daemon, cntr *container.Container
173173
}
174174
// Note: Go's json package will handle invalid UTF-8 for us
175175
out := output.String()
176-
return &types.HealthcheckResult{
176+
return &containertypes.HealthcheckResult{
177177
End: time.Now(),
178178
ExitCode: exitCode,
179179
Output: out,
180180
}, nil
181181
}
182182

183183
// Update the container's Status.Health struct based on the latest probe's result.
184-
func handleProbeResult(d *Daemon, c *container.Container, result *types.HealthcheckResult, done chan struct{}) {
184+
func handleProbeResult(d *Daemon, c *container.Container, result *containertypes.HealthcheckResult, done chan struct{}) {
185185
c.Lock()
186186
defer c.Unlock()
187187

@@ -208,14 +208,14 @@ func handleProbeResult(d *Daemon, c *container.Container, result *types.Healthch
208208

209209
if result.ExitCode == exitStatusHealthy {
210210
h.FailingStreak = 0
211-
h.SetStatus(types.Healthy)
211+
h.SetStatus(containertypes.Healthy)
212212
} else { // Failure (including invalid exit code)
213213
shouldIncrementStreak := true
214214

215215
// If the container is starting (i.e. we never had a successful health check)
216216
// then we check if we are within the start period of the container in which
217217
// case we do not increment the failure streak.
218-
if h.Status() == types.Starting {
218+
if h.Status() == containertypes.Starting {
219219
startPeriod := timeoutWithDefault(c.Config.Healthcheck.StartPeriod, defaultStartPeriod)
220220
timeSinceStart := result.Start.Sub(c.State.StartedAt)
221221

@@ -229,7 +229,7 @@ func handleProbeResult(d *Daemon, c *container.Container, result *types.Healthch
229229
h.FailingStreak++
230230

231231
if h.FailingStreak >= retries {
232-
h.SetStatus(types.Unhealthy)
232+
h.SetStatus(containertypes.Unhealthy)
233233
}
234234
}
235235
// Else we're starting or healthy. Stay in that state.
@@ -270,7 +270,7 @@ func monitor(d *Daemon, c *container.Container, stop chan struct{}, probe probe)
270270
status := c.Health.Health.Status
271271
c.Unlock()
272272

273-
if status == types.Starting {
273+
if status == containertypes.Starting {
274274
return startInterval
275275
}
276276
return probeInterval
@@ -288,14 +288,14 @@ func monitor(d *Daemon, c *container.Container, stop chan struct{}, probe probe)
288288
log.G(context.TODO()).Debugf("Running health check for container %s ...", c.ID)
289289
startTime := time.Now()
290290
ctx, cancelProbe := context.WithCancel(context.Background())
291-
results := make(chan *types.HealthcheckResult, 1)
291+
results := make(chan *containertypes.HealthcheckResult, 1)
292292
go func() {
293293
healthChecksCounter.Inc()
294294
result, err := probe.run(ctx, d, c)
295295
if err != nil {
296296
healthChecksFailedCounter.Inc()
297297
log.G(ctx).Warnf("Health check for container %s error: %v", c.ID, err)
298-
results <- &types.HealthcheckResult{
298+
results <- &containertypes.HealthcheckResult{
299299
ExitCode: -1,
300300
Output: err.Error(),
301301
Start: startTime,
@@ -379,11 +379,11 @@ func (daemon *Daemon) initHealthMonitor(c *container.Container) {
379379
daemon.stopHealthchecks(c)
380380

381381
if h := c.State.Health; h != nil {
382-
h.SetStatus(types.Starting)
382+
h.SetStatus(containertypes.Starting)
383383
h.FailingStreak = 0
384384
} else {
385385
h := &container.Health{}
386-
h.SetStatus(types.Starting)
386+
h.SetStatus(containertypes.Starting)
387387
c.State.Health = h
388388
}
389389

daemon/health_test.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"testing"
55
"time"
66

7-
"github.com/docker/docker/api/types"
87
containertypes "github.com/docker/docker/api/types/container"
98
eventtypes "github.com/docker/docker/api/types/events"
109
"github.com/docker/docker/container"
@@ -14,7 +13,7 @@ import (
1413
func reset(c *container.Container) {
1514
c.State = &container.State{}
1615
c.State.Health = &container.Health{}
17-
c.State.Health.SetStatus(types.Starting)
16+
c.State.Health.SetStatus(containertypes.Starting)
1817
}
1918

2019
func TestNoneHealthcheck(t *testing.T) {
@@ -87,7 +86,7 @@ func TestHealthStates(t *testing.T) {
8786
reset(c)
8887

8988
handleResult := func(startTime time.Time, exitCode int) {
90-
handleProbeResult(daemon, c, &types.HealthcheckResult{
89+
handleProbeResult(daemon, c, &containertypes.HealthcheckResult{
9190
Start: startTime,
9291
End: startTime,
9392
ExitCode: exitCode,
@@ -112,7 +111,7 @@ func TestHealthStates(t *testing.T) {
112111

113112
handleResult(c.State.StartedAt.Add(20*time.Second), 1)
114113
handleResult(c.State.StartedAt.Add(40*time.Second), 1)
115-
if status := c.State.Health.Status(); status != types.Starting {
114+
if status := c.State.Health.Status(); status != containertypes.Starting {
116115
t.Errorf("Expecting starting, but got %#v\n", status)
117116
}
118117
if c.State.Health.FailingStreak != 2 {
@@ -134,14 +133,14 @@ func TestHealthStates(t *testing.T) {
134133
c.Config.Healthcheck.StartPeriod = 30 * time.Second
135134

136135
handleResult(c.State.StartedAt.Add(20*time.Second), 1)
137-
if status := c.State.Health.Status(); status != types.Starting {
136+
if status := c.State.Health.Status(); status != containertypes.Starting {
138137
t.Errorf("Expecting starting, but got %#v\n", status)
139138
}
140139
if c.State.Health.FailingStreak != 0 {
141140
t.Errorf("Expecting FailingStreak=0, but got %d\n", c.State.Health.FailingStreak)
142141
}
143142
handleResult(c.State.StartedAt.Add(50*time.Second), 1)
144-
if status := c.State.Health.Status(); status != types.Starting {
143+
if status := c.State.Health.Status(); status != containertypes.Starting {
145144
t.Errorf("Expecting starting, but got %#v\n", status)
146145
}
147146
if c.State.Health.FailingStreak != 1 {

0 commit comments

Comments
 (0)