1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
package ops
import (
"os"
"syscall"
"github.com/containerd/continuity/fs"
"github.com/moby/buildkit/snapshot"
"github.com/moby/buildkit/solver/pb"
"github.com/moby/buildkit/worker"
"github.com/moby/sys/user"
"github.com/pkg/errors"
copy "github.com/tonistiigi/fsutil/copy"
)
func getReadUserFn(_ worker.Worker) func(chopt *pb.ChownOpt, mu, mg snapshot.Mountable) (*copy.User, error) {
return readUser
}
func readUser(chopt *pb.ChownOpt, mu, mg snapshot.Mountable) (*copy.User, error) {
if chopt == nil {
return nil, nil
}
var us copy.User
if chopt.User != nil {
switch u := chopt.User.User.(type) {
case *pb.UserOpt_ByName:
if mu == nil {
return nil, errors.Errorf("invalid missing user mount")
}
lm := snapshot.LocalMounter(mu)
dir, err := lm.Mount()
if err != nil {
return nil, err
}
defer lm.Unmount()
passwdPath, err := user.GetPasswdPath()
if err != nil {
return nil, err
}
passwdPath, err = fs.RootPath(dir, passwdPath)
if err != nil {
return nil, err
}
ufile, err := os.Open(passwdPath)
if errors.Is(err, os.ErrNotExist) || errors.Is(err, syscall.ENOTDIR) {
// Couldn't open the file. Considering this case as not finding the user in the file.
break
}
if err != nil {
return nil, err
}
defer ufile.Close()
users, err := user.ParsePasswdFilter(ufile, func(uu user.User) bool {
return uu.Name == u.ByName.Name
})
if err != nil {
return nil, err
}
if len(users) > 0 {
us.UID = users[0].Uid
us.GID = users[0].Gid
}
case *pb.UserOpt_ByID:
us.UID = int(u.ByID)
us.GID = int(u.ByID)
}
}
if chopt.Group != nil {
switch u := chopt.Group.User.(type) {
case *pb.UserOpt_ByName:
if mg == nil {
return nil, errors.Errorf("invalid missing group mount")
}
lm := snapshot.LocalMounter(mg)
dir, err := lm.Mount()
if err != nil {
return nil, err
}
defer lm.Unmount()
groupPath, err := user.GetGroupPath()
if err != nil {
return nil, err
}
groupPath, err = fs.RootPath(dir, groupPath)
if err != nil {
return nil, err
}
gfile, err := os.Open(groupPath)
if errors.Is(err, os.ErrNotExist) || errors.Is(err, syscall.ENOTDIR) {
// Couldn't open the file. Considering this case as not finding the group in the file.
break
}
if err != nil {
return nil, err
}
defer gfile.Close()
groups, err := user.ParseGroupFilter(gfile, func(g user.Group) bool {
return g.Name == u.ByName.Name
})
if err != nil {
return nil, err
}
if len(groups) > 0 {
us.GID = groups[0].Gid
}
case *pb.UserOpt_ByID:
us.GID = int(u.ByID)
}
}
return &us, nil
}
|