Skip to content

Commit 4101c78

Browse files
committed
feat: add WSL2 driver
Signed-off-by: Justin Alvarez <alvajus@amazon.com>
1 parent 93eab33 commit 4101c78

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1577
-153
lines changed

Makefile

+11
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,17 @@ GO_BUILDTAGS += no_vz
2222
endif
2323
endif
2424

25+
ifeq ($(GOOS),windows)
26+
WINVER_MAJOR=$(shell powershell.exe "[System.Environment]::OSVersion.Version.Major")
27+
ifeq ($(WINVER_MAJOR),10)
28+
WINVER_BUILD=$(shell powershell.exe "[System.Environment]::OSVersion.Version.Build")
29+
WINVER_BUILD_HIGH_ENOUGH=$(shell powershell.exe $(WINVER_BUILD) -ge 19041)
30+
ifeq ($(WINVER_BUILD_HIGH_ENOUGH),False)
31+
GO_BUILDTAGS += no_wsl
32+
endif
33+
endif
34+
endif
35+
2536
PACKAGE := github.com/lima-vm/lima
2637

2738
VERSION=$(shell git describe --match 'v[0-9]*' --dirty='.m' --always --tags)

cmd/lima-guestagent/daemon_linux.go

+39-7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"errors"
5+
"fmt"
56
"net"
67
"net/http"
78
"os"
@@ -10,6 +11,7 @@ import (
1011
"github.com/gorilla/mux"
1112
"github.com/lima-vm/lima/pkg/guestagent"
1213
"github.com/lima-vm/lima/pkg/guestagent/api/server"
14+
"github.com/mdlayher/vsock"
1315
"github.com/sirupsen/logrus"
1416
"github.com/spf13/cobra"
1517
)
@@ -21,6 +23,9 @@ func newDaemonCommand() *cobra.Command {
2123
RunE: daemonAction,
2224
}
2325
daemonCommand.Flags().Duration("tick", 3*time.Second, "tick for polling events")
26+
daemonCommand.Flags().Int("tcp-port", 0, "use tcp server instead a UNIX socket")
27+
daemonCommand.Flags().Int("vsock-port", 0, "use vsock server instead a UNIX socket")
28+
daemonCommand.MarkFlagsMutuallyExclusive("tcp-port", "vsock-port")
2429
return daemonCommand
2530
}
2631

@@ -30,6 +35,14 @@ func daemonAction(cmd *cobra.Command, _ []string) error {
3035
if err != nil {
3136
return err
3237
}
38+
tcpPort, err := cmd.Flags().GetInt("tcp-port")
39+
if err != nil {
40+
return err
41+
}
42+
vSockPort, err := cmd.Flags().GetInt("vsock-port")
43+
if err != nil {
44+
return err
45+
}
3346
if tick == 0 {
3447
return errors.New("tick must be specified")
3548
}
@@ -60,13 +73,32 @@ func daemonAction(cmd *cobra.Command, _ []string) error {
6073
if err != nil {
6174
return err
6275
}
63-
l, err := net.Listen("unix", socket)
64-
if err != nil {
65-
return err
66-
}
67-
if err := os.Chmod(socket, 0777); err != nil {
68-
return err
76+
77+
var l net.Listener
78+
if vSockPort != 0 {
79+
vsockL, err := vsock.Listen(uint32(vSockPort), nil)
80+
if err != nil {
81+
return err
82+
}
83+
l = vsockL
84+
logrus.Infof("serving the guest agent on vsock port: %d", vSockPort)
85+
} else if tcpPort != 0 {
86+
tcpL, err := net.Listen("tcp", fmt.Sprintf(":%d", tcpPort))
87+
if err != nil {
88+
return err
89+
}
90+
l = tcpL
91+
logrus.Infof("serving the guest agent at :%d", tcpPort)
92+
} else {
93+
socketL, err := net.Listen("unix", socket)
94+
if err != nil {
95+
return err
96+
}
97+
if err := os.Chmod(socket, 0777); err != nil {
98+
return err
99+
}
100+
l = socketL
101+
logrus.Infof("serving the guest agent on %q", socket)
69102
}
70-
logrus.Infof("serving the guest agent on %q", socket)
71103
return srv.Serve(l)
72104
}

cmd/lima-guestagent/install_systemd_linux.go

+27-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
_ "embed"
55
"errors"
6+
"fmt"
67
"os"
78
"os/exec"
89
"path/filepath"
@@ -19,11 +20,22 @@ func newInstallSystemdCommand() *cobra.Command {
1920
Short: "install a systemd unit (user)",
2021
RunE: installSystemdAction,
2122
}
23+
installSystemdCommand.Flags().Int("tcp-port", 0, "use tcp server on specified port")
24+
installSystemdCommand.Flags().Int("vsock-port", 0, "use vsock server on specified port")
25+
installSystemdCommand.MarkFlagsMutuallyExclusive("tcp-port", "vsock-port")
2226
return installSystemdCommand
2327
}
2428

25-
func installSystemdAction(_ *cobra.Command, _ []string) error {
26-
unit, err := generateSystemdUnit()
29+
func installSystemdAction(cmd *cobra.Command, _ []string) error {
30+
tcp, err := cmd.Flags().GetInt("tcp-port")
31+
if err != nil {
32+
return err
33+
}
34+
vsock, err := cmd.Flags().GetInt("vsock-port")
35+
if err != nil {
36+
return err
37+
}
38+
unit, err := generateSystemdUnit(tcp, vsock)
2739
if err != nil {
2840
return err
2941
}
@@ -40,11 +52,11 @@ func installSystemdAction(_ *cobra.Command, _ []string) error {
4052
return err
4153
}
4254
logrus.Infof("Written file %q", unitPath)
43-
argss := [][]string{
55+
args := [][]string{
4456
{"daemon-reload"},
4557
{"enable", "--now", "lima-guestagent.service"},
4658
}
47-
for _, args := range argss {
59+
for _, args := range args {
4860
cmd := exec.Command("systemctl", append([]string{"--system"}, args...)...)
4961
cmd.Stdout = os.Stdout
5062
cmd.Stderr = os.Stderr
@@ -60,13 +72,23 @@ func installSystemdAction(_ *cobra.Command, _ []string) error {
6072
//go:embed lima-guestagent.TEMPLATE.service
6173
var systemdUnitTemplate string
6274

63-
func generateSystemdUnit() ([]byte, error) {
75+
func generateSystemdUnit(tcpPort, vsockPort int) ([]byte, error) {
6476
selfExeAbs, err := os.Executable()
6577
if err != nil {
6678
return nil, err
6779
}
80+
81+
var args []string
82+
if tcpPort != 0 {
83+
args = append(args, fmt.Sprintf("--tcp-port %d", tcpPort))
84+
}
85+
if vsockPort != 0 {
86+
args = append(args, fmt.Sprintf("--vsock-port %d", vsockPort))
87+
}
88+
6889
m := map[string]string{
6990
"Binary": selfExeAbs,
91+
"Args": strings.Join(args, " "),
7092
}
7193
return textutil.ExecuteTemplate(systemdUnitTemplate, m)
7294
}

cmd/lima-guestagent/lima-guestagent.TEMPLATE.service

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Description=lima-guestagent
33

44
[Service]
5-
ExecStart={{.Binary}} daemon
5+
ExecStart={{.Binary}} daemon {{.Args}}
66
Type=simple
77
Restart=on-failure
88

cmd/limactl/delete.go

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ func deleteInstance(ctx context.Context, inst *store.Instance, force bool) error
6262
if err := os.RemoveAll(inst.Dir); err != nil {
6363
return fmt.Errorf("failed to remove %q: %w", inst.Dir, err)
6464
}
65+
6566
return nil
6667
}
6768

cmd/limactl/hostagent.go

+1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ func hostagentAction(cmd *cobra.Command, args []string) error {
9898
return err
9999
}
100100
l, err := net.Listen("unix", socket)
101+
logrus.Infof("hostagent socket created at %s", socket)
101102
if err != nil {
102103
return err
103104
}

cmd/limactl/shell.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ func shellAction(cmd *cobra.Command, args []string) error {
184184
sshArgs = append(sshArgs, []string{
185185
"-q",
186186
"-p", strconv.Itoa(inst.SSHLocalPort),
187-
"127.0.0.1",
187+
inst.SSHAddress,
188188
"--",
189189
script,
190190
}...)

examples/default.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,11 @@ hostResolver:
442442
# 🟢 Builtin default: /usr/local
443443
guestInstallPrefix: null
444444

445+
# Adjust options for the guestAgent which runs inside of the Linux VM
446+
guestAgent:
447+
# 🟢 Builtin default: UNIX (macOS, Linux), VSOCK (Windows/WSL2)
448+
protocol: null
449+
445450
# ===================================================================== #
446451
# GLOBAL DEFAULTS AND OVERRIDES
447452
# ===================================================================== #

examples/experimental/wsl.yaml

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# ===================================================================== #
2+
# BASIC CONFIGURATION
3+
# ===================================================================== #
4+
5+
# Default values in this YAML file are specified by `null` instead of Lima's "builtin default" values,
6+
# so they can be overridden by the $LIMA_HOME/_config/default.yaml mechanism documented at the end of this file.
7+
8+
# VM type: "qemu" or "vz" (on macOS 13 and later).
9+
# The vmType can be specified only on creating the instance.
10+
# The vmType of existing instances cannot be changed.
11+
# 🟢 Builtin default: "qemu"
12+
vmType: wsl2
13+
14+
# OpenStack-compatible disk image.
15+
# 🟢 Builtin default: null (must be specified)
16+
# 🔵 This file: Ubuntu 23.04 Lunar Lobster images
17+
images:
18+
# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
19+
- location: "file://C:/Users/Administrator/Downloads/fedora-38-cloud-rootfs.tar"
20+
arch: "x86_64"
21+
digest: "sha256:112400224d801c3781c1e301408685920ba980024bfb20877628a0bd82fdc574"
22+
23+
mountType: wsl
24+
25+
containerd:
26+
system: true
27+
user: false

go.mod

+5-4
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ require (
5050

5151
require (
5252
github.com/Code-Hex/go-infinity-channel v1.0.0 // indirect
53-
github.com/Microsoft/go-winio v0.6.1 // indirect
53+
github.com/Microsoft/go-winio v0.6.1
5454
github.com/VividCortex/ewma v1.2.0 // indirect
5555
github.com/a8m/envsubst v1.4.2 // indirect
5656
github.com/alecthomas/participle/v2 v2.0.0 // indirect
@@ -89,7 +89,7 @@ require (
8989
github.com/mattn/go-colorable v0.1.13 // indirect
9090
github.com/mattn/go-runewidth v0.0.14 // indirect
9191
github.com/mdlayher/socket v0.4.1 // indirect
92-
github.com/mdlayher/vsock v1.2.1 // indirect
92+
github.com/mdlayher/vsock v1.2.1
9393
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
9494
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
9595
github.com/modern-go/reflect2 v1.0.2 // indirect
@@ -103,11 +103,12 @@ require (
103103
go.uber.org/atomic v1.7.0 // indirect
104104
go.uber.org/multierr v1.7.0 // indirect
105105
golang.org/x/crypto v0.12.0 // indirect
106-
golang.org/x/mod v0.10.0 // indirect
106+
golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b
107+
golang.org/x/mod v0.11.0 // indirect
107108
golang.org/x/net v0.14.0 // indirect
108109
golang.org/x/oauth2 v0.8.0 // indirect
109110
golang.org/x/term v0.11.0 // indirect
110-
golang.org/x/text v0.12.0 // indirect
111+
golang.org/x/text v0.12.0
111112
golang.org/x/time v0.3.0 // indirect
112113
golang.org/x/tools v0.9.3 // indirect
113114
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect

go.sum

+4-2
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,8 @@ golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0
296296
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
297297
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
298298
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
299+
golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b h1:r+vk0EmXNmekl0S0BascoeeoHk/L7wmaW2QF90K+kYI=
300+
golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
299301
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
300302
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
301303
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
@@ -305,8 +307,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
305307
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
306308
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
307309
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
308-
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
309-
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
310+
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
311+
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
310312
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
311313
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
312314
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=

pkg/cidata/cidata.TEMPLATE.d/boot.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ fi
7272

7373
# Signal that provisioning is done. The instance-id in the meta-data file changes on every boot,
7474
# so any copy from a previous boot cycle will have different content.
75-
cp "${LIMA_CIDATA_MNT}"/meta-data /run/lima-boot-done
75+
sudo cp "${LIMA_CIDATA_MNT}"/meta-data /run/lima-boot-done
7676

7777
INFO "Exiting with code $CODE"
7878
exit "$CODE"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/bin/sh
2+
# This script replaces the cloud-init functionality of creating a user and setting its SSH keys
3+
# when using a WSL2 VM.
4+
[ "$LIMA_CIDATA_VMTYPE" = "wsl2" ] || exit 0
5+
6+
# create user
7+
sudo useradd -u "${LIMA_CIDATA_UID}" "${LIMA_CIDATA_USER}" -d /home/"${LIMA_CIDATA_USER}".linux/
8+
sudo mkdir /home/"${LIMA_CIDATA_USER}".linux/.ssh/
9+
sudo cp "${LIMA_CIDATA_MNT}"/ssh_authorized_keys /home/"${LIMA_CIDATA_USER}".linux/.ssh/authorized_keys
10+
sudo chown "${LIMA_CIDATA_USER}" /home/"${LIMA_CIDATA_USER}".linux/.ssh/authorized_keys
11+
12+
# add lima to sudoers
13+
sudo echo "lima ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/99_lima_sudoers
14+
15+
# copy some CIDATA to the hardcoded path for requirement checks (TODO: make this not hardcoded)
16+
sudo mkdir -p /mnt/lima-cidata
17+
sudo cp "${LIMA_CIDATA_MNT}"/meta-data /mnt/lima-cidata/meta-data

pkg/cidata/cidata.TEMPLATE.d/boot/25-guestagent-base.sh

+5-1
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,9 @@ else
4040
# Remove legacy systemd service
4141
rm -f "/home/${LIMA_CIDATA_USER}.linux/.config/systemd/user/lima-guestagent.service"
4242

43-
sudo "${LIMA_CIDATA_GUEST_INSTALL_PREFIX}"/bin/lima-guestagent install-systemd
43+
if [ "$LIMA_CIDATA_VMTYPE" = "wsl2" ]; then
44+
sudo "${LIMA_CIDATA_GUEST_INSTALL_PREFIX}"/bin/lima-guestagent install-systemd --vsock-port "${LIMA_CIDATA_VSOCK_PORT}"
45+
else
46+
sudo "${LIMA_CIDATA_GUEST_INSTALL_PREFIX}"/bin/lima-guestagent install-systemd
47+
fi
4448
fi

pkg/cidata/cidata.TEMPLATE.d/lima.env

+2
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,5 @@ LIMA_CIDATA_SKIP_DEFAULT_DEPENDENCY_RESOLUTION=1
3838
{{- else}}
3939
LIMA_CIDATA_SKIP_DEFAULT_DEPENDENCY_RESOLUTION=
4040
{{- end}}
41+
LIMA_CIDATA_VMTYPE={{ .VMType }}
42+
LIMA_CIDATA_VSOCK_PORT={{ .VSockPort }}

pkg/cidata/cidata.TEMPLATE.d/user-data

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ write_files:
3333
LIMA_CIDATA_MNT="/mnt/lima-cidata"
3434
LIMA_CIDATA_DEV="/dev/disk/by-label/cidata"
3535
mkdir -p -m 700 "${LIMA_CIDATA_MNT}"
36-
mount -o ro,mode=0700,dmode=0700,overriderockperm,exec,uid=0 "${LIMA_CIDATA_DEV}" "${LIMA_CIDATA_MNT}"
3736
export LIMA_CIDATA_MNT
37+
mount -o ro,mode=0700,dmode=0700,overriderockperm,exec,uid=0 "${LIMA_CIDATA_DEV}" "${LIMA_CIDATA_MNT}"
3838
exec "${LIMA_CIDATA_MNT}"/boot.sh
3939
owner: root:root
4040
path: /var/lib/cloud/scripts/per-boot/00-lima.boot.sh

0 commit comments

Comments
 (0)