Browse Source

Return "invalid parameter" when linking to non-existing container

Trying to link to a non-existing container is not valid, and should return an
"invalid parameter" (400) error. Returning a "not found" error in this situation
would make the client report the container's image could not be found.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Sebastiaan van Stijn 5 năm trước cách đây
mục cha
commit
422067ba7b
2 tập tin đã thay đổi với 37 bổ sung0 xóa
  1. 15 0
      daemon/daemon_unix.go
  2. 22 0
      integration/container/create_test.go

+ 15 - 0
daemon/daemon_unix.go

@@ -24,6 +24,7 @@ import (
 	"github.com/docker/docker/container"
 	"github.com/docker/docker/daemon/config"
 	"github.com/docker/docker/daemon/initlayer"
+	"github.com/docker/docker/errdefs"
 	"github.com/docker/docker/opts"
 	"github.com/docker/docker/pkg/containerfs"
 	"github.com/docker/docker/pkg/idtools"
@@ -1324,12 +1325,26 @@ func (daemon *Daemon) registerLinks(container *container.Container, hostConfig *
 		}
 		child, err := daemon.GetContainer(name)
 		if err != nil {
+			if errdefs.IsNotFound(err) {
+				// Trying to link to a non-existing container is not valid, and
+				// should return an "invalid parameter" error. Returning a "not
+				// found" error here would make the client report the container's
+				// image could not be found (see moby/moby#39823)
+				err = errdefs.InvalidParameter(err)
+			}
 			return errors.Wrapf(err, "could not get container for %s", name)
 		}
 		for child.HostConfig.NetworkMode.IsContainer() {
 			parts := strings.SplitN(string(child.HostConfig.NetworkMode), ":", 2)
 			child, err = daemon.GetContainer(parts[1])
 			if err != nil {
+				if errdefs.IsNotFound(err) {
+					// Trying to link to a non-existing container is not valid, and
+					// should return an "invalid parameter" error. Returning a "not
+					// found" error here would make the client report the container's
+					// image could not be found (see moby/moby#39823)
+					err = errdefs.InvalidParameter(err)
+				}
 				return errors.Wrapf(err, "Could not get container for %s", parts[1])
 			}
 		}

+ 22 - 0
integration/container/create_test.go

@@ -65,6 +65,28 @@ func TestCreateFailsWhenIdentifierDoesNotExist(t *testing.T) {
 	}
 }
 
+// TestCreateLinkToNonExistingContainer verifies that linking to a non-existing
+// container returns an "invalid parameter" (400) status, and not the underlying
+// "non exists" (404).
+func TestCreateLinkToNonExistingContainer(t *testing.T) {
+	skip.If(t, testEnv.DaemonInfo.OSType == "windows", "legacy links are not supported on windows")
+	defer setupTest(t)()
+	c := testEnv.APIClient()
+
+	_, err := c.ContainerCreate(context.Background(),
+		&container.Config{
+			Image: "busybox",
+		},
+		&container.HostConfig{
+			Links: []string{"no-such-container"},
+		},
+		&network.NetworkingConfig{},
+		"",
+	)
+	assert.Check(t, is.ErrorContains(err, "could not get container for no-such-container"))
+	assert.Check(t, errdefs.IsInvalidParameter(err))
+}
+
 func TestCreateWithInvalidEnv(t *testing.T) {
 	defer setupTest(t)()
 	client := testEnv.APIClient()