Browse Source

Merge pull request #41638 from TBBle/37352-fix-Windows-CI-pipeline

Reinstate Windows CI Pipeline usefulness
Sebastiaan van Stijn 4 năm trước cách đây
mục cha
commit
0e8023ddea

+ 0 - 5
hack/ci/windows.ps1

@@ -1012,9 +1012,6 @@ Catch [Exception] {
     Throw $_
 }
 Finally {
-    # Preserve the LastExitCode of the tests
-    $tmpLastExitCode = $LastExitCode
-
     $ErrorActionPreference="SilentlyContinue"
     $global:ProgressPreference=$origProgressPreference
     Write-Host  -ForegroundColor Green "INFO: Tidying up at end of run"
@@ -1053,6 +1050,4 @@ Finally {
 
     $Dur=New-TimeSpan -Start $StartTime -End $(Get-Date)
     Write-Host -ForegroundColor $FinallyColour "`nINFO: executeCI.ps1 exiting at $(date). Duration $dur`n"
-
-    exit $tmpLastExitCode
 }

+ 1 - 2
integration-cli/docker_api_containers_test.go

@@ -30,7 +30,6 @@ import (
 	"github.com/docker/docker/testutil/request"
 	"github.com/docker/docker/volume"
 	"github.com/docker/go-connections/nat"
-	"github.com/moby/sys/mount"
 	"gotest.tools/v3/assert"
 	is "gotest.tools/v3/assert/cmp"
 	"gotest.tools/v3/poll"
@@ -2056,7 +2055,7 @@ func (s *DockerSuite) TestContainersAPICreateMountsCreate(c *testing.T) {
 			assert.NilError(c, err)
 			defer os.RemoveAll(tmpDir3)
 
-			assert.Assert(c, mount.Mount(tmpDir3, tmpDir3, "none", "bind,shared") == nil)
+			assert.Assert(c, mountWrapper(tmpDir3, tmpDir3, "none", "bind,shared") == nil)
 
 			cases = append(cases, []testCase{
 				{

+ 9 - 0
integration-cli/docker_api_containers_unix_test.go

@@ -0,0 +1,9 @@
+// +build !windows
+
+package main
+
+import "github.com/moby/sys/mount"
+
+func mountWrapper(device, target, mType, options string) error {
+	return mount.Mount(device, target, mType, options)
+}

+ 6 - 0
integration-cli/docker_api_containers_windows_test.go

@@ -15,6 +15,7 @@ import (
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/mount"
+	"github.com/pkg/errors"
 	"gotest.tools/v3/assert"
 	is "gotest.tools/v3/assert/cmp"
 )
@@ -75,3 +76,8 @@ func (s *DockerSuite) TestContainersAPICreateMountsBindNamedPipe(c *testing.T) {
 	assert.NilError(c, err)
 	assert.Check(c, is.Equal(text, strings.TrimSpace(string(b))))
 }
+
+func mountWrapper(device, target, mType, options string) error {
+	// This should never be called.
+	return errors.Errorf("there is no implementation of Mount on this platform")
+}

+ 0 - 81
integration-cli/docker_cli_run_test.go

@@ -34,7 +34,6 @@ import (
 	"github.com/docker/go-connections/nat"
 	"github.com/docker/libnetwork/resolvconf"
 	"github.com/docker/libnetwork/types"
-	"github.com/moby/sys/mount"
 	"github.com/moby/sys/mountinfo"
 	"gotest.tools/v3/assert"
 	"gotest.tools/v3/icmd"
@@ -3764,86 +3763,6 @@ func (s *DockerSuite) TestRunWithOomScoreAdjInvalidRange(c *testing.T) {
 	}
 }
 
-func (s *DockerSuite) TestRunVolumesMountedAsShared(c *testing.T) {
-	// Volume propagation is linux only. Also it creates directories for
-	// bind mounting, so needs to be same host.
-	testRequires(c, DaemonIsLinux, testEnv.IsLocalDaemon, NotUserNamespace)
-
-	// Prepare a source directory to bind mount
-	tmpDir, err := ioutil.TempDir("", "volume-source")
-	if err != nil {
-		c.Fatal(err)
-	}
-	defer os.RemoveAll(tmpDir)
-
-	if err := os.Mkdir(path.Join(tmpDir, "mnt1"), 0755); err != nil {
-		c.Fatal(err)
-	}
-
-	// Convert this directory into a shared mount point so that we do
-	// not rely on propagation properties of parent mount.
-	icmd.RunCommand("mount", "--bind", tmpDir, tmpDir).Assert(c, icmd.Success)
-	icmd.RunCommand("mount", "--make-private", "--make-shared", tmpDir).Assert(c, icmd.Success)
-
-	dockerCmd(c, "run", "--privileged", "-v", fmt.Sprintf("%s:/volume-dest:shared", tmpDir), "busybox", "mount", "--bind", "/volume-dest/mnt1", "/volume-dest/mnt1")
-
-	// Make sure a bind mount under a shared volume propagated to host.
-	if mounted, _ := mountinfo.Mounted(path.Join(tmpDir, "mnt1")); !mounted {
-		c.Fatalf("Bind mount under shared volume did not propagate to host")
-	}
-
-	mount.Unmount(path.Join(tmpDir, "mnt1"))
-}
-
-func (s *DockerSuite) TestRunVolumesMountedAsSlave(c *testing.T) {
-	// Volume propagation is linux only. Also it creates directories for
-	// bind mounting, so needs to be same host.
-	testRequires(c, DaemonIsLinux, testEnv.IsLocalDaemon, NotUserNamespace)
-
-	// Prepare a source directory to bind mount
-	tmpDir, err := ioutil.TempDir("", "volume-source")
-	if err != nil {
-		c.Fatal(err)
-	}
-	defer os.RemoveAll(tmpDir)
-
-	if err := os.Mkdir(path.Join(tmpDir, "mnt1"), 0755); err != nil {
-		c.Fatal(err)
-	}
-
-	// Prepare a source directory with file in it. We will bind mount this
-	// directory and see if file shows up.
-	tmpDir2, err := ioutil.TempDir("", "volume-source2")
-	if err != nil {
-		c.Fatal(err)
-	}
-	defer os.RemoveAll(tmpDir2)
-
-	if err := ioutil.WriteFile(path.Join(tmpDir2, "slave-testfile"), []byte("Test"), 0644); err != nil {
-		c.Fatal(err)
-	}
-
-	// Convert this directory into a shared mount point so that we do
-	// not rely on propagation properties of parent mount.
-	icmd.RunCommand("mount", "--bind", tmpDir, tmpDir).Assert(c, icmd.Success)
-	icmd.RunCommand("mount", "--make-private", "--make-shared", tmpDir).Assert(c, icmd.Success)
-
-	dockerCmd(c, "run", "-i", "-d", "--name", "parent", "-v", fmt.Sprintf("%s:/volume-dest:slave", tmpDir), "busybox", "top")
-
-	// Bind mount tmpDir2/ onto tmpDir/mnt1. If mount propagates inside
-	// container then contents of tmpDir2/slave-testfile should become
-	// visible at "/volume-dest/mnt1/slave-testfile"
-	icmd.RunCommand("mount", "--bind", tmpDir2, path.Join(tmpDir, "mnt1")).Assert(c, icmd.Success)
-
-	out, _ := dockerCmd(c, "exec", "parent", "cat", "/volume-dest/mnt1/slave-testfile")
-
-	mount.Unmount(path.Join(tmpDir, "mnt1"))
-
-	if out != "Test" {
-		c.Fatalf("Bind mount under slave volume did not propagate to container")
-	}
-}
-
 func (s *DockerSuite) TestRunNamedVolumesMountedAsShared(c *testing.T) {
 	testRequires(c, DaemonIsLinux, NotUserNamespace)
 	out, exitCode, _ := dockerCmdWithError("run", "-v", "foo:/test:shared", "busybox", "touch", "/test/somefile")

+ 125 - 0
integration/container/mounts_linux_test.go

@@ -16,6 +16,7 @@ import (
 	"github.com/docker/docker/integration/internal/container"
 	"github.com/docker/docker/pkg/system"
 	"github.com/moby/sys/mount"
+	"github.com/moby/sys/mountinfo"
 	"gotest.tools/v3/assert"
 	is "gotest.tools/v3/assert/cmp"
 	"gotest.tools/v3/fs"
@@ -266,3 +267,127 @@ func TestContainerBindMountNonRecursive(t *testing.T) {
 		poll.WaitOn(t, container.IsSuccessful(ctx, client, c), poll.WithDelay(100*time.Millisecond))
 	}
 }
+
+func TestContainerVolumesMountedAsShared(t *testing.T) {
+	// Volume propagation is linux only. Also it creates directories for
+	// bind mounting, so needs to be same host.
+	skip.If(t, testEnv.IsRemoteDaemon)
+	skip.If(t, testEnv.IsUserNamespace)
+	skip.If(t, testEnv.IsRootless, "cannot be tested because RootlessKit executes the daemon in private mount namespace (https://github.com/rootless-containers/rootlesskit/issues/97)")
+
+	defer setupTest(t)()
+
+	// Prepare a source directory to bind mount
+	tmpDir1 := fs.NewDir(t, "volume-source", fs.WithMode(0755),
+		fs.WithDir("mnt1", fs.WithMode(0755)))
+	defer tmpDir1.Remove()
+	tmpDir1Mnt := filepath.Join(tmpDir1.Path(), "mnt1")
+
+	// Convert this directory into a shared mount point so that we do
+	// not rely on propagation properties of parent mount.
+	if err := mount.Mount(tmpDir1.Path(), tmpDir1.Path(), "none", "bind,private"); err != nil {
+		t.Fatal(err)
+	}
+	defer func() {
+		if err := mount.Unmount(tmpDir1.Path()); err != nil {
+			t.Fatal(err)
+		}
+	}()
+	if err := mount.Mount("none", tmpDir1.Path(), "none", "shared"); err != nil {
+		t.Fatal(err)
+	}
+
+	sharedMount := mounttypes.Mount{
+		Type:   mounttypes.TypeBind,
+		Source: tmpDir1.Path(),
+		Target: "/volume-dest",
+		BindOptions: &mounttypes.BindOptions{
+			Propagation: mounttypes.PropagationShared,
+		},
+	}
+
+	bindMountCmd := []string{"mount", "--bind", "/volume-dest/mnt1", "/volume-dest/mnt1"}
+
+	ctx := context.Background()
+	client := testEnv.APIClient()
+	containerID := container.Run(ctx, t, client, container.WithPrivileged(true), container.WithMount(sharedMount), container.WithCmd(bindMountCmd...))
+	poll.WaitOn(t, container.IsSuccessful(ctx, client, containerID), poll.WithDelay(100*time.Millisecond))
+
+	// Make sure a bind mount under a shared volume propagated to host.
+	if mounted, _ := mountinfo.Mounted(tmpDir1Mnt); !mounted {
+		t.Fatalf("Bind mount under shared volume did not propagate to host")
+	}
+
+	mount.Unmount(tmpDir1Mnt)
+}
+
+func TestContainerVolumesMountedAsSlave(t *testing.T) {
+	// Volume propagation is linux only. Also it creates directories for
+	// bind mounting, so needs to be same host.
+	skip.If(t, testEnv.IsRemoteDaemon)
+	skip.If(t, testEnv.IsUserNamespace)
+	skip.If(t, testEnv.IsRootless, "cannot be tested because RootlessKit executes the daemon in private mount namespace (https://github.com/rootless-containers/rootlesskit/issues/97)")
+
+	// Prepare a source directory to bind mount
+	tmpDir1 := fs.NewDir(t, "volume-source", fs.WithMode(0755),
+		fs.WithDir("mnt1", fs.WithMode(0755)))
+	defer tmpDir1.Remove()
+	tmpDir1Mnt := filepath.Join(tmpDir1.Path(), "mnt1")
+
+	// Prepare a source directory with file in it. We will bind mount this
+	// directory and see if file shows up.
+	tmpDir2 := fs.NewDir(t, "volume-source2", fs.WithMode(0755),
+		fs.WithFile("slave-testfile", "Test", fs.WithMode(0644)))
+	defer tmpDir2.Remove()
+
+	// Convert this directory into a shared mount point so that we do
+	// not rely on propagation properties of parent mount.
+	if err := mount.Mount(tmpDir1.Path(), tmpDir1.Path(), "none", "bind,private"); err != nil {
+		t.Fatal(err)
+	}
+	defer func() {
+		if err := mount.Unmount(tmpDir1.Path()); err != nil {
+			t.Fatal(err)
+		}
+	}()
+	if err := mount.Mount("none", tmpDir1.Path(), "none", "shared"); err != nil {
+		t.Fatal(err)
+	}
+
+	slaveMount := mounttypes.Mount{
+		Type:   mounttypes.TypeBind,
+		Source: tmpDir1.Path(),
+		Target: "/volume-dest",
+		BindOptions: &mounttypes.BindOptions{
+			Propagation: mounttypes.PropagationSlave,
+		},
+	}
+
+	topCmd := []string{"top"}
+
+	ctx := context.Background()
+	client := testEnv.APIClient()
+	containerID := container.Run(ctx, t, client, container.WithTty(true), container.WithMount(slaveMount), container.WithCmd(topCmd...))
+
+	// Bind mount tmpDir2/ onto tmpDir1/mnt1. If mount propagates inside
+	// container then contents of tmpDir2/slave-testfile should become
+	// visible at "/volume-dest/mnt1/slave-testfile"
+	if err := mount.Mount(tmpDir2.Path(), tmpDir1Mnt, "none", "bind"); err != nil {
+		t.Fatal(err)
+	}
+	defer func() {
+		if err := mount.Unmount(tmpDir1Mnt); err != nil {
+			t.Fatal(err)
+		}
+	}()
+
+	mountCmd := []string{"cat", "/volume-dest/mnt1/slave-testfile"}
+
+	if result, err := container.Exec(ctx, client, containerID, mountCmd); err == nil {
+		if result.Stdout() != "Test" {
+			t.Fatalf("Bind mount under slave volume did not propagate to container")
+		}
+	} else {
+		t.Fatal(err)
+	}
+}

+ 0 - 43
pkg/mount/deprecated.go

@@ -4,52 +4,9 @@ package mount // import "github.com/docker/docker/pkg/mount"
 // Use github.com/moby/sys/mount and github.com/moby/sys/mountinfo instead.
 
 import (
-	sysmount "github.com/moby/sys/mount"
 	"github.com/moby/sys/mountinfo"
 )
 
-// Deprecated: use github.com/moby/sys/mount instead.
-//nolint:golint
-var (
-	Mount            = sysmount.Mount
-	ForceMount       = sysmount.Mount // a deprecated synonym
-	Unmount          = sysmount.Unmount
-	RecursiveUnmount = sysmount.RecursiveUnmount
-)
-
-// Deprecated: use github.com/moby/sys/mount instead.
-//nolint:golint
-const (
-	RDONLY      = sysmount.RDONLY
-	NOSUID      = sysmount.NOSUID
-	NOEXEC      = sysmount.NOEXEC
-	SYNCHRONOUS = sysmount.SYNCHRONOUS
-	NOATIME     = sysmount.NOATIME
-	BIND        = sysmount.BIND
-	DIRSYNC     = sysmount.DIRSYNC
-	MANDLOCK    = sysmount.MANDLOCK
-	NODEV       = sysmount.NODEV
-	NODIRATIME  = sysmount.NODIRATIME
-	UNBINDABLE  = sysmount.UNBINDABLE
-	RUNBINDABLE = sysmount.RUNBINDABLE
-	PRIVATE     = sysmount.PRIVATE
-	RPRIVATE    = sysmount.RPRIVATE
-	SHARED      = sysmount.SHARED
-	RSHARED     = sysmount.RSHARED
-	SLAVE       = sysmount.SLAVE
-	RSLAVE      = sysmount.RSLAVE
-	RBIND       = sysmount.RBIND
-	RELATIME    = sysmount.RELATIME
-	REMOUNT     = sysmount.REMOUNT
-	STRICTATIME = sysmount.STRICTATIME
-)
-
-// Deprecated: use github.com/moby/sys/mount instead.
-//nolint:golint
-var (
-	MergeTmpfsOptions = sysmount.MergeTmpfsOptions
-)
-
 //nolint:golint
 type (
 	// FilterFunc is a type.

+ 52 - 0
pkg/mount/deprecated_unix.go

@@ -0,0 +1,52 @@
+// +build !darwin,!windows
+
+package mount // import "github.com/docker/docker/pkg/mount"
+
+// Deprecated: this package is not maintained and will be removed.
+// Use github.com/moby/sys/mount and github.com/moby/sys/mountinfo instead.
+
+import (
+	sysmount "github.com/moby/sys/mount"
+)
+
+// Deprecated: use github.com/moby/sys/mount instead.
+//nolint:golint
+var (
+	Mount            = sysmount.Mount
+	ForceMount       = sysmount.Mount // a deprecated synonym
+	Unmount          = sysmount.Unmount
+	RecursiveUnmount = sysmount.RecursiveUnmount
+)
+
+// Deprecated: use github.com/moby/sys/mount instead.
+//nolint:golint
+const (
+	RDONLY      = sysmount.RDONLY
+	NOSUID      = sysmount.NOSUID
+	NOEXEC      = sysmount.NOEXEC
+	SYNCHRONOUS = sysmount.SYNCHRONOUS
+	NOATIME     = sysmount.NOATIME
+	BIND        = sysmount.BIND
+	DIRSYNC     = sysmount.DIRSYNC
+	MANDLOCK    = sysmount.MANDLOCK
+	NODEV       = sysmount.NODEV
+	NODIRATIME  = sysmount.NODIRATIME
+	UNBINDABLE  = sysmount.UNBINDABLE
+	RUNBINDABLE = sysmount.RUNBINDABLE
+	PRIVATE     = sysmount.PRIVATE
+	RPRIVATE    = sysmount.RPRIVATE
+	SHARED      = sysmount.SHARED
+	RSHARED     = sysmount.RSHARED
+	SLAVE       = sysmount.SLAVE
+	RSLAVE      = sysmount.RSLAVE
+	RBIND       = sysmount.RBIND
+	RELATIME    = sysmount.RELATIME
+	REMOUNT     = sysmount.REMOUNT
+	STRICTATIME = sysmount.STRICTATIME
+)
+
+// Deprecated: use github.com/moby/sys/mount instead.
+//nolint:golint
+var (
+	MergeTmpfsOptions = sysmount.MergeTmpfsOptions
+)

+ 0 - 50
pkg/system/rm_test.go

@@ -2,14 +2,7 @@ package system // import "github.com/docker/docker/pkg/system"
 
 import (
 	"io/ioutil"
-	"os"
-	"path/filepath"
-	"runtime"
 	"testing"
-	"time"
-
-	"github.com/moby/sys/mount"
-	"gotest.tools/v3/skip"
 )
 
 func TestEnsureRemoveAllNotExist(t *testing.T) {
@@ -39,46 +32,3 @@ func TestEnsureRemoveAllWithFile(t *testing.T) {
 		t.Fatal(err)
 	}
 }
-
-func TestEnsureRemoveAllWithMount(t *testing.T) {
-	skip.If(t, runtime.GOOS == "windows", "mount not supported on Windows")
-	skip.If(t, os.Getuid() != 0, "skipping test that requires root")
-
-	dir1, err := ioutil.TempDir("", "test-ensure-removeall-with-dir1")
-	if err != nil {
-		t.Fatal(err)
-	}
-	dir2, err := ioutil.TempDir("", "test-ensure-removeall-with-dir2")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(dir2)
-
-	bindDir := filepath.Join(dir1, "bind")
-	if err := os.MkdirAll(bindDir, 0755); err != nil {
-		t.Fatal(err)
-	}
-
-	if err := mount.Mount(dir2, bindDir, "none", "bind"); err != nil {
-		t.Fatal(err)
-	}
-
-	done := make(chan struct{}, 1)
-	go func() {
-		err = EnsureRemoveAll(dir1)
-		close(done)
-	}()
-
-	select {
-	case <-done:
-		if err != nil {
-			t.Fatal(err)
-		}
-	case <-time.After(5 * time.Second):
-		t.Fatal("timeout waiting for EnsureRemoveAll to finish")
-	}
-
-	if _, err := os.Stat(dir1); !os.IsNotExist(err) {
-		t.Fatalf("expected %q to not exist", dir1)
-	}
-}

+ 58 - 0
pkg/system/rm_unix_test.go

@@ -0,0 +1,58 @@
+// +build !windows
+
+package system // import "github.com/docker/docker/pkg/system"
+
+import (
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"runtime"
+	"testing"
+	"time"
+
+	"github.com/moby/sys/mount"
+	"gotest.tools/v3/skip"
+)
+
+func TestEnsureRemoveAllWithMount(t *testing.T) {
+	skip.If(t, runtime.GOOS == "windows", "mount not supported on Windows")
+	skip.If(t, os.Getuid() != 0, "skipping test that requires root")
+
+	dir1, err := ioutil.TempDir("", "test-ensure-removeall-with-dir1")
+	if err != nil {
+		t.Fatal(err)
+	}
+	dir2, err := ioutil.TempDir("", "test-ensure-removeall-with-dir2")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dir2)
+
+	bindDir := filepath.Join(dir1, "bind")
+	if err := os.MkdirAll(bindDir, 0755); err != nil {
+		t.Fatal(err)
+	}
+
+	if err := mount.Mount(dir2, bindDir, "none", "bind"); err != nil {
+		t.Fatal(err)
+	}
+
+	done := make(chan struct{}, 1)
+	go func() {
+		err = EnsureRemoveAll(dir1)
+		close(done)
+	}()
+
+	select {
+	case <-done:
+		if err != nil {
+			t.Fatal(err)
+		}
+	case <-time.After(5 * time.Second):
+		t.Fatal("timeout waiting for EnsureRemoveAll to finish")
+	}
+
+	if _, err := os.Stat(dir1); !os.IsNotExist(err) {
+		t.Fatalf("expected %q to not exist", dir1)
+	}
+}