658 Commits
Author SHA1 Message Date
Akihiro Suda 6c727759c1 Merge pull request #5649 from thc1006/fix/autostart-disable-error-reporting
fix(autostart): report errors in the macOS disable path
2026-10-28 08:47:17 +09:00
Akihiro Suda 7d7a49eb9e Merge pull request #5672 from jandubois/template-param-set-flags
limactl template: add --set and --param to copy and validate
2026-10-28 07:11:04 +09:00
Akihiro Suda b0a0d62f7e limactl-menu: do not leak limactl list warnings to the terminal
`listInstances` passed the stderr of `limactl list --json` through to the
terminal. On a fresh installation it printed "No instance found. Run
`limactl create` to create an instance." before the TUI started. The
warning stayed hidden behind the TUI and reappeared when the menu
suspended to run `limactl create`, which was confusing.

Buffer the stderr and only include it in the error when the command fails.
Also fix the error from `cmd.Start()` being discarded.

Fixes #5681

Assisted-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2026-10-26 17:31:01 +09:00
Jan Dubois 78c1dc3838 Merge pull request #5669 from unsuman/blockdevice-sudoers-digest
sudoers: pin every helper in `lima/privileged` to its sha256 digest
2026-10-25 14:23:25 -07:00
Jan Dubois 2b36b100b2 limactl template: add --set and --param to copy and validate
A template can leave a param empty for `limactl create --param` to
fill in. When that param sets a mount location, `limactl validate`
fails, because an empty location is not an absolute path.
`validate` and `copy` now accept the `--set` and `--param` flags that
`limactl create` already has, so `validate` can check a template with
the values that `create` will get.

Shell completion for `--set` now works for every command that takes
the flag, so the new template flags complete too. Before, only
`limactl create` and `limactl start` completed it; `edit`, `clone`,
`rename` and `restart` did not.

Fixes #5670

Signed-off-by: Jan Dubois <jan.dubois@suse.com>
2026-10-23 14:15:18 -07:00
Jan Dubois 75ab55d9a7 Merge pull request #4917 from peschmae/feat/sync-exclude-flags
shell: Add sync-exclude flag and .limasyncignore file
2026-10-23 12:59:24 -07:00
Ansuman Sahoo 37c9abfd9d sudoers: pin every helper in lima/privileged to its sha256 digest
Signed-off-by: Ansuman Sahoo <anshumansahoo500@gmail.com>
2026-10-24 00:58:37 +05:30
Mathias Petermann ace0b1bf98 shell: Add sync-exclude flag and .limasyncignore file
To avoid syncing generated or sensitive data into a vm, a new sync-exclude flag
is added, to be used in conjunction with --sync. This allows to specify rsync excludes
which are then not synced.

Additionally a .limasyncignore file can be created, which also considered and
passed to rsync as the exclude-from flag.

Signed-off-by: Mathias Petermann <mathias.petermann@gmail.com>
Signed-off-by: Ansuman Sahoo <anshumansahoo500@gmail.com>
2026-10-24 00:31:00 +05:30
Akihiro Suda 02eafe9cfe limactl-menu: add a form for creating new instances
Press `c` or F7 in the instance list (or "Create Instance" in the
empty state) to open a form for the instance name, template, CPUs,
memory, disk, VM type, and whether to start the instance after
creation. Empty fields fall back to the template defaults.

The other `limactl create` flags (mounts, networks, port forwards,
`--set`, `--param`, etc.) are available in the "Details" section, which
is hidden by default. Its fields are generated from the flag
definitions of `limactl create`, and the description of the focused
field is shown below the form.

To minimize free-text input, the values are chosen from dropdowns
whenever the choices are known: the shell completion values of the
flags, the drivers, and the image variants of the selected template.
"Other..." in a dropdown allows entering a value that is not in the
list.

"Create" runs `limactl start` (or `limactl create`) with the
corresponding flags. "Edit" opens an editor for the template YAML with
the form values applied, and then creates the instance from the edited
YAML. In both cases, the menu is suspended while limactl is running, and
the new instance is selected when returning to the menu.

The form can be navigated with the arrow keys as well as with Tab:
Up/Down move between the fields and the buttons (except in an open
dropdown list, and except between the lines of a text area), and
Left/Right move between the buttons.

The single-key shortcuts of the instance list are now only handled
while the list has the focus, so that they do not interfere with typing
into the form.

Fixes #5595

Assisted-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2026-10-22 00:43:51 +09:00
deltron-fr 65a9e7d5ad limactl-menu: improve color contrast across terminal themes
Use terminal-default colors for text and explicit styles for focused list items, modal buttons, and borders.

Signed-off-by: deltron-fr <kayceoogbonnaya2304@gmail.com>
2026-10-21 15:16:17 +01:00
秀吉 031dc9e42b docs(autostart): clarify daemon uninstall comment
Describe the existing best-effort cleanup behavior without assuming why launchctl commands fail.

Signed-off-by: thc1006 <hctsai@linux.com>

Signed-off-by: 秀吉 <hctsai@linux.com>
2026-10-21 03:26:57 +08:00
thc1006 488cc78567 fix(autostart): report errors in the macOS disable path
autostartDisableAction treated any os.Stat error on the LaunchDaemon plist as
"not registered", so a permission or I/O error read as "nothing to disable".
Report a Stat error other than os.ErrNotExist instead.

daemonUninstall discarded the launchctl bootout and disable errors before
removing the plist. Those commands return an error when the job was never
loaded or is already unloaded, a normal state here that launchctl's exit status
does not reliably distinguish from a real failure, so log them and continue
rather than hide them.

This is the error-reporting part of #5643. The boot daemon left behind after a
login+boot disable, disabling a deleted instance, and the shared name-only
label are identity and lifecycle changes left for follow-ups.

Signed-off-by: thc1006 <84045975+thc1006@users.noreply.github.com>
2026-10-19 12:02:00 +08:00
deltron-fr c2bc318c37 display binary units on menu info page
Signed-off-by: deltron-fr <kayceoogbonnaya2304@gmail.com>
2026-10-16 12:04:06 +01:00
deltron-fr a977095835 limactl-menu: return to menu after actions
Suspend the TUI while running actions and refresh the instance list before resuming the menu.

Signed-off-by: deltron-fr <kayceoogbonnaya2304@gmail.com>
2026-10-16 09:00:35 +01:00
Jan Dubois 5e86a5fc98 Merge pull request #5579 from Sarthak-Shreshtha01/fix/issue-5535
autostart: set PATH in launchd plist
2026-10-15 13:07:33 -07:00
Sarthak 6d29bb8ca7 autostart: set PATH in launchd plist
launchd starts agents with a minimal PATH, so `limactl start` could not
find qemu-system-* installed outside the default system directories
(e.g. Homebrew). Save the PATH of the registering shell in the plist,
as is already done for LIMA_HOME. The value is XML-escaped so a PATH
containing characters such as `&` still produces a valid plist.

Both the agent and the boot daemon renderers take LIMA_HOME and PATH
from autostart.EnvTemplateVars, so `limactl autostart --condition boot`
gets the PATH entry too.

Signed-off-by: Sarthak <sarthakshreshtha345@gmail.com>
2026-10-16 00:14:02 +05:30
HMM-210 37e1fe57e1 fix(limactl-menu): rename [LOCKED] to [PROTECTED]
Signed-off-by: HMM-210 <HMM-210@users.noreply.github.com>
2026-10-15 19:03:04 +03:00
Shaurya Bisht 0e1c79fa5f limactl-menu: show separate titled CPUS and MEMORY columns
Replace the combined "4CPU/4GiB" cell with separate CPUS and MEMORY
columns, add a header row with column titles, and escape the [LOCKED]
marker so tview renders it instead of treating it as a color tag.

Fixes #5600

Signed-off-by: Shaurya Bisht <shauryabisht707@gmail.com>
2026-10-15 02:32:07 +05:30
Akihiro Suda 6c9920c57d Merge pull request #5485 from unsuman/net/pr3-linux-config-sudoers
networks: generate Linux defaults, validation and sudoers rules
2026-10-11 03:49:34 +09:00
dawud khan bd93523073 fix(menu): show VM type instead of SSH address
The last column of the instance list showed the SSH address, which is
almost always 127.0.0.1:<port> and not useful at a glance. Show the
VM type (vz, qemu, wsl2, krunkit) instead, or "-" if it is unset.

The SSH address and port are still shown in the Info (F3) panel.

Closes: https://github.com/lima-vm/lima/issues/5592
Signed-off-by: dawud khan <dawudkhan147@gmail.com>
2026-10-10 01:37:28 +05:00
Ansuman Sahoo f3d2492a9c networks: generate Linux defaults, validation and sudoers rules
Teach the networks.yaml defaults, the path validation and the sudoers generator
about Linux hosts:

- The default networks.yaml now points at the lima-privileged-net binary in
  libexec/lima/privileged, uses /run/lima and /etc/sudoers.d/lima, picks the
  "sudo" or "wheel" group, and documents that "bridged" needs an already
  existing bridge (Lima never enslaves a physical interface).
- Validate() checks paths.socketVMNet only on macOS, and the lima-privileged-net
  binary on Linux. A paths.socketVMNet left on Linux is rejected with a hint to
  regenerate networks.yaml: earlier releases wrote the macOS defaults there on
  every host, and the file is never rewritten. varRun only has to be
  daemon-group-writable on macOS.
- Sudoers() iterates over RequiredDaemons() and, for lima-privileged-net,
  additionally allows the tap command, restricted by tapCmdPattern() so that no
  extra arguments can be smuggled in. The mkdir rule stays macOS-only. The
  rendering takes the resolved helpers, so that a test asserts the grants of
  both helpers on every host.
- `limactl sudoers` is enabled on Linux; its help scopes the socket_vmnet
  documentation link to macOS.

Everything that is about sudoers rather than about networking moves into
pkg/sudoers, so that it is shared by every helper under
libexec/lima/privileged instead of being reimplemented per feature:

- Pin() prefixes a helper's commands with a sudo `Digest_Spec`, so that sudo
  itself refuses to run the helper once the binary no longer matches the sha256
  recorded when the file was generated. It replaces the networks-only
  Config.DigestSpec(). /usr/bin/pkill is not pinned, as it is a system binary
  that is updated independently of Lima.
- ReadFile() tolerates an unreadable sudoers file, as /etc/sudoers.d is
  typically 0750 root:root: a correctly installed file cannot be verified from
  an unprivileged process, and a wrong one still fails loudly inside sudo.
  `limactl sudoers --check` does not tolerate it, and suggests piping the file
  through `sudo cat` instead.
- VerifyPasswordLess() and VerifyFragment() replace the Config methods
  passwordLessSudo() and the body of VerifySudoAccess(), which now only
  collects the identities of the required daemons and renders its own fragment.
- RegenerateHint() is the one place wording the regeneration command, replacing
  limactl's sudoersCheckHint() and the diverging copy in pkg/networks. It drops
  the `-g wheel` from the hint on Linux, where that group often does not exist.

pkg/networks/sudoers.go is left with the rendering of the network grants, and
its file-verification tests move to pkg/sudoers, where they no longer depend on
the macOS-only mkdir entry to have something to verify.

Signed-off-by: Ansuman Sahoo <anshumansahoo500@gmail.com>
2026-10-09 22:24:51 +05:30
nightcityblade 3f5df5f524 fix(menu): display memory with binary units
Signed-off-by: nightcityblade <jackchen@haloailabs.com>
2026-10-10 00:52:13 +08:00
Soumya Sagar feb8e94960 feat(cli): add limactl-menu TUI plugin for instance management
Implements #5285 - adds 'limactl menu' TUI plugin for managing Lima instances through an interactive terminal UI.

Features:
- Single-panel instance list showing status icon, name, status, arch, CPUs/memory, and SSH address
- Midnight Commander-style function keys (F1 Help, F2 Start/Stop Toggle, F3 Info, F5 Refresh, F8 Delete, F10 Quit)
- Interactive action popup menu on Enter
- F5 refreshes the instance list in-place
- Confirmation modals for destructive actions (Stop, Delete)
- Modals for instance details and port forwards
- Footer help bar with keyboard shortcut legend
- Empty state with option to create a new instance when no VMs exist

Developed with AI assistance.

Signed-off-by: Soumya Sagar <soumya.sagar.codr@gmail.com>
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2026-10-09 18:42:10 +09:00
Akihiro Suda c2d003c42c Merge pull request #5513 from unsuman/net/pr5-review-fixes
networks: derive the tap name in the helper, validate its path
2026-10-06 23:13:35 +09:00
Ansuman Sahoo 1e25cca695 networks: derive the tap name in the helper, validate its path
Signed-off-by: Ansuman Sahoo <anshumansahoo500@gmail.com>
2026-10-05 20:55:17 +05:30
olamilekan000 5b5c0aeb28 driver: return structured snapshot metadata
Signed-off-by: olamilekan000 <odukoyaonline@gmail.com>
2026-10-05 09:47:26 +01:00
Kir Kolyshkin eaba0be694 limactl-url-fedora-rawhide: don't rely on COMPOSE_ID
The rawhide/COMPOSE_ID file on dl.fedoraproject.org is sometimes out of
sync with the contents of the images directory. For example, currently
COMPOSE_ID says Fedora-Rawhide-20260929.n.0, while the only image
available is Fedora-Cloud-Base-Generic-Rawhide-20261002.n.0, so
starting an instance from experimental/fedora-rawhide fails with:

	failed to download `https://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-Rawhide-20260929.n.0.x86_64.qcow2`: unexpected HTTP status Not Found

Instead, get the image file name from the CHECKSUM file in the images
directory, which describes the images actually present there. As a
bonus, this also gives us the image digest.

While at it, add --retry to curl invocations.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
2026-10-02 16:37:11 -07:00
Jan Dubois fee349adab CI: factor Windows setup into composite actions; add plain-Windows jobs
Lima should run on a Windows host whose only ssh is the native OpenSSH
client, but the existing Windows jobs run with Git for Windows and MSYS2
installed, so a new dependency on their tools would go unnoticed. The
plain-Windows jobs remove both toolchains before testing.

The MSYS2 jobs got a Cygwin ssh from Git for Windows through
_LIMA_WINDOWS_EXTRA_PATH and now install MSYS2's openssh instead. That
was the experimental variable's last use in the repo, so remove it.

The MSYS2 jobs also install rsync, so the integration tests cover the
rsync copy backend on Windows. Because MSYS2 setup now runs before the
unit tests and make, the unit tests that skip without rsync run on
Windows too.

The WSL2 job's id changes from windows to windows-wsl2.

Signed-off-by: Jan Dubois <jan.dubois@suse.com>
2026-10-02 00:28:58 -07:00
Akihiro Suda 96d73a5b5f Merge pull request #5299 from jandubois/copytool-native-windows-openssh
copytool: support native Windows OpenSSH
2026-10-02 11:06:38 +09:00
Akihiro Suda 573bada617 Merge pull request #5088 from resker/feature/vz-shutdown-recovery
fix(start): recover from the broken states left by an unclean shutdown
2026-09-30 12:43:25 +09:00
Nick Sweeting aa8f132f00 Support secure host block-device attachment on macOS VZ
Attach explicitly allowed host disks through a dedicated root-owned helper,
passing validated file descriptors to unprivileged VZ over an authenticated
Unix socket. Scope sudoers grants to the invoking user and exact device paths,
reject unsafe helper paths and socket symlinks, authenticate both peers, and
validate the received device identity.

Retain descriptors per VM while preserving process-lifetime network wrappers
used by krunkit. Lock whole host disks across instances sharing LIMA_HOME,
including raw/block aliases and partitions. Reject duplicate configuration
entries and external VZ drivers at runtime.

Compose network and block-device sudoers fragments through pkg/sudoers, match
complete generated lines, and warn when regeneration removes existing grants.
Keep integration-test grants in temporary fragments and revoke them before
detaching the test RAM disk. Add security, lifecycle, and real-disk regression
coverage and document installation requirements and remaining grant limits.

Signed-off-by: Nick Sweeting <git@sweeting.me>
2026-09-23 10:08:04 -07:00
Robert EskerandClaude Opus 5 e1268fd101 fix(start): recover from the broken states left by an unclean shutdown
A host agent that dies without stopping the VM can leave an instance in one of two
broken states, and `limactl start` then refuses to start it until they are cleared
by hand. Recover from both instead:

- the VM driver is running with no host agent attached, which is force-stopped;
- nothing is listening on the host agent socket, whose files are removed without
  signaling any process, since the recorded PID may since belong to an unrelated
  one.

Only the host agent's own ha.pid and ha.sock are removed. A driver that runs as
its own process may still be alive, and deleting its PID file would hide it from
the next inspection and allow a second driver to be started for the same
instance; the exception is a driver that runs the VM inside the host agent
process, such as vz, which records the same PID and so is removed with them.

The two run in sequence rather than as alternatives, because clearing a departed
host agent can reveal a driver that is still running and has to be stopped on
its own. Doing that after ha.pid is gone also means the force stop cannot signal
a reused PID.

Two upstream changes have since narrowed how these states arise, without closing
them. e529ce08 makes `ReadPIDFile` ignore PID files written during a previous boot,
which covers PID reuse across a reboot. #5436 removes `vz.pid` whenever the vz
driver stops, which covers the launchd SIGTERM path for vz. What is left:

- a driver that runs as its own process, such as qemu, outliving a host agent that
  died within the same boot. No reboot and no PID reuse are needed, and nothing
  stops that VM or clears its PID file;
- PID reuse within a single boot;
- instances whose directory carries no boot session marker, because they were
  started by an older version of Lima;
- platforms that expose no boot session ID (`osutil.ErrBootSessionNotSupported`),
  where PID files are handled as they were before the marker.

#5436 fixed the first of the two bugs of #5087; this is the rest of it.

Fixes #5087.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Robert Esker <resker@gmail.com>
2026-09-22 07:52:19 -06:00
Jan Dubois 49c5471e28 copytool: support native Windows OpenSSH
On Windows, `limactl copy` converted host paths to the Cygwin/MSYS form
no matter which tool would consume them, and it passed ControlMaster
options unconditionally. Native OpenSSH cannot use that path form and
has no multiplexing, so scp failed with "getsockname failed".

The two backends need different path forms. scp takes whatever its own
toolchain uses, while rsync on Windows is always Cygwin-based and reads
a drive letter as a hostspec. So every path now takes the form of the
binary that reads it, operands and ssh options alike, because scp hands
its options to the ssh beside itself while rsync hands them to the ssh
it names.

Both backends now skip multiplexing on Windows, so they stop building
a control socket path they never use.

Signed-off-by: Jan Dubois <jan.dubois@suse.com>
2026-09-18 21:08:03 -07:00
Akihiro Suda 1e6e2b38c5 copytool: make copy -r into an existing directory consistent across backends
For a recursive copy whose destination is an existing directory, the rsync
backend copied the *contents* of the source directory, while the scp backend
copied the directory itself, like `cp -r` and `scp -r` do. Since `--backend=auto`
prefers rsync and only falls back to scp when the guest has no rsync, the
outcome of the very same command depended on the guest image.

The rsync backend appended a trailing slash to every path of a recursive copy,
and a trailing slash on the source is what tells rsync to copy the contents.
Derive the form to pass to rsync from the destination instead, so that a
trailing slash spelled by the user is no longer significant:

- the destination is an existing directory: `SRC DST`, copying SRC into DST;
- the destination does not exist yet: `SRC/ DST`, making DST a copy of SRC.

A destination that can neither be confirmed nor ruled out to be a directory
fails the copy, instead of being assumed to be missing, which would put the
files in the wrong place again.

This also fixes two related defects of the previous code: `copy -r` of a
non-directory into a destination that does not exist made rsync fail on the
appended slash, and multiple sources were merged into the destination instead
of being copied by name.

Add the missing case to copy.bats (both backends, both directions), which only
covered a plain `SRC DST` copy into a destination that does not exist yet, plus
unit tests for the path rewriting, which needs no VM.

`limactl shell --sync` does want the form that copies the contents, so let it
spell its own paths with a trailing slash and stop setting Options.Recursive,
which for rsync only added a `-r` that `-a` already implies.

Fixes #5500

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2026-09-16 15:46:24 +09:00
Akihiro Suda 3148fe7f2a Merge pull request #5418 from chrisanderton/fsync-drop
hostagent: don't fsync every log record
2026-09-14 15:09:05 +09:00
Akihiro Suda a85206649d Merge pull request #5489 from resker/fix/autostart-lima-home
fix(autostart): propagate LIMA_HOME into generated launchd/systemd units
2026-09-12 04:37:21 +09:00
Akihiro Suda ba798aceff Merge pull request #5483 from unsuman/net/pr1-lima-net-helper
`lima-privileged-net`: add the privileged network helper for Linux hosts
2026-09-11 23:56:16 +09:00
Robert EskerandClaude Opus 5 67c7362173 fix(autostart): propagate LIMA_HOME into generated launchd/systemd units
`limactl autostart enable` rendered a launchd plist or systemd unit that carried
no LIMA_HOME. Neither launchd nor systemd inherits the environment of the shell
that registered the instance, so the autostarted `limactl start <instance>`
resolved LIMA_HOME to its default ~/.lima and could not find an instance kept
anywhere else. Both conditions were affected, `--condition=login` as well as
`--condition=boot`.

Pass the LIMA_HOME in effect at registration time to the templates and emit it:
an EnvironmentVariables dict in the two plists, and an Environment= line in the
systemd unit.

The system LaunchDaemon is rendered by `daemonInstall` rather than by the shared
manager, so it needs the value supplied separately. Its rendering moves to
`renderDaemonPlist` to be testable: a key the template references but the map
omits renders as the literal "<no value>" instead of failing, which would then be
written into /Library/LaunchDaemons.

The render tests pin LIMA_HOME so the generated units do not vary with the host
running the test.

Fixes #5488

Signed-off-by: Robert Esker <resker@gmail.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 14:50:03 -05:00
Ansuman Sahoo 707103d11a lima-privileged-net: add the privileged network helper for Linux hosts
Linux has no equivalent of socket_vmnet, so add lima-privileged-net, a small
helper that limactl runs via sudo to set up the "shared", "host" and "bridged"
networks. It is installed into libexec/lima/privileged/, a directory reserved
for helpers that run with elevated privileges, so that they are easy to tell
apart from the unprivileged helpers and easy to audit.

`lima-privileged-net start` creates (for "shared" and "host") the lima-<name>
bridge, assigns the gateway address, spawns dnsmasq for DHCP, and installs the
NAT/forwarding rules of the "shared" mode. `lima-privileged-net tap` creates the
tap device of a single instance, hands it to the calling user, and attaches it
to the bridge. Both take all parameters from the command line rather than
reading the user-writable networks.yaml, because the arguments are what the
sudoers file pins down.

The tap device is created with `ip tuntap`, falling back to the /dev/net/tun
ioctls that iproute2 itself uses, because busybox's `ip` applet does not
implement the tuntap subcommand.

The helper tears the network down again when the last instance leaves, and only
ever touches bridges and tap devices that follow the Lima naming scheme.

networks.IsManagedBridge() and networks.IsTapName() recognize the bridges and
tap devices that lima-privileged-net owns, so it never touches an interface it
did not create itself. Config.Validate() rejects a network name that would make
the derived bridge name exceed IFNAMSIZ-1. A daemon-side commit adds the
matching name generators and the command lines that start the helper and attach
an instance to its bridge.

Signed-off-by: Ansuman Sahoo <anshumansahoo500@gmail.com>
2026-09-09 17:37:22 +05:30
Akihiro Suda 1973a8c680 Merge pull request #5462 from iamstarkov/vz-audio-microphone
vz: add audio.microphone to attach a capture stream
2026-09-08 11:16:46 +09:00
Vladimir StarkovandClaude Opus 5 99357638c4 vz: add audio.microphone to attach a capture stream
The vz driver only creates a host output stream, so a guest with
`audio.device: vz` gets a speaker and no microphone: `/dev/snd` has
`pcmC0D0p` but no capture device, and nothing in the guest can record.

Add an opt-in `audio.microphone` boolean, default false. When it is set,
the driver also creates a host input stream and passes both streams to
SetStreams. It is opt-in because an input stream makes macOS ask for
microphone permission on behalf of the process that runs the VM, and
enabling sound alone should not trigger that prompt.

Code-Hex/vz exposes the input stream as
NewVirtioSoundDeviceHostInputStreamConfiguration. It requires macOS 12,
the same as the output stream the driver already creates, so this adds
no new platform requirement.

The key warns as experimental, and setting it without `audio.device`
warns and is ignored, like an `hda` interface request. The QEMU, WSL2,
and krunkit drivers report ignored audio fields via
reflectutil.UnknownNonEmptyFields in validateConfig; FillDefault
materializes every audio field, so zero-value defaults are normalized
back to nil before the check. WSL2's Start()-time audio.interface
warning is removed in favor of that check, and "Audio" joins its
knownYamlProperties so audio settings are reported once. The
--audio-microphone flag and the experimental-features docs entry follow
the audio.interface commit (a9b8e59a).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Vladimir Starkov <iamstarkov@gmail.com>
2026-09-05 01:31:28 +02:00
Chris Anderton c9dd3de918 hostagent: flush coalesced logs after idle periods
Signed-off-by: Chris Anderton <chris@cga.io>
2026-09-04 01:25:38 +01:00
Chris Anderton daf56e690b hostagent: coalesce log flushes instead of syncing every record
syncWriter called Sync() after every write. logrus holds its output mutex
across Out.Write, so every record held that lock for a full fsync, throttling
all logging in the hostagent to ~240 records/s. The gRPC port forwarder logs
once per tunnel teardown, so a burst of closing connections stalled port
publication behind the backlog.

Flush at most once per 100ms instead. Every record is still written.

The flush cannot be dropped entirely: limactl start follows these files with
fsnotify, and on Windows the tailer stops seeing new lines without it.

Fixes #5410

Signed-off-by: Chris Anderton <chris@cga.io>
2026-09-04 01:25:38 +01:00
Akihiro Suda dd909d0973 Merge pull request #5449 from mie313/hcs-driver
Implement HCS driver
2026-09-01 14:56:41 +09:00
Robert Esker 6f99b4b349 feat(autostart): add --keep-alive flag to limactl autostart enable
Add --keep-alive (default: true) to both LaunchAgent and LaunchDaemon
plist templates. When enabled, launchd restarts the Lima host agent
automatically if it exits unexpectedly, preventing instances from
remaining in a Broken state until the next login or reboot.

The flag is accepted on all platforms; on Linux it is a no-op since
systemd restart behavior is configured separately in the unit file.

Closes: #4992

Signed-off-by: Robert Esker <resker@gmail.com>
2026-08-30 12:37:04 -05:00
mie313 15463f7275 Implement HCS driver
Signed-off-by: mie313 <mie313.tanaka@gmail.com>
2026-08-30 15:13:43 +01:00
Akihiro Suda 3612b71bd8 lint: fix printf: fmt.Errorf format %#q has arg ans of wrong type int
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2026-08-24 10:39:06 +09:00
Akihiro Suda baf8e947a3 lint: fix stditerators: NumField/Field loop can simplified using Type.Fields iteration
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2026-08-24 10:29:50 +09:00
Eugene Kalinin e529ce0874 fix(store): do not trust PID files left behind by a previous boot
`ReadPIDFile` decides whether a PID file belongs to a running process by signaling
the PID. Within a single boot this is fine, because a PID file of a process that
has already exited gets removed. Across a reboot it is not: the recorded PID may
have been reused by an unrelated process, and Lima then reports the instance as
`Broken`, either with "driver is running but host agent is not", or by trying to
connect to a stale `ha.sock`. `limactl start` fails, and a LaunchDaemon with
`KeepAlive` crash-loops it.

Record the boot session ID of the host next to the PID files of an instance, and
ignore a PID file that was written during a different boot. The ID is read from
the `kern.bootsessionuuid` sysctl on macOS and from
`/proc/sys/kernel/random/boot_id` on Linux; on platforms without such an
identifier the behavior is unchanged, as it is for instances that were started by
an older version of Lima and have no marker.

The marker is shared by the PID files of the directory, so writing a PID file
during a new boot removes all of them before the marker is refreshed: refreshing
it must never make a PID file of a previous boot look current. Readers check the
boot before they read the PID, and leave the removal to the next writer, so that
a reader can never remove a PID file that another process is writing at that very
moment. The PID file itself is renamed into place.

When the boot session ID cannot be determined the PID file is not written at all,
because a marker left over from a previous boot would otherwise void a PID file
that is current. Only the platforms without support for a boot session ID fall
back to the previous behavior.

The PID of a stale PID file is never signaled, because it may belong to an
unrelated process.

`StartWithPaths` checked for `ha.pid` with `os.Stat`, which bypassed this logic;
it now uses `ReadPIDFile` as well.

Related to #5087
Related to #5075

Signed-off-by: Eugene Kalinin <e.v.kalinin@gmail.com>
2026-08-23 22:13:03 +03:00
Akihiro Suda 216c0f8aa5 Merge pull request #5348 from mie313/autoappend-common-QEMUpath-to-PATH
Autoappend common tool directories to PATH
2026-08-03 11:53:37 +09:00