mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
API: add Platform (OS and Architecture) to /containers/json
Adds platform information to containers (for `docker ps`). Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com>
This commit is contained in:
@@ -113,6 +113,13 @@ func (c *containerRouter) getContainersJSON(ctx context.Context, w http.Response
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if versions.LessThan(version, "1.48") {
|
||||||
|
// ImageManifestDescriptor information was added in API 1.48
|
||||||
|
for _, c := range containers {
|
||||||
|
c.ImageManifestDescriptor = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return httputils.WriteJSON(w, http.StatusOK, containers)
|
return httputils.WriteJSON(w, http.StatusOK, containers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5109,6 +5109,17 @@ definitions:
|
|||||||
ImageID:
|
ImageID:
|
||||||
description: "The ID of the image that this container was created from"
|
description: "The ID of the image that this container was created from"
|
||||||
type: "string"
|
type: "string"
|
||||||
|
ImageManifestDescriptor:
|
||||||
|
$ref: "#/definitions/OCIDescriptor"
|
||||||
|
x-nullable: true
|
||||||
|
description: |
|
||||||
|
OCI descriptor of the platform-specific manifest of the image
|
||||||
|
the container was created from.
|
||||||
|
|
||||||
|
Note: Only available if the daemon provides a multi-platform
|
||||||
|
image store.
|
||||||
|
|
||||||
|
This field is not populated in the `GET /system/df` endpoint.
|
||||||
Command:
|
Command:
|
||||||
description: "Command to run when starting the container"
|
description: "Command to run when starting the container"
|
||||||
type: "string"
|
type: "string"
|
||||||
|
|||||||
@@ -121,19 +121,20 @@ type State struct {
|
|||||||
// Summary contains response of Engine API:
|
// Summary contains response of Engine API:
|
||||||
// GET "/containers/json"
|
// GET "/containers/json"
|
||||||
type Summary struct {
|
type Summary struct {
|
||||||
ID string `json:"Id"`
|
ID string `json:"Id"`
|
||||||
Names []string
|
Names []string
|
||||||
Image string
|
Image string
|
||||||
ImageID string
|
ImageID string
|
||||||
Command string
|
ImageManifestDescriptor *ocispec.Descriptor `json:"ImageManifestDescriptor,omitempty"`
|
||||||
Created int64
|
Command string
|
||||||
Ports []Port
|
Created int64
|
||||||
SizeRw int64 `json:",omitempty"`
|
Ports []Port
|
||||||
SizeRootFs int64 `json:",omitempty"`
|
SizeRw int64 `json:",omitempty"`
|
||||||
Labels map[string]string
|
SizeRootFs int64 `json:",omitempty"`
|
||||||
State string
|
Labels map[string]string
|
||||||
Status string
|
State string
|
||||||
HostConfig struct {
|
Status string
|
||||||
|
HostConfig struct {
|
||||||
NetworkMode string `json:",omitempty"`
|
NetworkMode string `json:",omitempty"`
|
||||||
Annotations map[string]string `json:",omitempty"`
|
Annotations map[string]string `json:",omitempty"`
|
||||||
}
|
}
|
||||||
@@ -183,5 +184,5 @@ type InspectResponse struct {
|
|||||||
Config *Config
|
Config *Config
|
||||||
NetworkSettings *NetworkSettings
|
NetworkSettings *NetworkSettings
|
||||||
// ImageManifestDescriptor is the descriptor of a platform-specific manifest of the image used to create the container.
|
// ImageManifestDescriptor is the descriptor of a platform-specific manifest of the image used to create the container.
|
||||||
ImageManifestDescriptor *ocispec.Descriptor `json:",omitempty"`
|
ImageManifestDescriptor *ocispec.Descriptor `json:"ImageManifestDescriptor,omitempty"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -301,14 +301,15 @@ func (v *View) transform(ctr *Container) *Snapshot {
|
|||||||
}
|
}
|
||||||
snapshot := &Snapshot{
|
snapshot := &Snapshot{
|
||||||
Summary: container.Summary{
|
Summary: container.Summary{
|
||||||
ID: ctr.ID,
|
ID: ctr.ID,
|
||||||
Names: v.getNames(ctr.ID),
|
Names: v.getNames(ctr.ID),
|
||||||
ImageID: ctr.ImageID.String(),
|
ImageID: ctr.ImageID.String(),
|
||||||
Ports: []container.Port{},
|
ImageManifestDescriptor: ctr.ImageManifest,
|
||||||
Mounts: ctr.GetMountPoints(),
|
Ports: []container.Port{},
|
||||||
State: ctr.State.StateString(),
|
Mounts: ctr.GetMountPoints(),
|
||||||
Status: ctr.State.String(),
|
State: ctr.State.StateString(),
|
||||||
Created: ctr.Created.Unix(),
|
Status: ctr.State.String(),
|
||||||
|
Created: ctr.Created.Unix(),
|
||||||
},
|
},
|
||||||
CreatedAt: ctr.Created,
|
CreatedAt: ctr.Created,
|
||||||
StartedAt: ctr.StartedAt,
|
StartedAt: ctr.StartedAt,
|
||||||
@@ -416,6 +417,10 @@ func (v *View) transform(ctr *Container) *Snapshot {
|
|||||||
}
|
}
|
||||||
snapshot.NetworkSettings = &container.NetworkSettingsSummary{Networks: networks}
|
snapshot.NetworkSettings = &container.NetworkSettingsSummary{Networks: networks}
|
||||||
|
|
||||||
|
if ctr.ImageManifest != nil && ctr.ImageManifest.Platform == nil {
|
||||||
|
ctr.ImageManifest.Platform = &ctr.ImagePlatform
|
||||||
|
}
|
||||||
|
|
||||||
return snapshot
|
return snapshot
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,12 @@ func (daemon *Daemon) containerDiskUsage(ctx context.Context) ([]*container.Summ
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to retrieve container list: %v", err)
|
return nil, fmt.Errorf("failed to retrieve container list: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove image manifest descriptor from the result as it should not be included.
|
||||||
|
// https://github.com/moby/moby/pull/49407#discussion_r1954396666
|
||||||
|
for _, c := range containers {
|
||||||
|
c.ImageManifestDescriptor = nil
|
||||||
|
}
|
||||||
return containers, nil
|
return containers, nil
|
||||||
})
|
})
|
||||||
return res, err
|
return res, err
|
||||||
|
|||||||
@@ -89,6 +89,10 @@ keywords: "API, Docker, rcli, REST, documentation"
|
|||||||
paths (`/v<API-version>/<endpoint>`).
|
paths (`/v<API-version>/<endpoint>`).
|
||||||
* `POST /build/prune` renames `keep-bytes` to `reserved-space` and now supports
|
* `POST /build/prune` renames `keep-bytes` to `reserved-space` and now supports
|
||||||
additional prune parameters `max-used-space` and `min-free-space`.
|
additional prune parameters `max-used-space` and `min-free-space`.
|
||||||
|
* `GET /containers/json` now returns an `ImageManifestDescriptor` field
|
||||||
|
matching the same field in `/containers/{name}/json`.
|
||||||
|
This field is only populated if the daemon provides a multi-platform image
|
||||||
|
store.
|
||||||
|
|
||||||
## v1.47 API changes
|
## v1.47 API changes
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/docker/docker/testutil"
|
"github.com/docker/docker/testutil"
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
|
"gotest.tools/v3/skip"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPsFilter(t *testing.T) {
|
func TestPsFilter(t *testing.T) {
|
||||||
@@ -47,3 +48,29 @@ func TestPsFilter(t *testing.T) {
|
|||||||
assert.Check(t, is.Contains(containerIDs(results), prev))
|
assert.Check(t, is.Contains(containerIDs(results), prev))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestPsPlatform verifies that containers have a platform set
|
||||||
|
func TestPsImageManifestPlatform(t *testing.T) {
|
||||||
|
skip.If(t, testEnv.IsRemoteDaemon)
|
||||||
|
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
|
||||||
|
skip.If(t, !testEnv.UsingSnapshotter())
|
||||||
|
|
||||||
|
ctx := setupTest(t)
|
||||||
|
apiClient := testEnv.APIClient()
|
||||||
|
|
||||||
|
container.Create(ctx, t, apiClient)
|
||||||
|
|
||||||
|
containers, err := apiClient.ContainerList(ctx, containertypes.ListOptions{
|
||||||
|
All: true,
|
||||||
|
})
|
||||||
|
assert.NilError(t, err)
|
||||||
|
assert.Check(t, len(containers) > 0)
|
||||||
|
|
||||||
|
ctr := containers[0]
|
||||||
|
if assert.Check(t, ctr.ImageManifestDescriptor != nil && ctr.ImageManifestDescriptor.Platform != nil) {
|
||||||
|
// Check that at least OS and Architecture have a value. Other values
|
||||||
|
// depend on the platform on which we're running the test.
|
||||||
|
assert.Equal(t, ctr.ImageManifestDescriptor.Platform.OS, testEnv.DaemonInfo.OSType)
|
||||||
|
assert.Check(t, ctr.ImageManifestDescriptor.Platform.Architecture != "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -107,6 +107,9 @@ func TestDiskUsage(t *testing.T) {
|
|||||||
// previously used prev.Images[0].Size, which may differ from content data
|
// previously used prev.Images[0].Size, which may differ from content data
|
||||||
assert.Check(t, is.Equal(du.Containers[0].SizeRootFs, du.LayersSize))
|
assert.Check(t, is.Equal(du.Containers[0].SizeRootFs, du.LayersSize))
|
||||||
|
|
||||||
|
// ImageManifestDescriptor should NOT be populated.
|
||||||
|
assert.Check(t, is.Nil(du.Containers[0].ImageManifestDescriptor))
|
||||||
|
|
||||||
return du
|
return du
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user