From 0785109ae4285716082c5803d3bf3f442b12c2ca Mon Sep 17 00:00:00 2001 From: Michael Schurter Date: Thu, 12 Jan 2017 11:15:31 -0800 Subject: [PATCH 1/2] Stop trying to use mount for image based drivers Fixes #2178 and allows using Docker and other image based drivers even when nomad is run as a non-root user. `client/allocdir` tests can be run as a non-root user to ensure this behavior and tests that rely on root or non-root users properly detect their effective user and skip instead of fail. --- client/allocdir/alloc_dir_test.go | 10 +++++----- client/allocdir/task_dir.go | 11 ++++++----- client/allocdir/task_dir_test.go | 25 +++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/client/allocdir/alloc_dir_test.go b/client/allocdir/alloc_dir_test.go index 834d0f903fc..8f9c4c32c58 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 71bd1985b96..97594d71352 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 c769287b52c..e57ff42bd25 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) + } +} From 054d6f8bb6d60aa74f46c33636fb449b5d53b7a6 Mon Sep 17 00:00:00 2001 From: Michael Schurter Date: Tue, 17 Jan 2017 13:36:19 -0800 Subject: [PATCH 2/2] Remove BC note --- CHANGELOG.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8953727b8a4..6ed1cb648c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,5 @@ ## 0.5.3 (Unreleased) -__BACKWARDS INCOMPATIBILITIES:__ - * Client must be run as user with ability to call mount syscall - IMPROVEMENTS: * core: Introduce Constructor jobs and Dispatch command/API [GH-2128] * core: Cancel blocked evals upon successful one for job [GH-2155]