Merge pull request #229 from thaJeztah/19.03_backport_windows_tag
[19.03 backport] Consider WINDOWS_BASE_IMAGE_TAG override when setting Windows base image for tests
diff --git a/api/swagger.yaml b/api/swagger.yaml
index 76d2150..fb980dd 100644
--- a/api/swagger.yaml
+++ b/api/swagger.yaml
@@ -463,10 +463,6 @@
type: "array"
items:
$ref: "#/definitions/DeviceRequest"
- DiskQuota:
- description: "Disk limit (in bytes)."
- type: "integer"
- format: "int64"
KernelMemory:
description: "Kernel memory limit in bytes."
type: "integer"
@@ -1145,6 +1141,7 @@
type: "object"
additionalProperties:
type: "array"
+ x-nullable: true
items:
$ref: "#/definitions/PortBinding"
example:
@@ -1169,7 +1166,6 @@
PortBinding represents a binding between a host IP address and a host
port.
type: "object"
- x-nullable: true
properties:
HostIp:
description: "Host IP address that the container's port is mapped to."
@@ -5466,7 +5462,7 @@
/containers/{id}/resize:
post:
summary: "Resize a container TTY"
- description: "Resize the TTY for a container. You must restart the container for the resize to take effect."
+ description: "Resize the TTY for a container."
operationId: "ContainerResize"
consumes:
- "application/octet-stream"
@@ -9110,7 +9106,9 @@
type: "string"
RemoteAddrs:
description: "Addresses of manager nodes already participating in the swarm."
- type: "string"
+ type: "array"
+ items:
+ type: "string"
JoinToken:
description: "Secret token for joining this swarm."
type: "string"
diff --git a/api/templates/server/operation.gotmpl b/api/templates/server/operation.gotmpl
index cf24aac..dbcecaf 100644
--- a/api/templates/server/operation.gotmpl
+++ b/api/templates/server/operation.gotmpl
@@ -1,4 +1,4 @@
-package {{ .Package }}
+package {{ .Package }} // import "github.com/docker/docker/api/types/{{ .Package }}"
// ----------------------------------------------------------------------------
// DO NOT EDIT THIS FILE
diff --git a/api/types/container/container_changes.go b/api/types/container/container_changes.go
index c909d6c..222d141 100644
--- a/api/types/container/container_changes.go
+++ b/api/types/container/container_changes.go
@@ -1,4 +1,4 @@
-package container
+package container // import "github.com/docker/docker/api/types/container"
// ----------------------------------------------------------------------------
// DO NOT EDIT THIS FILE
diff --git a/api/types/container/container_create.go b/api/types/container/container_create.go
index 49efa0f..1ec9c37 100644
--- a/api/types/container/container_create.go
+++ b/api/types/container/container_create.go
@@ -1,4 +1,4 @@
-package container
+package container // import "github.com/docker/docker/api/types/container"
// ----------------------------------------------------------------------------
// DO NOT EDIT THIS FILE
diff --git a/api/types/container/container_top.go b/api/types/container/container_top.go
index ba41edc..f8a6066 100644
--- a/api/types/container/container_top.go
+++ b/api/types/container/container_top.go
@@ -1,4 +1,4 @@
-package container
+package container // import "github.com/docker/docker/api/types/container"
// ----------------------------------------------------------------------------
// DO NOT EDIT THIS FILE
diff --git a/api/types/container/container_update.go b/api/types/container/container_update.go
index 7630ae5..33added 100644
--- a/api/types/container/container_update.go
+++ b/api/types/container/container_update.go
@@ -1,4 +1,4 @@
-package container
+package container // import "github.com/docker/docker/api/types/container"
// ----------------------------------------------------------------------------
// DO NOT EDIT THIS FILE
diff --git a/api/types/container/container_wait.go b/api/types/container/container_wait.go
index 9e3910a..94b6a20 100644
--- a/api/types/container/container_wait.go
+++ b/api/types/container/container_wait.go
@@ -1,4 +1,4 @@
-package container
+package container // import "github.com/docker/docker/api/types/container"
// ----------------------------------------------------------------------------
// DO NOT EDIT THIS FILE
diff --git a/api/types/container/host_config.go b/api/types/container/host_config.go
index c710107..c3de3d9 100644
--- a/api/types/container/host_config.go
+++ b/api/types/container/host_config.go
@@ -338,7 +338,6 @@
Devices []DeviceMapping // List of devices to map inside the container
DeviceCgroupRules []string // List of rule to be added to the device cgroup
DeviceRequests []DeviceRequest // List of device requests for device drivers
- DiskQuota int64 // Disk limit (in bytes)
KernelMemory int64 // Kernel memory limit (in bytes)
KernelMemoryTCP int64 // Hard limit for kernel TCP buffer memory (in bytes)
MemoryReservation int64 // Memory soft limit (in bytes)
diff --git a/api/types/image/image_history.go b/api/types/image/image_history.go
index d6b354b..b5a7a0c 100644
--- a/api/types/image/image_history.go
+++ b/api/types/image/image_history.go
@@ -1,4 +1,4 @@
-package image
+package image // import "github.com/docker/docker/api/types/image"
// ----------------------------------------------------------------------------
// DO NOT EDIT THIS FILE
diff --git a/api/types/volume/volume_create.go b/api/types/volume/volume_create.go
index f12e486..0c3772d 100644
--- a/api/types/volume/volume_create.go
+++ b/api/types/volume/volume_create.go
@@ -1,4 +1,4 @@
-package volume
+package volume // import "github.com/docker/docker/api/types/volume"
// ----------------------------------------------------------------------------
// DO NOT EDIT THIS FILE
diff --git a/api/types/volume/volume_list.go b/api/types/volume/volume_list.go
index 020198f..45c3c1c 100644
--- a/api/types/volume/volume_list.go
+++ b/api/types/volume/volume_list.go
@@ -1,4 +1,4 @@
-package volume
+package volume // import "github.com/docker/docker/api/types/volume"
// ----------------------------------------------------------------------------
// DO NOT EDIT THIS FILE
diff --git a/builder/builder-next/executor_unix.go b/builder/builder-next/executor_unix.go
index 132b928..620ffb4 100644
--- a/builder/builder-next/executor_unix.go
+++ b/builder/builder-next/executor_unix.go
@@ -31,6 +31,7 @@
CommandCandidates: []string{"runc"},
DefaultCgroupParent: cgroupParent,
Rootless: rootless,
+ NoPivot: os.Getenv("DOCKER_RAMDISK") != "",
}, networkProviders)
}
diff --git a/client/ping.go b/client/ping.go
index 4553e0f..90f39ec 100644
--- a/client/ping.go
+++ b/client/ping.go
@@ -31,6 +31,8 @@
// Server handled the request, so parse the response
return parsePingResponse(cli, serverResp)
}
+ } else if IsErrConnectionFailed(err) {
+ return ping, err
}
req, err = cli.buildRequest("GET", path.Join(cli.basePath, "/_ping"), nil, nil)
diff --git a/container/container_windows.go b/container/container_windows.go
index 181750b..719caca 100644
--- a/container/container_windows.go
+++ b/container/container_windows.go
@@ -153,7 +153,6 @@
resources.CpusetMems != "" ||
len(resources.Devices) != 0 ||
len(resources.DeviceCgroupRules) != 0 ||
- resources.DiskQuota != 0 ||
resources.KernelMemory != 0 ||
resources.MemoryReservation != 0 ||
resources.MemorySwap != 0 ||
diff --git a/contrib/dockerd-rootless.sh b/contrib/dockerd-rootless.sh
index 3206134..214162f 100755
--- a/contrib/dockerd-rootless.sh
+++ b/contrib/dockerd-rootless.sh
@@ -75,7 +75,7 @@
# namespace from being unexpectedly unmounted when `/etc/resolv.conf` is recreated on the host
# (by either systemd-networkd or NetworkManager)
# * /run: copy-up is required so that we can create /run/docker (hardcoded for plugins) in our namespace
- $rootlesskit \
+ exec $rootlesskit \
--net=$net --mtu=$mtu \
--disable-host-loopback --port-driver=builtin \
--copy-up=/etc --copy-up=/run \
@@ -86,5 +86,5 @@
# remove the symlinks for the existing files in the parent namespace if any,
# so that we can create our own files in our mount namespace.
rm -f /run/docker /run/xtables.lock
- dockerd $@
+ exec dockerd $@
fi
diff --git a/daemon/cluster/executor/container/container.go b/daemon/cluster/executor/container/container.go
index abbd6bf..a768d9d 100644
--- a/daemon/cluster/executor/container/container.go
+++ b/daemon/cluster/executor/container/container.go
@@ -6,7 +6,6 @@
"net"
"strconv"
"strings"
- "time"
"github.com/sirupsen/logrus"
@@ -31,10 +30,6 @@
)
const (
- // Explicitly use the kernel's default setting for CPU quota of 100ms.
- // https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt
- cpuQuotaPeriod = 100 * time.Millisecond
-
// systemLabelPrefix represents the reserved namespace for system labels.
systemLabelPrefix = "com.docker.swarm"
)
@@ -451,9 +446,7 @@
}
if r.Limits.NanoCPUs > 0 {
- // CPU Period must be set in microseconds.
- resources.CPUPeriod = int64(cpuQuotaPeriod / time.Microsecond)
- resources.CPUQuota = r.Limits.NanoCPUs * resources.CPUPeriod / 1e9
+ resources.NanoCPUs = r.Limits.NanoCPUs
}
return resources
diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go
index ec53ab0..3d0c38b 100644
--- a/daemon/daemon_unix.go
+++ b/daemon/daemon_unix.go
@@ -191,8 +191,8 @@
}
weight := weightDevice.Weight
d := specs.LinuxWeightDevice{Weight: &weight}
- d.Major = int64(stat.Rdev / 256)
- d.Minor = int64(stat.Rdev % 256)
+ d.Major = int64(unix.Major(stat.Rdev))
+ d.Minor = int64(unix.Minor(stat.Rdev))
blkioWeightDevices = append(blkioWeightDevices, d)
}
@@ -262,8 +262,8 @@
return nil, err
}
d := specs.LinuxThrottleDevice{Rate: d.Rate}
- d.Major = int64(stat.Rdev / 256)
- d.Minor = int64(stat.Rdev % 256)
+ d.Major = int64(unix.Major(stat.Rdev))
+ d.Minor = int64(unix.Minor(stat.Rdev))
throttleDevices = append(throttleDevices, d)
}
diff --git a/daemon/daemon_unix_test.go b/daemon/daemon_unix_test.go
index c8575ad..c884681 100644
--- a/daemon/daemon_unix_test.go
+++ b/daemon/daemon_unix_test.go
@@ -6,12 +6,15 @@
"errors"
"io/ioutil"
"os"
+ "path/filepath"
"testing"
+ "github.com/docker/docker/api/types/blkiodev"
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/container"
"github.com/docker/docker/daemon/config"
"github.com/docker/docker/pkg/sysinfo"
+ "golang.org/x/sys/unix"
"gotest.tools/assert"
is "gotest.tools/assert/cmp"
)
@@ -376,3 +379,61 @@
}
return si
}
+
+const (
+ // prepare major 0x1FD(509 in decimal) and minor 0x130(304)
+ DEVNO = 0x11FD30
+ MAJOR = 509
+ MINOR = 304
+ WEIGHT = 1024
+)
+
+func deviceTypeMock(t *testing.T, testAndCheck func(string)) {
+ if os.Getuid() != 0 {
+ t.Skip("root required") // for mknod
+ }
+
+ t.Parallel()
+
+ tempDir, err := ioutil.TempDir("", "tempDevDir"+t.Name())
+ assert.NilError(t, err, "create temp file")
+ tempFile := filepath.Join(tempDir, "dev")
+
+ defer os.RemoveAll(tempDir)
+
+ if err = unix.Mknod(tempFile, unix.S_IFCHR, DEVNO); err != nil {
+ t.Fatalf("mknod error %s(%x): %v", tempFile, DEVNO, err)
+ }
+
+ testAndCheck(tempFile)
+}
+
+func TestGetBlkioWeightDevices(t *testing.T) {
+ deviceTypeMock(t, func(tempFile string) {
+ mockResource := containertypes.Resources{
+ BlkioWeightDevice: []*blkiodev.WeightDevice{{Path: tempFile, Weight: WEIGHT}},
+ }
+
+ weightDevs, err := getBlkioWeightDevices(mockResource)
+
+ assert.NilError(t, err, "getBlkioWeightDevices")
+ assert.Check(t, is.Len(weightDevs, 1), "getBlkioWeightDevices")
+ assert.Check(t, weightDevs[0].Major == MAJOR, "get major device type")
+ assert.Check(t, weightDevs[0].Minor == MINOR, "get minor device type")
+ assert.Check(t, *weightDevs[0].Weight == WEIGHT, "get device weight")
+ })
+}
+
+func TestGetBlkioThrottleDevices(t *testing.T) {
+ deviceTypeMock(t, func(tempFile string) {
+ mockDevs := []*blkiodev.ThrottleDevice{{Path: tempFile, Rate: WEIGHT}}
+
+ retDevs, err := getBlkioThrottleDevices(mockDevs)
+
+ assert.NilError(t, err, "getBlkioThrottleDevices")
+ assert.Check(t, is.Len(retDevs, 1), "getBlkioThrottleDevices")
+ assert.Check(t, retDevs[0].Major == MAJOR, "get major device type")
+ assert.Check(t, retDevs[0].Minor == MINOR, "get minor device type")
+ assert.Check(t, retDevs[0].Rate == WEIGHT, "get device rate")
+ })
+}
diff --git a/hack/dockerfile/install/proxy.installer b/hack/dockerfile/install/proxy.installer
index f419693..65ebeba 100755
--- a/hack/dockerfile/install/proxy.installer
+++ b/hack/dockerfile/install/proxy.installer
@@ -3,7 +3,7 @@
# LIBNETWORK_COMMIT is used to build the docker-userland-proxy binary. When
# updating the binary version, consider updating github.com/docker/libnetwork
# in vendor.conf accordingly
-LIBNETWORK_COMMIT=9ff9b57c344df5cd47443ad9e65702ec85c5aeb0
+LIBNETWORK_COMMIT=5ac07abef4eee176423fdc1b870d435258e2d381
install_proxy() {
case "$1" in
diff --git a/hack/dockerfile/install/rootlesskit.installer b/hack/dockerfile/install/rootlesskit.installer
index 7872640..912f1cf 100755
--- a/hack/dockerfile/install/rootlesskit.installer
+++ b/hack/dockerfile/install/rootlesskit.installer
@@ -1,7 +1,7 @@
#!/bin/sh
-# v0.4.0
-ROOTLESSKIT_COMMIT=e92d5e772ee7e103aecf380c5874a40c52876ff0
+# v0.4.1
+ROOTLESSKIT_COMMIT=27a0c7a2483732b33d4192c1d178c83c6b9e202d
install_rootlesskit() {
case "$1" in
diff --git a/integration-cli/docker_cli_daemon_test.go b/integration-cli/docker_cli_daemon_test.go
index a2c8896..c9e88fa 100644
--- a/integration-cli/docker_cli_daemon_test.go
+++ b/integration-cli/docker_cli_daemon_test.go
@@ -1715,7 +1715,7 @@
dockerCmd(c, "run", "--rm", "-v", testDir+":/test", "busybox", "sh", "-c", "dd of=/test/testfs.img bs=1M seek=3 count=0")
icmd.RunCommand("mkfs.ext4", "-F", filepath.Join(testDir, "testfs.img")).Assert(c, icmd.Success)
- dockerCmd(c, "run", "--privileged", "--rm", "-v", testDir+":/test:shared", "busybox", "sh", "-c", "mkdir -p /test/test-mount/vfs && mount -n /test/testfs.img /test/test-mount/vfs")
+ dockerCmd(c, "run", "--privileged", "--rm", "-v", testDir+":/test:shared", "busybox", "sh", "-c", "mkdir -p /test/test-mount/vfs && mount -n -t ext4 /test/testfs.img /test/test-mount/vfs")
defer mount.Unmount(filepath.Join(testDir, "test-mount"))
s.d.Start(c, "--storage-driver", "vfs", "--data-root", filepath.Join(testDir, "test-mount"))
diff --git a/integration-cli/docker_cli_run_unix_test.go b/integration-cli/docker_cli_run_unix_test.go
index e1c501e..67d6a9a 100644
--- a/integration-cli/docker_cli_run_unix_test.go
+++ b/integration-cli/docker_cli_run_unix_test.go
@@ -1544,6 +1544,10 @@
{
"name": "chmod",
"action": "SCMP_ACT_ERRNO"
+ },
+ {
+ "name": "fchmodat",
+ "action": "SCMP_ACT_ERRNO"
}
]
}`
diff --git a/integration-cli/docker_cli_search_test.go b/integration-cli/docker_cli_search_test.go
index 2f811d4..95ad9ce 100644
--- a/integration-cli/docker_cli_search_test.go
+++ b/integration-cli/docker_cli_search_test.go
@@ -44,54 +44,6 @@
assert.Assert(c, strings.Contains(out, "invalid syntax"), "couldn't find the invalid value warning")
}
-func (s *DockerSuite) TestSearchCmdOptions(c *check.C) {
- testRequires(c, Network, DaemonIsLinux)
-
- out, _ := dockerCmd(c, "search", "--help")
- assert.Assert(c, strings.Contains(out, "Usage:\tdocker search [OPTIONS] TERM"))
-
- outSearchCmd, _ := dockerCmd(c, "search", "busybox")
- outSearchCmdNotrunc, _ := dockerCmd(c, "search", "--no-trunc=true", "busybox")
-
- assert.Assert(c, len(outSearchCmd) <= len(outSearchCmdNotrunc), "The no-trunc option can't take effect.")
-
- outSearchCmdautomated, _ := dockerCmd(c, "search", "--filter", "is-automated=true", "busybox") //The busybox is a busybox base image, not an AUTOMATED image.
- outSearchCmdautomatedSlice := strings.Split(outSearchCmdautomated, "\n")
- for i := range outSearchCmdautomatedSlice {
- assert.Assert(c, !strings.HasPrefix(outSearchCmdautomatedSlice[i], "busybox "), "The busybox is not an AUTOMATED image: %s", outSearchCmdautomated)
- }
-
- outSearchCmdNotOfficial, _ := dockerCmd(c, "search", "--filter", "is-official=false", "busybox") //The busybox is a busybox base image, official image.
- outSearchCmdNotOfficialSlice := strings.Split(outSearchCmdNotOfficial, "\n")
- for i := range outSearchCmdNotOfficialSlice {
- assert.Assert(c, !strings.HasPrefix(outSearchCmdNotOfficialSlice[i], "busybox "), "The busybox is not an OFFICIAL image: %s", outSearchCmdNotOfficial)
- }
-
- outSearchCmdOfficial, _ := dockerCmd(c, "search", "--filter", "is-official=true", "busybox") //The busybox is a busybox base image, official image.
- outSearchCmdOfficialSlice := strings.Split(outSearchCmdOfficial, "\n")
- assert.Equal(c, len(outSearchCmdOfficialSlice), 3) // 1 header, 1 line, 1 carriage return
- assert.Assert(c, strings.HasPrefix(outSearchCmdOfficialSlice[1], "busybox "), "The busybox is an OFFICIAL image: %s", outSearchCmdOfficial)
-
- outSearchCmdStars, _ := dockerCmd(c, "search", "--filter", "stars=2", "busybox")
- assert.Assert(c, strings.Count(outSearchCmdStars, "[OK]") <= strings.Count(outSearchCmd, "[OK]"), "The quantity of images with stars should be less than that of all images: %s", outSearchCmdStars)
-
- dockerCmd(c, "search", "--filter", "is-automated=true", "--filter", "stars=2", "--no-trunc=true", "busybox")
-
- // --automated deprecated since Docker 1.13
- outSearchCmdautomated1, _ := dockerCmd(c, "search", "--automated=true", "busybox") //The busybox is a busybox base image, not an AUTOMATED image.
- outSearchCmdautomatedSlice1 := strings.Split(outSearchCmdautomated1, "\n")
- for i := range outSearchCmdautomatedSlice1 {
- assert.Assert(c, !strings.HasPrefix(outSearchCmdautomatedSlice1[i], "busybox "), "The busybox is not an AUTOMATED image: %s", outSearchCmdautomated)
- }
-
- // -s --stars deprecated since Docker 1.13
- outSearchCmdStars1, _ := dockerCmd(c, "search", "--stars=2", "busybox")
- assert.Assert(c, strings.Count(outSearchCmdStars1, "[OK]") <= strings.Count(outSearchCmd, "[OK]"), "The quantity of images with stars should be less than that of all images: %s", outSearchCmdStars1)
-
- // -s --stars deprecated since Docker 1.13
- dockerCmd(c, "search", "--stars=2", "--automated=true", "--no-trunc=true", "busybox")
-}
-
// search for repos which start with "ubuntu-" on the central registry
func (s *DockerSuite) TestSearchOnCentralRegistryWithDash(c *check.C) {
testRequires(c, Network, DaemonIsLinux)
diff --git a/vendor.conf b/vendor.conf
index 0719a40..6b4df60 100644
--- a/vendor.conf
+++ b/vendor.conf
@@ -39,7 +39,7 @@
# libnetwork
# When updating, also update LIBNETWORK_COMMIT in hack/dockerfile/install/proxy.installer accordingly
-github.com/docker/libnetwork 9ff9b57c344df5cd47443ad9e65702ec85c5aeb0
+github.com/docker/libnetwork 5ac07abef4eee176423fdc1b870d435258e2d381
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
diff --git a/vendor/github.com/docker/libnetwork/drivers/windows/port_mapping.go b/vendor/github.com/docker/libnetwork/drivers/windows/port_mapping.go
index 51791fd..4ad25c1 100644
--- a/vendor/github.com/docker/libnetwork/drivers/windows/port_mapping.go
+++ b/vendor/github.com/docker/libnetwork/drivers/windows/port_mapping.go
@@ -48,6 +48,12 @@
err error
)
+ // Windows does not support a host ip for port bindings (this is validated in ConvertPortBindings()).
+ // If the HostIP is nil, force it to be 0.0.0.0 for use as the key in portMapper.
+ if bnd.HostIP == nil {
+ bnd.HostIP = net.IPv4zero
+ }
+
// Store the container interface address in the operational binding
bnd.IP = containerIP
diff --git a/vendor/github.com/docker/libnetwork/drivers/windows/windows.go b/vendor/github.com/docker/libnetwork/drivers/windows/windows.go
index c8ab047..b8a5f73 100644
--- a/vendor/github.com/docker/libnetwork/drivers/windows/windows.go
+++ b/vendor/github.com/docker/libnetwork/drivers/windows/windows.go
@@ -462,7 +462,7 @@
return nil, fmt.Errorf("Windows does not support more than one host port in NAT settings")
}
- if len(elem.HostIP) != 0 {
+ if len(elem.HostIP) != 0 && !elem.HostIP.IsUnspecified() {
return nil, fmt.Errorf("Windows does not support host IP addresses in NAT settings")
}
diff --git a/volume/mounts/linux_parser.go b/volume/mounts/linux_parser.go
index 035a24a..22ab2d6 100644
--- a/volume/mounts/linux_parser.go
+++ b/volume/mounts/linux_parser.go
@@ -82,7 +82,10 @@
}
if validateBindSourceExists {
- exists, _, _ := currentFileInfoProvider.fileInfo(mnt.Source)
+ exists, _, err := currentFileInfoProvider.fileInfo(mnt.Source)
+ if err != nil {
+ return &errMountConfig{mnt, err}
+ }
if !exists {
return &errMountConfig{mnt, errBindSourceDoesNotExist(mnt.Source)}
}
diff --git a/volume/mounts/parser_test.go b/volume/mounts/parser_test.go
index 27257d6..f9b32e5 100644
--- a/volume/mounts/parser_test.go
+++ b/volume/mounts/parser_test.go
@@ -1,6 +1,7 @@
package mounts // import "github.com/docker/docker/volume/mounts"
import (
+ "errors"
"io/ioutil"
"os"
"runtime"
@@ -8,6 +9,8 @@
"testing"
"github.com/docker/docker/api/types/mount"
+ "gotest.tools/assert"
+ "gotest.tools/assert/cmp"
)
type parseMountRawTestSet struct {
@@ -477,4 +480,51 @@
t.Errorf("Expected mount copy data to match. Expected: '%v', Actual: '%v'", c.expected.CopyData, mp.CopyData)
}
}
+
+}
+
+// always returns the configured error
+// this is used to test error handling
+type mockFiProviderWithError struct{ err error }
+
+func (m mockFiProviderWithError) fileInfo(path string) (bool, bool, error) {
+ return false, false, m.err
+}
+
+// TestParseMountSpecBindWithFileinfoError makes sure that the parser returns
+// the error produced by the fileinfo provider.
+//
+// Some extra context for the future in case of changes and possible wtf are we
+// testing this for:
+//
+// Currently this "fileInfoProvider" returns (bool, bool, error)
+// The 1st bool is "does this path exist"
+// The 2nd bool is "is this path a dir"
+// Then of course the error is an error.
+//
+// The issue is the parser was ignoring the error and only looking at the
+// "does this path exist" boolean, which is always false if there is an error.
+// Then the error returned to the caller was a (slightly, maybe) friendlier
+// error string than what comes from `os.Stat`
+// So ...the caller was always getting an error saying the path doesn't exist
+// even if it does exist but got some other error (like a permission error).
+// This is confusing to users.
+func TestParseMountSpecBindWithFileinfoError(t *testing.T) {
+ previousProvider := currentFileInfoProvider
+ defer func() { currentFileInfoProvider = previousProvider }()
+
+ testErr := errors.New("some crazy error")
+ currentFileInfoProvider = &mockFiProviderWithError{err: testErr}
+
+ p := "/bananas"
+ if runtime.GOOS == "windows" {
+ p = `c:\bananas`
+ }
+ m := mount.Mount{Type: mount.TypeBind, Source: p, Target: p}
+
+ parser := NewParser(runtime.GOOS)
+
+ _, err := parser.ParseMountSpec(m)
+ assert.Assert(t, err != nil)
+ assert.Assert(t, cmp.Contains(err.Error(), "some crazy error"))
}