Skip to content

Commit 84d5ab9

Browse files
committed
fix validation of non-existing bind-mount source
Unlike `docker run -v..`, `docker service create --mount` does not allow bind-mounting non-existing host paths. This adds validation for the specified `source`, and produces an error if the path is not found on the host. Signed-off-by: Sebastiaan van Stijn <[email protected]>
1 parent 2684459 commit 84d5ab9

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

daemon/cluster/executor/container/validate.go

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package container
22

33
import (
44
"fmt"
5+
"os"
56
"path/filepath"
67

78
"github.com/docker/swarmkit/api"
@@ -23,6 +24,9 @@ func validateMounts(mounts []api.Mount) error {
2324
if !filepath.IsAbs(mount.Source) {
2425
return fmt.Errorf("invalid bind mount source, must be an absolute path: %s", mount.Source)
2526
}
27+
if _, err := os.Stat(mount.Source); os.IsNotExist(err) {
28+
return fmt.Errorf("invalid bind mount source, source path not found: %s", mount.Source)
29+
}
2630
case api.MountTypeVolume:
2731
if filepath.IsAbs(mount.Source) {
2832
return fmt.Errorf("invalid volume mount source, must not be an absolute path: %s", mount.Source)

daemon/cluster/executor/container/validate_test.go

+25-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package container
22

33
import (
4+
"io/ioutil"
5+
"os"
46
"strings"
57
"testing"
68

@@ -37,10 +39,25 @@ func TestControllerValidateMountBind(t *testing.T) {
3739
t.Fatalf("expected error, got: %v", err)
3840
}
3941

42+
// with non-existing source
43+
if _, err := newTestControllerWithMount(api.Mount{
44+
Type: api.MountTypeBind,
45+
Source: "/some-non-existing-host-path/",
46+
Target: testAbsPath,
47+
}); err == nil || !strings.Contains(err.Error(), "invalid bind mount source") {
48+
t.Fatalf("expected error, got: %v", err)
49+
}
50+
4051
// with proper source
52+
tmpdir, err := ioutil.TempDir("", "TestControllerValidateMountBind")
53+
if err != nil {
54+
t.Fatalf("failed to create temp dir: %v", err)
55+
}
56+
defer os.Remove(tmpdir)
57+
4158
if _, err := newTestControllerWithMount(api.Mount{
4259
Type: api.MountTypeBind,
43-
Source: testAbsPath,
60+
Source: tmpdir,
4461
Target: testAbsPath,
4562
}); err != nil {
4663
t.Fatalf("expected error, got: %v", err)
@@ -68,6 +85,12 @@ func TestControllerValidateMountVolume(t *testing.T) {
6885
}
6986

7087
func TestControllerValidateMountTarget(t *testing.T) {
88+
tmpdir, err := ioutil.TempDir("", "TestControllerValidateMountTarget")
89+
if err != nil {
90+
t.Fatalf("failed to create temp dir: %v", err)
91+
}
92+
defer os.Remove(tmpdir)
93+
7194
// with improper target
7295
if _, err := newTestControllerWithMount(api.Mount{
7396
Type: api.MountTypeBind,
@@ -80,7 +103,7 @@ func TestControllerValidateMountTarget(t *testing.T) {
80103
// with proper target
81104
if _, err := newTestControllerWithMount(api.Mount{
82105
Type: api.MountTypeBind,
83-
Source: testAbsPath,
106+
Source: tmpdir,
84107
Target: testAbsPath,
85108
}); err != nil {
86109
t.Fatalf("expected no error, got: %v", err)

0 commit comments

Comments
 (0)