From 8c0d9f9835bbe848b9c6f6f4a3a23f7dc97de927 Mon Sep 17 00:00:00 2001 From: Michael Weibel Date: Mon, 10 Feb 2025 15:55:25 +0100 Subject: [PATCH] use windowsMatchComparer for OSVersion match order Windows OS version should match based on the full OSVersion. When sorting a manifest, the entries should be sorted using the `Less` function. Signed-off-by: Michael Weibel --- defaults_windows.go | 2 +- platform_windows_compat.go | 15 +------ platform_windows_compat_test.go | 75 +++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 15 deletions(-) diff --git a/defaults_windows.go b/defaults_windows.go index 0165ade..64e2846 100644 --- a/defaults_windows.go +++ b/defaults_windows.go @@ -38,5 +38,5 @@ func DefaultSpec() specs.Platform { // Default returns the current platform's default platform specification. func Default() MatchComparer { - return Only(DefaultSpec()) + return &windowsMatchComparer{Matcher: NewMatcher(DefaultSpec())} } diff --git a/platform_windows_compat.go b/platform_windows_compat.go index f55f608..f31ebe0 100644 --- a/platform_windows_compat.go +++ b/platform_windows_compat.go @@ -135,18 +135,6 @@ func getWindowsOSVersion(osVersionPrefix string) windowsOSVersion { } } -func winRevision(v string) int { - parts := strings.Split(v, ".") - if len(parts) < 4 { - return 0 - } - r, err := strconv.Atoi(parts[3]) - if err != nil { - return 0 - } - return r -} - type windowsVersionMatcher struct { windowsOSVersion } @@ -170,8 +158,7 @@ type windowsMatchComparer struct { func (c *windowsMatchComparer) Less(p1, p2 specs.Platform) bool { m1, m2 := c.Match(p1), c.Match(p2) if m1 && m2 { - r1, r2 := winRevision(p1.OSVersion), winRevision(p2.OSVersion) - return r1 > r2 + return p1.OSVersion > p2.OSVersion } return m1 && !m2 } diff --git a/platform_windows_compat_test.go b/platform_windows_compat_test.go index 4920a97..7a506a4 100644 --- a/platform_windows_compat_test.go +++ b/platform_windows_compat_test.go @@ -18,7 +18,10 @@ package platforms import ( "fmt" + "sort" "testing" + + specs "github.com/opencontainers/image-spec/specs-go/v1" ) // Test the platform compatibility of the different OS Versions @@ -110,3 +113,75 @@ func Test_PlatformCompat(t *testing.T) { }) } } + +func Test_PlatformOrder(t *testing.T) { + linuxPlatform := specs.Platform{ + Architecture: "amd64", + OS: "linux", + OSVersion: "", + OSFeatures: nil, + Variant: "", + } + ws2022Platform := specs.Platform{ + Architecture: "amd64", + OS: "windows", + OSVersion: "10.0.20348.3091", + OSFeatures: nil, + Variant: "", + } + ws2025Platform := specs.Platform{ + Architecture: "amd64", + OS: "windows", + OSVersion: "10.0.26100.2894", + OSFeatures: nil, + Variant: "", + } + ws2025Rev3000Platform := specs.Platform{ + Architecture: "amd64", + OS: "windows", + OSVersion: "10.0.26100.3000", + OSFeatures: nil, + Variant: "", + } + + tt := []struct { + name string + hostPlatform specs.Platform + platforms []specs.Platform + wantPlatform specs.Platform + }{ + { + name: "Windows Server 2022 should select 2022", + hostPlatform: ws2022Platform, + platforms: []specs.Platform{linuxPlatform, ws2022Platform, ws2025Platform}, + wantPlatform: ws2022Platform, + }, + { + name: "Windows Server 2025 should select 2025", + hostPlatform: ws2025Platform, + platforms: []specs.Platform{linuxPlatform, ws2022Platform, ws2025Platform}, + wantPlatform: ws2025Platform, + }, + { + name: "Windows Server 2025 should select 2025 latest rev", + hostPlatform: ws2025Platform, + platforms: []specs.Platform{linuxPlatform, ws2022Platform, ws2025Rev3000Platform}, + wantPlatform: ws2025Rev3000Platform, + }, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + comparer := &windowsMatchComparer{Matcher: NewMatcher(tc.hostPlatform)} + + sort.SliceStable(tc.platforms, func(i, j int) bool { + return comparer.Less(tc.platforms[i], tc.platforms[j]) + }) + + if tc.platforms[0].OS != tc.wantPlatform.OS || tc.platforms[0].OSVersion != tc.wantPlatform.OSVersion { + t.Errorf("Platform mismatch, want %q/%q, got %q/%q", tc.wantPlatform.OS, tc.wantPlatform.OSVersion, tc.platforms[0].OS, tc.platforms[0].OSVersion) + } + }) + } + +}