Skip to content
Draft
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
21 changes: 20 additions & 1 deletion pkg/configurer/windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func (c WindowsConfigurer) InstallMCRLicense(h os.Host, lic string) error {

// InstallMCR install MCR on Windows.
func (c WindowsConfigurer) InstallMCR(h os.Host, engineConfig commonconfig.MCRConfig) error {
version := "latest"
version := windowsInstallerVersion(engineConfig.Channel)

installerPath, getInstallerErr := GetInstaller(engineConfig.InstallURLWindows)
if getInstallerErr != nil {
Expand Down Expand Up @@ -124,6 +124,25 @@ func isExitCode3010(err error) bool {
return err != nil && strings.Contains(err.Error(), "non-zero exit code: 3010")
}

// windowsInstallerVersion returns the version token to pass as DOCKER_VERSION
// to install.ps1. For non-FIPS channels the repo publishes only
// docker-latest.zip so "latest" is correct. For FIPS channels (suffix /fips)
// the repo publishes docker-<version>+fips.zip but no docker-latest+fips.zip,
// so the version must be extracted from the channel string.
func windowsInstallerVersion(channel string) string {
if !strings.HasSuffix(channel, "/fips") {
return "latest"
}
ch := strings.TrimSuffix(channel, "/fips")
parts := strings.Split(ch, "-")
for i, p := range parts {
if len(p) > 0 && p[0] >= '0' && p[0] <= '9' {
return strings.Join(parts[i:], "-")
}
}
return "latest"
}

// Reboot triggers an immediate forced restart by scheduling a SYSTEM-context
// one-shot task that runs 'shutdown /r /f /t 5', then immediately triggering
// and deleting it within the 5-second countdown window.
Expand Down
32 changes: 32 additions & 0 deletions pkg/configurer/windows_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package configurer

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestWindowsInstallerVersion(t *testing.T) {
tests := []struct {
channel string
want string
}{
// Standard channels — always "latest"; docker-latest.zip is published
{"stable-29.2", "latest"},
{"stable-25.0", "latest"},
{"ee-stable-29.2", "latest"},
// FIPS channels — version extracted; only docker-<version>+fips.zip is published
{"stable-29.2.1/fips", "29.2.1"},
{"stable-29.4.1/fips", "29.4.1"},
{"test-29.4.1/fips", "29.4.1"},
// FIPS RC channel
{"test-29.4.1-rc3/fips", "29.4.1-rc3"},
// FIPS channel with no parseable version — falls back to latest
{"stable/fips", "latest"},
}
for _, tt := range tests {
t.Run(tt.channel, func(t *testing.T) {
require.Equal(t, tt.want, windowsInstallerVersion(tt.channel), "channel=%q", tt.channel)
})
}
}
Loading