From bdc3040586839e95d90e74f3d38a227150c73e75 Mon Sep 17 00:00:00 2001 From: "Jason T. Greene" Date: Fri, 18 Aug 2023 23:08:41 -0500 Subject: [PATCH] Validate current generation of WSL2 with user-mode-networking Fail with a helpful message when older version is present. [NO NEW TESTS NEEDED] Signed-off-by: Jason T. Greene --- pkg/machine/wsl/machine.go | 6 +++++ pkg/machine/wsl/usermodenet.go | 20 +++++++++++++++ pkg/machine/wsl/wutil/wutil.go | 47 +++++++++++++++++++++++++--------- 3 files changed, 61 insertions(+), 12 deletions(-) diff --git a/pkg/machine/wsl/machine.go b/pkg/machine/wsl/machine.go index 27745ce274..f24eccb96f 100644 --- a/pkg/machine/wsl/machine.go +++ b/pkg/machine/wsl/machine.go @@ -338,6 +338,12 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) { v.Rootful = opts.Rootful v.Version = currentMachineVersion + if v.UserModeNetworking { + if err := verifyWSLUserModeCompat(); err != nil { + return false, err + } + } + if err := downloadDistro(v, opts); err != nil { return false, err } diff --git a/pkg/machine/wsl/usermodenet.go b/pkg/machine/wsl/usermodenet.go index 798c248a16..9af0072de3 100644 --- a/pkg/machine/wsl/usermodenet.go +++ b/pkg/machine/wsl/usermodenet.go @@ -10,6 +10,7 @@ import ( "path/filepath" "github.com/containers/podman/v4/pkg/machine" + "github.com/containers/podman/v4/pkg/machine/wsl/wutil" "github.com/containers/podman/v4/pkg/specgen" "github.com/sirupsen/logrus" ) @@ -53,6 +54,21 @@ ip route add $ROUTE rm -rf /mnt/wsl/podman-usermodenet ` +func verifyWSLUserModeCompat() error { + if wutil.IsWSLStoreVersionInstalled() { + return nil + } + + prefix := "" + if !winVersionAtLeast(10, 0, 19043) { + prefix = "upgrade to 22H2, " + } + + return fmt.Errorf("user-mode networking requires a newer version of WSL: "+ + "%sapply all outstanding windows updates, and then run `wsl --update`", + prefix) +} + func (v *MachineVM) startUserModeNetworking() error { if !v.UserModeNetworking { return nil @@ -299,6 +315,10 @@ func (v *MachineVM) obtainUserModeNetLock() (*fileLock, error) { } func changeDistUserModeNetworking(dist string, user string, image string, enable bool) error { + if err := verifyWSLUserModeCompat(); err != nil { + return err + } + // Only install if user-mode is being enabled and there was an image path passed if enable && len(image) > 0 { if err := installUserModeDist(dist, image); err != nil { diff --git a/pkg/machine/wsl/wutil/wutil.go b/pkg/machine/wsl/wutil/wutil.go index b1fb02afd5..ee72c665b4 100644 --- a/pkg/machine/wsl/wutil/wutil.go +++ b/pkg/machine/wsl/wutil/wutil.go @@ -5,6 +5,7 @@ package wutil import ( "bufio" + "io" "os/exec" "strings" "syscall" @@ -37,19 +38,41 @@ func IsWSLInstalled() bool { if err = cmd.Start(); err != nil { return false } - scanner := bufio.NewScanner(transform.NewReader(out, unicode.UTF16(unicode.LittleEndian, unicode.UseBOM).NewDecoder())) - result := true - for scanner.Scan() { - line := scanner.Text() - // Windows 11 does not set an error exit code when a kernel is not avail - if strings.Contains(line, "kernel file is not found") { - result = false - break - } - } - if err := cmd.Wait(); !result || err != nil { + + kernelNotFound := matchOutputLine(out, "kernel file is not found") + + if err := cmd.Wait(); err != nil { return false } - return true + return !kernelNotFound +} + +func IsWSLStoreVersionInstalled() bool { + cmd := SilentExecCmd("wsl", "--version") + out, err := cmd.StdoutPipe() + cmd.Stderr = nil + if err != nil { + return false + } + if err = cmd.Start(); err != nil { + return false + } + hasVersion := matchOutputLine(out, "WSL version:") + if err := cmd.Wait(); err != nil { + return false + } + + return hasVersion +} + +func matchOutputLine(output io.ReadCloser, match string) bool { + scanner := bufio.NewScanner(transform.NewReader(output, unicode.UTF16(unicode.LittleEndian, unicode.UseBOM).NewDecoder())) + for scanner.Scan() { + line := scanner.Text() + if strings.Contains(line, match) { + return true + } + } + return false }