Skip to content

Commit

Permalink
feat: add WSL2 driver
Browse files Browse the repository at this point in the history
Signed-off-by: Justin Alvarez <[email protected]>
  • Loading branch information
pendo324 committed Aug 15, 2023
1 parent 93eab33 commit bdc225f
Show file tree
Hide file tree
Showing 59 changed files with 1,652 additions and 140 deletions.
11 changes: 11 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@ GO_BUILDTAGS += no_vz
endif
endif

ifeq ($(GOOS),windows)
WINVER_MAJOR=$(shell powershell.exe "[System.Environment]::OSVersion.Version.Major")
ifeq ($(WINVER_MAJOR),10)
WINVER_BUILD=$(shell powershell.exe "[System.Environment]::OSVersion.Version.Build")
WINVER_BUILD_HIGH_ENOUGH=$(shell powershell.exe $(WINVER_BUILD) -ge 19041)
ifeq ($(WINVER_BUILD_HIGH_ENOUGH),False)
GO_BUILDTAGS += no_wsl
endif
endif
endif

PACKAGE := github.com/lima-vm/lima

VERSION=$(shell git describe --match 'v[0-9]*' --dirty='.m' --always --tags)
Expand Down
46 changes: 39 additions & 7 deletions cmd/lima-guestagent/daemon_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"errors"
"fmt"
"net"
"net/http"
"os"
Expand All @@ -10,6 +11,7 @@ import (
"github.com/gorilla/mux"
"github.com/lima-vm/lima/pkg/guestagent"
"github.com/lima-vm/lima/pkg/guestagent/api/server"
"github.com/mdlayher/vsock"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
Expand All @@ -21,6 +23,9 @@ func newDaemonCommand() *cobra.Command {
RunE: daemonAction,
}
daemonCommand.Flags().Duration("tick", 3*time.Second, "tick for polling events")
daemonCommand.Flags().Int("tcp-port", 0, "use tcp server instead a UNIX socket")
daemonCommand.Flags().Int("vsock-port", 0, "use vsock server instead a UNIX socket")
daemonCommand.MarkFlagsMutuallyExclusive("tcp-port", "vsock-port")
return daemonCommand
}

Expand All @@ -30,6 +35,14 @@ func daemonAction(cmd *cobra.Command, _ []string) error {
if err != nil {
return err
}
tcpPort, err := cmd.Flags().GetInt("tcp-port")
if err != nil {
return err
}
vSockPort, err := cmd.Flags().GetInt("vsock-port")
if err != nil {
return err
}
if tick == 0 {
return errors.New("tick must be specified")
}
Expand Down Expand Up @@ -60,13 +73,32 @@ func daemonAction(cmd *cobra.Command, _ []string) error {
if err != nil {
return err
}
l, err := net.Listen("unix", socket)
if err != nil {
return err
}
if err := os.Chmod(socket, 0777); err != nil {
return err

var l net.Listener
if vSockPort != 0 {
vsockL, err := vsock.Listen(uint32(vSockPort), nil)
if err != nil {
return err
}
l = vsockL
logrus.Infof("serving the guest agent on vsock port: %d", vSockPort)
} else if tcpPort != 0 {
tcpL, err := net.Listen("tcp", fmt.Sprintf(":%d", tcpPort))
if err != nil {
return err
}
l = tcpL
logrus.Infof("serving the guest agent at :%d", tcpPort)
} else {
socketL, err := net.Listen("unix", socket)
if err != nil {
return err
}
if err := os.Chmod(socket, 0777); err != nil {
return err
}
l = socketL
logrus.Infof("serving the guest agent on %q", socket)
}
logrus.Infof("serving the guest agent on %q", socket)
return srv.Serve(l)
}
32 changes: 27 additions & 5 deletions cmd/lima-guestagent/install_systemd_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
_ "embed"
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
Expand All @@ -19,11 +20,22 @@ func newInstallSystemdCommand() *cobra.Command {
Short: "install a systemd unit (user)",
RunE: installSystemdAction,
}
installSystemdCommand.Flags().Int("tcp-port", 0, "use tcp server on specified port")
installSystemdCommand.Flags().Int("vsock-port", 0, "use vsock server on specified port")
installSystemdCommand.MarkFlagsMutuallyExclusive("tcp-port", "vsock-port")
return installSystemdCommand
}

func installSystemdAction(_ *cobra.Command, _ []string) error {
unit, err := generateSystemdUnit()
func installSystemdAction(cmd *cobra.Command, _ []string) error {
tcp, err := cmd.Flags().GetInt("tcp-port")
if err != nil {
return err
}
vsock, err := cmd.Flags().GetInt("vsock-port")
if err != nil {
return err
}
unit, err := generateSystemdUnit(tcp, vsock)
if err != nil {
return err
}
Expand All @@ -40,11 +52,11 @@ func installSystemdAction(_ *cobra.Command, _ []string) error {
return err
}
logrus.Infof("Written file %q", unitPath)
argss := [][]string{
args := [][]string{
{"daemon-reload"},
{"enable", "--now", "lima-guestagent.service"},
}
for _, args := range argss {
for _, args := range args {
cmd := exec.Command("systemctl", append([]string{"--system"}, args...)...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
Expand All @@ -60,13 +72,23 @@ func installSystemdAction(_ *cobra.Command, _ []string) error {
//go:embed lima-guestagent.TEMPLATE.service
var systemdUnitTemplate string

func generateSystemdUnit() ([]byte, error) {
func generateSystemdUnit(tcpPort, vsockPort int) ([]byte, error) {
selfExeAbs, err := os.Executable()
if err != nil {
return nil, err
}

var args []string
if tcpPort != 0 {
args = append(args, fmt.Sprintf("--tcp-port %d", tcpPort))
}
if vsockPort != 0 {
args = append(args, fmt.Sprintf("--vsock-port %d", vsockPort))
}

m := map[string]string{
"Binary": selfExeAbs,
"Args": strings.Join(args, " "),
}
return textutil.ExecuteTemplate(systemdUnitTemplate, m)
}
2 changes: 1 addition & 1 deletion cmd/lima-guestagent/lima-guestagent.TEMPLATE.service
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Description=lima-guestagent

[Service]
ExecStart={{.Binary}} daemon
ExecStart={{.Binary}} daemon {{.Args}}
Type=simple
Restart=on-failure

Expand Down
1 change: 1 addition & 0 deletions cmd/limactl/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ func deleteInstance(ctx context.Context, inst *store.Instance, force bool) error
if err := os.RemoveAll(inst.Dir); err != nil {
return fmt.Errorf("failed to remove %q: %w", inst.Dir, err)
}

return nil
}

Expand Down
1 change: 1 addition & 0 deletions cmd/limactl/hostagent.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ func hostagentAction(cmd *cobra.Command, args []string) error {
return err
}
l, err := net.Listen("unix", socket)
logrus.Infof("hostagent socket created at %s", socket)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/limactl/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ func shellAction(cmd *cobra.Command, args []string) error {
sshArgs = append(sshArgs, []string{
"-q",
"-p", strconv.Itoa(inst.SSHLocalPort),
"127.0.0.1",
inst.SSHAddress,
"--",
script,
}...)
Expand Down
5 changes: 5 additions & 0 deletions examples/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,11 @@ hostResolver:
# 🟢 Builtin default: /usr/local
guestInstallPrefix: null

# Adjust options for the guestAgent which runs inside of the Linux VM
guestAgent:
# 🟢 Builtin default: UNIX (macOS, Linux), VSOCK (Windows/WSL2)
protocol: null

# ===================================================================== #
# GLOBAL DEFAULTS AND OVERRIDES
# ===================================================================== #
Expand Down
27 changes: 27 additions & 0 deletions examples/experimental/wsl.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# ===================================================================== #
# BASIC CONFIGURATION
# ===================================================================== #

# Default values in this YAML file are specified by `null` instead of Lima's "builtin default" values,
# so they can be overridden by the $LIMA_HOME/_config/default.yaml mechanism documented at the end of this file.

# VM type: "qemu" or "vz" (on macOS 13 and later).
# The vmType can be specified only on creating the instance.
# The vmType of existing instances cannot be changed.
# 🟢 Builtin default: "qemu"
vmType: wsl2

# OpenStack-compatible disk image.
# 🟢 Builtin default: null (must be specified)
# 🔵 This file: Ubuntu 23.04 Lunar Lobster images
images:
# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
- location: "file://C:/Users/Administrator/Downloads/fedora-38-cloud-rootfs.tar"
arch: "x86_64"
digest: "sha256:112400224d801c3781c1e301408685920ba980024bfb20877628a0bd82fdc574"

mountType: wsl

containerd:
system: true
user: false
9 changes: 5 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ require (

require (
github.com/Code-Hex/go-infinity-channel v1.0.0 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/Microsoft/go-winio v0.6.1
github.com/VividCortex/ewma v1.2.0 // indirect
github.com/a8m/envsubst v1.4.2 // indirect
github.com/alecthomas/participle/v2 v2.0.0 // indirect
Expand Down Expand Up @@ -89,7 +89,7 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/mdlayher/socket v0.4.1 // indirect
github.com/mdlayher/vsock v1.2.1 // indirect
github.com/mdlayher/vsock v1.2.1
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
Expand All @@ -103,11 +103,12 @@ require (
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.7.0 // indirect
golang.org/x/crypto v0.12.0 // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b
golang.org/x/mod v0.11.0 // indirect
golang.org/x/net v0.14.0 // indirect
golang.org/x/oauth2 v0.8.0 // indirect
golang.org/x/term v0.11.0 // indirect
golang.org/x/text v0.12.0 // indirect
golang.org/x/text v0.12.0
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.9.3 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,8 @@ golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b h1:r+vk0EmXNmekl0S0BascoeeoHk/L7wmaW2QF90K+kYI=
golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
Expand All @@ -305,8 +307,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand Down
2 changes: 1 addition & 1 deletion pkg/cidata/cidata.TEMPLATE.d/boot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ fi

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

INFO "Exiting with code $CODE"
exit "$CODE"
17 changes: 17 additions & 0 deletions pkg/cidata/cidata.TEMPLATE.d/boot/02-wsl-setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/sh
# This script replaces the cloud-init functionality of creating a user and setting its SSH keys
# when using a WSL2 VM.
[ "$LIMA_CIDATA_VMTYPE" = "wsl2" ] || exit 0

# create user
sudo useradd -u "${LIMA_CIDATA_UID}" "${LIMA_CIDATA_USER}" -d /home/"${LIMA_CIDATA_USER}".linux/
sudo mkdir /home/"${LIMA_CIDATA_USER}".linux/.ssh/
sudo cp "${LIMA_CIDATA_MNT}"/ssh_authorized_keys /home/"${LIMA_CIDATA_USER}".linux/.ssh/authorized_keys
sudo chown "${LIMA_CIDATA_USER}" /home/"${LIMA_CIDATA_USER}".linux/.ssh/authorized_keys

# add lima to sudoers
sudo echo "lima ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/99_lima_sudoers

# copy some CIDATA to the hardcoded path for requirement checks (TODO: make this not hardcoded)
sudo mkdir -p /mnt/lima-cidata
sudo cp "${LIMA_CIDATA_MNT}"/meta-data /mnt/lima-cidata/meta-data
6 changes: 5 additions & 1 deletion pkg/cidata/cidata.TEMPLATE.d/boot/25-guestagent-base.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,9 @@ else
# Remove legacy systemd service
rm -f "/home/${LIMA_CIDATA_USER}.linux/.config/systemd/user/lima-guestagent.service"

sudo "${LIMA_CIDATA_GUEST_INSTALL_PREFIX}"/bin/lima-guestagent install-systemd
if [ "$LIMA_CIDATA_VMTYPE" = "wsl2" ]; then
sudo "${LIMA_CIDATA_GUEST_INSTALL_PREFIX}"/bin/lima-guestagent install-systemd --vsock-port "${LIMA_CIDATA_VSOCK_PORT}"
else
sudo "${LIMA_CIDATA_GUEST_INSTALL_PREFIX}"/bin/lima-guestagent install-systemd
fi
fi
2 changes: 2 additions & 0 deletions pkg/cidata/cidata.TEMPLATE.d/lima.env
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,5 @@ LIMA_CIDATA_SKIP_DEFAULT_DEPENDENCY_RESOLUTION=1
{{- else}}
LIMA_CIDATA_SKIP_DEFAULT_DEPENDENCY_RESOLUTION=
{{- end}}
LIMA_CIDATA_VMTYPE={{ .VMType }}
LIMA_CIDATA_VSOCK_PORT={{ .VSockPort }}
2 changes: 1 addition & 1 deletion pkg/cidata/cidata.TEMPLATE.d/user-data
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ write_files:
LIMA_CIDATA_MNT="/mnt/lima-cidata"
LIMA_CIDATA_DEV="/dev/disk/by-label/cidata"
mkdir -p -m 700 "${LIMA_CIDATA_MNT}"
mount -o ro,mode=0700,dmode=0700,overriderockperm,exec,uid=0 "${LIMA_CIDATA_DEV}" "${LIMA_CIDATA_MNT}"
export LIMA_CIDATA_MNT
mount -o ro,mode=0700,dmode=0700,overriderockperm,exec,uid=0 "${LIMA_CIDATA_DEV}" "${LIMA_CIDATA_MNT}"
exec "${LIMA_CIDATA_MNT}"/boot.sh
owner: root:root
path: /var/lib/cloud/scripts/per-boot/00-lima.boot.sh
Expand Down
Loading

0 comments on commit bdc225f

Please sign in to comment.