1
0
mirror of https://github.com/moby/moby.git synced 2025-07-29 07:21:35 +03:00

client: normalize and validate empty ID / name arguments to fail early

In situations where an empty ID was passed, the client would construct an
invalid API endpoint URL, which either resulted in the "not found" handler
being hit (resulting in a "page not found" error), or even the wrong endpoint
being hit if the client follows redirects.

For example, `/containers/<empty id>/json` (inspect) redirects to `/containers/json`
(docker ps))

Given that empty IDs should never be expected (especially if they're part of
the API URL path), we can validate these and return early.

Its worth noting that a few methods already had an error in place; those
methods were related to the situation mentioned above, where (e.g.) an
"inspect" would redirect to a "list" endpoint. The existing errors, for
convenience, mimicked a "not found" error; this patch changes such errors
to an "Invalid Parameter" instead, which is more correct, but it could be
a breaking change for some edge cases where users parsed the output;

    git grep 'objectNotFoundError{'
    client/config_inspect.go:        return swarm.Config{}, nil, objectNotFoundError{object: "config", id: id}
    client/container_inspect.go:     return container.InspectResponse{}, nil, objectNotFoundError{object: "container", id: containerID}
    client/container_inspect.go:     return container.InspectResponse{}, objectNotFoundError{object: "container", id: containerID}
    client/distribution_inspect.go:  return distributionInspect, objectNotFoundError{object: "distribution", id: imageRef}
    client/image_inspect.go:         return image.InspectResponse{}, nil, objectNotFoundError{object: "image", id: imageID}
    client/network_inspect.go:       return network.Inspect{}, nil, objectNotFoundError{object: "network", id: networkID}
    client/node_inspect.go:          return swarm.Node{}, nil, objectNotFoundError{object: "node", id: nodeID}
    client/plugin_inspect.go:        return nil, nil, objectNotFoundError{object: "plugin", id: name}
    client/secret_inspect.go:        return swarm.Secret{}, nil, objectNotFoundError{object: "secret", id: id}
    client/service_inspect.go:       return swarm.Service{}, nil, objectNotFoundError{object: "service", id: serviceID}
    client/task_inspect.go:          return swarm.Task{}, nil, objectNotFoundError{object: "task", id: taskID}
    client/volume_inspect.go:        return volume.Volume{}, nil, objectNotFoundError{object: "volume", id: volumeID}

Two such errors are still left, as "ID or name" would probably be confusing,
but perhaps we can use a more generic error to include those as well (e.g.
"invalid <object> reference: value is empty");

    client/distribution_inspect.go:  return distributionInspect, objectNotFoundError{object: "distribution", id: imageRef}
    client/image_inspect.go:         return image.InspectResponse{}, nil, objectNotFoundError{object: "image", id: imageID}

Before this patch:

    docker container start ""
    Error response from daemon: page not found
    Error: failed to start containers:

    docker container start " "
    Error response from daemon: No such container:
    Error: failed to start containers:

With this patch:

    docker container start ""
    invalid container name or ID: value is empty
    Error: failed to start containers:

    docker container start " "
    invalid container name or ID: value is empty
    Error: failed to start containers:

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2025-02-03 10:35:25 +01:00
parent 96ded2a1ba
commit 329b2a26f3
100 changed files with 706 additions and 70 deletions

View File

@ -12,7 +12,12 @@ import (
)
// ContainerCommit applies changes to a container and creates a new tagged image.
func (cli *Client) ContainerCommit(ctx context.Context, container string, options container.CommitOptions) (types.IDResponse, error) {
func (cli *Client) ContainerCommit(ctx context.Context, containerID string, options container.CommitOptions) (types.IDResponse, error) {
containerID, err := trimID("container", containerID)
if err != nil {
return types.IDResponse{}, err
}
var repository, tag string
if options.Reference != "" {
ref, err := reference.ParseNormalizedNamed(options.Reference)
@ -32,7 +37,7 @@ func (cli *Client) ContainerCommit(ctx context.Context, container string, option
}
query := url.Values{}
query.Set("container", container)
query.Set("container", containerID)
query.Set("repo", repository)
query.Set("tag", tag)
query.Set("comment", options.Comment)