From 36fcfde6335dd395ed34329064de39fc5e32a070 Mon Sep 17 00:00:00 2001 From: Akihiro Suda Date: Tue, 26 Sep 2023 22:52:36 +0900 Subject: [PATCH] Add "plain" mode (disables mounts, port forwarding, containerd, etc.) ```bash limactl start --plain ``` When the "plain" mode is enabled: - the YAML properties for mounts, port forwarding, containerd, etc. will be ignored - guest agent will not be running - dependency packages like sshfs will not be installed into the VM User-specified provisioning scripts will be still executed. Fixes issue 1739 Signed-off-by: Akihiro Suda --- cmd/limactl/editflags/editflags.go | 3 +++ examples/default.yaml | 8 ++++++++ pkg/cidata/cidata.TEMPLATE.d/boot.sh | 18 ++++++++++------- pkg/cidata/cidata.TEMPLATE.d/lima.env | 5 +++++ pkg/cidata/cidata.go | 1 + pkg/cidata/template.go | 1 + pkg/hostagent/hostagent.go | 9 +++++++-- pkg/hostagent/requirements.go | 8 ++++++-- pkg/limayaml/defaults.go | 24 +++++++++++++++++++++++ pkg/limayaml/defaults_test.go | 3 +++ pkg/limayaml/limayaml.go | 1 + pkg/start/start.go | 6 +++++- pkg/vz/vz_driver_darwin.go | 1 + pkg/wsl2/wsl_driver_windows.go | 1 + website/content/en/docs/faq/_index.md | 28 +++++++++++++++++++++++++++ 15 files changed, 105 insertions(+), 12 deletions(-) diff --git a/cmd/limactl/editflags/editflags.go b/cmd/limactl/editflags/editflags.go index a3f4c292483..3a408dec1c8 100644 --- a/cmd/limactl/editflags/editflags.go +++ b/cmd/limactl/editflags/editflags.go @@ -88,6 +88,8 @@ func RegisterCreate(cmd *cobra.Command, commentPrefix string) { _ = cmd.RegisterFlagCompletionFunc("vm-type", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { return []string{"qemu", "vz"}, cobra.ShellCompDirectiveNoFileComp }) + + flags.Bool("plain", false, commentPrefix+"plain mode. Disable mounts, port forwarding, containerd, etc.") } func defaultExprFunc(expr string) func(v *flag.Flag) (string, error) { @@ -225,6 +227,7 @@ func YQExpressions(flags *flag.FlagSet, newInstance bool) ([]string, error) { {"disk", d(".disk= \"%sGiB\""), true, false}, {"vm-type", d(".vmType = %q"), true, false}, + {"plain", d(".plain = %s"), true, false}, } var exprs []string for _, def := range defs { diff --git a/examples/default.yaml b/examples/default.yaml index 73443b3d31c..c47bb1f0237 100644 --- a/examples/default.yaml +++ b/examples/default.yaml @@ -444,6 +444,14 @@ hostResolver: # 🟢 Builtin default: /usr/local guestInstallPrefix: null +# When the "plain" mode is enabled: +# - the YAML properties for mounts, port forwarding, containerd, etc. will be ignored +# - guest agent will not be running +# - dependency packages like sshfs will not be installed into the VM +# User-specified provisioning scripts will be still executed. +# 🟢 Builtin default: false +plain: null + # ===================================================================== # # GLOBAL DEFAULTS AND OVERRIDES # ===================================================================== # diff --git a/pkg/cidata/cidata.TEMPLATE.d/boot.sh b/pkg/cidata/cidata.TEMPLATE.d/boot.sh index 7e26757b291..65bf2f2318e 100644 --- a/pkg/cidata/cidata.TEMPLATE.d/boot.sh +++ b/pkg/cidata/cidata.TEMPLATE.d/boot.sh @@ -34,13 +34,17 @@ CODE=0 # has run because it might move the directories to /mnt/data on first boot. In that # case changes made on restart would be lost. -for f in "${LIMA_CIDATA_MNT}"/boot/*; do - INFO "Executing $f" - if ! "$f"; then - WARNING "Failed to execute $f" - CODE=1 - fi -done +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 + fi + done +fi if [ -d "${LIMA_CIDATA_MNT}"/provision.system ]; then for f in "${LIMA_CIDATA_MNT}"/provision.system/*; do diff --git a/pkg/cidata/cidata.TEMPLATE.d/lima.env b/pkg/cidata/cidata.TEMPLATE.d/lima.env index d1c7a2b0507..e43a3329175 100644 --- a/pkg/cidata/cidata.TEMPLATE.d/lima.env +++ b/pkg/cidata/cidata.TEMPLATE.d/lima.env @@ -41,3 +41,8 @@ LIMA_CIDATA_SKIP_DEFAULT_DEPENDENCY_RESOLUTION= {{- end}} LIMA_CIDATA_VMTYPE={{ .VMType }} LIMA_CIDATA_VSOCK_PORT={{ .VSockPort }} +{{- if .Plain}} +LIMA_CIDATA_PLAIN=1 +{{- else}} +LIMA_CIDATA_PLAIN= +{{- end}} diff --git a/pkg/cidata/cidata.go b/pkg/cidata/cidata.go index 2798b0ff1a0..d8b5ec71a2f 100644 --- a/pkg/cidata/cidata.go +++ b/pkg/cidata/cidata.go @@ -135,6 +135,7 @@ func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML, udpDNSLocalPort RosettaBinFmt: *y.Rosetta.BinFmt, VMType: *y.VMType, VSockPort: vsockPort, + Plain: *y.Plain, } firstUsernetIndex := limayaml.FirstUsernetIndex(y) diff --git a/pkg/cidata/template.go b/pkg/cidata/template.go index 956c36638f3..089a085f76b 100644 --- a/pkg/cidata/template.go +++ b/pkg/cidata/template.go @@ -81,6 +81,7 @@ type TemplateArgs struct { SkipDefaultDependencyResolution bool VMType string VSockPort int + Plain bool } func ValidateTemplateArgs(args TemplateArgs) error { diff --git a/pkg/hostagent/hostagent.go b/pkg/hostagent/hostagent.go index 0951551fe6c..e2aef3dfb54 100644 --- a/pkg/hostagent/hostagent.go +++ b/pkg/hostagent/hostagent.go @@ -427,6 +427,9 @@ func (a *HostAgent) Info(_ context.Context) (*hostagentapi.Info, error) { } func (a *HostAgent) startHostAgentRoutines(ctx context.Context) error { + if *a.y.Plain { + logrus.Info("Running in plain mode. Mounts, port forwarding, containerd, etc. will be ignored. Guest agent will not be running.") + } a.onClose = append(a.onClose, func() error { logrus.Debugf("shutting down the SSH master") if exitMasterErr := ssh.ExitMaster(a.instSSHAddress, a.sshLocalPort, a.sshConfig); exitMasterErr != nil { @@ -451,7 +454,7 @@ sudo chown -R "${USER}" /run/host-services` errs = append(errs, fmt.Errorf("stdout=%q, stderr=%q: %w", stdout, stderr, err)) } } - if *a.y.MountType == limayaml.REVSSHFS { + if *a.y.MountType == limayaml.REVSSHFS && !*a.y.Plain { mounts, err := a.setupMounts() if err != nil { errs = append(errs, err) @@ -483,7 +486,9 @@ sudo chown -R "${USER}" /run/host-services` return errors.Join(unlockErrs...) }) } - go a.watchGuestAgentEvents(ctx) + if !*a.y.Plain { + go a.watchGuestAgentEvents(ctx) + } if err := a.waitForRequirements("optional", a.optionalRequirements()); err != nil { errs = append(errs, err) } diff --git a/pkg/hostagent/requirements.go b/pkg/hostagent/requirements.go index 46057ed3c0b..fe1c4979622 100644 --- a/pkg/hostagent/requirements.go +++ b/pkg/hostagent/requirements.go @@ -71,7 +71,11 @@ true Make sure that the YAML field "ssh.localPort" is not used by other processes on the host. If any private key under ~/.ssh is protected with a passphrase, you need to have ssh-agent to be running. `, - }, + }) + if *a.y.Plain { + return req + } + req = append(req, requirement{ description: "user session is ready for ssh", script: `#!/bin/bash @@ -156,7 +160,7 @@ A possible workaround is to run "lima-guestagent install-systemd" in the guest. func (a *HostAgent) optionalRequirements() []requirement { req := make([]requirement, 0) - if *a.y.Containerd.System || *a.y.Containerd.User { + if (*a.y.Containerd.System || *a.y.Containerd.User) && !*a.y.Plain { req = append(req, requirement{ description: "systemd must be available", diff --git a/pkg/limayaml/defaults.go b/pkg/limayaml/defaults.go index 3b907c0dae4..0b4958c7fd7 100644 --- a/pkg/limayaml/defaults.go +++ b/pkg/limayaml/defaults.go @@ -665,6 +665,30 @@ func FillDefault(y, d, o *LimaYAML, filePath string) { if y.Rosetta.BinFmt == nil { y.Rosetta.BinFmt = pointer.Bool(false) } + + if y.Plain == nil { + y.Plain = d.Plain + } + if o.Plain != nil { + y.Plain = o.Plain + } + if y.Plain == nil { + y.Plain = pointer.Bool(false) + } + + fixUpForPlainMode(y) +} + +func fixUpForPlainMode(y *LimaYAML) { + if !*y.Plain { + return + } + y.Mounts = nil + y.PortForwards = nil + y.Containerd.System = pointer.Bool(false) + y.Containerd.User = pointer.Bool(false) + y.Rosetta.BinFmt = pointer.Bool(false) + y.Rosetta.Enabled = pointer.Bool(false) } func executeGuestTemplate(format string) (bytes.Buffer, error) { diff --git a/pkg/limayaml/defaults_test.go b/pkg/limayaml/defaults_test.go index a9e37366151..c2a326dc881 100644 --- a/pkg/limayaml/defaults_test.go +++ b/pkg/limayaml/defaults_test.go @@ -105,6 +105,7 @@ func TestFillDefault(t *testing.T) { CACertificates: CACertificates{ RemoveDefaults: pointer.Bool(false), }, + Plain: pointer.Bool(false), } if IsAccelOS() { if HasHostCPU() { @@ -405,6 +406,7 @@ func TestFillDefault(t *testing.T) { BinFmt: pointer.Bool(true), } } + expect.Plain = pointer.Bool(false) y = LimaYAML{} FillDefault(&y, &d, &LimaYAML{}, filePath) @@ -617,6 +619,7 @@ func TestFillDefault(t *testing.T) { Enabled: pointer.Bool(false), BinFmt: pointer.Bool(false), } + expect.Plain = pointer.Bool(false) FillDefault(&y, &d, &o, filePath) assert.DeepEqual(t, &y, &expect, opts...) diff --git a/pkg/limayaml/limayaml.go b/pkg/limayaml/limayaml.go index f79e902c092..708b1b23dfd 100644 --- a/pkg/limayaml/limayaml.go +++ b/pkg/limayaml/limayaml.go @@ -38,6 +38,7 @@ type LimaYAML struct { PropagateProxyEnv *bool `yaml:"propagateProxyEnv,omitempty" json:"propagateProxyEnv,omitempty"` CACertificates CACertificates `yaml:"caCerts,omitempty" json:"caCerts,omitempty"` Rosetta Rosetta `yaml:"rosetta,omitempty" json:"rosetta,omitempty"` + Plain *bool `yaml:"plain,omitempty" json:"plain,omitempty"` } type OS = string diff --git a/pkg/start/start.go b/pkg/start/start.go index 2df500907a6..022645e2fe3 100644 --- a/pkg/start/start.go +++ b/pkg/start/start.go @@ -240,7 +240,11 @@ func watchHostAgentEvents(ctx context.Context, inst *store.Instance, haStdoutPat return true } - logrus.Infof("READY. Run `%s` to open the shell.", LimactlShellCmd(inst.Name)) + if *inst.Config.Plain { + logrus.Infof("READY. Run `ssh -F %q lima-%s` to open the shell.", inst.SSHConfigFile, inst.Name) + } else { + logrus.Infof("READY. Run `%s` to open the shell.", LimactlShellCmd(inst.Name)) + } ShowMessage(inst) err = nil return true diff --git a/pkg/vz/vz_driver_darwin.go b/pkg/vz/vz_driver_darwin.go index 8e2cb19eab1..1b283b532af 100644 --- a/pkg/vz/vz_driver_darwin.go +++ b/pkg/vz/vz_driver_darwin.go @@ -74,6 +74,7 @@ func (l *LimaVzDriver) Validate() error { "Audio", "Video", "OS", + "Plain", ); len(unknown) > 0 { logrus.Warnf("vmType %s: ignoring %+v", *l.Yaml.VMType, unknown) } diff --git a/pkg/wsl2/wsl_driver_windows.go b/pkg/wsl2/wsl_driver_windows.go index 8983158bc4a..e7519f260ab 100644 --- a/pkg/wsl2/wsl_driver_windows.go +++ b/pkg/wsl2/wsl_driver_windows.go @@ -49,6 +49,7 @@ func (l *LimaWslDriver) Validate() error { "DNS", "HostResolver", "PropagateProxyEnv", + "Plain", ); len(unknown) > 0 { logrus.Warnf("Ignoring: vmType %s: %+v", *l.Yaml.VMType, unknown) } diff --git a/website/content/en/docs/faq/_index.md b/website/content/en/docs/faq/_index.md index ebd65e4dcf6..aac03567e97 100644 --- a/website/content/en/docs/faq/_index.md +++ b/website/content/en/docs/faq/_index.md @@ -16,6 +16,8 @@ weight: 6 - ["Can I run other container engines such as Docker and Podman? What about Kubernetes?"](#can-i-run-other-container-engines-such-as-docker-and-podman-what-about-kubernetes) - ["Can I run Lima with a remote Linux machine?"](#can-i-run-lima-with-a-remote-linux-machine) - ["Advantages compared to Docker for Mac?"](#advantages-compared-to-docker-for-mac) +- [Configuration](#configuration) + - ["Is it possible to disable mounts, port forwarding, containerd, etc. ?"](#is-it-possible-to-disable-mounts-port-forwarding-containerd-etc-) - [QEMU](#qemu) - ["QEMU crashes with `HV_ERROR`"](#qemu-crashes-with-hv_error) - ["QEMU is slow"](#qemu-is-slow) @@ -105,6 +107,32 @@ and forward `localhost:8080` to the port 80 of the remote machine. #### "Advantages compared to Docker for Mac?" Lima is free software (Apache License 2.0), while Docker for Mac is not. +### Configuration +#### "Is it possible to disable mounts, port forwarding, containerd, etc. ?" + +Yes, since Lima v0.18: + +{{< tabpane text=true >}} +{{% tab header="CLI" %}} +```bash +limactl start --plain +``` +{{% /tab %}} +{{% tab header="YAML" %}} +```yaml +plain: true +``` +{{% /tab %}} +{{< /tabpane >}} + + +When the "plain" mode is enabled: +- the YAML properties for mounts, port forwarding, containerd, etc. will be ignored +- guest agent will not be running +- dependency packages like sshfs will not be installed into the VM + +User-specified provisioning scripts will be still executed. + ### QEMU #### "QEMU crashes with `HV_ERROR`" If you have installed QEMU v6.0.0 or later on macOS 11 via homebrew, your QEMU binary should have been already automatically signed to enable HVF acceleration.