From aca323ec7d30c9aead2b7e48da4bac4b0d386833 Mon Sep 17 00:00:00 2001 From: Gabriel Adrian Samfira Date: Mon, 14 Aug 2023 20:21:08 +0300 Subject: [PATCH] Implement readUser on Windows Signed-off-by: Gabriel Adrian Samfira --- solver/llbsolver/file/backend.go | 48 +++-------------------- solver/llbsolver/file/backend_unix.go | 49 ++++++++++++++++++++++++ solver/llbsolver/file/backend_windows.go | 22 +++++++++++ solver/llbsolver/file/user_linux.go | 3 +- solver/llbsolver/file/user_nolinux.go | 18 --------- solver/llbsolver/file/user_other.go | 19 +++++++++ solver/llbsolver/file/user_windows.go | 45 ++++++++++++++++++++++ solver/llbsolver/ops/file.go | 2 +- 8 files changed, 143 insertions(+), 63 deletions(-) create mode 100644 solver/llbsolver/file/backend_unix.go create mode 100644 solver/llbsolver/file/backend_windows.go delete mode 100644 solver/llbsolver/file/user_nolinux.go create mode 100644 solver/llbsolver/file/user_other.go create mode 100644 solver/llbsolver/file/user_windows.go diff --git a/solver/llbsolver/file/backend.go b/solver/llbsolver/file/backend.go index 6656050b9038..2c8bb23e57f2 100644 --- a/solver/llbsolver/file/backend.go +++ b/solver/llbsolver/file/backend.go @@ -11,6 +11,7 @@ import ( "github.com/containerd/continuity/fs" "github.com/docker/docker/pkg/idtools" + "github.com/moby/buildkit/executor" "github.com/moby/buildkit/snapshot" "github.com/moby/buildkit/solver/llbsolver/ops/fileoptypes" "github.com/moby/buildkit/solver/pb" @@ -27,46 +28,6 @@ func timestampToTime(ts int64) *time.Time { return &tm } -func mapUserToChowner(user *copy.User, idmap *idtools.IdentityMapping) (copy.Chowner, error) { - if user == nil { - return func(old *copy.User) (*copy.User, error) { - if old == nil { - if idmap == nil { - return nil, nil - } - old = ©.User{} // root - // non-nil old is already mapped - if idmap != nil { - identity, err := idmap.ToHost(idtools.Identity{ - UID: old.UID, - GID: old.GID, - }) - if err != nil { - return nil, err - } - return ©.User{UID: identity.UID, GID: identity.GID}, nil - } - } - return old, nil - }, nil - } - u := *user - if idmap != nil { - identity, err := idmap.ToHost(idtools.Identity{ - UID: user.UID, - GID: user.GID, - }) - if err != nil { - return nil, err - } - u.UID = identity.UID - u.GID = identity.GID - } - return func(*copy.User) (*copy.User, error) { - return &u, nil - }, nil -} - func mkdir(ctx context.Context, d string, action pb.FileActionMkDir, user *copy.User, idmap *idtools.IdentityMapping) error { p, err := fs.RootPath(d, action.Path) if err != nil { @@ -251,6 +212,7 @@ func docopy(ctx context.Context, src, dest string, action pb.FileActionCopy, u * } type Backend struct { + Executor executor.Executor } func (fb *Backend) Mkdir(ctx context.Context, m, user, group fileoptypes.Mount, action pb.FileActionMkDir) error { @@ -266,7 +228,7 @@ func (fb *Backend) Mkdir(ctx context.Context, m, user, group fileoptypes.Mount, } defer lm.Unmount() - u, err := readUser(action.Owner, user, group) + u, err := readUser(action.Owner, user, group, fb.Executor) if err != nil { return err } @@ -287,7 +249,7 @@ func (fb *Backend) Mkfile(ctx context.Context, m, user, group fileoptypes.Mount, } defer lm.Unmount() - u, err := readUser(action.Owner, user, group) + u, err := readUser(action.Owner, user, group, fb.Executor) if err != nil { return err } @@ -335,7 +297,7 @@ func (fb *Backend) Copy(ctx context.Context, m1, m2, user, group fileoptypes.Mou } defer lm2.Unmount() - u, err := readUser(action.Owner, user, group) + u, err := readUser(action.Owner, user, group, fb.Executor) if err != nil { return err } diff --git a/solver/llbsolver/file/backend_unix.go b/solver/llbsolver/file/backend_unix.go new file mode 100644 index 000000000000..d01290f300ac --- /dev/null +++ b/solver/llbsolver/file/backend_unix.go @@ -0,0 +1,49 @@ +//go:build !windows +// +build !windows + +package file + +import ( + "github.com/docker/docker/pkg/idtools" + copy "github.com/tonistiigi/fsutil/copy" +) + +func mapUserToChowner(user *copy.User, idmap *idtools.IdentityMapping) (copy.Chowner, error) { + if user == nil { + return func(old *copy.User) (*copy.User, error) { + if old == nil { + if idmap == nil { + return nil, nil + } + old = ©.User{} // root + // non-nil old is already mapped + if idmap != nil { + identity, err := idmap.ToHost(idtools.Identity{ + UID: old.UID, + GID: old.GID, + }) + if err != nil { + return nil, err + } + return ©.User{UID: identity.UID, GID: identity.GID}, nil + } + } + return old, nil + }, nil + } + u := *user + if idmap != nil { + identity, err := idmap.ToHost(idtools.Identity{ + UID: user.UID, + GID: user.GID, + }) + if err != nil { + return nil, err + } + u.UID = identity.UID + u.GID = identity.GID + } + return func(*copy.User) (*copy.User, error) { + return &u, nil + }, nil +} diff --git a/solver/llbsolver/file/backend_windows.go b/solver/llbsolver/file/backend_windows.go new file mode 100644 index 000000000000..03f3bbe7b308 --- /dev/null +++ b/solver/llbsolver/file/backend_windows.go @@ -0,0 +1,22 @@ +package file + +import ( + "github.com/docker/docker/pkg/idtools" + copy "github.com/tonistiigi/fsutil/copy" +) + +func mapUserToChowner(user *copy.User, idmap *idtools.IdentityMapping) (copy.Chowner, error) { + if user == nil || user.SID == "" { + return func(old *copy.User) (*copy.User, error) { + if old == nil || old.SID == "" { + old = ©.User{ + SID: idtools.ContainerAdministratorSidString, + } + } + return old, nil + }, nil + } + return func(*copy.User) (*copy.User, error) { + return user, nil + }, nil +} diff --git a/solver/llbsolver/file/user_linux.go b/solver/llbsolver/file/user_linux.go index 1f17431f5c32..1d2970ce9bde 100644 --- a/solver/llbsolver/file/user_linux.go +++ b/solver/llbsolver/file/user_linux.go @@ -5,6 +5,7 @@ import ( "syscall" "github.com/containerd/continuity/fs" + "github.com/moby/buildkit/executor" "github.com/moby/buildkit/snapshot" "github.com/moby/buildkit/solver/llbsolver/ops/fileoptypes" "github.com/moby/buildkit/solver/pb" @@ -13,7 +14,7 @@ import ( copy "github.com/tonistiigi/fsutil/copy" ) -func readUser(chopt *pb.ChownOpt, mu, mg fileoptypes.Mount) (*copy.User, error) { +func readUser(chopt *pb.ChownOpt, mu, mg fileoptypes.Mount, exec executor.Executor) (*copy.User, error) { if chopt == nil { return nil, nil } diff --git a/solver/llbsolver/file/user_nolinux.go b/solver/llbsolver/file/user_nolinux.go deleted file mode 100644 index 80652fd4abe4..000000000000 --- a/solver/llbsolver/file/user_nolinux.go +++ /dev/null @@ -1,18 +0,0 @@ -//go:build !linux -// +build !linux - -package file - -import ( - "github.com/moby/buildkit/solver/llbsolver/ops/fileoptypes" - "github.com/moby/buildkit/solver/pb" - "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 - } - return nil, errors.New("only implemented in linux") -} diff --git a/solver/llbsolver/file/user_other.go b/solver/llbsolver/file/user_other.go new file mode 100644 index 000000000000..34f6e8d2d029 --- /dev/null +++ b/solver/llbsolver/file/user_other.go @@ -0,0 +1,19 @@ +//go:build !linux && !windows +// +build !linux,!windows + +package file + +import ( + "github.com/moby/buildkit/executor" + "github.com/moby/buildkit/solver/llbsolver/ops/fileoptypes" + "github.com/moby/buildkit/solver/pb" + "github.com/pkg/errors" + copy "github.com/tonistiigi/fsutil/copy" +) + +func readUser(chopt *pb.ChownOpt, mu, mg fileoptypes.Mount, exec executor.Executor) (*copy.User, error) { + if chopt == nil { + return nil, nil + } + return nil, errors.New("only implemented in linux and windows") +} diff --git a/solver/llbsolver/file/user_windows.go b/solver/llbsolver/file/user_windows.go new file mode 100644 index 000000000000..d0eb76b579fe --- /dev/null +++ b/solver/llbsolver/file/user_windows.go @@ -0,0 +1,45 @@ +package file + +import ( + "context" + + "github.com/docker/docker/pkg/idtools" + "github.com/moby/buildkit/executor" + "github.com/moby/buildkit/solver/llbsolver/ops/fileoptypes" + "github.com/moby/buildkit/solver/pb" + "github.com/moby/buildkit/util/windows" + "github.com/pkg/errors" + copy "github.com/tonistiigi/fsutil/copy" +) + +func readUser(chopt *pb.ChownOpt, mu, mg fileoptypes.Mount, exec executor.Executor) (*copy.User, error) { + if chopt == nil { + return nil, nil + } + + 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) + } + rootMounts, release, err := mmu.m.Mount() + if err != nil { + return nil, err + } + defer release() + ident, err := windows.ResolveUsernameToSID(context.Background(), exec, rootMounts, u.ByName.Name) + if err != nil { + return nil, err + } + return ©.User{SID: ident.SID}, nil + default: + return ©.User{SID: idtools.ContainerAdministratorSidString}, nil + } + } + return ©.User{SID: idtools.ContainerAdministratorSidString}, nil +} diff --git a/solver/llbsolver/ops/file.go b/solver/llbsolver/ops/file.go index db81201f1ac5..128fffbe2cb9 100644 --- a/solver/llbsolver/ops/file.go +++ b/solver/llbsolver/ops/file.go @@ -167,7 +167,7 @@ func (f *fileOp) Exec(ctx context.Context, g session.Group, inputs []solver.Resu inpRefs = append(inpRefs, workerRef.ImmutableRef) } - fs := NewFileOpSolver(f.w, &file.Backend{}, f.refManager) + fs := NewFileOpSolver(f.w, &file.Backend{Executor: f.w.Executor()}, f.refManager) outs, err := fs.Solve(ctx, inpRefs, f.op.Actions, g) if err != nil { return nil, err