mirror of https://github.com/docker/docs.git
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 <github@gone.nl> (cherry picked from commit 84d5ab96ef33355e65f5c31210eb1777db372c52) Signed-off-by: Tibor Vass <tibor@docker.com>
This commit is contained in:
parent
98bbe72549
commit
a345cc11c9
|
@ -2,6 +2,7 @@ package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/docker/swarmkit/api"
|
"github.com/docker/swarmkit/api"
|
||||||
|
@ -23,6 +24,9 @@ func validateMounts(mounts []api.Mount) error {
|
||||||
if !filepath.IsAbs(mount.Source) {
|
if !filepath.IsAbs(mount.Source) {
|
||||||
return fmt.Errorf("invalid bind mount source, must be an absolute path: %s", mount.Source)
|
return fmt.Errorf("invalid bind mount source, must be an absolute path: %s", mount.Source)
|
||||||
}
|
}
|
||||||
|
if _, err := os.Stat(mount.Source); os.IsNotExist(err) {
|
||||||
|
return fmt.Errorf("invalid bind mount source, source path not found: %s", mount.Source)
|
||||||
|
}
|
||||||
case api.MountTypeVolume:
|
case api.MountTypeVolume:
|
||||||
if filepath.IsAbs(mount.Source) {
|
if filepath.IsAbs(mount.Source) {
|
||||||
return fmt.Errorf("invalid volume mount source, must not be an absolute path: %s", mount.Source)
|
return fmt.Errorf("invalid volume mount source, must not be an absolute path: %s", mount.Source)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -37,10 +39,25 @@ func TestControllerValidateMountBind(t *testing.T) {
|
||||||
t.Fatalf("expected error, got: %v", err)
|
t.Fatalf("expected error, got: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// with proper source
|
// with non-existing source
|
||||||
if _, err := newTestControllerWithMount(api.Mount{
|
if _, err := newTestControllerWithMount(api.Mount{
|
||||||
Type: api.MountTypeBind,
|
Type: api.MountTypeBind,
|
||||||
Source: testAbsPath,
|
Source: "/some-non-existing-host-path/",
|
||||||
|
Target: testAbsPath,
|
||||||
|
}); err == nil || !strings.Contains(err.Error(), "invalid bind mount source") {
|
||||||
|
t.Fatalf("expected error, got: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// with proper source
|
||||||
|
tmpdir, err := ioutil.TempDir("", "TestControllerValidateMountBind")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create temp dir: %v", err)
|
||||||
|
}
|
||||||
|
defer os.Remove(tmpdir)
|
||||||
|
|
||||||
|
if _, err := newTestControllerWithMount(api.Mount{
|
||||||
|
Type: api.MountTypeBind,
|
||||||
|
Source: tmpdir,
|
||||||
Target: testAbsPath,
|
Target: testAbsPath,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
t.Fatalf("expected error, got: %v", err)
|
t.Fatalf("expected error, got: %v", err)
|
||||||
|
@ -68,6 +85,12 @@ func TestControllerValidateMountVolume(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestControllerValidateMountTarget(t *testing.T) {
|
func TestControllerValidateMountTarget(t *testing.T) {
|
||||||
|
tmpdir, err := ioutil.TempDir("", "TestControllerValidateMountTarget")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create temp dir: %v", err)
|
||||||
|
}
|
||||||
|
defer os.Remove(tmpdir)
|
||||||
|
|
||||||
// with improper target
|
// with improper target
|
||||||
if _, err := newTestControllerWithMount(api.Mount{
|
if _, err := newTestControllerWithMount(api.Mount{
|
||||||
Type: api.MountTypeBind,
|
Type: api.MountTypeBind,
|
||||||
|
@ -80,7 +103,7 @@ func TestControllerValidateMountTarget(t *testing.T) {
|
||||||
// with proper target
|
// with proper target
|
||||||
if _, err := newTestControllerWithMount(api.Mount{
|
if _, err := newTestControllerWithMount(api.Mount{
|
||||||
Type: api.MountTypeBind,
|
Type: api.MountTypeBind,
|
||||||
Source: testAbsPath,
|
Source: tmpdir,
|
||||||
Target: testAbsPath,
|
Target: testAbsPath,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
t.Fatalf("expected no error, got: %v", err)
|
t.Fatalf("expected no error, got: %v", err)
|
||||||
|
|
Loading…
Reference in New Issue