diff --git a/pkg/machine/fedora.go b/pkg/machine/fedora.go index 4972652694..cf9bbb793d 100644 --- a/pkg/machine/fedora.go +++ b/pkg/machine/fedora.go @@ -18,7 +18,8 @@ import ( ) const ( - githubLatestReleaseURL = "https://github.com/containers/podman-wsl-fedora/releases/latest/download/rootfs.tar.xz" + githubX86ReleaseURL = "https://github.com/containers/podman-wsl-fedora/releases/latest/download/rootfs.tar.xz" + githubArmReleaseURL = "https://github.com/containers/podman-wsl-fedora-arm/releases/latest/download/rootfs.tar.xz" ) type FedoraDownload struct { @@ -26,7 +27,7 @@ type FedoraDownload struct { } func NewFedoraDownloader(vmType, vmName, releaseStream string) (DistributionDownload, error) { - downloadURL, version, size, err := getFedoraDownload(githubLatestReleaseURL) + downloadURL, version, arch, size, err := getFedoraDownload() if err != nil { return nil, err } @@ -36,7 +37,7 @@ func NewFedoraDownloader(vmType, vmName, releaseStream string) (DistributionDown return nil, err } - imageName := fmt.Sprintf("fedora-podman-%s.tar.xz", version) + imageName := fmt.Sprintf("fedora-podman-%s-%s.tar.xz", arch, version) f := FedoraDownload{ Download: Download{ @@ -80,21 +81,32 @@ func (f FedoraDownload) CleanCache() error { return removeImageAfterExpire(f.CacheDir, expire) } -func getFedoraDownload(releaseURL string) (*url.URL, string, int64, error) { +func getFedoraDownload() (*url.URL, string, string, int64, error) { + var releaseURL string + arch := determineFedoraArch() + switch arch { + case "arm64": + releaseURL = githubArmReleaseURL + case "amd64": + releaseURL = githubX86ReleaseURL + default: + return nil, "", "", -1, fmt.Errorf("CPU architecture %q is not supported", arch) + } + downloadURL, err := url.Parse(releaseURL) if err != nil { - return nil, "", -1, fmt.Errorf("invalid URL generated from discovered Fedora file: %s: %w", releaseURL, err) + return nil, "", "", -1, fmt.Errorf("invalid URL generated from discovered Fedora file: %s: %w", releaseURL, err) } resp, err := http.Head(releaseURL) if err != nil { - return nil, "", -1, fmt.Errorf("head request failed: %s: %w", releaseURL, err) + return nil, "", "", -1, fmt.Errorf("head request failed: %s: %w", releaseURL, err) } _ = resp.Body.Close() contentLen := resp.ContentLength if resp.StatusCode != http.StatusOK { - return nil, "", -1, fmt.Errorf("head request failed: %s: %w", releaseURL, err) + return nil, "", "", -1, fmt.Errorf("head request failed: %s: %w", releaseURL, err) } verURL := *downloadURL @@ -102,14 +114,14 @@ func getFedoraDownload(releaseURL string) (*url.URL, string, int64, error) { resp, err = http.Get(verURL.String()) if err != nil { - return nil, "", -1, fmt.Errorf("get request failed: %s: %w", verURL.String(), err) + return nil, "", "", -1, fmt.Errorf("get request failed: %s: %w", verURL.String(), err) } defer resp.Body.Close() bytes, err := io.ReadAll(&io.LimitedReader{R: resp.Body, N: 1024}) if err != nil { - return nil, "", -1, fmt.Errorf("failed reading: %s: %w", verURL.String(), err) + return nil, "", "", -1, fmt.Errorf("failed reading: %s: %w", verURL.String(), err) } - return downloadURL, strings.TrimSpace(string(bytes)), contentLen, nil + return downloadURL, strings.TrimSpace(string(bytes)), arch, contentLen, nil } diff --git a/pkg/machine/fedora_unix.go b/pkg/machine/fedora_unix.go new file mode 100644 index 0000000000..0fa1d1ad9f --- /dev/null +++ b/pkg/machine/fedora_unix.go @@ -0,0 +1,12 @@ +//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd +// +build darwin dragonfly freebsd linux netbsd openbsd + +package machine + +import ( + "runtime" +) + +func determineFedoraArch() string { + return runtime.GOARCH +} diff --git a/pkg/machine/fedora_windows.go b/pkg/machine/fedora_windows.go new file mode 100644 index 0000000000..ff25520e0c --- /dev/null +++ b/pkg/machine/fedora_windows.go @@ -0,0 +1,32 @@ +package machine + +import ( + "runtime" + "syscall" + + "github.com/sirupsen/logrus" + "golang.org/x/sys/windows" +) + +func determineFedoraArch() string { + const fallbackMsg = "this may result in the wrong Linux arch under emulation" + var machine, native uint16 + current, _ := syscall.GetCurrentProcess() + + if err := windows.IsWow64Process2(windows.Handle(current), &machine, &native); err != nil { + logrus.Warnf("Failure detecting native system architecture, %s: %w", fallbackMsg, err) + // Fall-back to binary arch + return runtime.GOARCH + } + + switch native { + // Only care about archs in use with WSL + case 0xAA64: + return "arm64" + case 0x8664: + return "amd64" + default: + logrus.Warnf("Unknown or unsupported native system architecture [%d], %s", fallbackMsg) + return runtime.GOARCH + } +}