Browse code

Merge pull request #37400 from olljanat/34795-allow-npipe

Allow mount type npipe on service/stack

Yong Tang authored on 2018/09/27 01:54:42
Showing 4 changed files
... ...
@@ -238,11 +238,13 @@ definitions:
238 238
           - `bind` Mounts a file or directory from the host into the container. Must exist prior to creating the container.
239 239
           - `volume` Creates a volume with the given name and options (or uses a pre-existing volume with the same name and options). These are **not** removed when the container is removed.
240 240
           - `tmpfs` Create a tmpfs with the given options. The mount source cannot be specified for tmpfs.
241
+          - `npipe` Mounts a named pipe from the host into the container. Must exist prior to creating the container.
241 242
         type: "string"
242 243
         enum:
243 244
           - "bind"
244 245
           - "volume"
245 246
           - "tmpfs"
247
+          - "npipe"
246 248
       ReadOnly:
247 249
         description: "Whether the mount should be read-only."
248 250
         type: "boolean"
... ...
@@ -285,6 +285,8 @@ func convertMount(m api.Mount) enginemount.Mount {
285 285
 		mount.Type = enginemount.TypeVolume
286 286
 	case api.MountTypeTmpfs:
287 287
 		mount.Type = enginemount.TypeTmpfs
288
+	case api.MountTypeNamedPipe:
289
+		mount.Type = enginemount.TypeNamedPipe
288 290
 	}
289 291
 
290 292
 	if m.BindOptions != nil {
... ...
@@ -11,7 +11,8 @@ import (
11 11
 func validateMounts(mounts []api.Mount) error {
12 12
 	for _, mount := range mounts {
13 13
 		// Target must always be absolute
14
-		if !filepath.IsAbs(mount.Target) {
14
+		// except if target is Windows named pipe
15
+		if !filepath.IsAbs(mount.Target) && mount.Type != api.MountTypeNamedPipe {
15 16
 			return fmt.Errorf("invalid mount target, must be an absolute path: %s", mount.Target)
16 17
 		}
17 18
 
... ...
@@ -32,6 +33,10 @@ func validateMounts(mounts []api.Mount) error {
32 32
 			if mount.Source != "" {
33 33
 				return errors.New("invalid tmpfs source, source must be empty")
34 34
 			}
35
+		case api.MountTypeNamedPipe:
36
+			if mount.Source == "" {
37
+				return errors.New("invalid npipe source, source must not be empty")
38
+			}
35 39
 		default:
36 40
 			return fmt.Errorf("invalid mount type: %s", mount.Type)
37 41
 		}
... ...
@@ -1,8 +1,24 @@
1 1
 // +build windows
2 2
 
3 3
 package container // import "github.com/docker/docker/daemon/cluster/executor/container"
4
+import (
5
+	"strings"
6
+	"testing"
7
+
8
+	"github.com/docker/swarmkit/api"
9
+)
4 10
 
5 11
 const (
6 12
 	testAbsPath        = `c:\foo`
7 13
 	testAbsNonExistent = `c:\some-non-existing-host-path\`
8 14
 )
15
+
16
+func TestControllerValidateMountNamedPipe(t *testing.T) {
17
+	if _, err := newTestControllerWithMount(api.Mount{
18
+		Type:   api.MountTypeNamedPipe,
19
+		Source: "",
20
+		Target: `\\.\pipe\foo`,
21
+	}); err == nil || !strings.Contains(err.Error(), "invalid npipe source, source must not be empty") {
22
+		t.Fatalf("expected error, got: %v", err)
23
+	}
24
+}