Browse Source

Add integration test for #38995, #43390

Modify the DinD entrypoint scripts to make the issue reproducible inside
a DinD container.

Co-authored-by: Bjorn Neergaard <bneergaard@mirantis.com>
Signed-off-by: Bjorn Neergaard <bneergaard@mirantis.com>
Signed-off-by: Cory Snider <csnider@mirantis.com>
Cory Snider 2 năm trước cách đây
mục cha
commit
1f32e3c95d
3 tập tin đã thay đổi với 44 bổ sung0 xóa
  1. 4 0
      hack/dind
  2. 5 0
      hack/dind-systemd
  3. 35 0
      integration/container/mounts_linux_test.go

+ 4 - 0
hack/dind

@@ -37,6 +37,10 @@ if [ -f /sys/fs/cgroup/cgroup.controllers ]; then
 		> /sys/fs/cgroup/cgroup.subtree_control
 fi
 
+# Change mount propagation to shared to make the environment more similar to a
+# modern Linux system, e.g. with SystemD as PID 1.
+mount --make-rshared /
+
 if [ $# -gt 0 ]; then
 	exec "$@"
 fi

+ 5 - 0
hack/dind-systemd

@@ -13,6 +13,11 @@ if [ ! -t 0 ]; then
 	exit 1
 fi
 
+# Change mount propagation to shared, which SystemD PID 1 would normally do
+# itself when started by the kernel. SystemD skips that when it detects it is
+# running in a container.
+mount --make-rshared /
+
 env > /etc/docker-entrypoint-env
 
 cat > /etc/systemd/system/docker-entrypoint.target << EOF

+ 35 - 0
integration/container/mounts_linux_test.go

@@ -391,3 +391,38 @@ func TestContainerVolumesMountedAsSlave(t *testing.T) {
 		t.Fatal(err)
 	}
 }
+
+// Regression test for #38995 and #43390.
+func TestContainerCopyLeaksMounts(t *testing.T) {
+	defer setupTest(t)()
+
+	bindMount := mounttypes.Mount{
+		Type:   mounttypes.TypeBind,
+		Source: "/var",
+		Target: "/hostvar",
+		BindOptions: &mounttypes.BindOptions{
+			Propagation: mounttypes.PropagationRSlave,
+		},
+	}
+
+	ctx := context.Background()
+	client := testEnv.APIClient()
+	cid := container.Run(ctx, t, client, container.WithMount(bindMount), container.WithCmd("sleep", "120s"))
+
+	getMounts := func() string {
+		t.Helper()
+		res, err := container.Exec(ctx, client, cid, []string{"cat", "/proc/self/mountinfo"})
+		assert.NilError(t, err)
+		assert.Equal(t, res.ExitCode, 0)
+		return res.Stdout()
+	}
+
+	mountsBefore := getMounts()
+
+	_, _, err := client.CopyFromContainer(ctx, cid, "/etc/passwd")
+	assert.NilError(t, err)
+
+	mountsAfter := getMounts()
+
+	assert.Equal(t, mountsBefore, mountsAfter)
+}