api: image inspect: remove temporary backfill for Config fields

Commit 4dc961d0e9 (API v1.50) fixed the type
used for Config to point to the correct type, which is the Config struct
from the [Docker image spec] (which embeds the [OCI Image Specification]
type); however, those types use an omitempty, which wasn't documented as
part of the API changes, so f85394dd5d added
a temporary backfill for empty fields.

This removes that backfill for API v1.52 so that empty image config fields
are now omitted.

[OCI Image Specification]: https://github.com/opencontainers/image-spec/blob/v1.1.1/specs-go/v1/config.go#L23-L62
[Docker image spec]: https://github.com/moby/docker-image-spec/blob/v1.3.1/specs-go/v1/image.go#L19-L32

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2025-09-05 18:23:02 +02:00
parent 7777b86d53
commit 0525ae2aed
4 changed files with 16 additions and 10 deletions

View File

@@ -26,6 +26,9 @@ keywords: "API, Docker, rcli, REST, documentation"
a PortBinding with an empty HostIP and HostPort when calling `POST /containers/{id}/start`.
This behavior is now deprecated, and a warning is returned by `POST /containers/create`.
The next API version will drop empty `PortBindings` list altogether.
* `GET /images/{name}/json` now omits the following `Config` fields when
not set, to closer align with the implementation of the [OCI Image Specification](https://github.com/opencontainers/image-spec/blob/v1.1.1/specs-go/v1/config.go#L23-L62)
`Cmd`, `Entrypoint`, `Env`, `Labels`, `OnBuild`, `User`, `Volumes`, and `WorkingDir`.
## v1.51 API changes

View File

@@ -372,12 +372,8 @@ func (ir *imageRouter) getImagesByName(ctx context.Context, w http.ResponseWrite
return err
}
// inspectResponse preserves fields in the response that have an
// "omitempty" in the OCI spec, but didn't omit such fields in
// legacy responses before API v1.50.
imageInspect := &inspectCompatResponse{
InspectResponse: resp,
legacyConfig: legacyConfigFields["current"],
}
// Make sure we output empty arrays instead of nil. While Go nil slice is functionally equivalent to an empty slice,
@@ -406,8 +402,15 @@ func (ir *imageRouter) getImagesByName(ctx context.Context, w http.ResponseWrite
if versions.LessThan(version, "1.48") {
imageInspect.Descriptor = nil
}
if versions.LessThan(version, "1.50") {
imageInspect.legacyConfig = legacyConfigFields["v1.49"]
if versions.LessThan(version, "1.52") {
if versions.LessThan(version, "1.50") {
imageInspect.legacyConfig = legacyConfigFields["v1.49"]
} else {
// inspectResponse preserves fields in the response that have an
// "omitempty" in the OCI spec, but didn't omit such fields in
// legacy responses before API v1.50.
imageInspect.legacyConfig = legacyConfigFields["v1.50-v1.51"]
}
}
return httputils.WriteJSON(w, http.StatusOK, imageInspect)

View File

@@ -31,10 +31,10 @@ var legacyConfigFields = map[string]map[string]any{
"Volumes": nil,
"WorkingDir": "",
},
// Legacy fields for current API versions (v1.50 and up). These fields
// Legacy fields for current API versions (v1.50 and v1.52). These fields
// did not have an "omitempty" and were always included in the response,
// even if not set; see https://github.com/moby/moby/issues/50134
"current": {
"v1.50-v1.51": {
"Cmd": nil,
"Entrypoint": nil,
"Env": nil,

View File

@@ -40,12 +40,12 @@ func TestInspectResponse(t *testing.T) {
expected: `{"AttachStderr":false,"AttachStdin":false,"AttachStdout":false,"Cmd":["/bin/sh"],"Domainname":"","Entrypoint":null,"Env":null,"Hostname":"","Image":"","Labels":null,"OnBuild":null,"OpenStdin":false,"StdinOnce":false,"StopSignal":"SIGQUIT","Tty":false,"User":"","Volumes":null,"WorkingDir":""}`,
},
{
doc: "api >= v1.50",
doc: "api v1.50 - v1.51",
cfg: &ocispec.ImageConfig{
Cmd: []string{"/bin/sh"},
StopSignal: "SIGQUIT",
},
legacyConfig: legacyConfigFields["current"],
legacyConfig: legacyConfigFields["v1.50-v1.51"],
expected: `{"Cmd":["/bin/sh"],"Entrypoint":null,"Env":null,"Labels":null,"OnBuild":null,"StopSignal":"SIGQUIT","User":"","Volumes":null,"WorkingDir":""}`,
},
}