diff --git a/drivers/shared/executor/executor.go b/drivers/shared/executor/executor.go index cb7acfa65..301deb45b 100644 --- a/drivers/shared/executor/executor.go +++ b/drivers/shared/executor/executor.go @@ -579,47 +579,6 @@ func lookupBin(taskDir string, bin string) (string, error) { return "", fmt.Errorf("binary %q could not be found", bin) } -// lookupTaskBin finds the file in: -// taskDir/local, taskDir, PATH search inside taskDir -// and returns an absolute path -func lookupTaskBin(taskDir string, bin string) (string, error) { - // Check in the local directory - localDir := filepath.Join(taskDir, allocdir.TaskLocal) - local := filepath.Join(localDir, bin) - if _, err := os.Stat(local); err == nil { - return local, nil - } - - // Check at the root of the task's directory - root := filepath.Join(taskDir, bin) - if _, err := os.Stat(root); err == nil { - return root, nil - } - - // Check the host PATH anchored inside the taskDir - if !strings.Contains(bin, "/") { - envPath := os.Getenv("PATH") - for _, dir := range filepath.SplitList(envPath) { - if dir == "" { - // match unix shell behavior, empty path element == . - dir = "." - } - for _, root := range []string{localDir, taskDir} { - path := filepath.Join(root, dir, bin) - f, err := os.Stat(path) - if err != nil { - continue - } - if m := f.Mode(); !m.IsDir() { - return path, nil - } - } - } - } - - return "", fmt.Errorf("file %s not found under path %s", bin, taskDir) -} - // makeExecutable makes the given file executable for root,group,others. func makeExecutable(binPath string) error { if runtime.GOOS == "windows" { diff --git a/drivers/shared/executor/executor_linux.go b/drivers/shared/executor/executor_linux.go index 91ec6ad98..3757cd746 100644 --- a/drivers/shared/executor/executor_linux.go +++ b/drivers/shared/executor/executor_linux.go @@ -17,6 +17,7 @@ import ( "github.com/hashicorp/consul-template/signals" hclog "github.com/hashicorp/go-hclog" multierror "github.com/hashicorp/go-multierror" + "github.com/hashicorp/nomad/client/allocdir" "github.com/hashicorp/nomad/client/stats" cstructs "github.com/hashicorp/nomad/client/structs" shelpers "github.com/hashicorp/nomad/helper/stats" @@ -770,3 +771,43 @@ func cmdMounts(mounts []*drivers.MountConfig) []*lconfigs.Mount { return r } + +// lookupTaskBin finds the file `bin` in taskDir/local, taskDir in that order, then performs +// a PATH search inside taskDir. It returns an absolute path. See also executor.lookupBin +func lookupTaskBin(taskDir string, bin string) (string, error) { + // Check in the local directory + localDir := filepath.Join(taskDir, allocdir.TaskLocal) + local := filepath.Join(localDir, bin) + if _, err := os.Stat(local); err == nil { + return local, nil + } + + // Check at the root of the task's directory + root := filepath.Join(taskDir, bin) + if _, err := os.Stat(root); err == nil { + return root, nil + } + + // Check the host PATH anchored inside the taskDir + if !strings.Contains(bin, "/") { + envPath := os.Getenv("PATH") + for _, dir := range filepath.SplitList(envPath) { + if dir == "" { + // match unix shell behavior, empty path element == . + dir = "." + } + for _, root := range []string{localDir, taskDir} { + path := filepath.Join(root, dir, bin) + f, err := os.Stat(path) + if err != nil { + continue + } + if m := f.Mode(); !m.IsDir() { + return path, nil + } + } + } + } + + return "", fmt.Errorf("file %s not found under path %s", bin, taskDir) +} diff --git a/drivers/shared/executor/executor_linux_test.go b/drivers/shared/executor/executor_linux_test.go index a90e1d200..1b9318775 100644 --- a/drivers/shared/executor/executor_linux_test.go +++ b/drivers/shared/executor/executor_linux_test.go @@ -161,6 +161,41 @@ ld.so.conf.d/` }, func(err error) { t.Error(err) }) } +func TestUniversalExecutor_LookupTaskBin(t *testing.T) { + t.Parallel() + require := require.New(t) + + // Create a temp dir + tmpDir, err := ioutil.TempDir("", "") + require.Nil(err) + defer os.Remove(tmpDir) + + // Make a foo subdir + os.MkdirAll(filepath.Join(tmpDir, "foo"), 0700) + + // Write a file under foo + filePath := filepath.Join(tmpDir, "foo", "tmp.txt") + err = ioutil.WriteFile(filePath, []byte{1, 2}, os.ModeAppend) + require.NoError(err) + + // Lookout with an absolute path to the binary + _, err = lookupTaskBin(tmpDir, "/foo/tmp.txt") + require.NoError(err) + + // Write a file under local subdir + os.MkdirAll(filepath.Join(tmpDir, "local"), 0700) + filePath2 := filepath.Join(tmpDir, "local", "tmp.txt") + ioutil.WriteFile(filePath2, []byte{1, 2}, os.ModeAppend) + + // Lookup with file name, should find the one we wrote above + _, err = lookupTaskBin(tmpDir, "tmp.txt") + require.NoError(err) + + // Lookup a host absolute path + _, err = lookupTaskBin(tmpDir, "/bin/sh") + require.Error(err) +} + // Exec Launch looks for the binary only inside the chroot func TestExecutor_EscapeContainer(t *testing.T) { t.Parallel() diff --git a/drivers/shared/executor/executor_test.go b/drivers/shared/executor/executor_test.go index 9db7689db..65af774a5 100644 --- a/drivers/shared/executor/executor_test.go +++ b/drivers/shared/executor/executor_test.go @@ -452,41 +452,6 @@ func TestUniversalExecutor_LookupPath(t *testing.T) { require.NoError(err) } -func TestUniversalExecutor_LookupTaskBin(t *testing.T) { - t.Parallel() - require := require.New(t) - - // Create a temp dir - tmpDir, err := ioutil.TempDir("", "") - require.Nil(err) - defer os.Remove(tmpDir) - - // Make a foo subdir - os.MkdirAll(filepath.Join(tmpDir, "foo"), 0700) - - // Write a file under foo - filePath := filepath.Join(tmpDir, "foo", "tmp.txt") - err = ioutil.WriteFile(filePath, []byte{1, 2}, os.ModeAppend) - require.NoError(err) - - // Lookout with an absolute path to the binary - _, err = lookupTaskBin(tmpDir, "/foo/tmp.txt") - require.NoError(err) - - // Write a file under local subdir - os.MkdirAll(filepath.Join(tmpDir, "local"), 0700) - filePath2 := filepath.Join(tmpDir, "local", "tmp.txt") - ioutil.WriteFile(filePath2, []byte{1, 2}, os.ModeAppend) - - // Lookup with file name, should find the one we wrote above - _, err = lookupTaskBin(tmpDir, "tmp.txt") - require.NoError(err) - - // Lookup a host absolute path - _, err = lookupTaskBin(tmpDir, "/bin/sh") - require.Error(err) -} - // setupRoootfs setups the rootfs for libcontainer executor // It uses busybox to make some binaries available - somewhat cheaper // than mounting the underlying host filesystem