mirror of
https://github.com/kemko/nomad.git
synced 2026-01-08 03:15:42 +03:00
Merge pull request #1960 from hashicorp/fix-perm-issues
Fixed permission issues on client
This commit is contained in:
@@ -313,13 +313,12 @@ func (d *AllocDir) Embed(task string, entries map[string]string) error {
|
||||
|
||||
// Embedding a single file
|
||||
if !s.IsDir() {
|
||||
destDir := filepath.Join(taskdir, filepath.Dir(dest))
|
||||
if err := os.MkdirAll(destDir, s.Mode().Perm()); err != nil {
|
||||
return fmt.Errorf("Couldn't create destination directory %v: %v", destDir, err)
|
||||
if err := d.createDir(taskdir, filepath.Dir(dest)); err != nil {
|
||||
return fmt.Errorf("Couldn't create destination directory %v: %v", dest, err)
|
||||
}
|
||||
|
||||
// Copy the file.
|
||||
taskEntry := filepath.Join(destDir, filepath.Base(dest))
|
||||
taskEntry := filepath.Join(taskdir, dest)
|
||||
if err := d.linkOrCopy(source, taskEntry, s.Mode().Perm()); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -329,7 +328,8 @@ func (d *AllocDir) Embed(task string, entries map[string]string) error {
|
||||
|
||||
// Create destination directory.
|
||||
destDir := filepath.Join(taskdir, dest)
|
||||
if err := os.MkdirAll(destDir, s.Mode().Perm()); err != nil {
|
||||
|
||||
if err := d.createDir(taskdir, dest); err != nil {
|
||||
return fmt.Errorf("Couldn't create destination directory %v: %v", destDir, err)
|
||||
}
|
||||
|
||||
@@ -565,3 +565,67 @@ func (d *AllocDir) GetSecretDir(task string) (string, error) {
|
||||
return filepath.Join(t, TaskSecrets), nil
|
||||
}
|
||||
}
|
||||
|
||||
// createDir creates a directory structure inside the basepath. This functions
|
||||
// preserves the permissions of each of the subdirectories in the relative path
|
||||
// by looking up the permissions in the host.
|
||||
func (d *AllocDir) createDir(basePath, relPath string) error {
|
||||
filePerms, err := d.splitPath(relPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// We are going backwards since we create the root of the directory first
|
||||
// and then create the entire nested structure.
|
||||
for i := len(filePerms) - 1; i >= 0; i-- {
|
||||
fi := filePerms[i]
|
||||
destDir := filepath.Join(basePath, fi.Name)
|
||||
if err := os.MkdirAll(destDir, fi.Perm); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// fileInfo holds the path and the permissions of a file
|
||||
type fileInfo struct {
|
||||
Name string
|
||||
Perm os.FileMode
|
||||
}
|
||||
|
||||
// splitPath stats each subdirectory of a path. The first element of the array
|
||||
// is the file passed to this method, and the last element is the root of the
|
||||
// path.
|
||||
func (d *AllocDir) splitPath(path string) ([]fileInfo, error) {
|
||||
var mode os.FileMode
|
||||
i, err := os.Stat(path)
|
||||
|
||||
// If the path is not present in the host then we respond with the most
|
||||
// flexible permission.
|
||||
if err != nil {
|
||||
mode = os.ModePerm
|
||||
} else {
|
||||
mode = i.Mode()
|
||||
}
|
||||
var dirs []fileInfo
|
||||
dirs = append(dirs, fileInfo{Name: path, Perm: mode})
|
||||
currentDir := path
|
||||
for {
|
||||
dir := filepath.Dir(filepath.Clean(currentDir))
|
||||
if dir == currentDir {
|
||||
break
|
||||
}
|
||||
|
||||
// We try to find the permission of the file in the host. If the path is not
|
||||
// present in the host then we respond with the most flexible permission.
|
||||
i, err = os.Stat(dir)
|
||||
if err != nil {
|
||||
mode = os.ModePerm
|
||||
} else {
|
||||
mode = i.Mode()
|
||||
}
|
||||
dirs = append(dirs, fileInfo{Name: dir, Perm: mode})
|
||||
currentDir = dir
|
||||
}
|
||||
return dirs, nil
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
@@ -417,3 +418,67 @@ func TestAllocDir_ReadAt_SecretDir(t *testing.T) {
|
||||
t.Fatalf("ReadAt of secret file didn't error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllocDir_SplitPath(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("/tmp", "tmpdirtest")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
dest := filepath.Join(dir, "/foo/bar/baz")
|
||||
if err := os.MkdirAll(dest, os.ModePerm); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
d := NewAllocDir(dir)
|
||||
defer d.Destroy()
|
||||
|
||||
info, err := d.splitPath(dest)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if len(info) != 6 {
|
||||
t.Fatalf("expected: %v, actual: %v", 6, len(info))
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllocDir_CreateDir(t *testing.T) {
|
||||
dir, err := ioutil.TempDir("/tmp", "tmpdirtest")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
// create a subdir and a file
|
||||
subdir := filepath.Join(dir, "subdir")
|
||||
if err := os.MkdirAll(subdir, 0760); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
subdirMode, err := os.Stat(subdir)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Create the above hierarchy under another destination
|
||||
dir1, err := ioutil.TempDir("/tmp", "tempdirdest")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
d := NewAllocDir(dir)
|
||||
defer d.Destroy()
|
||||
|
||||
if err := d.createDir(dir1, subdir); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Ensure that the subdir had the right perm
|
||||
fi, err := os.Stat(filepath.Join(dir1, dir, "subdir"))
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if fi.Mode() != subdirMode.Mode() {
|
||||
t.Fatalf("wrong file mode: %v, expected: %v", fi.Mode(), subdirMode.Mode())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user