github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/client/allocdir/fs_unix.go (about) 1 //go:build unix 2 3 package allocdir 4 5 import ( 6 "fmt" 7 "os" 8 "os/user" 9 "path/filepath" 10 "strconv" 11 "syscall" 12 13 "github.com/hashicorp/nomad/helper/users" 14 "golang.org/x/sys/unix" 15 ) 16 17 var ( 18 // SharedAllocContainerPath is the path inside container for mounted 19 // directory shared across tasks in a task group. 20 SharedAllocContainerPath = filepath.Join("/", SharedAllocName) 21 22 // TaskLocalContainerPath is the path inside a container for mounted directory 23 // for local storage. 24 TaskLocalContainerPath = filepath.Join("/", TaskLocal) 25 26 // TaskSecretsContainerPath is the path inside a container for mounted 27 // secrets directory 28 TaskSecretsContainerPath = filepath.Join("/", TaskSecrets) 29 ) 30 31 // dropDirPermissions gives full access to a directory to all users and sets 32 // the owner to nobody. 33 func dropDirPermissions(path string, desired os.FileMode) error { 34 if err := os.Chmod(path, desired|0777); err != nil { 35 return fmt.Errorf("Chmod(%v) failed: %v", path, err) 36 } 37 38 // Can't change owner if not root. 39 if unix.Geteuid() != 0 { 40 return nil 41 } 42 43 nobody := users.Nobody() 44 45 uid, err := getUid(&nobody) 46 if err != nil { 47 return err 48 } 49 50 gid, err := getGid(&nobody) 51 if err != nil { 52 return err 53 } 54 55 if err := os.Chown(path, uid, gid); err != nil { 56 return fmt.Errorf("Couldn't change owner/group of %v to (uid: %v, gid: %v): %v", path, uid, gid, err) 57 } 58 59 return nil 60 } 61 62 // getUid for a user 63 func getUid(u *user.User) (int, error) { 64 uid, err := strconv.Atoi(u.Uid) 65 if err != nil { 66 return 0, fmt.Errorf("Unable to convert Uid to an int: %v", err) 67 } 68 69 return uid, nil 70 } 71 72 // getGid for a user 73 func getGid(u *user.User) (int, error) { 74 gid, err := strconv.Atoi(u.Gid) 75 if err != nil { 76 return 0, fmt.Errorf("Unable to convert Gid to an int: %v", err) 77 } 78 79 return gid, nil 80 } 81 82 // linkOrCopy attempts to hardlink dst to src and fallsback to copying if the 83 // hardlink fails. 84 func linkOrCopy(src, dst string, uid, gid int, perm os.FileMode) error { 85 // Avoid link/copy if the file already exists in the chroot 86 // TODO 0.6 clean this up. This was needed because chroot creation fails 87 // when a process restarts. 88 if fileInfo, _ := os.Stat(dst); fileInfo != nil { 89 return nil 90 } 91 // Attempt to hardlink. 92 if err := os.Link(src, dst); err == nil { 93 return nil 94 } 95 96 return fileCopy(src, dst, uid, gid, perm) 97 } 98 99 func getOwner(fi os.FileInfo) (int, int) { 100 stat, ok := fi.Sys().(*syscall.Stat_t) 101 if !ok { 102 return -1, -1 103 } 104 return int(stat.Uid), int(stat.Gid) 105 }