mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
Add Health attribute on the docker ps command
Signed-off-by: Muhammad Daffa Dinaya <muhammaddaffadinaya@gmail.com> Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
committed by
Sebastiaan van Stijn
parent
81caabae43
commit
6e7a2c830d
@@ -5346,6 +5346,29 @@ definitions:
|
||||
List of mounts used by the container.
|
||||
items:
|
||||
$ref: "#/definitions/MountPoint"
|
||||
Health:
|
||||
type: "object"
|
||||
description: |-
|
||||
Summary of health status
|
||||
|
||||
Added in v1.52, before that version all container summary not include Health.
|
||||
After this attribute introduced, it includes containers with no health checks configured,
|
||||
or containers that are not running with none
|
||||
properties:
|
||||
Status:
|
||||
type: "string"
|
||||
description: |-
|
||||
the health status of the container
|
||||
enum:
|
||||
- "none"
|
||||
- "starting"
|
||||
- "healthy"
|
||||
- "unhealthy"
|
||||
example: "healthy"
|
||||
FailingStreak:
|
||||
description: "FailingStreak is the number of consecutive failures"
|
||||
type: "integer"
|
||||
example: 0
|
||||
|
||||
Driver:
|
||||
description: "Driver represents a driver (network, logging, secrets)."
|
||||
|
||||
@@ -128,6 +128,7 @@ type Summary struct {
|
||||
NetworkMode string `json:",omitempty"`
|
||||
Annotations map[string]string `json:",omitempty"`
|
||||
}
|
||||
Health *HealthSummary `json:",omitempty"`
|
||||
NetworkSettings *NetworkSettingsSummary
|
||||
Mounts []MountPoint
|
||||
}
|
||||
|
||||
@@ -26,6 +26,12 @@ type Health struct {
|
||||
Log []*HealthcheckResult // Log contains the last few results (oldest first)
|
||||
}
|
||||
|
||||
// HealthSummary stores a summary of the container's healthcheck results.
|
||||
type HealthSummary struct {
|
||||
Status HealthStatus // Status is one of [NoHealthcheck], [Starting], [Healthy] or [Unhealthy].
|
||||
FailingStreak int // FailingStreak is the number of consecutive failures
|
||||
}
|
||||
|
||||
// HealthcheckResult stores information about a single run of a healthcheck probe
|
||||
type HealthcheckResult struct {
|
||||
Start time.Time // Start is the time this check started
|
||||
|
||||
@@ -296,9 +296,17 @@ func (v *View) GetAllNames() map[string][]string {
|
||||
// A lock on the Container is not held because these are immutable deep copies.
|
||||
func (v *View) transform(ctr *Container) *Snapshot {
|
||||
health := container.NoHealthcheck
|
||||
failingStreak := 0
|
||||
if ctr.Health != nil {
|
||||
health = ctr.Health.Status()
|
||||
failingStreak = ctr.Health.FailingStreak
|
||||
}
|
||||
|
||||
healthSummary := &container.HealthSummary{
|
||||
Status: health,
|
||||
FailingStreak: failingStreak,
|
||||
}
|
||||
|
||||
snapshot := &Snapshot{
|
||||
Summary: container.Summary{
|
||||
ID: ctr.ID,
|
||||
@@ -308,6 +316,7 @@ func (v *View) transform(ctr *Container) *Snapshot {
|
||||
Mounts: ctr.GetMountPoints(),
|
||||
State: ctr.State.StateString(),
|
||||
Status: ctr.State.String(),
|
||||
Health: healthSummary,
|
||||
Created: ctr.Created.Unix(),
|
||||
},
|
||||
CreatedAt: ctr.Created,
|
||||
|
||||
@@ -119,6 +119,12 @@ func (c *containerRouter) getContainersJSON(ctx context.Context, w http.Response
|
||||
}
|
||||
}
|
||||
|
||||
if versions.LessThan(version, "1.52") {
|
||||
for _, c := range containers {
|
||||
c.Health = nil
|
||||
}
|
||||
}
|
||||
|
||||
return httputils.WriteJSON(w, http.StatusOK, containers)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
package container
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/integration/internal/container"
|
||||
"github.com/docker/docker/testutil"
|
||||
"github.com/docker/docker/testutil/request"
|
||||
containertypes "github.com/moby/moby/api/types/container"
|
||||
"github.com/moby/moby/api/types/filters"
|
||||
"github.com/moby/moby/api/types/versions"
|
||||
"github.com/moby/moby/client"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
"gotest.tools/v3/poll"
|
||||
"gotest.tools/v3/skip"
|
||||
)
|
||||
|
||||
@@ -143,3 +147,57 @@ func TestContainerList_ImageManifestPlatform(t *testing.T) {
|
||||
assert.Check(t, ctr.ImageManifestDescriptor.Platform.Architecture != "")
|
||||
}
|
||||
}
|
||||
|
||||
func pollForHealthStatusSummary(ctx context.Context, client client.APIClient, containerID string, healthStatus containertypes.HealthStatus) func(log poll.LogT) poll.Result {
|
||||
return func(log poll.LogT) poll.Result {
|
||||
containers, err := client.ContainerList(ctx, containertypes.ListOptions{
|
||||
All: true,
|
||||
Filters: filters.NewArgs(filters.Arg("id", containerID)),
|
||||
})
|
||||
if err != nil {
|
||||
return poll.Error(err)
|
||||
}
|
||||
total := 0
|
||||
version := client.ClientVersion()
|
||||
for _, ctr := range containers {
|
||||
if ctr.Health == nil && versions.LessThan(version, "1.52") {
|
||||
total++
|
||||
} else if ctr.Health != nil && ctr.Health.Status == healthStatus && versions.GreaterThanOrEqualTo(version, "1.52") {
|
||||
total++
|
||||
}
|
||||
}
|
||||
|
||||
if total == len(containers) {
|
||||
return poll.Success()
|
||||
}
|
||||
|
||||
return poll.Continue("waiting for container to become %s", healthStatus)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContainerList_HealthSummary(t *testing.T) {
|
||||
skip.If(t, testEnv.DaemonInfo.OSType == "windows", "FIXME")
|
||||
ctx := setupTest(t)
|
||||
testcases := []struct {
|
||||
apiVersion string
|
||||
}{
|
||||
{apiVersion: "1.51"},
|
||||
{apiVersion: "1.52"},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
t.Run(fmt.Sprintf("run with version v%s", tc.apiVersion), func(t *testing.T) {
|
||||
apiClient := request.NewAPIClient(t, client.WithVersion(tc.apiVersion))
|
||||
|
||||
cID := container.Run(ctx, t, apiClient, container.WithTty(true), container.WithWorkingDir("/foo"), func(c *container.TestContainerConfig) {
|
||||
c.Config.Healthcheck = &containertypes.HealthConfig{
|
||||
Test: []string{"CMD-SHELL", "if [ \"$PWD\" = \"/foo\" ]; then exit 0; else exit 1; fi;"},
|
||||
Interval: 50 * time.Millisecond,
|
||||
Retries: 3,
|
||||
}
|
||||
})
|
||||
|
||||
poll.WaitOn(t, pollForHealthStatusSummary(ctx, apiClient, cID, containertypes.Healthy))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
23
vendor/github.com/moby/moby/api/swagger.yaml
generated
vendored
23
vendor/github.com/moby/moby/api/swagger.yaml
generated
vendored
@@ -5346,6 +5346,29 @@ definitions:
|
||||
List of mounts used by the container.
|
||||
items:
|
||||
$ref: "#/definitions/MountPoint"
|
||||
Health:
|
||||
type: "object"
|
||||
description: |-
|
||||
Summary of health status
|
||||
|
||||
Added in v1.52, before that version all container summary not include Health.
|
||||
After this attribute introduced, it includes containers with no health checks configured,
|
||||
or containers that are not running with none
|
||||
properties:
|
||||
Status:
|
||||
type: "string"
|
||||
description: |-
|
||||
the health status of the container
|
||||
enum:
|
||||
- "none"
|
||||
- "starting"
|
||||
- "healthy"
|
||||
- "unhealthy"
|
||||
example: "healthy"
|
||||
FailingStreak:
|
||||
description: "FailingStreak is the number of consecutive failures"
|
||||
type: "integer"
|
||||
example: 0
|
||||
|
||||
Driver:
|
||||
description: "Driver represents a driver (network, logging, secrets)."
|
||||
|
||||
1
vendor/github.com/moby/moby/api/types/container/container.go
generated
vendored
1
vendor/github.com/moby/moby/api/types/container/container.go
generated
vendored
@@ -128,6 +128,7 @@ type Summary struct {
|
||||
NetworkMode string `json:",omitempty"`
|
||||
Annotations map[string]string `json:",omitempty"`
|
||||
}
|
||||
Health *HealthSummary `json:",omitempty"`
|
||||
NetworkSettings *NetworkSettingsSummary
|
||||
Mounts []MountPoint
|
||||
}
|
||||
|
||||
6
vendor/github.com/moby/moby/api/types/container/health.go
generated
vendored
6
vendor/github.com/moby/moby/api/types/container/health.go
generated
vendored
@@ -26,6 +26,12 @@ type Health struct {
|
||||
Log []*HealthcheckResult // Log contains the last few results (oldest first)
|
||||
}
|
||||
|
||||
// HealthSummary stores a summary of the container's healthcheck results.
|
||||
type HealthSummary struct {
|
||||
Status HealthStatus // Status is one of [NoHealthcheck], [Starting], [Healthy] or [Unhealthy].
|
||||
FailingStreak int // FailingStreak is the number of consecutive failures
|
||||
}
|
||||
|
||||
// HealthcheckResult stores information about a single run of a healthcheck probe
|
||||
type HealthcheckResult struct {
|
||||
Start time.Time // Start is the time this check started
|
||||
|
||||
Reference in New Issue
Block a user