api/types/container: StatsResponse: add OSType field

Adds a per-stats OSType field to allow handle the platform-specific fields.
Before this change, the client had to get the OSType field from the server's
API response header and copy it to each record.

Older daemon versions don't have this field, so the client still needs to
handle fallbacks.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2025-10-27 15:34:14 +01:00
parent 25d16ddc0e
commit 6a2a1dd6cf
9 changed files with 42 additions and 10 deletions

View File

@@ -69,6 +69,8 @@ keywords: "API, Docker, rcli, REST, documentation"
of the `Resource` requirements.
* `GET /tasks/{id}` now returns `SwapBytes` and `MemorySwappiness` fields as
part of the `Resource` requirements.
* `GET /containers/{id}/stats` now returns an `os_type` field to allow platform-
specific handling of the stats.
## v1.51 API changes

View File

@@ -5639,6 +5639,13 @@ definitions:
type: "string"
x-nullable: true
example: "boring_wozniak"
os_type:
description: |
OSType is the OS of the container ("linux" or "windows") to allow
platform-specific handling of stats.
type: "string"
x-nullable: true
example: "linux"
read:
description: |
Date and time at which this sample was collected.

View File

@@ -5639,6 +5639,13 @@ definitions:
type: "string"
x-nullable: true
example: "boring_wozniak"
os_type:
description: |
OSType is the OS of the container ("linux" or "windows") to allow
platform-specific handling of stats.
type: "string"
x-nullable: true
example: "linux"
read:
description: |
Date and time at which this sample was collected.

View File

@@ -155,6 +155,10 @@ type StatsResponse struct {
// Name is the name of the container for which the stats were collected.
Name string `json:"name,omitempty"`
// OSType is the OS of the container ("linux" or "windows") to allow
// platform-specific handling of stats.
OSType string `json:"os_type,omitempty"`
// Read is the date and time at which this sample was collected.
Read time.Time `json:"read"`

View File

@@ -29,8 +29,9 @@ func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, c
if !ctr.State.IsRunning() || ctr.State.IsRestarting() {
// The container is either not running or restarting, return an empty stats.
return json.NewEncoder(config.OutStream()).Encode(&containertypes.StatsResponse{
Name: ctr.Name,
ID: ctr.ID,
ID: ctr.ID,
Name: ctr.Name,
OSType: runtime.GOOS,
})
}
if config.OneShot {
@@ -133,8 +134,9 @@ done:
if cerrdefs.IsNotFound(err) || cerrdefs.IsConflict(err) {
// return empty stats containing only name and ID if not running or not found
return &containertypes.StatsResponse{
Name: ctr.Name,
ID: ctr.ID,
ID: ctr.ID,
Name: ctr.Name,
OSType: runtime.GOOS,
}, nil
}
log.G(context.TODO()).Errorf("collecting stats for container %s: %v", ctr.Name, err)

View File

@@ -1,6 +1,7 @@
package stats
import (
"runtime"
"sync"
"time"
@@ -109,8 +110,9 @@ func (s *Collector) Run() {
stats, err := s.supervisor.GetContainerStats(pair.container)
if err != nil {
stats = &containertypes.StatsResponse{
Name: pair.container.Name,
ID: pair.container.ID,
ID: pair.container.ID,
Name: pair.container.Name,
OSType: runtime.GOOS,
}
}
pair.publisher.Publish(*stats)

View File

@@ -8,6 +8,7 @@ import (
"fmt"
"io"
"os"
"runtime"
"strconv"
"strings"
@@ -47,9 +48,10 @@ func (daemon *Daemon) stats(c *container.Container) (*containertypes.StatsRespon
return nil, err
}
s := &containertypes.StatsResponse{
Name: c.Name,
ID: c.ID,
Read: cs.Read,
ID: c.ID,
Name: c.Name,
OSType: runtime.GOOS,
Read: cs.Read,
}
switch t := cs.Metrics.(type) {
case *statsV1.Metrics:

View File

@@ -2,6 +2,7 @@ package daemon
import (
"context"
"runtime"
cerrdefs "github.com/containerd/errdefs"
containertypes "github.com/moby/moby/api/types/container"
@@ -28,8 +29,9 @@ func (daemon *Daemon) stats(c *container.Container) (*containertypes.StatsRespon
// Start with an empty structure
s := &containertypes.StatsResponse{
Name: c.Name,
ID: c.ID,
Name: c.Name,
OSType: runtime.GOOS,
Read: stats.Read,
NumProcs: platform.NumProcs(),
}

View File

@@ -155,6 +155,10 @@ type StatsResponse struct {
// Name is the name of the container for which the stats were collected.
Name string `json:"name,omitempty"`
// OSType is the OS of the container ("linux" or "windows") to allow
// platform-specific handling of stats.
OSType string `json:"os_type,omitempty"`
// Read is the date and time at which this sample was collected.
Read time.Time `json:"read"`