Skip to content

feat(monitors): expose a configurable control socket#841

Open
Anamika1608 wants to merge 5 commits into
urunc-dev:mainfrom
Anamika1608:firecracker-socket-path
Open

feat(monitors): expose a configurable control socket#841
Anamika1608 wants to merge 5 commits into
urunc-dev:mainfrom
Anamika1608:firecracker-socket-path

Conversation

@Anamika1608

@Anamika1608 Anamika1608 commented Jul 21, 2026

Copy link
Copy Markdown

Description

Expose a control socket on the socket-capable monitors and let its path be configured, without changing how the guest boots.

  • Firecracker launches with --api-sock (instead of --no-api) while keeping --config-file, so the guest still boots from the config file and the socket stays open afterwards.
  • New socket_path field under [monitors.<name>], falling back to a per-container default (/tmp/<id>.sock).
  • QEMU exposes a QMP socket (-qmp unix:<path>,server,nowait) and Cloud Hypervisor its REST API socket (--api-socket), both honoring socket_path.

Related issues

How was this tested?

  • go build ./... and go test ./internal/... ./pkg/... pass (Ubuntu 24.04 aarch64 VM, KVM). Added QEMU BuildExecCmd test cases for the new socket arg.
  • make lint reports no findings in the changed files.
  • Firecracker, end-to-end: the guest boots from the config file and returns HTTP 200 through real containerd + nerdctl (Firecracker v1.7.0), and the API socket is reachable afterwards (state: Running). Verified with the default socket path and a configured socket_path.
  • QEMU, end-to-end: an aarch64 image boots through real containerd + nerdctl (QEMU 10.2.1) and returns HTTP 200, launched with -qmp unix:<socket_path>,server,nowait; the QMP socket negotiates and query-status returns running.
  • Cloud Hypervisor: no aarch64 guest image was available to boot it on the aarch64 test host, so its change is covered by the launch-command construction and unit tests only, not booted end-to-end.

LLM usage

claude code (opus 4.8), for understanding the codebase, approach decisions and reviews.

Checklist

  • I have read the contribution guide.
  • The linter passes locally (make lint).
  • The e2e tests of at least one tool pass locally (make test_ctr, make test_nerdctl, make test_docker, make test_crictl).
  • If LLMs were used: I have read the llm policy.

Launch Firecracker with --api-sock instead of --no-api, keeping
--config-file so the guest still boots from the config file exactly as
before. The only change is that the control socket now stays open and
reachable after the guest starts, so the runtime can talk to the VMM
afterwards.

Signed-off-by: Anamika Aggarwal <anamikaagg18@gmail.com>
Add a socket_path field under a monitor's configuration, wired through
MonitorConfig, ExecArgs and the state.json annotation passthrough the
same way the existing monitor fields are. Firecracker's launch command
uses it when set, falling back to the per-container default
/tmp/<id>.sock otherwise.

Signed-off-by: Anamika Aggarwal <anamikaagg18@gmail.com>
Add a shared resolveSocketPath helper and use it across the monitors
that expose a control socket. QEMU now exposes a QMP socket
(-qmp unix:<path>,server,nowait) alongside the disabled human monitor,
and Cloud Hypervisor exposes its REST API socket (--api-socket). Both
honor socket_path, falling back to the per-container default, matching
Firecracker. Extend the QEMU BuildExecCmd tests to cover the new arg.

Signed-off-by: Anamika Aggarwal <anamikaagg18@gmail.com>
@netlify

netlify Bot commented Jul 21, 2026

Copy link
Copy Markdown

Deploy Preview for urunc ready!

Name Link
🔨 Latest commit 0647fcb
🔍 Latest deploy log https://app.netlify.com/projects/urunc/deploys/6a625c9053945f00080f8ada
😎 Deploy Preview https://deploy-preview-841--urunc.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Signed-off-by: Anamika Aggarwal <anamikaagg18@gmail.com>
@Anamika1608
Anamika1608 force-pushed the firecracker-socket-path branch from 74479f7 to 7bc678b Compare July 21, 2026 13:44
@Anamika1608

Copy link
Copy Markdown
Author

hi @cmainas,

a couple of things on this PR i wanted to check with you.

1. socket_path and the /tmp constraint

the socket_path field works, but there is a constraint: the monitor creates the socket inside its own pivoted rootfs (after changeRoot), and that rootfs only has a standard set of directories. so a custom socket_path has to be placed under /tmp, which is always present there. i verified this end to end: with socket_path = "/tmp/firecracker.sock" firecracker boots from the config file, the guest serves HTTP 200, and the socket is reachable and reports state Running. an arbitrary directory like /run/urunc fails, since it does not exist inside the monitor rootfs (bind returns "no such file or directory").

is keeping socket_path scoped to /tmp fine for now, or do you want it fully configurable?

2. testing the other monitors

i wired the socket for qemu (a QMP socket) and cloud hypervisor (its REST api socket) too, both honoring socket_path.

for qemu i was able to test it fully end to end: i found harbor.nbfc.io/nubificus/urunc/chttp-qemu-linux-aarch64 and it worked perfectly on my aarch64 setup. qemu boots with -qmp unix:<socket_path>,server,nowait, the guest returns HTTP 200, and the QMP socket negotiates and query-status returns running.

for cloud hypervisor i could only cover it with unit tests (asserting the launch args), because i could not find an aarch64 cloud hypervisor image in the registry. i probed a few names (chttp/busybox/nginx variants of *-cloud-hypervisor-linux-aarch64) and they all 404.

is there an aarch64 cloud hypervisor image i can use to test it end to end, or is x86 only expected there for now?

@cmainas

cmainas commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Hello @Anamika1608 ,

is keeping socket_path scoped to /tmp fine for now, or do you want it fully configurable?

The default location can be /tmp and we can have a constant to specify that. However, if a user specifies a specific path, we need to ensure that this path exists inside the monitor rootfs. Except of course if it is an invalid location (e.g. another file already exists)

is there an aarch64 cloud hypervisor image i can use to test it end to end, or is x86 only expected there for now?

I have created the harbor.nbfc.io/nubificus/urunc/ubuntu-cloud-hypervisor-linux-raw:latest, but I am afraid you might have issues with cloud-hypervisor in aarch64. You can give it a try, otherwise, we will test it manually.

…otfs

A configured socket_path can point at a directory that does not exist in
the monitor rootfs, which made the monitor fail to bind its socket. After
changeRoot, create the socket path's directory inside the monitor rootfs
so any path works; it fails only if the location is invalid (e.g. a file
already exists at one of the path's components). The default stays under
/tmp, now via a DefaultSocketDir constant.

Signed-off-by: Anamika Aggarwal <anamikaagg18@gmail.com>
@Anamika1608

Copy link
Copy Markdown
Author

hi @cmainas,

did both things you mentioned.

  • socket_path now creates the directory

default stays /tmp (behind a constant), and for a custom socket_path urunc creates the directory inside the monitor rootfs, so any path works.

  • cloud hypervisor on aarch64

the socket part works: it launches with --api-socket path=/tmp/<id>.sock, the socket is created, and it answers api calls (queried /api/v1/vm.info, got the vm config back).

the guest does not boot though, looks like the aarch64 issue you warned about.

so the socket is verified on all three monitors now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants