summaryrefslogtreecommitdiff
path: root/cmd/podman-wslkerninst/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/podman-wslkerninst/main.go')
-rw-r--r--cmd/podman-wslkerninst/main.go103
1 files changed, 103 insertions, 0 deletions
diff --git a/cmd/podman-wslkerninst/main.go b/cmd/podman-wslkerninst/main.go
new file mode 100644
index 000000000..0485db13c
--- /dev/null
+++ b/cmd/podman-wslkerninst/main.go
@@ -0,0 +1,103 @@
+//go:build windows
+// +build windows
+
+package main
+
+import (
+ "fmt"
+ "os"
+ "path"
+ "syscall"
+ "time"
+ "unsafe"
+
+ "github.com/containers/podman/v4/pkg/machine/wsl"
+ "github.com/sirupsen/logrus"
+ "golang.org/x/sys/windows/svc/eventlog"
+)
+
+const (
+ MB_ICONWARNING = 0x00000030
+ MB_OK = 0x00000000
+ MB_DEFBUTTON1 = 0x00000000
+)
+
+const KernelWarning = "WSL Kernel installation did not complete successfully. " +
+ "Podman machine will attempt to install this at a later time. " +
+ "You can also manually complete the installation using the " +
+ "\"wsl --update\" command."
+
+func setupLogging(name string) (*eventlog.Log, error) {
+ // Reuse the Built-in .NET Runtime Source so that we do not
+ // have to provide a messaage table and modify the system
+ // event configuration
+ log, err := eventlog.Open(".NET Runtime")
+ if err != nil {
+ return nil, err
+ }
+
+ logrus.AddHook(NewEventHook(log, name))
+ logrus.SetLevel(logrus.InfoLevel)
+
+ return log, nil
+}
+
+func installWslKernel() error {
+ logrus.Info("Installing WSL Kernel update")
+ var (
+ err error
+ )
+ backoff := 500 * time.Millisecond
+ for i := 1; i < 6; i++ {
+ err = wsl.SilentExec("wsl", "--update")
+ if err == nil {
+ break
+ }
+
+ // In case of unusual circumstances (e.g. race with installer actions)
+ // retry a few times
+ logrus.Warn("An error occurred attempting the WSL Kernel update, retrying...")
+ time.Sleep(backoff)
+ backoff *= 2
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could not install WSL Kernel: %w", err)
+ }
+
+ return err
+}
+
+// Creates an "warn" style pop-up window
+func warn(title string, caption string) int {
+ format := MB_ICONWARNING | MB_OK | MB_DEFBUTTON1
+
+ user32 := syscall.NewLazyDLL("user32.dll")
+ captionPtr, _ := syscall.UTF16PtrFromString(caption)
+ titlePtr, _ := syscall.UTF16PtrFromString(title)
+ ret, _, _ := user32.NewProc("MessageBoxW").Call(
+ uintptr(0),
+ uintptr(unsafe.Pointer(captionPtr)),
+ uintptr(unsafe.Pointer(titlePtr)),
+ uintptr(format))
+
+ return int(ret)
+}
+
+func main() {
+ args := os.Args
+ setupLogging(path.Base(args[0]))
+ if wsl.IsWSLInstalled() {
+ // nothing to do
+ logrus.Info("WSL Kernel already installed")
+ return
+ }
+
+ result := installWslKernel()
+ if result != nil {
+ logrus.Error(result.Error())
+ _ = warn("Podman Setup", KernelWarning)
+ }
+
+ logrus.Info("WSL Kernel update successful")
+}