Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 16 additions & 9 deletions platform_windows_compat.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,26 @@ func checkWindowsHostAndContainerCompat(host, ctr windowsOSVersion) bool {
return host.Build == ctr.Build
}

// Find the latest LTSC version that is earlier than the host version.
// This is the earliest version of container that the host can run.
// Find the floor of the compatible container range. Per the Windows stable
// ABI policy, every host from LTSC N up to (but not including) LTSC N+1 can
// run containers from LTSC N-1 up to the host build.
//
// If the host version is an LTSC, then it supports compatibility with
// everything from the previous LTSC up to itself, so we want supportedLTSCRelease
// to be the previous entry.
// So we find the largest LTSC <= host.Build, then step one entry back to
// get the floor. If host.Build is past the latest LTSC in the list
// (e.g. a 26200 host, which is in the WS2025 generation), the floor is
// still the previous LTSC (20348), not the latest LTSC itself.
//
// If no match is found, then we know that the host is LTSC2022 exactly,
// since we already checked that it's not less than LTSC2022.
// If host is the very first LTSC (or no entry matches, which is impossible
// here since we already checked host.Build >= ltsc2022), use that LTSC as
// the floor.
var supportedLTSCRelease uint16 = ltsc2022
for i := len(compatLTSCReleases) - 1; i >= 0; i-- {
if host.Build > compatLTSCReleases[i] {
supportedLTSCRelease = compatLTSCReleases[i]
if host.Build >= compatLTSCReleases[i] {
if i == 0 {
supportedLTSCRelease = compatLTSCReleases[i]
} else {
supportedLTSCRelease = compatLTSCReleases[i-1]
}
break
}
}
Expand Down
35 changes: 35 additions & 0 deletions platform_windows_compat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,28 @@ func Test_PlatformCompat(t *testing.T) {
ctrOS: v22H2Win11,
shouldRun: true,
},
// A WS2025-generation host with a build past the latest LTSC (e.g.
// 26200) must still accept WS2022 containers per the stable ABI policy.
{
hostOS: 26200,
ctrOS: ltsc2022,
shouldRun: true,
},
{
hostOS: 26200,
ctrOS: ltsc2025,
shouldRun: true,
},
{
hostOS: 26200,
ctrOS: v22H2Win11,
shouldRun: true,
},
{
hostOS: 26200,
ctrOS: ltsc2019,
shouldRun: false,
},
} {
t.Run(fmt.Sprintf("Host_%d_Ctr_%d", tc.hostOS, tc.ctrOS), func(t *testing.T) {
hostOSVersion := windowsOSVersion{
Expand Down Expand Up @@ -143,6 +165,13 @@ func Test_PlatformOrder(t *testing.T) {
OSFeatures: nil,
Variant: "",
}
ws2025PatchedPlatform := specs.Platform{
Architecture: "amd64",
OS: "windows",
OSVersion: "10.0.26200.0",
OSFeatures: nil,
Variant: "",
}

tt := []struct {
name string
Expand All @@ -168,6 +197,12 @@ func Test_PlatformOrder(t *testing.T) {
platforms: []specs.Platform{linuxPlatform, ws2022Platform, ws2025Rev3000Platform},
wantPlatform: ws2025Rev3000Platform,
},
{
name: "Windows Server 2025 host past latest LTSC should still accept 2022",
hostPlatform: ws2025PatchedPlatform,
platforms: []specs.Platform{linuxPlatform, ws2022Platform},
wantPlatform: ws2022Platform,
},
}

for _, tc := range tt {
Expand Down
Loading