daemon/server/router/container: postCommit: only decode Config#50458
daemon/server/router/container: postCommit: only decode Config#50458thaJeztah merged 1 commit intomoby:masterfrom
Conversation
| config, _, _, err := c.decoder.DecodeConfig(r.Body) | ||
| if err != nil && !errors.Is(err, io.EOF) { // Do not fail if body is empty. | ||
| var config *container.Config | ||
| if err := httputils.ReadJSON(r, config); err != nil && !errors.Is(err, io.EOF) { // Do not fail if body is empty. |
There was a problem hiding this comment.
Checking for io.EOF looks redundant as well; ReadJSON returns nil for an empty Body;
moby/daemon/server/httputils/httputils.go
Lines 62 to 71 in 79f802d
It will return an error when getting an io.EOF on unmarshaling, but that would be invalid JSON;
moby/daemon/server/httputils/httputils.go
Lines 74 to 79 in 79f802d
7fba745 to
c1aaf66
Compare
c1aaf66 to
cdd1a61
Compare
|
Failure is related; it expects config to be |
cdd1a61 to
8a372d4
Compare
The postCommit used the container-decoder from runconfig to unmarshal the body. However, this function was written to decode a container CreateRequest. Commit only accepts a container Config, so we can just unmarshal to that type. A local `commitRequest` type was added because the client posts a bare `*container.Config` but it may be empty / nil (see [Client.ContainerCommit] and [container.CommitOptions]), in which case it must be ignored, and no overrides to be applied. [Client.ContainerCommit]: https://github.com/moby/moby/blob/c4afa7715715a1020e50b19ad60728c4479fb0a5/client/container_commit.go#L52 [container.CommitOptions]: https://github.com/moby/moby/blob/c4afa7715715a1020e50b19ad60728c4479fb0a5/api/types/container/options.go#L30 Signed-off-by: Sebastiaan van Stijn <[email protected]>
8a372d4 to
b448dc5
Compare
|
This test looks flaky;
|
| // are discarded here, but decoder.DecodeConfig also performs validation, | ||
| // so a request containing those additional fields would result in a | ||
| // validation error. | ||
| config, _, _, err := c.decoder.DecodeConfig(r.Body) |
There was a problem hiding this comment.
This one had some additional logic for validation:
Lines 20 to 78 in b486373
Looks like most of them were related to HostConfig (which isn't present in the commit request though), but there are some related to Config like:
- (making sure Volumes map isn't nil, but perhaps this one isn't needed anymore)
Lines 74 to 76 in b486373
moby/runconfig/hostconfig_unix.go
Lines 20 to 22 in afd6487
- (for container-mode networking only)
Lines 39 to 41 in afd6487
But I assume these would fail at later point of the commit anyway, so perhaps it's not worth to bother with them?
There was a problem hiding this comment.
Ah, yes, I stared at that a few times as well, but the old one would return early if there's no HostConfig, so none of those paths would be hit!
Lines 37 to 47 in a7d4b91
It was actually because I looked at that code at the time that I considered "why are we even using this decoder if nothing it does is used for docker commit ? Then I looked at the API side, and .... basically commit only accepts a Config, nothing else.
There was a problem hiding this comment.
Also "fun fact" that docker commit never sends a body; we only send the changes to the daemon; https://github.com/docker/cli/blob/a1035b0796241b3bbd0f41940525373001fc146c/cli/command/container/commit.go#L59-L66
func runCommit(ctx context.Context, dockerCli command.Cli, options *commitOptions) error {
response, err := dockerCli.Client().ContainerCommit(ctx, options.container, container.CommitOptions{
Reference: options.reference,
Comment: options.comment,
Author: options.author,
Changes: options.changes.GetSlice(),
Pause: options.pause,
})Which brought me back to a ticket I created a while ago, but at the time didn't even realise we already have an "option" for this (send overrides as body), but it's ... not used (for some reason). Possibly it was used by the classic builder?
|
Let me bring this one in, then I can also remove some special handling in #50532 |
The postCommit used the container-decoder from runconfig to unmarshal the body. However, this function was written to decode a container CreateRequest. Commit only accepts a container Config, so we can just unmarshal to that type.
The postCommit used the container-decoder from runconfig to unmarshal the body. However, this function was written to decode a container
CreateRequest. Commit only accepts a container Config, so we can just unmarshal to that type.A local
commitRequesttype was added because the client posts a bare*container.Configbut it may be empty / nil (see Client.ContainerCommit and container.CommitOptions), in which case it must be ignored, and no overrides to be applied.- A picture of a cute animal (not mandatory but encouraged)