-
Notifications
You must be signed in to change notification settings - Fork 1.3k
local: fix platform-split=true option #6007
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
1707034
to
e30a4fc
Compare
@profnandaa Any idea what happened to the windows tests here? |
Taking a look rn. |
We missed that path that calls (dlv)
> github.com/moby/buildkit/exporter/local.(*localExporterInstance).Export.func2.1() C:/dev/core-containers/buildkit/exporter/local/export.go:128 (PC: 0x224b379)
123: }
124: if cleanup != nil {
125: defer cleanup()
126: }
127:
=> 128: if !e.opts.PlatformSplit {
129: // check for duplicate paths
130: err = outputFS.Walk(ctx, "", func(p string, entry os.DirEntry, err error) error {
131: if entry.IsDir() {
132: return nil
133: }
(dlv) p e.opts.PlatformSplit
true Cross-checking with the rest of the exporters then send a patch. Ref #4994 |
PFA the patch to your branch, ran on my fork here |
@profnandaa So previously this code path did not run for windows? |
Yes, did not run previously. |
db3590b
to
65f3ddc
Compare
@profnandaa This test failure looks related to this commit 30b572b https://github.com/moby/buildkit/actions/runs/15430742302/job/43437060882?pr=6007#step:8:307
|
@crazy-max -- I doubt... I've tried to dig through to find where the failure is happening but can't find it since it fails just silently. Same happens even if I revert my change. Ran the debugger till
Any ideas? |
Hum wonder if it could be the folder name with os version 🤔 |
That was my first suspicion but |
@profnandaa Do the platform directories work correctly for wcow on multi-platform builds that don't require |
Since we don't have multi-platform build support yet, I'm unable to test this. I was just about to write to you that since this is actually not needed at the moment coz of the single-platform support, I suggest we skip the test on Windows for now; as I continue with the investigation. |
@tonistiigi -- this is besides our current issue. I just noticed that you cherry-picked a slightly older fix from my branch then (if you see the patch). I have done a refactor here to match, will be nice if you can pick that - profnandaa@780b19b |
@crazy-max @tonistiigi -- I think I've finally found where the bug is at last, in > github.com/tonistiigi/fsutil.(*subDirFS).Walk() C:/dev/core-containers/buildkit/vendor/github.com/tonistiigi/fsutil/fs.go:125 (PC: 0x1501600)
120: func (fs *subDirFS) Walk(ctx context.Context, target string, fn gofs.WalkDirFunc) error {
121: first, rest, _ := strings.Cut(target, string(filepath.Separator))
122:
123: for _, d := range fs.dirs {
124: if first != "" && first != d.Stat.Path {
=> 125: continue
126: }
127:
128: fi := &StatInfo{d.Stat.Clone()}
129: if !fi.IsDir() {
130: return errors.WithStack(&os.PathError{Path: d.Stat.Path, Err: syscall.ENOTDIR, Op: "walk subdir"})
(dlv) p first
"/"
(dlv) p rest
""
(dlv) p target
"/"
(dlv) p d.Stat.Path
"windows_amd64"
Exploring how best to fix... |
Looks like we'll have to fix from the https://github.com/tonistiigi/fsutil/blob/3f76f81301443083e015c78ea5526da2823bf419/send.go#L151 err := s.fs.Walk(ctx, "/", func(path string, entry os.DirEntry, err error) error { Already diff --git a/vendor/github.com/tonistiigi/fsutil/send.go b/vendor/github.com/tonistiigi/fsutil/send.go
index e4a315638..6584ccef7 100644
--- a/vendor/github.com/tonistiigi/fsutil/send.go
+++ b/vendor/github.com/tonistiigi/fsutil/send.go
@@ -148,7 +148,7 @@ func (s *sender) sendFile(h *sendHandle) error {
func (s *sender) walk(ctx context.Context) error {
var i uint32 = 0
- err := s.fs.Walk(ctx, "/", func(path string, entry os.DirEntry, err error) error {
+ err := s.fs.Walk(ctx, string(filepath.Separator), func(path string, entry os.DirEntry, err error) error {
if err != nil {
return err
} |
Using "/" was causing a silent bug later on at `fs.go:121` that is expecting platform-specific separators. See discussion at moby/buildkit#6007 Fix this by using `\\` on Windows and `/` on unix. Signed-off-by: Anthony Nandaa <profnandaa@gmail.com>
|
||
expPlatform := runtime.GOOS + "_" + runtime.GOARCH | ||
_, err = os.Stat(filepath.Join(destDir, expPlatform+"/")) | ||
require.NoError(t, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how do we deal with the windows case where the build number is added to the os name? Unless you explicitly specify --opt platform=...
, eg.
#10 exporting to client directory
#10 copying files windows(10.0.22631)/amd64
#10 copying files windows(10.0.22631)/amd64 6.01MB 11.4s
#10 copying files windows(10.0.22631)/amd64 150.83MB 16.5s
#10 copying files windows(10.0.22631)/amd64 239.47MB 23.7s
#10 copying files windows(10.0.22631)/amd64 239.47MB 23.9s done
#10 DONE 24.2s
should we normalize that from the code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are these ()
invalid names for windows?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
they are not invalid, I think this change was brought in some time back here - containerd/platforms#6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what do you think about this? profnandaa@3fc6393
Currently the option only worked when platform-split=false was set for multi-platform build but not for setting single platform build to use platform-split=true. Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
65f3ddc
to
31a8c4e
Compare
Rebased to include #6017 |
@crazy-max -- the failure now is coz the directory is named differently on windows with a |
I have updated the test to use @tonistiigi Feel free to squash with your commit.
I agree that it would be better to strip the os version but I think we should just change the key here: buildkit/exporter/local/export.go Line 184 in 25c7c80
Instead of We can look at this as follow-up. |
@crazy-max One last thing, can cherry pick this refactor instead? Tonis has picked a slightly older version from my branch, I'd thought he'll use my patch file. |
7c3c4fe
to
c818a97
Compare
Done, thanks! |
c818a97
to
d7f98a9
Compare
Signed-off-by: Anthony Nandaa <profnandaa@gmail.com>
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
d7f98a9
to
db03322
Compare
@ArthurFlag Needs docs follow-up in https://docs.docker.com/build/exporters/local-tar/ with some examples as well similar to what we have in BuildKit README but with Buildx: https://github.com/moby/buildkit?tab=readme-ov-file#local-directory |
* Fix to respect special bit specified in the mode of copier Signed-off-by: Kotaro Inoue <inoue.kotaro@linecorp.com> * Add tests Signed-off-by: Kotaro Inoue <inoue.kotaro@linecorp.com> * Add support for always overwriting existing paths Before this, copy would always refuse to replace an existing path in the dest with something from the source of a different type. E.g. if there was a symlink at the dest, you'd get an error if copying src meant replacing the symlink w/ a directory. This is the right default behavior but there are situations in which callers may want to opt in to instead always replacing what's in dest with what's in source. This adds an option to enable that behavior. Signed-off-by: Erik Sipsma <erik@sipsma.dev> * Migrate off of gogo/protobuf gogo/protobuf has been deprecated since 2022. This change uses Google's code generator instead of gogo/protobuf. Signed-off-by: Kazuyoshi Kato <kato.kazuyoshi@gmail.com> * Fix to use internal representation for setting special bits Signed-off-by: Kotaro Inoue <k.musaino@gmail.com> * Fix cross-device copy failing on macOS Downstream issue: https://github.com/macOScontainers/rund/issues/28 Signed-off-by: Marat Radchenko <marat@slonopotamus.org> * followlinks: sanitize root path Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * chore: fix typos in NewFilterFS docstring Signed-off-by: Justin Chadwell <me@jedevc.com> * Revert "Migrate off of gogo/protobuf" This reverts commit bea810c. Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * chore: run once on vagrant init Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * ci: increase vm boot time to 15m Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * ci: switch to macos-13 runner for freebsd job Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * ci: retry logic for freebsd test step Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * ci: add windows to test matrix Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * diskwriter: fix test scope Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * fix file path separator Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * test with coverage and send to codecov Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * ci: align events Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * readme badges Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * ci: fix test step for windows Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * ci: bump actions to latest stable Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * chore: dependabot to keep gha up to date Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * update to go 1.21 Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * update golangci-lint to 1.54.2 also update config to show all issues at once and set linter setting for io/ioutil. Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * dockerfile: update xx to 1.4.0 Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * filter: allow SkipDir return with lazy parents When using include/exclude options in a file walk, we lazily store the parents, and only later call the target function with them when we find a file inside. This handles the case where `**/*.go` should only walk directories that contain `.go` files, and not every directory in the tree. However, when storing lazy parents, we weren't appropriately handling the `SkipDir` value that could be returned. We were making two incorrect assumptions: 1. An error value from `fn()` was always an error case - this isn't true, since we have control error values like `SkipDir`. Because of this, we need to ensure that `calledFn` is *always* set to true when calling `fn` (even in an error case). 2. We can return `SkipDir` to skip this parent directory. This isn't *quite* right, since returning `SkipDir` would return it only for the child directory - we need to make sure it's called everytime for each child directory of this parent directory, by storing it as a boolean `skipFn` field. With these changes, the new test passes, and we don't end up with duplicate parent calls, as was happening before: Error: Not equal: expected: []string{"foo"} actual : []string{"foo", "foo"} Signed-off-by: Justin Chadwell <me@jedevc.com> * filter: ensure MapResult is followed for parent directories Similar to the previous commit, we weren't properly respecting MapResult return values for parent directories. To resolve this, we just store into `skipFn` just like previously, and return `SkipDir` instead of `continue`ing on. After these changes, the new test passes, and we don't end up including entries that were in excluded directories, as was happening before: Error: Not equal: expected: "dir y\nfile y/b.txt\n" actual : "file x/a.txt\ndir y\nfile y/b.txt\n" Signed-off-by: Justin Chadwell <me@jedevc.com> * chore: codecov config Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * ci: set codecov token Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * ci: set workflow_dispatch event this is for manual testing from a fork Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * send: ensure file path to unix form when sending files Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * fix data race in progressCb Fixes a silly data race where progressCurrent is incremented (and later accessed) by 1 of 4 threads. Signed-off-by: Alex Couture-Beil <alex@earthly.dev> * receive: ensure callback errors are propagated Previously, it was possible for errors returned by an asyncronous callback function to not be propagated, and to instead return "context canceled" from `Receive`. This could happen based on this specific sequence of events: - An asyncronous callback is called from `HandleChange`, and returns an error, completing the async errorgroup context with an error state. - Another call to `HandleChange` completes, and uses the context syncronously, returning `context.Canceled`. - This in turn propagates to `doubleWalkDiff`, which returns the canceled error, instead of calling `Wait` which would contain the actual error group error. This behavior is racy, based on exactly how and when the asyncronous callback is called. The fix to this is relatively straightforward: we just need to make sure that syncronous and asyncronous function calls are kept separate, and don't reuse the same context. This means that a failure in an async callback, doesn't cause later sync ones to fail. Signed-off-by: Justin Chadwell <me@jedevc.com> * receive: translate unix-paths off the wire to native Then, inside all our validations, and our double walking, we don't have to worry about translating between different path formats. Additionally, we ensure that all received paths can be represented on the target host system. A path like `foo/bar\baz` can only be stored on linux (a dir with `foo`, containing a file `bar\baz`). On windows, this would later be interpreted to be `foo\bar\baz` (a dir with `foo`, containing a dir `bar`, containing a file `baz`). Signed-off-by: Justin Chadwell <me@jedevc.com> * chore: remove old windows todo comments Signed-off-by: Justin Chadwell <me@jedevc.com> * chore: add fsutil protocol description Signed-off-by: Justin Chadwell <me@jedevc.com> * recv: translate linkname to wire format Signed-off-by: Justin Chadwell <me@jedevc.com> * fix hardlink filter regression With the refactor to FilterFS the hardlink handling was changed so that the hardlink detection is in a separate FS instance and then FilterFS is layered on top of it. This means that the file that was the source for the hardlink could be filtered out, but the Stat pointing to that link is still sent as is. New function validates if source files are not present in FS anymore and correct the linking. It could be better if all the FS implementation did this automatically, but there is quite a lot of layering going on atm. with multiple layers of FilterFS that would all need to keep own hardlink memory, so atm. the new function is only called before send. Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com> * chore(deps): Bump docker/bake-action from 4 to 5 Bumps [docker/bake-action](https://github.com/docker/bake-action) from 4 to 5. - [Release notes](https://github.com/docker/bake-action/releases) - [Commits](docker/bake-action@v4...v5) --- updated-dependencies: - dependency-name: docker/bake-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * Fixup fallout with new FS changed API * ci: switch to ubuntu runner for freebsd job Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * deps: remove deprecated gogo proto This removes the deprecated gogo proto in favor of the standard implementation. Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com> * types: stat clone drops hidden proto fields The stat clone returned by protobuf returns a version of `types.Stat` that isn't compatible with some tests in buildkit. This changes clone to create a new type without cloning the hidden protobuf types. Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com> * update Go to 1.23 Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com> * update golangci-lint to 1.61.0 Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com> * update xx to v1.5.0 Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com> * add support for non-octal mode setting Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com> * protobuf: add vtproto to supplement protobuf marshaling This adds the vtproto generator to generate code that results in faster marshaling and unmarshaling. vtproto is similar to gogo but it generates additional code on top of the existing protobuf structures rather than changing the generator itself. Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com> * fix correcting timestamps for created destination dir after copy Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com> * Fixed build on OpenBSD This fixes docker/buildx#2772 * build and test openbsd Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * bench: bump modules Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * enable golangci-lint for supported platforms Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * fix issues in .golangci.yml Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * fix lint issues Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * fixes for netbsd Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * build and test netbsd Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * chore(deps): Bump codecov/codecov-action from 4 to 5 Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4 to 5. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](codecov/codecov-action@v4...v5) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * ci: fix deprecated input for codecov-action Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * update xx to v1.6.1 for compatibility with alpine 3.21 and file 5.46+ This fixes compatibility with alpine 3.21 and file 5.46+ - Fix additional possible `xx-cc`/`xx-cargo` compatibility issue with Alpine 3.21 - Support for Alpine 3.21 - Fix `xx-verify` with `file` 5.46+ - Fix possible error taking lock in `xx-apk` in latest Alpine without `coreutils` full diff: tonistiigi/xx@v1.5.0...v1.6.1 Signed-off-by: Sebastiaan van Stijn <github@gone.nl> * fix error message for invalid includepatterns The patterns returned in the error message were missing the ones added via opts.FollowLinks Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com> * ci: update bake-action to v6 Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * copy: fix custom chmod for parent directories Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com> * chore(deps): Bump nick-fields/retry from 3.0.0 to 3.0.2 Bumps [nick-fields/retry](https://github.com/nick-fields/retry) from 3.0.0 to 3.0.2. - [Release notes](https://github.com/nick-fields/retry/releases) - [Changelog](https://github.com/nick-fields/retry/blob/master/.releaserc.js) - [Commits](nick-fields/retry@7152eba...ce71cc2) --- updated-dependencies: - dependency-name: nick-fields/retry dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * add gopls linter fixes Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com> * fix linter after merge conflict Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com> * copy: support for linux X mode Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com> * ci: install latest vagrant Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * ci: infer go version from workflow for bsd tests Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * ci: fix freebsd package repository Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> * Allow metadata-only receivers This optional mode allows skipping transferring the file data if remote side just hopes to analyze how the local files look like. Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com> * receive: add parent memory for metadata transfers This is needed because metadata-only parent may have a data file as a child. Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com> * stat: ignore apple extended attributes Extended attributes from `com.apple` will bust remote layer caches and shouldn't be transferred to a Linux environment. Skip loading these extended attributes as part of loading xattrs. Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com> * fix: send: use platform-specific root path Using "/" was causing a silent bug later on at `fs.go:121` that is expecting platform-specific separators. See discussion at moby/buildkit#6007 Fix this by using `\\` on Windows and `/` on unix. Signed-off-by: Anthony Nandaa <profnandaa@gmail.com> * ci: add CODEOWNERS * chore: tidy ci.yml --------- Signed-off-by: Kotaro Inoue <inoue.kotaro@linecorp.com> Signed-off-by: Erik Sipsma <erik@sipsma.dev> Signed-off-by: Kazuyoshi Kato <kato.kazuyoshi@gmail.com> Signed-off-by: Kotaro Inoue <k.musaino@gmail.com> Signed-off-by: Marat Radchenko <marat@slonopotamus.org> Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> Signed-off-by: Justin Chadwell <me@jedevc.com> Signed-off-by: Alex Couture-Beil <alex@earthly.dev> Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com> Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com> Signed-off-by: Sebastiaan van Stijn <github@gone.nl> Signed-off-by: Anthony Nandaa <profnandaa@gmail.com> Co-authored-by: Kotaro Inoue <inoue.kotaro@linecorp.com> Co-authored-by: Erik Sipsma <erik@sipsma.dev> Co-authored-by: Kazuyoshi Kato <kato.kazuyoshi@gmail.com> Co-authored-by: Tõnis Tiigi <tonistiigi@gmail.com> Co-authored-by: Kotaro Inoue <k.musaino@gmail.com> Co-authored-by: Marat Radchenko <marat@slonopotamus.org> Co-authored-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> Co-authored-by: Justin Chadwell <me@jedevc.com> Co-authored-by: Alex Couture-Beil <alex@earthly.dev> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Nilesh Patra <nilesh@nileshpatra.info> Co-authored-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com> Co-authored-by: Kirill A. Korinsky <kirill@korins.ky> Co-authored-by: Sebastiaan van Stijn <github@gone.nl> Co-authored-by: Anthony Nandaa <profnandaa@gmail.com>
Currently the option only worked when platform-split=false was set for multi-platform build but not for setting single platform build to use platform-split=true.
docker/buildx#3215