diff --git a/go.mod b/go.mod index ffec0e8503b4..bd91bfd9817c 100644 --- a/go.mod +++ b/go.mod @@ -246,3 +246,5 @@ require ( // restore junctions to have os.ModeSymlink flag set on Windows: https://github.com/docker/buildx/issues/3221 godebug winsymlink=0 + +replace github.com/moby/buildkit => github.com/crazy-max/buildkit v0.7.1-0.20260306115246-48e766ece564 diff --git a/go.sum b/go.sum index 092a4168c525..4a9f73322567 100644 --- a/go.sum +++ b/go.sum @@ -148,6 +148,8 @@ github.com/coreos/go-oidc/v3 v3.17.0/go.mod h1:wqPbKFrVnE90vty060SB40FCJ8fTHTxSw github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo= github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/crazy-max/buildkit v0.7.1-0.20260306115246-48e766ece564 h1:BNmgxrgf1XLKlz9HaeObj/SJ4F5WJ68VT13E1JOAGig= +github.com/crazy-max/buildkit v0.7.1-0.20260306115246-48e766ece564/go.mod h1:RCuOcj/bVsCriBG8NeFzRxjiCFQKnKP7KOVlNTS18t4= github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 h1:uX1JmpONuD549D73r6cgnxyUu18Zb7yHAy5AYU0Pm4Q= @@ -422,8 +424,6 @@ github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4 github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/moby/buildkit v0.28.0 h1:rKulfRRSduHJPNpLTk481fHElqN9tps0VUx8YV/5zsA= -github.com/moby/buildkit v0.28.0/go.mod h1:RCuOcj/bVsCriBG8NeFzRxjiCFQKnKP7KOVlNTS18t4= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/go-archive v0.2.0 h1:zg5QDUM2mi0JIM9fdQZWC7U8+2ZfixfTYoHL7rWUcP8= diff --git a/vendor/github.com/moby/buildkit/client/solve.go b/vendor/github.com/moby/buildkit/client/solve.go index 3ac415527dde..a913217907e3 100644 --- a/vendor/github.com/moby/buildkit/client/solve.go +++ b/vendor/github.com/moby/buildkit/client/solve.go @@ -188,7 +188,15 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG if ex.OutputDir == "" { return nil, errors.Errorf("output directory is required for %s exporter", ex.Type) } - syncTargets = append(syncTargets, filesync.WithFSSyncDir(exID, ex.OutputDir)) + if ex.Type == ExporterLocal { + mode, err := parseLocalExporterMode(ex.Attrs) + if err != nil { + return nil, err + } + syncTargets = append(syncTargets, filesync.WithFSSyncDirMode(exID, ex.OutputDir, mode)) + } else { + syncTargets = append(syncTargets, filesync.WithFSSyncDir(exID, ex.OutputDir)) + } } if supportStore { store := ex.OutputStore @@ -595,3 +603,19 @@ func prepareMounts(opt *SolveOpt) (map[string]fsutil.FS, error) { } return mounts, nil } + +func parseLocalExporterMode(attrs map[string]string) (filesync.FSSyncDirMode, error) { + if attrs == nil { + return filesync.FSSyncDirModeCopy, nil + } + + mode := strings.TrimSpace(strings.ToLower(attrs["mode"])) + switch mode { + case "", string(filesync.FSSyncDirModeCopy): + return filesync.FSSyncDirModeCopy, nil + case string(filesync.FSSyncDirModeMirror): + return filesync.FSSyncDirModeMirror, nil + default: + return "", errors.Errorf("invalid local exporter mode %q", attrs["mode"]) + } +} diff --git a/vendor/github.com/moby/buildkit/session/filesync/diffcopy.go b/vendor/github.com/moby/buildkit/session/filesync/diffcopy.go index 5e8b40b93d94..078415b28046 100644 --- a/vendor/github.com/moby/buildkit/session/filesync/diffcopy.go +++ b/vendor/github.com/moby/buildkit/session/filesync/diffcopy.go @@ -111,12 +111,22 @@ func recvDiffCopy(ds grpc.ClientStream, dest string, cu CacheUpdater, progress p })) } -func syncTargetDiffCopy(ds grpc.ServerStream, dest string) error { +func syncTargetDiffCopy(ds grpc.ServerStream, dest string, mode FSSyncDirMode) error { + var merge bool + switch mode { + case "", FSSyncDirModeCopy: + merge = true + case FSSyncDirModeMirror: + merge = false + default: + return errors.Errorf("invalid local exporter mode %q", mode) + } + if err := os.MkdirAll(dest, 0700); err != nil { return errors.Wrapf(err, "failed to create synctarget dest dir %s", dest) } return errors.WithStack(fsutil.Receive(ds.Context(), ds, dest, fsutil.ReceiveOpt{ - Merge: true, + Merge: merge, Filter: func() func(string, *fstypes.Stat) bool { uid := os.Getuid() gid := os.Getgid() diff --git a/vendor/github.com/moby/buildkit/session/filesync/filesync.go b/vendor/github.com/moby/buildkit/session/filesync/filesync.go index 230493f1690f..1afba9c3b9ff 100644 --- a/vendor/github.com/moby/buildkit/session/filesync/filesync.go +++ b/vendor/github.com/moby/buildkit/session/filesync/filesync.go @@ -251,10 +251,18 @@ type FSSyncTarget interface { target() *fsSyncTarget } +type FSSyncDirMode string + +const ( + FSSyncDirModeCopy FSSyncDirMode = "copy" + FSSyncDirModeMirror FSSyncDirMode = "mirror" +) + type fsSyncTarget struct { - id int - outdir string - f FileOutputFunc + id int + outdir string + outdirMode FSSyncDirMode + f FileOutputFunc } func (target *fsSyncTarget) target() *fsSyncTarget { @@ -270,23 +278,40 @@ func WithFSSync(id int, f FileOutputFunc) FSSyncTarget { func WithFSSyncDir(id int, outdir string) FSSyncTarget { return &fsSyncTarget{ - id: id, - outdir: outdir, + id: id, + outdir: outdir, + outdirMode: FSSyncDirModeCopy, + } +} + +func WithFSSyncDirMode(id int, outdir string, mode FSSyncDirMode) FSSyncTarget { + if mode == "" { + mode = FSSyncDirModeCopy + } + return &fsSyncTarget{ + id: id, + outdir: outdir, + outdirMode: mode, } } func NewFSSyncTarget(targets ...FSSyncTarget) *SyncTarget { st := &SyncTarget{ fs: make(map[int]FileOutputFunc), - outdirs: make(map[int]string), + outdirs: make(map[int]syncTargetDir), } st.Add(targets...) return st } +type syncTargetDir struct { + dir string + mode FSSyncDirMode +} + type SyncTarget struct { fs map[int]FileOutputFunc - outdirs map[int]string + outdirs map[int]syncTargetDir } var _ session.Attachable = &SyncTarget{} @@ -298,7 +323,14 @@ func (sp *SyncTarget) Add(targets ...FSSyncTarget) { sp.fs[t.id] = t.f } if t.outdir != "" { - sp.outdirs[t.id] = t.outdir + mode := t.outdirMode + if mode == "" { + mode = FSSyncDirModeCopy + } + sp.outdirs[t.id] = syncTargetDir{ + dir: t.outdir, + mode: mode, + } } } } @@ -326,7 +358,7 @@ func (sp *SyncTarget) chooser(ctx context.Context) int { func (sp *SyncTarget) DiffCopy(stream FileSend_DiffCopyServer) (err error) { id := sp.chooser(stream.Context()) if outdir, ok := sp.outdirs[id]; ok { - return syncTargetDiffCopy(stream, outdir) + return syncTargetDiffCopy(stream, outdir.dir, outdir.mode) } f, ok := sp.fs[id] if !ok { diff --git a/vendor/modules.txt b/vendor/modules.txt index 42a1154acfc6..726557f4950f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -652,7 +652,7 @@ github.com/mitchellh/go-wordwrap # github.com/mitchellh/hashstructure/v2 v2.0.2 ## explicit; go 1.14 github.com/mitchellh/hashstructure/v2 -# github.com/moby/buildkit v0.28.0 +# github.com/moby/buildkit v0.28.0 => github.com/crazy-max/buildkit v0.7.1-0.20260306115246-48e766ece564 ## explicit; go 1.25.5 github.com/moby/buildkit/api/services/control github.com/moby/buildkit/api/types @@ -1840,3 +1840,4 @@ sigs.k8s.io/structured-merge-diff/v6/value # sigs.k8s.io/yaml v1.6.0 ## explicit; go 1.22 sigs.k8s.io/yaml +# github.com/moby/buildkit => github.com/crazy-max/buildkit v0.7.1-0.20260306115246-48e766ece564