diff --git a/client/allocdir/alloc_dir_test.go b/client/allocdir/alloc_dir_test.go index 834d0f903fcf..8f9c4c32c587 100644 --- a/client/allocdir/alloc_dir_test.go +++ b/client/allocdir/alloc_dir_test.go @@ -150,11 +150,11 @@ func TestAllocDir_Snapshot(t *testing.T) { // Build 2 task dirs td1 := d.NewTaskDir(t1.Name) - if err := td1.Build(nil, cstructs.FSIsolationNone); err != nil { + if err := td1.Build(nil, cstructs.FSIsolationImage); err != nil { t.Fatalf("error build task=%q dir: %v", t1.Name, err) } td2 := d.NewTaskDir(t2.Name) - if err := td2.Build(nil, cstructs.FSIsolationNone); err != nil { + if err := td2.Build(nil, cstructs.FSIsolationImage); err != nil { t.Fatalf("error build task=%q dir: %v", t2.Name, err) } @@ -224,12 +224,12 @@ func TestAllocDir_Move(t *testing.T) { defer d2.Destroy() td1 := d1.NewTaskDir(t1.Name) - if err := td1.Build(nil, cstructs.FSIsolationNone); err != nil { + if err := td1.Build(nil, cstructs.FSIsolationImage); err != nil { t.Fatalf("TaskDir.Build() faild: %v", err) } td2 := d2.NewTaskDir(t1.Name) - if err := td2.Build(nil, cstructs.FSIsolationNone); err != nil { + if err := td2.Build(nil, cstructs.FSIsolationImage); err != nil { t.Fatalf("TaskDir.Build() faild: %v", err) } @@ -322,7 +322,7 @@ func TestAllocDir_ReadAt_SecretDir(t *testing.T) { defer d.Destroy() td := d.NewTaskDir(t1.Name) - if err := td.Build(nil, cstructs.FSIsolationNone); err != nil { + if err := td.Build(nil, cstructs.FSIsolationImage); err != nil { t.Fatalf("TaskDir.Build() failed: %v", err) } diff --git a/client/allocdir/task_dir.go b/client/allocdir/task_dir.go index 71bd1985b961..97594d713529 100644 --- a/client/allocdir/task_dir.go +++ b/client/allocdir/task_dir.go @@ -89,11 +89,12 @@ func (t *TaskDir) Build(chroot map[string]string, fsi cstructs.FSIsolation) erro } } - // Always link the shared task directory even though image based - // filesystem isolalation doesn't require it. This way we have a - // consistent task dir. - if err := linkDir(t.SharedAllocDir, t.SharedTaskDir); err != nil { - return fmt.Errorf("Failed to mount shared directory for task: %v", err) + // Only link alloc dir into task dir for no and chroot fs isolation. + // Image based isolation will bind the shared alloc dir in the driver. + if fsi == cstructs.FSIsolationNone || fsi == cstructs.FSIsolationChroot { + if err := linkDir(t.SharedAllocDir, t.SharedTaskDir); err != nil { + return fmt.Errorf("Failed to mount shared directory for task: %v", err) + } } // Create the secret directory diff --git a/client/allocdir/task_dir_test.go b/client/allocdir/task_dir_test.go index c769287b52c5..e57ff42bd25a 100644 --- a/client/allocdir/task_dir_test.go +++ b/client/allocdir/task_dir_test.go @@ -5,6 +5,8 @@ import ( "os" "path/filepath" "testing" + + cstructs "github.com/hashicorp/nomad/client/structs" ) // Test that building a chroot will skip nonexistent directories. @@ -82,3 +84,26 @@ func TestTaskDir_EmbedDirs(t *testing.T) { } } } + +// Test that task dirs for image based isolation don't require root. +func TestTaskDir_NonRoot(t *testing.T) { + if os.Geteuid() == 0 { + t.Skip("test should be run as non-root user") + } + tmp, err := ioutil.TempDir("", "AllocDir") + if err != nil { + t.Fatalf("Couldn't create temp dir: %v", err) + } + defer os.RemoveAll(tmp) + + d := NewAllocDir(testLogger(), tmp) + defer d.Destroy() + td := d.NewTaskDir(t1.Name) + if err := d.Build(); err != nil { + t.Fatalf("Build() failed: %v", err) + } + + if err := td.Build(nil, cstructs.FSIsolationImage); err != nil { + t.Fatalf("TaskDir.Build failed: %v", err) + } +}