1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
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")
}
|