Skip to content

refactor(minimald): coalesce code paths between UDS and vsock listeners - #400

Merged
twitchyliquid64 merged 1 commit into
mainfrom
tom/minimald
Jun 13, 2026
Merged

refactor(minimald): coalesce code paths between UDS and vsock listeners#400
twitchyliquid64 merged 1 commit into
mainfrom
tom/minimald

Conversation

@twitchyliquid64

@twitchyliquid64 twitchyliquid64 commented Jun 12, 2026

Copy link
Copy Markdown
Member
  • Do not diverge code-paths for the UDS vs vsock listeners, use generic listeners and config knobs instead
  • Make Server methods generic over different kinds of listeners
  • Stamp the SSH host key in a known_hosts file so clients can connect without disabling host key verification + the associated warning

Summary by CodeRabbit

  • Refactor

    • Unified server transport behind a generic listener and simplified connection APIs.
    • Centralized micro‑VM startup and root filesystem entry; guest now pivots into a fixed newroot.
  • Improvements

    • Per‑instance SSH host‑key learning and instance‑scoped known_hosts and directories.
    • VSock port selection now derived per instance.
    • Added conversion from absolute to relative paths.
  • Tests

    • Test harness updated to use the streamlined connection path.
  • Chores

    • Added Linux‑only package support.

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6d1f4d15-65be-4f50-ba54-039d6fbb2d9b

📥 Commits

Reviewing files that changed from the base of the PR and between b7e244b and 80d7d01.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • crates/minimald/Cargo.toml
  • crates/minimald/src/connection.rs
  • crates/minimald/src/guest.rs
  • crates/minimald/src/main.rs
  • crates/minimald/src/server.rs
  • crates/minimald/src/test_harness.rs
  • crates/paths/src/lib.rs
💤 Files with no reviewable changes (1)
  • crates/minimald/src/connection.rs
✅ Files skipped from review due to trivial changes (1)
  • crates/minimald/Cargo.toml
🚧 Files skipped from review as they are similar to previous changes (5)
  • crates/paths/src/lib.rs
  • crates/minimald/src/test_harness.rs
  • crates/minimald/src/guest.rs
  • crates/minimald/src/server.rs
  • crates/minimald/src/main.rs

📝 Walkthrough

Walkthrough

Unifies server transport via a Listener trait, uses Connection::from_stream for all accept paths, centralizes micro‑VM guest mount/enter_rootfs flow (fixed /newroot), adds a Linux nix workspace flag, and adds AbsPath -> CwdRelative conversion.

Changes

VSOCK and Micro-VM Server Refactor

Layer / File(s) Summary
Transport‑Agnostic Server Listener Abstraction
crates/minimald/src/server.rs
Adds Listener trait with transport metadata and async accept contract, implements for UnixListener and Linux VsockListener, and consolidates server execution into Server::run<L: Listener>.
Connection Construction Unification and Test Updates
crates/minimald/src/connection.rs, crates/minimald/src/test_harness.rs
Removes Connection::from_socket and the UnixStream import; test harness and accept paths now construct server sessions with Connection::from_stream.
Main Entry Point, CLI, and Micro‑VM Flow
crates/minimald/src/main.rs
Renames vsock port base constant, adds Cli::listen_args()/instance_num(), extends ListenArgs and MainError, selects micro‑VM mode via is_minimal_microvm(), centralizes guest setup (mount_dev + enter_rootfs) with fallback behavior, learns per‑instance known_hosts, and dispatches UDS or VSOCK listener startup.
Guest rootfs, Linux dependency, and Path Conversion
crates/minimald/src/guest.rs, crates/minimald/Cargo.toml, crates/paths/src/lib.rs
Changes enter_rootfs to use fixed "/newroot" (removes parameter), sets nix.workspace = true under Linux target deps, and adds From<AbsPath<R>> for CwdRelative<R>.

Sequence Diagram

sequenceDiagram
  participant Init as InitProcess
  participant Main as async_main
  participant Guest as guest_setup
  participant Keys as known_hosts_writer
  participant Server as Server::run
  Init->>Main: detect_microvm_mode
  Main->>Guest: mount_dev_and_enter_rootfs
  Guest-->>Main: setup_result
  Main->>Keys: learn_host_key_for_instance
  Keys-->>Main: known_hosts_path_ready
  Main->>Server: start_with_uds_or_vsock_listener
  Server->>Server: accept() -> (stream, addr)
  Server->>Server: Connection::from_stream(stream, L::IS_LOCAL)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • gominimal/minimal#374: Overlaps on replacing UDS-specific connection paths with Connection::from_stream and server transport wiring.
  • gominimal/minimal#373: Related edits to enter_rootfs APIs and boot/init handling.

Suggested reviewers

  • norrietaylor
  • evanspearman
  • jtnkminimal

Poem

🐇 I hopped through sockets, ports, and roots tonight,
listeners hummed softly, and keys learned the light.
The guest found /newroot, the server took the stream,
vsock or UDS, the same quiet dream.
Carrots logged, servers spawned — a rabbit's dev team.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main refactoring: coalescing UDS and vsock listener code paths into a generic approach.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/minimald/src/test_harness.rs (1)

83-84: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Update stale constructor reference in comment.

Line 83 still references Connection::from_socket, but the code now uses Connection::from_stream. Keeping this aligned avoids confusion during future transport refactors.

Suggested edit
-        // `russh::server::run_stream` (called inside `Connection::from_socket`)
+        // `russh::server::run_stream` (called inside `Connection::from_stream`)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/minimald/src/test_harness.rs` around lines 83 - 84, The comment
referencing the old constructor is stale: update the text that mentions
`Connection::from_socket` to instead reference `Connection::from_stream` (the
function currently used) so the comment aligns with the actual code path (look
for the comment block mentioning `russh::server::run_stream` and change the
constructor name accordingly).
🧹 Nitpick comments (1)
crates/paths/src/lib.rs (1)

962-966: 📐 Maintainability & Code Quality | ⚡ Quick win

Add a focused unit test for this new conversion path.

This new public From<AbsPath<R>> path is untested directly; adding one assertion here would lock in behavior and prevent regressions.

Proposed test addition
@@
     #[test]
     fn cwd_relative_resolve_passes_absolute_through_unchanged() {
         let cli: CwdRelative<Host> = "/etc/minimal".parse().unwrap();
         let resolved = cli
             .resolve()
             .expect("resolve does not consult cwd for abs paths");
         assert_eq!(resolved.as_str(), "/etc/minimal");
     }
+
+    #[test]
+    fn cwd_relative_from_abs_path_preserves_abs_variant() {
+        let abs = HostAbsPath::try_new("/etc/minimal").unwrap();
+        let cli: CwdRelative<Host> = abs.clone().into();
+        assert!(cli.is_absolute());
+        assert_eq!(cli.as_either().as_abs(), Some(&abs));
+        assert_eq!(cli.resolve().unwrap(), abs);
+    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/paths/src/lib.rs` around lines 962 - 966, Add a unit test that
constructs an AbsPath (for a concrete R used by other tests), converts it via
CwdRelative::from(abs) or abs.into(), and asserts the resulting CwdRelative
contains the original AbsPath wrapped in EitherPath::Abs; reference the types
AbsPath, CwdRelative, the From<AbsPath<R>> impl, and the EitherPath::Abs variant
so the test verifies the conversion path and value are preserved.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/minimald/src/server.rs`:
- Around line 194-208: The JoinSet named session_set is never drained so
completed session tasks accumulate; modify the accept loop that spawns
session_set.spawn(...) to also poll and remove completed tasks (e.g., call
session_set.join_next() or a non-blocking poll variant inside the loop or via
tokio::select) and handle their results (log errors already done for
session_fut) so entries are removed from session_set; locate the accept loop
around listener.accept().await and the Connection::from_stream(...) ->
session_fut to add periodic draining of session_set to prevent unbounded growth.

---

Outside diff comments:
In `@crates/minimald/src/test_harness.rs`:
- Around line 83-84: The comment referencing the old constructor is stale:
update the text that mentions `Connection::from_socket` to instead reference
`Connection::from_stream` (the function currently used) so the comment aligns
with the actual code path (look for the comment block mentioning
`russh::server::run_stream` and change the constructor name accordingly).

---

Nitpick comments:
In `@crates/paths/src/lib.rs`:
- Around line 962-966: Add a unit test that constructs an AbsPath (for a
concrete R used by other tests), converts it via CwdRelative::from(abs) or
abs.into(), and asserts the resulting CwdRelative contains the original AbsPath
wrapped in EitherPath::Abs; reference the types AbsPath, CwdRelative, the
From<AbsPath<R>> impl, and the EitherPath::Abs variant so the test verifies the
conversion path and value are preserved.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a7a092c2-44e3-472a-8549-a01a5c30b729

📥 Commits

Reviewing files that changed from the base of the PR and between 1f65e57 and 6b80418.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • crates/minimald/Cargo.toml
  • crates/minimald/src/connection.rs
  • crates/minimald/src/guest.rs
  • crates/minimald/src/main.rs
  • crates/minimald/src/server.rs
  • crates/minimald/src/test_harness.rs
  • crates/paths/src/lib.rs
💤 Files with no reviewable changes (1)
  • crates/minimald/src/connection.rs

Comment thread crates/minimald/src/server.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/minimald/src/guest.rs`:
- Line 124: The log message incorrectly states "pivot_root" while the code
actually calls libc::chroot; update the tracing::info! invocation to accurately
reflect the operation (e.g., "switched to upstream rootfs (chroot)" or "changed
rootfs via chroot") so logs match the libc::chroot call and avoid misleading
debugging; locate the tracing::info! call near the libc::chroot usage in
guest.rs and change the message string accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b7a1b341-512c-4ae2-b444-d6e429e5c693

📥 Commits

Reviewing files that changed from the base of the PR and between 6b80418 and c7d808f.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • crates/minimald/Cargo.toml
  • crates/minimald/src/connection.rs
  • crates/minimald/src/guest.rs
  • crates/minimald/src/main.rs
  • crates/minimald/src/server.rs
  • crates/minimald/src/test_harness.rs
  • crates/paths/src/lib.rs
💤 Files with no reviewable changes (1)
  • crates/minimald/src/connection.rs
🚧 Files skipped from review as they are similar to previous changes (5)
  • crates/paths/src/lib.rs
  • crates/minimald/src/test_harness.rs
  • crates/minimald/Cargo.toml
  • crates/minimald/src/main.rs
  • crates/minimald/src/server.rs

std::env::set_current_dir("/")?;
tracing::info!(device, "entered upstream rootfs (chroot)");

tracing::info!(device, "switched to upstream rootfs (pivot_root)");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix misleading root-switch log text.

Line 124 reports pivot_root, but this function calls libc::chroot (Line 119). Please align the message with actual behavior to avoid misleading ops/debugging signals.

Suggested patch
-    tracing::info!(device, "switched to upstream rootfs (pivot_root)");
+    tracing::info!(device, "entered upstream rootfs (chroot)");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
tracing::info!(device, "switched to upstream rootfs (pivot_root)");
tracing::info!(device, "entered upstream rootfs (chroot)");
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/minimald/src/guest.rs` at line 124, The log message incorrectly states
"pivot_root" while the code actually calls libc::chroot; update the
tracing::info! invocation to accurately reflect the operation (e.g., "switched
to upstream rootfs (chroot)" or "changed rootfs via chroot") so logs match the
libc::chroot call and avoid misleading debugging; locate the tracing::info! call
near the libc::chroot usage in guest.rs and change the message string
accordingly.

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