diff --git a/api/docs/CHANGELOG.md b/api/docs/CHANGELOG.md index 16fc2b68bc..cf5c92c2ab 100644 --- a/api/docs/CHANGELOG.md +++ b/api/docs/CHANGELOG.md @@ -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 diff --git a/api/docs/v1.52.yaml b/api/docs/v1.52.yaml index 1f5ea81695..ee14466e0d 100644 --- a/api/docs/v1.52.yaml +++ b/api/docs/v1.52.yaml @@ -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. diff --git a/api/swagger.yaml b/api/swagger.yaml index 1f5ea81695..ee14466e0d 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -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. diff --git a/api/types/container/stats.go b/api/types/container/stats.go index 02133d44d0..6a34f6ab76 100644 --- a/api/types/container/stats.go +++ b/api/types/container/stats.go @@ -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"` diff --git a/daemon/stats.go b/daemon/stats.go index caaa1af966..5d6550e420 100644 --- a/daemon/stats.go +++ b/daemon/stats.go @@ -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) diff --git a/daemon/stats/collector.go b/daemon/stats/collector.go index 0735d17c03..adae57c5f2 100644 --- a/daemon/stats/collector.go +++ b/daemon/stats/collector.go @@ -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) diff --git a/daemon/stats_unix.go b/daemon/stats_unix.go index 33c535d06e..bceb6c7b7e 100644 --- a/daemon/stats_unix.go +++ b/daemon/stats_unix.go @@ -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: diff --git a/daemon/stats_windows.go b/daemon/stats_windows.go index ff4eafc65b..e2c6ec0043 100644 --- a/daemon/stats_windows.go +++ b/daemon/stats_windows.go @@ -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(), } diff --git a/vendor/github.com/moby/moby/api/types/container/stats.go b/vendor/github.com/moby/moby/api/types/container/stats.go index 02133d44d0..6a34f6ab76 100644 --- a/vendor/github.com/moby/moby/api/types/container/stats.go +++ b/vendor/github.com/moby/moby/api/types/container/stats.go @@ -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"`