mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
c8d/container/inspect: Return ImageManifestDescriptor
`ImageManifestDescriptor` will contain an OCI descriptor of platform-specific manifest of the image that was picked when creating the container. Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
This commit is contained in:
@@ -33,6 +33,9 @@ func (c *containerRouter) getContainersByName(ctx context.Context, w http.Respon
|
||||
}
|
||||
}
|
||||
}
|
||||
if versions.LessThan(version, "1.48") {
|
||||
ctr.ImageManifestDescriptor = nil
|
||||
}
|
||||
|
||||
return httputils.WriteJSON(w, http.StatusOK, ctr)
|
||||
}
|
||||
|
||||
@@ -7266,6 +7266,14 @@ paths:
|
||||
type: "string"
|
||||
Platform:
|
||||
type: "string"
|
||||
ImageManifestDescriptor:
|
||||
$ref: "#/definitions/OCIDescriptor"
|
||||
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.
|
||||
MountLabel:
|
||||
type: "string"
|
||||
ProcessLabel:
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/docker/docker/api/types/mount"
|
||||
"github.com/docker/docker/api/types/storage"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// PruneReport contains the response for Engine API:
|
||||
@@ -171,4 +172,6 @@ type InspectResponse struct {
|
||||
Mounts []MountPoint
|
||||
Config *Config
|
||||
NetworkSettings *NetworkSettings
|
||||
// ImageManifestDescriptor is the descriptor of a platform-specific manifest of the image used to create the container.
|
||||
ImageManifestDescriptor *ocispec.Descriptor `json:",omitempty"`
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import (
|
||||
"github.com/docker/docker/pkg/parsers/operatingsystem"
|
||||
"github.com/docker/docker/pkg/sysinfo"
|
||||
"github.com/docker/docker/registry"
|
||||
metrics "github.com/docker/go-metrics"
|
||||
"github.com/docker/go-metrics"
|
||||
"github.com/opencontainers/selinux/go-selinux"
|
||||
)
|
||||
|
||||
|
||||
@@ -77,11 +77,21 @@ func (daemon *Daemon) ContainerInspect(ctx context.Context, name string, options
|
||||
base.SizeRootFs = &sizeRootFs
|
||||
}
|
||||
|
||||
imageManifest := ctr.ImageManifest
|
||||
if imageManifest != nil && imageManifest.Platform == nil {
|
||||
// Copy the image manifest to avoid mutating the original
|
||||
c := *imageManifest
|
||||
imageManifest = &c
|
||||
|
||||
imageManifest.Platform = &ctr.ImagePlatform
|
||||
}
|
||||
|
||||
return &containertypes.InspectResponse{
|
||||
ContainerJSONBase: base,
|
||||
Mounts: mountPoints,
|
||||
Config: ctr.Config,
|
||||
NetworkSettings: networkSettings,
|
||||
ContainerJSONBase: base,
|
||||
Mounts: mountPoints,
|
||||
Config: ctr.Config,
|
||||
NetworkSettings: networkSettings,
|
||||
ImageManifestDescriptor: imageManifest,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,11 @@ keywords: "API, Docker, rcli, REST, documentation"
|
||||
image store.
|
||||
WARNING: This is experimental and may change at any time without any backward
|
||||
compatibility.
|
||||
* `GET /containers/{name}/json` now returns an `ImageManifestDescriptor` field
|
||||
containing the OCI descriptor of the platform-specific image manifest of the
|
||||
image that was used to create the container.
|
||||
This field is only populated if the daemon provides a multi-platform image
|
||||
store.
|
||||
* `POST /networks/create` now has an `EnableIPv4` field. Setting it to `false`
|
||||
disables IPv4 IPAM for the network. It can only be set to `false` if the
|
||||
daemon has experimental features enabled.
|
||||
|
||||
@@ -5,11 +5,14 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/containerd/platforms"
|
||||
containertypes "github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/docker/integration/internal/container"
|
||||
"github.com/docker/docker/testutil/request"
|
||||
"gotest.tools/v3/assert"
|
||||
is "gotest.tools/v3/assert/cmp"
|
||||
"gotest.tools/v3/skip"
|
||||
)
|
||||
|
||||
func TestInspectAnnotations(t *testing.T) {
|
||||
@@ -64,3 +67,78 @@ func TestNetworkAliasesAreEmpty(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestInspectImageManifestPlatform(t *testing.T) {
|
||||
skip.If(t, testEnv.IsRemoteDaemon)
|
||||
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
|
||||
skip.If(t, !testEnv.UsingSnapshotter())
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
image string
|
||||
skipIf func() bool
|
||||
expectedPlatform platforms.Platform
|
||||
}{
|
||||
{
|
||||
name: "amd64 only on any host",
|
||||
image: "busybox:latest",
|
||||
expectedPlatform: platforms.Platform{
|
||||
OS: "linux",
|
||||
Architecture: "amd64",
|
||||
Variant: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
skipIf: func() bool { return runtime.GOARCH != "amd64" },
|
||||
name: "amd64 image on non-amd64 host",
|
||||
|
||||
image: "hello-world:amd64",
|
||||
expectedPlatform: platforms.Platform{
|
||||
OS: "linux",
|
||||
Architecture: "amd64",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "arm64 image on non-arm64 host",
|
||||
skipIf: func() bool { return runtime.GOARCH != "arm64" },
|
||||
image: "hello-world:arm64",
|
||||
|
||||
expectedPlatform: platforms.Platform{
|
||||
OS: "linux",
|
||||
Architecture: "arm64",
|
||||
Variant: "",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
if tc.skipIf != nil && tc.skipIf() {
|
||||
continue
|
||||
}
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
ctx := setupTest(t)
|
||||
apiClient := request.NewAPIClient(t)
|
||||
|
||||
ctr := container.Create(ctx, t, apiClient, container.WithImage(tc.image))
|
||||
defer apiClient.ContainerRemove(ctx, ctr, containertypes.RemoveOptions{Force: true})
|
||||
|
||||
img, _, err := apiClient.ImageInspectWithRaw(ctx, tc.image)
|
||||
assert.NilError(t, err)
|
||||
|
||||
hostPlatform := platforms.Platform{
|
||||
OS: img.Os,
|
||||
Architecture: img.Architecture,
|
||||
Variant: img.Variant,
|
||||
}
|
||||
inspect := container.Inspect(ctx, t, apiClient, ctr)
|
||||
assert.Assert(t, inspect.ImageManifestDescriptor != nil)
|
||||
assert.Check(t, is.DeepEqual(*inspect.ImageManifestDescriptor.Platform, hostPlatform))
|
||||
|
||||
t.Run("pre 1.48", func(t *testing.T) {
|
||||
oldClient := request.NewAPIClient(t, client.WithVersion("1.47"))
|
||||
inspect := container.Inspect(ctx, t, oldClient, ctr)
|
||||
assert.Check(t, is.Nil(inspect.ImageManifestDescriptor))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user