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

Reinstate Windows CI Pipeline usefulness
This commit is contained in:
Sebastiaan van Stijn 2020-11-10 02:52:54 +01:00 committed by GitHub
commit 0e8023ddea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 251 additions and 181 deletions

View file

@ -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
}

View file

@ -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{
{

View file

@ -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)
}

View file

@ -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")
}

View file

@ -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")

View file

@ -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)
}
}

View file

@ -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.

View file

@ -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
)

View file

@ -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)
}
}

View file

@ -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)
}
}