podman
105 строк · 2.3 Кб
1//go:build windows
2
3package main
4
5import (
6"fmt"
7"os"
8"path"
9"syscall"
10"time"
11"unsafe"
12
13"github.com/containers/podman/v5/pkg/machine/wsl/wutil"
14"github.com/sirupsen/logrus"
15"golang.org/x/sys/windows/svc/eventlog"
16)
17
18const (
19//nolint:stylecheck
20MB_ICONWARNING = 0x00000030
21//nolint:stylecheck
22MB_OK = 0x00000000
23//nolint:stylecheck
24MB_DEFBUTTON1 = 0x00000000
25)
26
27const KernelWarning = "WSL Kernel installation did not complete successfully. " +
28"Podman machine will attempt to install this at a later time. " +
29"You can also manually complete the installation using the " +
30"\"wsl --update\" command."
31
32func setupLogging(name string) (*eventlog.Log, error) {
33// Reuse the Built-in .NET Runtime Source so that we do not
34// have to provide a message table and modify the system
35// event configuration
36log, err := eventlog.Open(".NET Runtime")
37if err != nil {
38return nil, err
39}
40
41logrus.AddHook(NewEventHook(log, name))
42logrus.SetLevel(logrus.InfoLevel)
43
44return log, nil
45}
46
47func installWslKernel() error {
48logrus.Info("Installing WSL Kernel update")
49var (
50err error
51)
52backoff := 500 * time.Millisecond
53for i := 1; i < 6; i++ {
54err = wutil.SilentExec(wutil.FindWSL(), "--update")
55if err == nil {
56break
57}
58
59// In case of unusual circumstances (e.g. race with installer actions)
60// retry a few times
61logrus.Warn("An error occurred attempting the WSL Kernel update, retrying...")
62time.Sleep(backoff)
63backoff *= 2
64}
65
66if err != nil {
67err = fmt.Errorf("could not install WSL Kernel: %w", err)
68}
69
70return err
71}
72
73// Creates an "warn" style pop-up window
74func warn(title string, caption string) int {
75format := MB_ICONWARNING | MB_OK | MB_DEFBUTTON1
76
77user32 := syscall.NewLazyDLL("user32.dll")
78captionPtr, _ := syscall.UTF16PtrFromString(caption)
79titlePtr, _ := syscall.UTF16PtrFromString(title)
80ret, _, _ := user32.NewProc("MessageBoxW").Call(
81uintptr(0),
82uintptr(unsafe.Pointer(captionPtr)),
83uintptr(unsafe.Pointer(titlePtr)),
84uintptr(format))
85
86return int(ret)
87}
88
89func main() {
90args := os.Args
91_, _ = setupLogging(path.Base(args[0]))
92if wutil.IsWSLInstalled() {
93// nothing to do
94logrus.Info("WSL Kernel already installed")
95return
96}
97
98result := installWslKernel()
99if result != nil {
100logrus.Error(result.Error())
101_ = warn("Podman Setup", KernelWarning)
102}
103
104logrus.Info("WSL Kernel update successful")
105}
106