mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
daemon: Daemon.getNetworkedContainer: fix errors for invalid network container
When failing to resolve the network container, a "not found" error should
not return a 404, but either a "invalid parameter" (400) or "system" (500)
error.
Given that this function is called on container start, not container create,
a 500 (internal server error) is more appropriate, because the API request
(start the container) is valid, but the state of the container isn't.
While working on this, I discovered that no validation happens during container
create; TODO's were added to look into that, but this may be partially
by design (allow a container to be created before the "donor" network
container is created).
Before this patch:
docker container create --name hello --network=container:nosuchcontainer alpine
docker container start hello
Error response from daemon: No such container: nosuchcontainer
Error: failed to start containers: hello
# daemon logs:
DEBU[2025-01-30T11:32:33.595636043Z] error response for POST request error-response="No such container: nosuchcontainer" method=POST module=api request-url=/v1.47/containers/hello/start status=404 vars="map[name:hello version:1.47]"
docker container create --name hello2 --network=container:hello2 alpine
docker container start hello2
Error response from daemon: cannot join own network
Error: failed to start containers: hello2
# daemon logs:
DEBU[2025-01-30T11:33:19.545287551Z] FIXME: Got an API for which error does not match any expected type!!! error="cannot join own network" error_type="*errors.errorString" module=api
DEBU[2025-01-30T11:33:19.545346093Z] error response for POST request error-response="cannot join own network" method=POST module=api request-url=/v1.47/containers/hello2/start status=500 vars="map[name:hello2 version:1.47]"
DEBU[2025-01-30T11:33:19.545369968Z] FIXME: Got an API for which error does not match any expected type!!! error="cannot join own network" error_type="*errors.errorString" module=api
ERRO[2025-01-30T11:33:19.545375426Z] Handler for POST /v1.47/containers/hello2/start returned error: cannot join own network
With this patch:
docker container create --name hello --network=container:nosuchcontainer alpine
docker container start hello
Error response from daemon: joining network of container: No such container: nosuchcontainer
Error: failed to start containers: hello
# daemon logs:
DEBU[2025-01-30T11:35:50.406462760Z] error response for POST request error-response="joining network of container: No such container: nosuchcontainer" method=POST module=api request-url=/v1.47/containers/hello/start status=500 vars="map[name:hello version:1.47]"
ERRO[2025-01-30T11:35:50.406501468Z] Handler for POST /v1.47/containers/hello/start returned error: joining network of container: No such container: nosuchcontainer
docker container create --name hello2 --network=container:hello2 alpine
docker container start hello2
Error response from daemon: cannot join own network namespace
Error: failed to start containers: hello2
# daemon logs:
DEBU[2025-01-30T11:36:15.178475049Z] error response for POST request error-response="cannot join own network" method=POST module=api request-url=/v1.47/containers/hello2/start status=500 vars="map[name:hello2 version:1.47]"
ERRO[2025-01-30T11:36:15.178536507Z] Handler for POST /v1.47/containers/hello2/start returned error: cannot join own network
docker run --name exitedcontainer alpine
docker run --rm --network=container:exitedcontainer alpine
docker: Error response from daemon: cannot join network namespace of a non running container: container exitedcontainer is exited.
# daemon logs:
DEBU[2025-01-30T12:54:28.040637429Z] error response for POST request error-response="cannot join network namespace of a non running container: container exitedcontainer is exited" method=POST module=api request-url=/v1.47/containers/hello2/start status=409 vars="map[name:hello2 version:1.47]"
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
@@ -901,19 +901,37 @@ func (daemon *Daemon) normalizeNetMode(ctr *container.Container) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (daemon *Daemon) getNetworkedContainer(containerID, connectedContainerID string) (*container.Container, error) {
|
||||
nc, err := daemon.GetContainer(connectedContainerID)
|
||||
func (daemon *Daemon) getNetworkedContainer(containerID, connectedContainerPrefixOrName string) (*container.Container, error) {
|
||||
nc, err := daemon.GetContainer(connectedContainerPrefixOrName)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("joining network namespace of container: %w", err)
|
||||
if errdefs.IsNotFound(err) {
|
||||
// Deliberately masking "not found" errors, because failing to find
|
||||
// the network container is a system error. We return a system error,
|
||||
// not an "invalid parameter" because getNetworkedContainer is called
|
||||
// during container start, not container "create"; we assume the container
|
||||
// did resolve successfully when creating the container.
|
||||
//
|
||||
// FIXME (thaJeztah): turns out we don't validate "--network container:<missing container>" during container create!
|
||||
// ^^ this may have been by design to allow the container to be created before the "donor" container is
|
||||
// created, so this must be looked into.
|
||||
return nil, errdefs.System(err)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if containerID == nc.ID {
|
||||
return nil, fmt.Errorf("cannot join own network")
|
||||
// We return a system error, not an "invalid parameter" because getNetworkedContainer is called
|
||||
// during container start, not container "create"; we assume the networked container did resolve
|
||||
// successfully when creating the container, and was validated during container create.
|
||||
//
|
||||
// FIXME (thaJeztah): turns out we don't validate "--network container:<self>" during container create!
|
||||
return nil, errdefs.System(errdefs.InvalidParameter(errors.New("cannot join own network namespace")))
|
||||
}
|
||||
if !nc.IsRunning() {
|
||||
return nil, errdefs.Conflict(fmt.Errorf("cannot join network of a non running container: %s", connectedContainerID))
|
||||
return nil, errdefs.Conflict(fmt.Errorf("cannot join network namespace of a non running container: container %s is %s", strings.TrimPrefix(nc.Name, "/"), nc.StateString()))
|
||||
}
|
||||
if nc.IsRestarting() {
|
||||
return nil, errContainerIsRestarting(connectedContainerID)
|
||||
return nil, fmt.Errorf("cannot join network namespace of container: %w", errContainerIsRestarting(connectedContainerPrefixOrName))
|
||||
}
|
||||
return nc, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user