Merge pull request #6913 from Mohammed-Thaha/6203-add-healthcheck-format

container/ps: add HealthStatus formatter field
This commit is contained in:
Paweł Gronowski
2026-05-13 14:01:16 +02:00
committed by GitHub
3 changed files with 59 additions and 23 deletions
+38 -7
View File
@@ -21,13 +21,14 @@ import (
const (
defaultContainerTableFormat = "table {{.ID}}\t{{.Image}}\t{{.Command}}\t{{.RunningFor}}\t{{.Status}}\t{{.Ports}}\t{{.Names}}"
namesHeader = "NAMES"
commandHeader = "COMMAND"
runningForHeader = "CREATED"
mountsHeader = "MOUNTS"
localVolumes = "LOCAL VOLUMES"
networksHeader = "NETWORKS"
platformHeader = "PLATFORM"
namesHeader = "NAMES"
commandHeader = "COMMAND"
runningForHeader = "CREATED"
mountsHeader = "MOUNTS"
localVolumes = "LOCAL VOLUMES"
networksHeader = "NETWORKS"
platformHeader = "PLATFORM"
healthStatusHeader = "HEALTH STATUS"
)
// Platform wraps a [ocispec.Platform] to implement the stringer interface.
@@ -121,6 +122,7 @@ func NewContainerContext() *ContainerContext {
"LocalVolumes": localVolumes,
"Networks": networksHeader,
"Platform": platformHeader,
"HealthStatus": healthStatusHeader,
}
return &containerCtx
}
@@ -352,6 +354,35 @@ func (c *ContainerContext) Networks() string {
return strings.Join(networks, ",")
}
// HealthStatus returns the container's health status (for example, "healthy","unhealthy", or "starting").
// If no healthcheck is configured, an empty
// string is returned.
func (c *ContainerContext) HealthStatus() string {
if c.c.Health != nil && c.c.Health.Status != "" {
return string(c.c.Health.Status)
}
// Fallback for API versions before v1.52, which include health only in Status text;
// see https://github.com/moby/moby/pull/50281
// see https://github.com/moby/moby/blob/docker-v29.4.3/daemon/container/health.go#L18-L43
_, health, ok := strings.Cut(c.c.Status, "(")
if !ok || !strings.HasSuffix(health, ")") {
return ""
}
health = strings.TrimSuffix(health, ")")
health = strings.TrimPrefix(health, "health: ")
switch container.HealthStatus(health) {
case container.Healthy, container.Unhealthy, container.Starting:
return health
case container.NoHealthcheck:
return ""
default:
return ""
}
}
// DisplayablePorts returns formatted string representing open ports of container
// e.g. "0.0.0.0:80->9090/tcp, 9988/tcp"
// it's used by command 'docker ps'
+4
View File
@@ -494,6 +494,7 @@ func TestContainerContextWriteJSON(t *testing.T) {
{
"Command": `""`,
"CreatedAt": expectedCreated,
"HealthStatus": "",
"ID": "containerID1",
"Image": "ubuntu",
"Labels": "",
@@ -511,6 +512,7 @@ func TestContainerContextWriteJSON(t *testing.T) {
{
"Command": `""`,
"CreatedAt": expectedCreated,
"HealthStatus": "",
"ID": "containerID2",
"Image": "ubuntu",
"Labels": "",
@@ -528,6 +530,7 @@ func TestContainerContextWriteJSON(t *testing.T) {
{
"Command": `""`,
"CreatedAt": expectedCreated,
"HealthStatus": "",
"ID": "containerID3",
"Image": "ubuntu",
"Labels": "",
@@ -615,6 +618,7 @@ func TestContainerBackCompat(t *testing.T) {
{field: "Image", expected: "docker.io/library/ubuntu"},
{field: "Command", expected: `"/bin/sh"`},
{field: "CreatedAt", expected: time.Unix(createdAtTime.Unix(), 0).String()},
{field: "HealthStatus", expected: ""},
{field: "RunningFor", expected: "12 months ago"},
{field: "Ports", expected: "8080/tcp"},
{field: "Status", expected: "running"},
+17 -16
View File
@@ -395,22 +395,23 @@ template.
Valid placeholders for the Go template are listed below:
| Placeholder | Description |
|:--------------|:------------------------------------------------------------------------------------------------|
| `.ID` | Container ID |
| `.Image` | Image ID |
| `.Command` | Quoted command |
| `.CreatedAt` | Time when the container was created. |
| `.RunningFor` | Elapsed time since the container was started. |
| `.Ports` | Exposed ports. |
| `.State` | Container status (for example; "created", "running", "exited"). |
| `.Status` | Container status with details about duration and health-status. |
| `.Size` | Container disk size. |
| `.Names` | Container names. |
| `.Labels` | All labels assigned to the container. |
| `.Label` | Value of a specific label for this container. For example `'{{.Label "com.docker.swarm.cpu"}}'` |
| `.Mounts` | Names of the volumes mounted in this container. |
| `.Networks` | Names of the networks attached to this container. |
| Placeholder | Description |
|:----------------|:------------------------------------------------------------------------------------------------|
| `.ID` | Container ID |
| `.Image` | Image ID |
| `.Command` | Quoted command |
| `.CreatedAt` | Time when the container was created. |
| `.RunningFor` | Elapsed time since the container was started. |
| `.Ports` | Exposed ports. |
| `.State` | Container status (for example; "created", "running", "exited"). |
| `.Status` | Container status with details about duration and health-status. |
| `.HealthStatus` | Container health status ("starting", "healthy", "unhealthy"; empty when unavailable). |
| `.Size` | Container disk size. |
| `.Names` | Container names. |
| `.Labels` | All labels assigned to the container. |
| `.Label` | Value of a specific label for this container. For example `'{{.Label "com.docker.swarm.cpu"}}'` |
| `.Mounts` | Names of the volumes mounted in this container. |
| `.Networks` | Names of the networks attached to this container. |
When using the `--format` option, the `ps` command will either output the data
exactly as the template declares or, when using the `table` directive, includes