From b4b993d0f3e7a992ca136fc6d224016d978104dd Mon Sep 17 00:00:00 2001 From: CrazyMax <1951866+crazy-max@users.noreply.github.com> Date: Wed, 26 Aug 2026 14:57:29 +0200 Subject: [PATCH] resolver: preserve OS version in worker platforms Use the full platform string when deduplicating platforms reported by BuildKit workers so Windows platforms that differ only by OS version remain distinct during node resolution. Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> --- build/resolver/driver.go | 13 ++++-------- util/platformutil/parse.go | 2 +- util/platformutil/parse_test.go | 37 +++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 util/platformutil/parse_test.go diff --git a/build/resolver/driver.go b/build/resolver/driver.go index 671b14c5bfe9..7044713b528e 100644 --- a/build/resolver/driver.go +++ b/build/resolver/driver.go @@ -10,6 +10,7 @@ import ( "github.com/containerd/platforms" "github.com/docker/buildx/builder" "github.com/docker/buildx/driver" + "github.com/docker/buildx/util/platformutil" "github.com/docker/buildx/util/progress" "github.com/moby/buildkit/client" gateway "github.com/moby/buildkit/frontend/gateway/client" @@ -147,17 +148,11 @@ func (r *nodeResolver) Resolve(ctx context.Context, optPlatforms map[string][]oc if err != nil { return errors.Wrap(err, "listing workers") } - - ps := make(map[string]ocispecs.Platform, len(ww)) + var ps []ocispecs.Platform for _, w := range ww { - for _, p := range w.Platforms { - pk := platforms.Format(platforms.Normalize(p)) - ps[pk] = p - } - } - for _, p := range ps { - workers[i] = append(workers[i], p) + ps = append(ps, w.Platforms...) } + workers[i] = platformutil.Dedupe(ps) return nil }) } diff --git a/util/platformutil/parse.go b/util/platformutil/parse.go index b95855ffab6a..dfc2721467b3 100644 --- a/util/platformutil/parse.go +++ b/util/platformutil/parse.go @@ -43,7 +43,7 @@ func Dedupe(in []ocispecs.Platform) []ocispecs.Platform { out := make([]ocispecs.Platform, 0, len(in)) for _, p := range in { p := platforms.Normalize(p) - key := platforms.Format(p) + key := platforms.FormatAll(p) if _, ok := m[key]; ok { continue } diff --git a/util/platformutil/parse_test.go b/util/platformutil/parse_test.go new file mode 100644 index 000000000000..0b05bd11452b --- /dev/null +++ b/util/platformutil/parse_test.go @@ -0,0 +1,37 @@ +package platformutil + +import ( + "testing" + + "github.com/containerd/platforms" + ocispecs "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/stretchr/testify/require" +) + +func TestDedupePreservesOSVersionAndFeatures(t *testing.T) { + t.Parallel() + + got := Dedupe([]ocispecs.Platform{ + platforms.MustParse("windows(10.0.17763)/amd64"), + platforms.MustParse("windows(10.0.20348)/amd64"), + platforms.MustParse("windows(10.0.20348+win32k)/amd64"), + platforms.MustParse("windows(10.0.17763)/amd64"), + platforms.MustParse("linux/x86_64"), + platforms.MustParse("linux/amd64"), + }) + + require.Equal(t, []string{ + "windows(10.0.17763)/amd64", + "windows(10.0.20348)/amd64", + "windows(10.0.20348+win32k)/amd64", + "linux/amd64", + }, formatAll(got)) +} + +func formatAll(pp []ocispecs.Platform) []string { + out := make([]string, 0, len(pp)) + for _, p := range pp { + out = append(out, platforms.FormatAll(p)) + } + return out +}