Skip to content

feat(monitors): expose a configurable control socket for each monitor - #850

Open
Anamika1608 wants to merge 1 commit into
urunc-dev:mainfrom
Anamika1608:config-socket-all-monitors
Open

feat(monitors): expose a configurable control socket for each monitor#850
Anamika1608 wants to merge 1 commit into
urunc-dev:mainfrom
Anamika1608:config-socket-all-monitors

Conversation

@Anamika1608

@Anamika1608 Anamika1608 commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Description

Expose each monitor's control socket in the normal (config-file / CLI) boot flow, so the runtime can talk to the VMM after the guest starts (graceful shutdown now, snapshots later). Each monitor still boots exactly as before — this only keeps its control socket open and reachable:

  • Firecracker: launches with --api-sock while keeping --config-file, so the guest still boots from the config file and the socket stays open (drops only --no-api).
  • QEMU: adds -qmp unix:<path>,server,nowait alongside the disabled human monitor.
  • Cloud Hypervisor: adds --api-socket path=<path>.

The socket path is configurable via a socket_path monitor field, shared across all monitors through a common ResolveSocketPath helper, defaulting to a per-container /tmp/<id>.sock. After changeRoot, urunc creates the socket path's directory inside the monitor rootfs so a custom path works; it fails only if the location is invalid (a file already exists on the path).

Related issues

How was this tested?

  • go build ./..., go test ./pkg/... ./internal/..., gofmt, make lint, and cspell pass; the QEMU BuildExecCmd tests cover the new -qmp argument (Ubuntu 24.04 aarch64 VM, KVM).
  • Live, through real containerd + nerdctl: Firecracker boots from its config file with the socket reachable (state Running) for both the default and a custom socket_path; QEMU (chttp-qemu-linux-aarch64) boots, the guest serves HTTP 200, launches with -qmp unix:/tmp/qemu.sock,server,nowait, and the QMP socket answers query-status with running.
  • Cloud Hypervisor is unit-tested only: no aarch64 Cloud Hypervisor image is published in the registry, so its socket could not be exercised live.

LLM usage

claude code (opus 4.8) for the understanding of 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.

@netlify

netlify Bot commented Jul 28, 2026

Copy link
Copy Markdown

Deploy Preview for urunc ready!

Name Link
🔨 Latest commit 3e02d31
🔍 Latest deploy log https://app.netlify.com/projects/urunc/deploys/6a689a50cddb6e0008c3a7e3
😎 Deploy Preview https://deploy-preview-850--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.

Expose each monitor's control socket in the normal boot flow, so the
runtime can keep talking to the VMM after the guest starts. Every
monitor boots exactly as before; the only change is that its control
socket stays open and reachable:

- Firecracker launches with --api-sock instead of --no-api, keeping
  --config-file so the guest still boots from the config file.
- QEMU exposes a QMP Unix socket in server mode, configured not to
  wait for a client before booting, alongside the disabled human
  monitor.
- Cloud Hypervisor exposes its REST API socket (--api-socket).

The socket location is configurable through a new socket_path option
under a monitor's configuration, wired through MonitorConfig, ExecArgs
and the state.json annotation passthrough, with a per-container default
of /tmp/<id>.sock behind a DefaultSocketDir constant and a shared
resolveSocketPath helper. After changeRoot, urunc creates the socket
path's directory inside the monitor rootfs, so any custom path works;
it fails only if the location is invalid, such as a file already
existing at one of the path's components.

Extend the QEMU BuildExecCmd tests to cover the new argument and
document the socket_path option.

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

@cmainas cmainas left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @Anamika1608 ,

thank you for the PR. I have added some comments in the code. Also, some generic comments:

  • There is still the case where an admin configures the urunc to run the monitors without any socket. This might be for security reasons or because they do not require it. Therefore, if the socket path is not in the configuration, then there should be no socket (no default value).
  • We need to cleanup the socket path, because in case of a container restart (e.g. pod) the monitor might fail to use the same path.

Comment on lines +653 to +665
// Ensure the monitor's control socket directory exists inside the monitor
// rootfs, so the monitor can bind its socket there. changeRoot has already
// made this process' root the monitor rootfs, so the socket path is
// created relative to it. The default (/tmp) already exists; a custom
// socket_path may point at a directory that does not, and MkdirAll fails
// if that location is invalid (e.g. a file already exists there).
if hypervisors.UsesControlSocket(hypervisors.VmmType(vmmType)) {
sockDir := filepath.Dir(hypervisors.ResolveSocketPath(vmmArgs))
if err = os.MkdirAll(sockDir, 0o755); err != nil {
return fmt.Errorf("failed to create control socket directory %q: %w", sockDir, err)
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be done after setupUser. We might not be able to access the socket or directory if the monitor is not a root user.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants