Browse code

Merge pull request #352 from thaJeztah/19.03_backport_detect_invalid_linked_container

[19.03 backport] Return "invalid parameter" when linking to non-existing container

Andrew Hsu authored on 2019/09/20 09:45:09
Showing 2 changed files
... ...
@@ -24,6 +24,7 @@ import (
24 24
 	"github.com/docker/docker/container"
25 25
 	"github.com/docker/docker/daemon/config"
26 26
 	"github.com/docker/docker/daemon/initlayer"
27
+	"github.com/docker/docker/errdefs"
27 28
 	"github.com/docker/docker/opts"
28 29
 	"github.com/docker/docker/pkg/containerfs"
29 30
 	"github.com/docker/docker/pkg/idtools"
... ...
@@ -1294,12 +1295,26 @@ func (daemon *Daemon) registerLinks(container *container.Container, hostConfig *
1294 1294
 		}
1295 1295
 		child, err := daemon.GetContainer(name)
1296 1296
 		if err != nil {
1297
+			if errdefs.IsNotFound(err) {
1298
+				// Trying to link to a non-existing container is not valid, and
1299
+				// should return an "invalid parameter" error. Returning a "not
1300
+				// found" error here would make the client report the container's
1301
+				// image could not be found (see moby/moby#39823)
1302
+				err = errdefs.InvalidParameter(err)
1303
+			}
1297 1304
 			return errors.Wrapf(err, "could not get container for %s", name)
1298 1305
 		}
1299 1306
 		for child.HostConfig.NetworkMode.IsContainer() {
1300 1307
 			parts := strings.SplitN(string(child.HostConfig.NetworkMode), ":", 2)
1301 1308
 			child, err = daemon.GetContainer(parts[1])
1302 1309
 			if err != nil {
1310
+				if errdefs.IsNotFound(err) {
1311
+					// Trying to link to a non-existing container is not valid, and
1312
+					// should return an "invalid parameter" error. Returning a "not
1313
+					// found" error here would make the client report the container's
1314
+					// image could not be found (see moby/moby#39823)
1315
+					err = errdefs.InvalidParameter(err)
1316
+				}
1303 1317
 				return errors.Wrapf(err, "Could not get container for %s", parts[1])
1304 1318
 			}
1305 1319
 		}
... ...
@@ -65,6 +65,28 @@ func TestCreateFailsWhenIdentifierDoesNotExist(t *testing.T) {
65 65
 	}
66 66
 }
67 67
 
68
+// TestCreateLinkToNonExistingContainer verifies that linking to a non-existing
69
+// container returns an "invalid parameter" (400) status, and not the underlying
70
+// "non exists" (404).
71
+func TestCreateLinkToNonExistingContainer(t *testing.T) {
72
+	skip.If(t, testEnv.DaemonInfo.OSType == "windows", "legacy links are not supported on windows")
73
+	defer setupTest(t)()
74
+	c := testEnv.APIClient()
75
+
76
+	_, err := c.ContainerCreate(context.Background(),
77
+		&container.Config{
78
+			Image: "busybox",
79
+		},
80
+		&container.HostConfig{
81
+			Links: []string{"no-such-container"},
82
+		},
83
+		&network.NetworkingConfig{},
84
+		"",
85
+	)
86
+	assert.Check(t, is.ErrorContains(err, "could not get container for no-such-container"))
87
+	assert.Check(t, errdefs.IsInvalidParameter(err))
88
+}
89
+
68 90
 func TestCreateWithInvalidEnv(t *testing.T) {
69 91
 	defer setupTest(t)()
70 92
 	client := testEnv.APIClient()