Windows: Support RO volumes 14350+
| ... | ... |
@@ -3,6 +3,7 @@ package main |
| 3 | 3 |
import ( |
| 4 | 4 |
"encoding/json" |
| 5 | 5 |
"fmt" |
| 6 |
+ "os" |
|
| 6 | 7 |
"os/exec" |
| 7 | 8 |
"strconv" |
| 8 | 9 |
"strings" |
| ... | ... |
@@ -209,8 +210,19 @@ func (s *DockerSuite) TestInspectContainerGraphDriver(c *check.C) {
|
| 209 | 209 |
} |
| 210 | 210 |
|
| 211 | 211 |
func (s *DockerSuite) TestInspectBindMountPoint(c *check.C) {
|
| 212 |
- testRequires(c, DaemonIsLinux) |
|
| 213 |
- dockerCmd(c, "run", "-d", "--name", "test", "-v", "/data:/data:ro,z", "busybox", "cat") |
|
| 212 |
+ modifier := ",z" |
|
| 213 |
+ prefix, slash := getPrefixAndSlashFromDaemonPlatform() |
|
| 214 |
+ if daemonPlatform == "windows" {
|
|
| 215 |
+ modifier = "" |
|
| 216 |
+ // TODO Windows: Temporary check - remove once TP5 support is dropped |
|
| 217 |
+ if windowsDaemonKV < 14350 {
|
|
| 218 |
+ c.Skip("Needs later Windows build for RO volumes")
|
|
| 219 |
+ } |
|
| 220 |
+ // Linux creates the host directory if it doesn't exist. Windows does not. |
|
| 221 |
+ os.Mkdir(`c:\data`, os.ModeDir) |
|
| 222 |
+ } |
|
| 223 |
+ |
|
| 224 |
+ dockerCmd(c, "run", "-d", "--name", "test", "-v", prefix+slash+"data:"+prefix+slash+"data:ro"+modifier, "busybox", "cat") |
|
| 214 | 225 |
|
| 215 | 226 |
vol := inspectFieldJSON(c, "test", "Mounts") |
| 216 | 227 |
|
| ... | ... |
@@ -225,9 +237,9 @@ func (s *DockerSuite) TestInspectBindMountPoint(c *check.C) {
|
| 225 | 225 |
|
| 226 | 226 |
c.Assert(m.Name, checker.Equals, "") |
| 227 | 227 |
c.Assert(m.Driver, checker.Equals, "") |
| 228 |
- c.Assert(m.Source, checker.Equals, "/data") |
|
| 229 |
- c.Assert(m.Destination, checker.Equals, "/data") |
|
| 230 |
- c.Assert(m.Mode, checker.Equals, "ro,z") |
|
| 228 |
+ c.Assert(m.Source, checker.Equals, prefix+slash+"data") |
|
| 229 |
+ c.Assert(m.Destination, checker.Equals, prefix+slash+"data") |
|
| 230 |
+ c.Assert(m.Mode, checker.Equals, "ro"+modifier) |
|
| 231 | 231 |
c.Assert(m.RW, checker.Equals, false) |
| 232 | 232 |
} |
| 233 | 233 |
|
| ... | ... |
@@ -443,18 +443,20 @@ func (s *DockerSuite) TestRunCreateVolumesInSymlinkDir2(c *check.C) {
|
| 443 | 443 |
} |
| 444 | 444 |
|
| 445 | 445 |
func (s *DockerSuite) TestRunVolumesMountedAsReadonly(c *check.C) {
|
| 446 |
- // TODO Windows (Post TP5): This test cannot run on a Windows daemon as |
|
| 447 |
- // Windows does not support read-only bind mounts. |
|
| 448 |
- testRequires(c, DaemonIsLinux) |
|
| 446 |
+ // TODO Windows: Temporary check - remove once TP5 support is dropped |
|
| 447 |
+ if daemonPlatform == "windows" && windowsDaemonKV < 14350 {
|
|
| 448 |
+ c.Skip("Needs later Windows build for RO volumes")
|
|
| 449 |
+ } |
|
| 449 | 450 |
if _, code, err := dockerCmdWithError("run", "-v", "/test:/test:ro", "busybox", "touch", "/test/somefile"); err == nil || code == 0 {
|
| 450 | 451 |
c.Fatalf("run should fail because volume is ro: exit code %d", code)
|
| 451 | 452 |
} |
| 452 | 453 |
} |
| 453 | 454 |
|
| 454 | 455 |
func (s *DockerSuite) TestRunVolumesFromInReadonlyModeFails(c *check.C) {
|
| 455 |
- // TODO Windows (Post TP5): This test cannot run on a Windows daemon as |
|
| 456 |
- // Windows does not support read-only bind mounts. Modified for when ro is supported. |
|
| 457 |
- testRequires(c, DaemonIsLinux) |
|
| 456 |
+ // TODO Windows: Temporary check - remove once TP5 support is dropped |
|
| 457 |
+ if daemonPlatform == "windows" && windowsDaemonKV < 14350 {
|
|
| 458 |
+ c.Skip("Needs later Windows build for RO volumes")
|
|
| 459 |
+ } |
|
| 458 | 460 |
var ( |
| 459 | 461 |
volumeDir string |
| 460 | 462 |
fileInVol string |
| ... | ... |
@@ -499,20 +501,23 @@ func (s *DockerSuite) TestRunVolumesFromInReadWriteMode(c *check.C) {
|
| 499 | 499 |
} |
| 500 | 500 |
|
| 501 | 501 |
func (s *DockerSuite) TestVolumesFromGetsProperMode(c *check.C) {
|
| 502 |
- // TODO Windows: This test cannot yet run on a Windows daemon as Windows does |
|
| 503 |
- // not support read-only bind mounts as at TP5 |
|
| 504 |
- testRequires(c, DaemonIsLinux) |
|
| 505 |
- dockerCmd(c, "run", "--name", "parent", "-v", "/test:/test:ro", "busybox", "true") |
|
| 502 |
+ prefix, slash := getPrefixAndSlashFromDaemonPlatform() |
|
| 503 |
+ |
|
| 504 |
+ // TODO Windows: Temporary check - remove once TP5 support is dropped |
|
| 505 |
+ if daemonPlatform == "windows" && windowsDaemonKV < 14350 {
|
|
| 506 |
+ c.Skip("Needs later Windows build for RO volumes")
|
|
| 507 |
+ } |
|
| 508 |
+ dockerCmd(c, "run", "--name", "parent", "-v", prefix+slash+"test:"+prefix+slash+"test:ro", "busybox", "true") |
|
| 506 | 509 |
|
| 507 | 510 |
// Expect this "rw" mode to be be ignored since the inherited volume is "ro" |
| 508 |
- if _, _, err := dockerCmdWithError("run", "--volumes-from", "parent:rw", "busybox", "touch", "/test/file"); err == nil {
|
|
| 511 |
+ if _, _, err := dockerCmdWithError("run", "--volumes-from", "parent:rw", "busybox", "touch", prefix+slash+"test"+slash+"file"); err == nil {
|
|
| 509 | 512 |
c.Fatal("Expected volumes-from to inherit read-only volume even when passing in `rw`")
|
| 510 | 513 |
} |
| 511 | 514 |
|
| 512 |
- dockerCmd(c, "run", "--name", "parent2", "-v", "/test:/test:ro", "busybox", "true") |
|
| 515 |
+ dockerCmd(c, "run", "--name", "parent2", "-v", prefix+slash+"test:"+prefix+slash+"test:ro", "busybox", "true") |
|
| 513 | 516 |
|
| 514 | 517 |
// Expect this to be read-only since both are "ro" |
| 515 |
- if _, _, err := dockerCmdWithError("run", "--volumes-from", "parent2:ro", "busybox", "touch", "/test/file"); err == nil {
|
|
| 518 |
+ if _, _, err := dockerCmdWithError("run", "--volumes-from", "parent2:ro", "busybox", "touch", prefix+slash+"test"+slash+"file"); err == nil {
|
|
| 516 | 519 |
c.Fatal("Expected volumes-from to inherit read-only volume even when passing in `ro`")
|
| 517 | 520 |
} |
| 518 | 521 |
} |
| ... | ... |
@@ -1936,6 +1941,8 @@ func (s *DockerSuite) TestRunBindMounts(c *check.C) {
|
| 1936 | 1936 |
testRequires(c, DaemonIsLinux, NotUserNamespace) |
| 1937 | 1937 |
} |
| 1938 | 1938 |
|
| 1939 |
+ prefix, _ := getPrefixAndSlashFromDaemonPlatform() |
|
| 1940 |
+ |
|
| 1939 | 1941 |
tmpDir, err := ioutil.TempDir("", "docker-test-container")
|
| 1940 | 1942 |
if err != nil {
|
| 1941 | 1943 |
c.Fatal(err) |
| ... | ... |
@@ -1944,10 +1951,10 @@ func (s *DockerSuite) TestRunBindMounts(c *check.C) {
|
| 1944 | 1944 |
defer os.RemoveAll(tmpDir) |
| 1945 | 1945 |
writeFile(path.Join(tmpDir, "touch-me"), "", c) |
| 1946 | 1946 |
|
| 1947 |
- // TODO Windows Post TP5. Windows does not yet support :ro binds |
|
| 1948 |
- if daemonPlatform != "windows" {
|
|
| 1947 |
+ // TODO Windows: Temporary check - remove once TP5 support is dropped |
|
| 1948 |
+ if daemonPlatform != "windows" || windowsDaemonKV >= 14350 {
|
|
| 1949 | 1949 |
// Test reading from a read-only bind mount |
| 1950 |
- out, _ := dockerCmd(c, "run", "-v", fmt.Sprintf("%s:/tmp:ro", tmpDir), "busybox", "ls", "/tmp")
|
|
| 1950 |
+ out, _ := dockerCmd(c, "run", "-v", fmt.Sprintf("%s:%s/tmp:ro", tmpDir, prefix), "busybox", "ls", prefix+"/tmp")
|
|
| 1951 | 1951 |
if !strings.Contains(out, "touch-me") {
|
| 1952 | 1952 |
c.Fatal("Container failed to read from bind mount")
|
| 1953 | 1953 |
} |
| ... | ... |
@@ -3147,12 +3154,12 @@ func (s *DockerSuite) TestRunCapAddCHOWN(c *check.C) {
|
| 3147 | 3147 |
|
| 3148 | 3148 |
// https://github.com/docker/docker/pull/14498 |
| 3149 | 3149 |
func (s *DockerSuite) TestVolumeFromMixedRWOptions(c *check.C) {
|
| 3150 |
- // TODO Windows post TP5. Enable the read-only bits once they are |
|
| 3151 |
- // supported on the platform. |
|
| 3152 | 3150 |
prefix, slash := getPrefixAndSlashFromDaemonPlatform() |
| 3153 | 3151 |
|
| 3154 | 3152 |
dockerCmd(c, "run", "--name", "parent", "-v", prefix+"/test", "busybox", "true") |
| 3155 |
- if daemonPlatform != "windows" {
|
|
| 3153 |
+ |
|
| 3154 |
+ // TODO Windows: Temporary check - remove once TP5 support is dropped |
|
| 3155 |
+ if daemonPlatform != "windows" || windowsDaemonKV >= 14350 {
|
|
| 3156 | 3156 |
dockerCmd(c, "run", "--volumes-from", "parent:ro", "--name", "test-volumes-1", "busybox", "true") |
| 3157 | 3157 |
} |
| 3158 | 3158 |
dockerCmd(c, "run", "--volumes-from", "parent:rw", "--name", "test-volumes-2", "busybox", "true") |
| ... | ... |
@@ -8,6 +8,7 @@ import ( |
| 8 | 8 |
"strings" |
| 9 | 9 |
|
| 10 | 10 |
"github.com/Sirupsen/logrus" |
| 11 |
+ "github.com/docker/docker/pkg/system" |
|
| 11 | 12 |
) |
| 12 | 13 |
|
| 13 | 14 |
// read-write modes |
| ... | ... |
@@ -68,17 +69,23 @@ const ( |
| 68 | 68 |
// - Variation on hostdir but can be a drive followed by colon as well |
| 69 | 69 |
// - If a path, must be absolute. Can include spaces |
| 70 | 70 |
// - Drive cannot be c: (explicitly checked in code, not RegEx) |
| 71 |
- // |
|
| 71 |
+) |
|
| 72 | 72 |
|
| 73 |
- // RXMode is the regex expression for the mode of the mount |
|
| 74 |
- RXMode = `(:(?P<mode>(?i)rw))?` |
|
| 75 |
- // Temporarily for TP4, disabling the use of ro as it's not supported yet |
|
| 76 |
- // in the platform. TODO Windows: `(:(?P<mode>(?i)ro|rw))?` |
|
| 77 |
- // mode (optional) |
|
| 78 |
- // - Hopefully self explanatory in comparison to above. |
|
| 73 |
+// RXMode is the regex expression for the mode of the mount |
|
| 74 |
+var RXMode string |
|
| 75 |
+ |
|
| 76 |
+func init() {
|
|
| 77 |
+ osv := system.GetOSVersion() |
|
| 78 |
+ // Read-only volumes supported from 14350 onwards (post Windows Server 2016 TP5) |
|
| 79 |
+ // Mode (optional): |
|
| 80 |
+ // - Hopefully self explanatory in comparison to above regex's. |
|
| 79 | 81 |
// - Colon is not in the capture group |
| 80 |
- // |
|
| 81 |
-) |
|
| 82 |
+ if osv.Build >= 14350 {
|
|
| 83 |
+ RXMode = `(:(?P<mode>(?i)ro|rw))?` |
|
| 84 |
+ } else {
|
|
| 85 |
+ RXMode = `(:(?P<mode>(?i)rw))?` |
|
| 86 |
+ } |
|
| 87 |
+} |
|
| 82 | 88 |
|
| 83 | 89 |
// BackwardsCompatible decides whether this mount point can be |
| 84 | 90 |
// used in old versions of Docker or not. |