From 2f3bda8ecbbe671a4773ebd89bda5da9e94dc6ee Mon Sep 17 00:00:00 2001 From: Gabriel Adrian Samfira Date: Thu, 5 Oct 2023 19:46:46 +0300 Subject: [PATCH] Use snapshot.Mountable as an argument type to readUser Signed-off-by: Gabriel Adrian Samfira --- solver/llbsolver/file/backend.go | 57 +++++++++++++++++++++------- solver/llbsolver/ops/file.go | 5 ++- solver/llbsolver/ops/user_linux.go | 28 +++----------- solver/llbsolver/ops/user_other.go | 8 ++-- solver/llbsolver/ops/user_windows.go | 25 ++++-------- 5 files changed, 64 insertions(+), 59 deletions(-) diff --git a/solver/llbsolver/file/backend.go b/solver/llbsolver/file/backend.go index 05c094eeb..7ea0378e8 100644 --- a/solver/llbsolver/file/backend.go +++ b/solver/llbsolver/file/backend.go @@ -212,19 +212,22 @@ func docopy(ctx context.Context, src, dest string, action pb.FileActionCopy, u * // NewFileOpBackend returns a new file operation backend. The executor is currently only used for Windows, // and it is used to construct the readUserFn field set in the returned Backend. -func NewFileOpBackend(readUserFn ReadUserCallback) *Backend { - return &Backend{ - readUserFn: readUserFn, +func NewFileOpBackend(readUser ReadUserCallback) (*backend, error) { + if readUser == nil { + return nil, errors.New("readUser callback must be provided") } + return &backend{ + readUser: readUser, + }, nil } -type ReadUserCallback func(chopt *pb.ChownOpt, mu, mg fileoptypes.Mount) (*copy.User, error) +type ReadUserCallback func(chopt *pb.ChownOpt, mu, mg snapshot.Mountable) (*copy.User, error) -type Backend struct { - readUserFn ReadUserCallback +type backend struct { + readUser ReadUserCallback } -func (fb *Backend) Mkdir(ctx context.Context, m, user, group fileoptypes.Mount, action pb.FileActionMkDir) error { +func (fb *backend) Mkdir(ctx context.Context, m, user, group fileoptypes.Mount, action pb.FileActionMkDir) error { mnt, ok := m.(*Mount) if !ok { return errors.Errorf("invalid mount type %T", m) @@ -237,8 +240,7 @@ func (fb *Backend) Mkdir(ctx context.Context, m, user, group fileoptypes.Mount, } defer lm.Unmount() - // u, err := readUser(action.Owner, user, group, fb.Executor) - u, err := fb.readUserFn(action.Owner, user, group) + u, err := fb.readUserWrapper(action.Owner, user, group) if err != nil { return err } @@ -246,7 +248,7 @@ func (fb *Backend) Mkdir(ctx context.Context, m, user, group fileoptypes.Mount, return mkdir(ctx, dir, action, u, mnt.m.IdentityMapping()) } -func (fb *Backend) Mkfile(ctx context.Context, m, user, group fileoptypes.Mount, action pb.FileActionMkFile) error { +func (fb *backend) Mkfile(ctx context.Context, m, user, group fileoptypes.Mount, action pb.FileActionMkFile) error { mnt, ok := m.(*Mount) if !ok { return errors.Errorf("invalid mount type %T", m) @@ -259,7 +261,7 @@ func (fb *Backend) Mkfile(ctx context.Context, m, user, group fileoptypes.Mount, } defer lm.Unmount() - u, err := fb.readUserFn(action.Owner, user, group) + u, err := fb.readUserWrapper(action.Owner, user, group) if err != nil { return err } @@ -267,7 +269,7 @@ func (fb *Backend) Mkfile(ctx context.Context, m, user, group fileoptypes.Mount, return mkfile(ctx, dir, action, u, mnt.m.IdentityMapping()) } -func (fb *Backend) Rm(ctx context.Context, m fileoptypes.Mount, action pb.FileActionRm) error { +func (fb *backend) Rm(ctx context.Context, m fileoptypes.Mount, action pb.FileActionRm) error { mnt, ok := m.(*Mount) if !ok { return errors.Errorf("invalid mount type %T", m) @@ -283,7 +285,7 @@ func (fb *Backend) Rm(ctx context.Context, m fileoptypes.Mount, action pb.FileAc return rm(ctx, dir, action) } -func (fb *Backend) Copy(ctx context.Context, m1, m2, user, group fileoptypes.Mount, action pb.FileActionCopy) error { +func (fb *backend) Copy(ctx context.Context, m1, m2, user, group fileoptypes.Mount, action pb.FileActionCopy) error { mnt1, ok := m1.(*Mount) if !ok { return errors.Errorf("invalid mount type %T", m1) @@ -307,7 +309,7 @@ func (fb *Backend) Copy(ctx context.Context, m1, m2, user, group fileoptypes.Mou } defer lm2.Unmount() - u, err := fb.readUserFn(action.Owner, user, group) + u, err := fb.readUserWrapper(action.Owner, user, group) if err != nil { return err } @@ -315,6 +317,33 @@ func (fb *Backend) Copy(ctx context.Context, m1, m2, user, group fileoptypes.Mou return docopy(ctx, src, dest, action, u, mnt2.m.IdentityMapping()) } +func (fb *backend) readUserWrapper(owner *pb.ChownOpt, user, group fileoptypes.Mount) (*copy.User, error) { + var userMountable, groupMountable snapshot.Mountable + if user != nil { + usr, ok := user.(*Mount) + if !ok { + return nil, errors.Errorf("invalid mount type %T", user) + } + userMountable = usr.Mountable() + } + + if group != nil { + grp, ok := group.(*Mount) + if !ok { + return nil, errors.Errorf("invalid mount type %T", group) + } + groupMountable = grp.Mountable() + } + + // We don't check the mountables for nil here. Depending on the ChownOpt value, + // one of them may be nil. Allow the readUser function to handle this. + u, err := fb.readUser(owner, userMountable, groupMountable) + if err != nil { + return nil, err + } + return u, nil +} + func cleanPath(s string) (string, error) { s, err := system.CheckSystemDriveAndRemoveDriveLetter(s, runtime.GOOS) if err != nil { diff --git a/solver/llbsolver/ops/file.go b/solver/llbsolver/ops/file.go index c9df96f0a..f17869381 100644 --- a/solver/llbsolver/ops/file.go +++ b/solver/llbsolver/ops/file.go @@ -167,7 +167,10 @@ func (f *fileOp) Exec(ctx context.Context, g session.Group, inputs []solver.Resu inpRefs = append(inpRefs, workerRef.ImmutableRef) } - backend := file.NewFileOpBackend(getReadUserFn(f.w.Executor())) + backend, err := file.NewFileOpBackend(getReadUserFn(f.w)) + if err != nil { + return nil, err + } fs := NewFileOpSolver(f.w, backend, f.refManager) outs, err := fs.Solve(ctx, inpRefs, f.op.Actions, g) diff --git a/solver/llbsolver/ops/user_linux.go b/solver/llbsolver/ops/user_linux.go index 75bb2ed18..68daeceab 100644 --- a/solver/llbsolver/ops/user_linux.go +++ b/solver/llbsolver/ops/user_linux.go @@ -5,21 +5,19 @@ import ( "syscall" "github.com/containerd/continuity/fs" - "github.com/moby/buildkit/executor" "github.com/moby/buildkit/snapshot" - "github.com/moby/buildkit/solver/llbsolver/file" - "github.com/moby/buildkit/solver/llbsolver/ops/fileoptypes" "github.com/moby/buildkit/solver/pb" + "github.com/moby/buildkit/worker" "github.com/opencontainers/runc/libcontainer/user" "github.com/pkg/errors" copy "github.com/tonistiigi/fsutil/copy" ) -func getReadUserFn(exec executor.Executor) func(chopt *pb.ChownOpt, mu, mg fileoptypes.Mount) (*copy.User, error) { +func getReadUserFn(worker worker.Worker) func(chopt *pb.ChownOpt, mu, mg snapshot.Mountable) (*copy.User, error) { return readUser } -func readUser(chopt *pb.ChownOpt, mu, mg fileoptypes.Mount) (*copy.User, error) { +func readUser(chopt *pb.ChownOpt, mu, mg snapshot.Mountable) (*copy.User, error) { if chopt == nil { return nil, nil } @@ -30,16 +28,8 @@ func readUser(chopt *pb.ChownOpt, mu, mg fileoptypes.Mount) (*copy.User, error) if mu == nil { return nil, errors.Errorf("invalid missing user mount") } - mmu, ok := mu.(*file.Mount) - if !ok { - return nil, errors.Errorf("invalid mount type %T", mu) - } - mountable := mmu.Mountable() - if mountable == nil { - return nil, errors.Errorf("invalid mountable") - } - lm := snapshot.LocalMounter(mountable) + lm := snapshot.LocalMounter(mu) dir, err := lm.Mount() if err != nil { return nil, err @@ -89,16 +79,8 @@ func readUser(chopt *pb.ChownOpt, mu, mg fileoptypes.Mount) (*copy.User, error) if mg == nil { return nil, errors.Errorf("invalid missing group mount") } - mmg, ok := mg.(*file.Mount) - if !ok { - return nil, errors.Errorf("invalid mount type %T", mg) - } - mountable := mmg.Mountable() - if mountable == nil { - return nil, errors.Errorf("invalid mountable") - } - lm := snapshot.LocalMounter(mountable) + lm := snapshot.LocalMounter(mg) dir, err := lm.Mount() if err != nil { return nil, err diff --git a/solver/llbsolver/ops/user_other.go b/solver/llbsolver/ops/user_other.go index 64f2683a9..f173ae38c 100644 --- a/solver/llbsolver/ops/user_other.go +++ b/solver/llbsolver/ops/user_other.go @@ -4,18 +4,18 @@ package ops import ( - "github.com/moby/buildkit/executor" - "github.com/moby/buildkit/solver/llbsolver/ops/fileoptypes" + "github.com/moby/buildkit/snapshot" "github.com/moby/buildkit/solver/pb" + "github.com/moby/buildkit/worker" "github.com/pkg/errors" copy "github.com/tonistiigi/fsutil/copy" ) -func getReadUserFn(exec executor.Executor) func(chopt *pb.ChownOpt, mu, mg fileoptypes.Mount) (*copy.User, error) { +func getReadUserFn(worker worker.Worker) func(chopt *pb.ChownOpt, mu, mg snapshot.Mountable) (*copy.User, error) { return readUser } -func readUser(chopt *pb.ChownOpt, mu, mg fileoptypes.Mount) (*copy.User, error) { +func readUser(chopt *pb.ChownOpt, mu, mg snapshot.Mountable) (*copy.User, error) { if chopt == nil { return nil, nil } diff --git a/solver/llbsolver/ops/user_windows.go b/solver/llbsolver/ops/user_windows.go index 4f95f224e..553a2d210 100644 --- a/solver/llbsolver/ops/user_windows.go +++ b/solver/llbsolver/ops/user_windows.go @@ -4,22 +4,21 @@ import ( "context" "github.com/docker/docker/pkg/idtools" - "github.com/moby/buildkit/executor" - "github.com/moby/buildkit/solver/llbsolver/file" - "github.com/moby/buildkit/solver/llbsolver/ops/fileoptypes" + "github.com/moby/buildkit/snapshot" "github.com/moby/buildkit/solver/pb" "github.com/moby/buildkit/util/windows" + "github.com/moby/buildkit/worker" "github.com/pkg/errors" copy "github.com/tonistiigi/fsutil/copy" ) -func getReadUserFn(exec executor.Executor) func(chopt *pb.ChownOpt, mu, mg fileoptypes.Mount) (*copy.User, error) { - return func(chopt *pb.ChownOpt, mu, mg fileoptypes.Mount) (*copy.User, error) { - return readUser(chopt, mu, mg, exec) +func getReadUserFn(worker worker.Worker) func(chopt *pb.ChownOpt, mu, mg snapshot.Mountable) (*copy.User, error) { + return func(chopt *pb.ChownOpt, mu, mg snapshot.Mountable) (*copy.User, error) { + return readUser(chopt, mu, mg, worker) } } -func readUser(chopt *pb.ChownOpt, mu, mg fileoptypes.Mount, exec executor.Executor) (*copy.User, error) { +func readUser(chopt *pb.ChownOpt, mu, mg snapshot.Mountable, worker worker.Worker) (*copy.User, error) { if chopt == nil { return nil, nil } @@ -30,21 +29,13 @@ func readUser(chopt *pb.ChownOpt, mu, mg fileoptypes.Mount, exec executor.Execut if mu == nil { return nil, errors.Errorf("invalid missing user mount") } - mmu, ok := mu.(*file.Mount) - if !ok { - return nil, errors.Errorf("invalid mount type %T", mu) - } - mountable := mmu.Mountable() - if mountable == nil { - return nil, errors.Errorf("invalid mountable") - } - rootMounts, release, err := mountable.Mount() + rootMounts, release, err := mu.Mount() if err != nil { return nil, err } defer release() - ident, err := windows.ResolveUsernameToSID(context.Background(), exec, rootMounts, u.ByName.Name) + ident, err := windows.ResolveUsernameToSID(context.Background(), worker.Executor(), rootMounts, u.ByName.Name) if err != nil { return nil, err }