Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,12 @@ native: clean limactl limactl-plugins helpers native-guestagent templates templa
################################################################################
# These configs were once customizable but should no longer be changed.
CONFIG_GUESTAGENT_OS_LINUX=y
CONFIG_GUESTAGENT_OS_DARWIN=
ifeq ($(GOOS),darwin)
ifeq ($(GOARCH),arm64)
CONFIG_GUESTAGENT_OS_DARWIN=y
endif
endif
CONFIG_GUESTAGENT_ARCH_X8664=y
CONFIG_GUESTAGENT_ARCH_AARCH64=y
CONFIG_GUESTAGENT_ARCH_ARMV7L=y
Expand Down Expand Up @@ -341,15 +347,20 @@ MKDIR_TARGETS += _output/bin
################################################################################
# _output/share/lima/lima-guestagent
LINUX_GUESTAGENT_PATH_COMMON = _output/share/lima/lima-guestagent.Linux-
DARWIN_GUESTAGENT_PATH_COMMON = _output/share/lima/lima-guestagent.Darwin-

# How to add architecture specific guestagent:
# 1. Add the architecture to GUESTAGENT_ARCHS
# 2. Add ENVS_$(*_GUESTAGENT_PATH_COMMON)<arch> to set GOOS, GOARCH, and other necessary environment variables
LINUX_GUESTAGENT_ARCHS = aarch64 armv7l ppc64le riscv64 s390x x86_64
DARWIN_GUESTAGENT_ARCHS = aarch64

ifeq ($(CONFIG_GUESTAGENT_OS_LINUX),y)
ALL_GUESTAGENTS_NOT_COMPRESSED += $(addprefix $(LINUX_GUESTAGENT_PATH_COMMON),$(LINUX_GUESTAGENT_ARCHS))
endif
ifeq ($(CONFIG_GUESTAGENT_OS_DARWIN),y)
ALL_GUESTAGENTS_NOT_COMPRESSED += $(addprefix $(DARWIN_GUESTAGENT_PATH_COMMON),$(DARWIN_GUESTAGENT_ARCHS))
endif
ifeq ($(CONFIG_GUESTAGENT_COMPRESS),y)
gz=.gz
endif
Expand All @@ -367,6 +378,13 @@ NATIVE_GUESTAGENT = $(call guestagent_path,LINUX,$(NATIVE_GUESTAGENT_ARCH))
ADDITIONAL_GUESTAGENT_ARCHS = $(filter-out $(NATIVE_GUESTAGENT_ARCH),$(LINUX_GUESTAGENT_ARCHS))
ADDITIONAL_GUESTAGENTS = $(call guestagent_path,LINUX,$(ADDITIONAL_GUESTAGENT_ARCHS))
endif
ifeq ($(CONFIG_GUESTAGENT_OS_DARWIN),y)
ifeq ($(GOARCH),arm64)
NATIVE_GUESTAGENT_ARCH = aarch64
NATIVE_GUESTAGENT += $(call guestagent_path,DARWIN,$(NATIVE_GUESTAGENT_ARCH))
endif
endif
# No ADDITIONAL_GUESTAGENTS for Darwin, as only one architecture is supported.

# config_guestagent_arch returns expanded value of CONFIG_GUESTAGENT_ARCH_<arch>
# $(1): architecture
Expand All @@ -381,13 +399,17 @@ ifeq ($(CONFIG_GUESTAGENT_OS_LINUX),y)
# apply CONFIG_GUESTAGENT_ARCH_*
GUESTAGENTS += $(foreach arch,$(LINUX_GUESTAGENT_ARCHS),$(call guestagent_path_enabled_by_config,LINUX,$(arch)))
endif
ifeq ($(CONFIG_GUESTAGENT_OS_DARWIN),y)
GUESTAGENTS += $(call guestagent_path,DARWIN,aarch64)
endif

.PHONY: guestagents native-guestagent additional-guestagents
guestagents: $(GUESTAGENTS)
native-guestagent: $(NATIVE_GUESTAGENT)
additional-guestagents: $(ADDITIONAL_GUESTAGENTS)
%-guestagent:
@[ "$(findstring $(*),$(LINUX_GUESTAGENT_ARCHS))" == "$(*)" ] && make $(call guestagent_path,LINUX,$*)
@[ "$(findstring $(*),$(DARWIN_GUESTAGENT_ARCHS))" == "$(*)" ] && make $(call guestagent_path,DARWIN,$*)

# environment variables for linux-guestagent. these variable are used for checking force build.
ENVS_$(LINUX_GUESTAGENT_PATH_COMMON)aarch64 = CGO_ENABLED=0 GOOS=linux GOARCH=arm64
Expand All @@ -396,11 +418,14 @@ ENVS_$(LINUX_GUESTAGENT_PATH_COMMON)ppc64le = CGO_ENABLED=0 GOOS=linux GOARCH=pp
ENVS_$(LINUX_GUESTAGENT_PATH_COMMON)riscv64 = CGO_ENABLED=0 GOOS=linux GOARCH=riscv64
ENVS_$(LINUX_GUESTAGENT_PATH_COMMON)s390x = CGO_ENABLED=0 GOOS=linux GOARCH=s390x
ENVS_$(LINUX_GUESTAGENT_PATH_COMMON)x86_64 = CGO_ENABLED=0 GOOS=linux GOARCH=amd64
ENVS_$(DARWIN_GUESTAGENT_PATH_COMMON)aarch64 = CGO_ENABLED=0 GOOS=darwin GOARCH=arm64
$(ALL_GUESTAGENTS_NOT_COMPRESSED): $(call dependencies_for_cmd,lima-guestagent) $$(call force_build_with_gunzip,$$@) | _output/share/lima
$(ENVS_$@) $(GO_BUILD) -o $@ ./cmd/lima-guestagent
chmod 644 $@
$(LINUX_GUESTAGENT_PATH_COMMON)%.gz: $(LINUX_GUESTAGENT_PATH_COMMON)% $$(call force_build_with_gunzip,$$@)
@set -x; gzip -n $<
$(DARWIN_GUESTAGENT_PATH_COMMON)%.gz: $(DARWIN_GUESTAGENT_PATH_COMMON)% $$(call force_build_with_gunzip,$$@)
@set -x; gzip -n $<

MKDIR_TARGETS += _output/share/lima

Expand Down
26 changes: 26 additions & 0 deletions cmd/lima-guestagent/fake_cloud_init_darwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-FileCopyrightText: Copyright The Lima Authors
// SPDX-License-Identifier: Apache-2.0

package main

import (
_ "embed"

"github.com/spf13/cobra"

"github.com/lima-vm/lima/v2/pkg/guestagent/fakecloudinit"
)

func newFakeCloudInitCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "fake-cloud-init",
Short: "Run fake cloud-init",
RunE: fakeCloudInitAction,
}
return cmd
}

func fakeCloudInitAction(cmd *cobra.Command, _ []string) error {
ctx := cmd.Context()
return fakecloudinit.Run(ctx)
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@
}
return nil
}
rootCmd.AddCommand(
newDaemonCommand(),
newInstallSystemdCommand(),
)
addRootCommands(rootCmd)

Check failure on line 41 in cmd/lima-guestagent/main.go

View workflow job for this annotation

GitHub Actions / Windows tests (WSL2)

undefined: addRootCommands

Check failure on line 41 in cmd/lima-guestagent/main.go

View workflow job for this annotation

GitHub Actions / Cross-compile (NetBSD, DragonFlyBSD)

undefined: addRootCommands
return rootCmd
}
14 changes: 14 additions & 0 deletions cmd/lima-guestagent/root_darwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-FileCopyrightText: Copyright The Lima Authors
// SPDX-License-Identifier: Apache-2.0

package main

import (
"github.com/spf13/cobra"
)

func addRootCommands(rootCmd *cobra.Command) {
rootCmd.AddCommand(
newFakeCloudInitCommand(),
)
}
15 changes: 15 additions & 0 deletions cmd/lima-guestagent/root_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-FileCopyrightText: Copyright The Lima Authors
// SPDX-License-Identifier: Apache-2.0

package main

import (
"github.com/spf13/cobra"
)

func addRootCommands(rootCmd *cobra.Command) {
rootCmd.AddCommand(
newDaemonCommand(),
newInstallSystemdCommand(),
)
}
5 changes: 4 additions & 1 deletion cmd/limactl/sudoers.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ To validate the existing /etc/sudoers.d/lima file:
$ limactl sudoers --check /etc/sudoers.d/lima
`,
Short: "Generate the content of the /etc/sudoers.d/lima file",
Long: fmt.Sprintf(`Generate the content of the /etc/sudoers.d/lima file for enabling vmnet.framework support (socket_vmnet) on macOS.
Long: fmt.Sprintf(`Generate the content of the /etc/sudoers.d/lima file for enabling:
- vmnet.framework support (socket_vmnet) on macOS
- macOS guest support on macOS.

The content is written to stdout, NOT to the file.
This command must not run as the root user.
See %s for the usage.`, socketVMNetURL),
Expand Down
34 changes: 26 additions & 8 deletions pkg/cidata/cidata.TEMPLATE.d/boot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ WARNING() {
echo "LIMA $(date -Iseconds)| WARNING: $*"
}

UNAME="$(uname -s)"

RUN="/run"
if [ "${UNAME}" != "Linux" ]; then
RUN="/var/run"
fi
rm -f "${RUN}/lima-boot-done"

# shellcheck disable=SC2163
while read -r line; do [ -n "$line" ] && export "$line"; done <"${LIMA_CIDATA_MNT}"/lima.env
# shellcheck disable=SC2163
Expand Down Expand Up @@ -43,13 +51,20 @@ CODE=0
if [ "$LIMA_CIDATA_PLAIN" = "1" ]; then
INFO "Plain mode. Skipping to run boot scripts. Provisioning scripts will be still executed. Guest agent will not be running."
else
for f in "${LIMA_CIDATA_MNT}"/boot/*; do
INFO "Executing $f"
if ! "$f"; then
WARNING "Failed to execute $f"
CODE=1
boot="${LIMA_CIDATA_MNT}/boot"
if [ "${UNAME}" != "Linux" ]; then
# TODO: rename boot to boot.Linux
boot="${boot}.${UNAME}"
fi
if [ -e "${boot}" ]; then
for f in "${LIMA_CIDATA_MNT}"/boot/*; do
INFO "Executing $f"
if ! "$f"; then
WARNING "Failed to execute $f"
CODE=1
fi
done
done
fi
fi

# indirect variable lookup, like ${!var} in bash
Expand Down Expand Up @@ -172,7 +187,10 @@ if [ -d "${LIMA_CIDATA_MNT}"/provision.user ]; then
cp "$f" "${USER_SCRIPT}"
chown "${LIMA_CIDATA_USER}" "${USER_SCRIPT}"
chmod 755 "${USER_SCRIPT}"
if ! sudo -iu "${LIMA_CIDATA_USER}" "--preserve-env=${params}" "XDG_RUNTIME_DIR=/run/user/${LIMA_CIDATA_UID}" "${USER_SCRIPT}"; then
if [ "${UNAME}" != "Linux" ]; then
WARNING "Provisioning user scripts are not supported on non-Linux platforms"
CODE=1
elif ! sudo -iu "${LIMA_CIDATA_USER}" "--preserve-env=${params}" "XDG_RUNTIME_DIR=/run/user/${LIMA_CIDATA_UID}" "${USER_SCRIPT}"; then
WARNING "Failed to execute $f (as user ${LIMA_CIDATA_USER})"
CODE=1
fi
Expand All @@ -182,7 +200,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
cp "${LIMA_CIDATA_MNT}"/meta-data "${RUN}/lima-boot-done"

INFO "Exiting with code $CODE"
exit "$CODE"
5 changes: 5 additions & 0 deletions pkg/cidata/cidata.TEMPLATE.d/user-data
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,11 @@ users:
{{- end }}
homedir: "{{.Home}}"
shell: {{.Shell}}
{{- if ne .OS "Darwin" }}
{{/* On macOS, the password is not locked so as to allow GUI login */}}
sudo: ALL=(ALL) NOPASSWD:ALL
lock_passwd: true
{{- end }}
ssh-authorized-keys:
{{- range $val := .SSHPubKeys }}
- {{ printf "%q" $val }}
Expand All @@ -47,6 +50,8 @@ write_files:
- content: |
#!/bin/sh
set -eux
# FIXME: On macOS, boot.sh is directly executed via fake-cloud-init
[ "$(uname)" = "Linux" ] || exit 0
LIMA_CIDATA_MNT="/mnt/lima-cidata"
LIMA_CIDATA_DEV="/dev/disk/by-label/cidata"
mkdir -p -m 700 "${LIMA_CIDATA_MNT}"
Expand Down
32 changes: 32 additions & 0 deletions pkg/cidata/cidata.TEMPLATE.d/util/timeout.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/bash

# SPDX-FileCopyrightText: Copyright The Lima Authors
# SPDX-License-Identifier: Apache-2.0

# Reimplementation of `timeout` command for non-GNU operating systems,
# such as macOS.

set -eu -o pipefail

if [ "$#" -lt 2 ]; then
echo "Usage: $0 DURATION COMMAND [ARG]..." >&2
exit 1
fi

timeout() {
local time=$1
shift
"$@" &
local pid=$!
(
sleep "$time"
kill -TERM "$pid" 2>/dev/null
) &
local killer=$!
wait "$pid"
local status=$?
kill -TERM "$killer" 2>/dev/null
return $status
}

timeout "$@"
8 changes: 7 additions & 1 deletion pkg/cidata/cidata.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ func templateArgs(ctx context.Context, bootScripts bool, instDir, name string, i
archive := "nerdctl-full.tgz"
args := TemplateArgs{
Debug: debugutil.Debug,
OS: *instConfig.OS,
BootScripts: bootScripts,
Name: name,
Hostname: hostname.FromInstName(name), // TODO: support customization
Expand Down Expand Up @@ -471,7 +472,12 @@ func GenerateISO9660(ctx context.Context, drv driver.Driver, instDir, name strin
return writeCIDataDir(filepath.Join(instDir, filenames.CIDataISODir), layout)
}

return iso9660util.Write(filepath.Join(instDir, filenames.CIDataISO), "cidata", layout)
var iso9660Options []iso9660util.WriteOpt
if instConfig.OS != nil && *instConfig.OS == limatype.DARWIN {
// Without Joliet, all the file names will be in upper case, and the hiphen will be replaced with underscore
iso9660Options = append(iso9660Options, iso9660util.WithJoliet())
}
return iso9660util.Write(filepath.Join(instDir, filenames.CIDataISO), "cidata", layout, iso9660Options...)
}

func removeControlChars(s string) string {
Expand Down
9 changes: 9 additions & 0 deletions pkg/cidata/cloudinittypes/metadata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-FileCopyrightText: Copyright The Lima Authors
// SPDX-License-Identifier: Apache-2.0

package cloudinittypes

type MetaData struct {
InstanceID string `yaml:"instance-id,omitempty"`
LocalHostname string `yaml:"local-hostname,omitempty"`
}
59 changes: 59 additions & 0 deletions pkg/cidata/cloudinittypes/userdata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// SPDX-FileCopyrightText: Copyright The Lima Authors
// SPDX-License-Identifier: Apache-2.0

package cloudinittypes

type UserData struct {
Growpart *Growpart `yaml:"growpart,omitempty"`

PackageUpdate bool `yaml:"package_update,omitempty"`
PackageUpgrade bool `yaml:"package_upgrade,omitempty"`
PackageRebootIfRequired bool `yaml:"package_reboot_if_required,omitempty"`

Mounts [][]string `yaml:"mounts,omitempty"`

Timezone string `yaml:"timezone,omitempty"`

Users []User `yaml:"users,omitempty"`

WriteFiles []WriteFile `yaml:"write_files,omitempty"`

ManageResolvConf bool `yaml:"manage_resolv_conf,omitempty"`
ResolvConf *ResolvConf `yaml:"resolv_conf,omitempty"`

CACerts *CACerts `yaml:"ca_certs,omitempty"`

BootCmd []string `yaml:"bootcmd,omitempty"`
}

type Growpart struct {
Mode string `yaml:"mode"`
Devices []string `yaml:"devices"`
}

type User struct {
Name string `yaml:"name,omitempty"`
Gecos string `yaml:"gecos,omitempty"`
UID string `yaml:"uid,omitempty"` // TODO: check if int is allowed too
Homedir string `yaml:"homedir,omitempty"`
Shell string `yaml:"shell,omitempty"`
Sudo string `yaml:"sudo,omitempty"`
LockPasswd string `yaml:"lock_passwd,omitempty"`
SSHAuthorizedKeys []string `yaml:"ssh-authorized-keys,omitempty"`
}

type WriteFile struct {
Content string `yaml:"content"`
Owner string `yaml:"owner,omitempty"`
Path string `yaml:"path"`
Permissions string `yaml:"permissions,omitempty"` // TODO: check if int is allowed too
}

type ResolvConf struct {
Nameservers []string `yaml:"nameservers,omitempty"`
}

type CACerts struct {
RemoveDefaults bool `yaml:"remove_defaults,omitempty"`
Trusted []string `yaml:"trusted,omitempty"`
}
2 changes: 2 additions & 0 deletions pkg/cidata/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

"github.com/lima-vm/lima/v2/pkg/identifiers"
"github.com/lima-vm/lima/v2/pkg/iso9660util"
"github.com/lima-vm/lima/v2/pkg/limatype"
"github.com/lima-vm/lima/v2/pkg/textutil"
)

Expand Down Expand Up @@ -75,6 +76,7 @@ type Disk struct {
}
type TemplateArgs struct {
Debug bool
OS limatype.OS
Name string // instance name
Hostname string // instance hostname
IID string // instance id
Expand Down
2 changes: 1 addition & 1 deletion pkg/driver/krunkit/krunkit_darwin_arm64.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func Cmdline(inst *limatype.Instance) (*exec.Cmd, error) {
"--restful-uri", "none://",

// First virtio-blk device is the boot disk
"--device", fmt.Sprintf("virtio-blk,path=%s,format=raw", filepath.Join(inst.Dir, filenames.DiffDisk)),
"--device", fmt.Sprintf("virtio-blk,path=%s,format=raw", filepath.Join(inst.Dir, filenames.Disk)),
"--device", fmt.Sprintf("virtio-blk,path=%s", filepath.Join(inst.Dir, filenames.CIDataISO)),
}

Expand Down
Loading
Loading