| package file |
| |
| import ( |
| "os" |
| |
| "github.com/containerd/continuity/fs" |
| "github.com/moby/buildkit/snapshot" |
| "github.com/moby/buildkit/solver/llbsolver/ops/fileoptypes" |
| "github.com/moby/buildkit/solver/pb" |
| "github.com/opencontainers/runc/libcontainer/user" |
| "github.com/pkg/errors" |
| copy "github.com/tonistiigi/fsutil/copy" |
| ) |
| |
| func readUser(chopt *pb.ChownOpt, mu, mg fileoptypes.Mount) (*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") |
| } |
| mmu, ok := mu.(*Mount) |
| if !ok { |
| return nil, errors.Errorf("invalid mount type %T", mu) |
| } |
| lm := snapshot.LocalMounter(mmu.m) |
| 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 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") |
| } |
| mmg, ok := mg.(*Mount) |
| if !ok { |
| return nil, errors.Errorf("invalid mount type %T", mg) |
| } |
| lm := snapshot.LocalMounter(mmg.m) |
| 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 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 |
| } |