Skip to content

fix(iii-worker): route 127.0.0.1 to host and fix ERROR-level VM console logs#1451

Merged
andersonleal merged 4 commits intomainfrom
fix/local-worker-logs-and-loopback
Apr 10, 2026
Merged

fix(iii-worker): route 127.0.0.1 to host and fix ERROR-level VM console logs#1451
andersonleal merged 4 commits intomainfrom
fix/local-worker-logs-and-loopback

Conversation

@andersonleal
Copy link
Copy Markdown
Contributor

@andersonleal andersonleal commented Apr 10, 2026

Summary

  • VM console output logged at ERROR: run_dev (local-path workers) did not pass --console-output to __vm-boot, so all guest output (cargo downloads, compiles, app logs) went through msb_krun's PortOutputLog which hardcodes log::Level::Error for every line. Now passes --console-output pointing to stdout.log, matching the managed worker path.
  • 127.0.0.1 unreachable from guest VM: The loopback interface inside the VM captured traffic to 127.0.0.1, preventing it from reaching the host via the smoltcp proxy. Now skips bringing up lo so 127.0.0.1 falls through to the default route via eth0. Also writes /etc/hosts mapping localhost to the gateway IP.
  • Cargo env sourcing: Guards .cargo/env sourcing with existence check and ensures HOME is set in the dev run script.

Test plan

  • 423 tests pass (cargo test -p iii-init -p iii-worker)
  • 4 new tests cover both fixes:
    • configure_network_source_omits_loopback_setup — verifies lo is not brought up
    • etc_hosts_format_maps_localhost_to_gateway — verifies /etc/hosts format
    • run_dev_console_output_path_convention — verifies stdout.log path convention
    • run_dev_console_output_parses_as_vm_boot_arg — verifies --console-output parsing
  • Manual: iii worker logs <name> -f should show clean output without ERROR prefix
  • Manual: Worker connecting to ws://127.0.0.1:49134 inside VM should reach engine

Summary by CodeRabbit

  • New Features

    • Dev VM background mode reports console output to a persistent stdout.log path.
    • Init now attempts to write a /etc/hosts entry mapping localhost to the configured gateway (failure now emits a warning rather than failing).
  • Improvements

    • Generated run script is placed under /opt/iii/ and executed from there; HOME is ensured (defaults to /root).
    • Cargo environment is sourced only when its env file exists.
  • Tests

    • Added tests for network hosts behavior, absence of loopback setup, console-output path handling, and conditional Cargo sourcing.

…le logs

Two bugs in local-path worker support:

1. VM console output logged at ERROR level: run_dev did not pass
   --console-output to __vm-boot, so all guest output went through
   msb_krun's PortOutputLog which hardcodes log::Level::Error for
   every line. Now passes --console-output pointing to stdout.log,
   matching the managed worker path.

2. 127.0.0.1 unreachable from guest: the loopback interface inside
   the VM captured traffic to 127.0.0.1, preventing it from reaching
   the host via the smoltcp proxy. Now skips bringing up lo so
   127.0.0.1 falls through to the default route via eth0. Also writes
   /etc/hosts mapping localhost to the gateway IP.

Also fixes cargo env sourcing to guard against missing .cargo/env
and ensures HOME is set in the dev run script.
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Apr 10, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
iii-website Ready Ready Preview, Comment Apr 10, 2026 7:43pm
motia-docs Ready Ready Preview, Comment Apr 10, 2026 7:43pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 10, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: fdd84e9e-799a-4b72-a76a-5e2b07c5a287

📥 Commits

Reviewing files that changed from the base of the PR and between ac2155f and e9e7dfe.

📒 Files selected for processing (1)
  • crates/iii-init/src/network.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/iii-init/src/network.rs

📝 Walkthrough

Walkthrough

Omit bringing up loopback in network setup, map localhost to the gateway in /etc/hosts (warnings on failure), add source-inspection tests; prepend HOME export in generated run scripts and move script path to /opt/iii/dev-run.sh; make Cargo sourcing conditional; pass --console-output for background VM runs and add console-output tests.

Changes

Cohort / File(s) Summary
Network configuration
crates/iii-init/src/network.rs, crates/iii-init/tests/init_integration.rs
configure_network() no longer calls set_interface_up for lo. It brings up eth0, adds default route, then attempts to write /etc/hosts with "{gw}\tlocalhost\n"; write failures are logged as warnings. Added static source-inspection tests asserting absence of lo setup and presence of gateway→localhost entry.
Local worker run script
crates/iii-worker/src/cli/local_worker.rs
build_libkrun_local_script now prepends export HOME=${HOME:-/root}. start_local_worker moves the generated run script from /tmp/iii-dev-run.sh to /opt/iii/dev-run.sh, updates directory creation, and invokes bash /opt/iii/dev-run.sh.
Project/Cargo command inference
crates/iii-worker/src/cli/project.rs
Auto-detected command strings changed to conditionally source Cargo env: "[ -f \"$HOME/.cargo/env\" ] && . \"$HOME/.cargo/env\"; cargo ..." instead of unconditional . $HOME/.cargo/env && cargo ....
VM boot args / logging
crates/iii-worker/src/cli/worker_manager/libkrun.rs, crates/iii-worker/tests/vm_args_integration.rs
run_dev background path adds --console-output pointing to logs_dir/stdout.log in addition to redirecting child stdout/stderr to log files. Added tests for console-output path construction and CLI parsing into VmBootArgs.console_output.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • sergiofilhowz
  • ytallo
  • guibeira

Poem

🐰 I hopped through network code at dawn,

skipped the loop, let eth0 yawn,
localhost greets the gateway bright,
HOME set firm before cargo's flight,
logs find paths where console lights are drawn.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the two main changes: routing 127.0.0.1 to host and fixing ERROR-level VM console logs. It is specific, concise, and reflects the primary objectives documented in the PR objectives.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/local-worker-logs-and-loopback

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

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/iii-init/tests/init_integration.rs (1)

3-8: ⚠️ Potential issue | 🟡 Minor

Update the module doc to match actual test gating.

Line 5 says every test is Linux-gated, but the new tests at Line 11 and Line 40 are intentionally cross-platform. The top-level comment should be updated to avoid confusion.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/iii-init/tests/init_integration.rs` around lines 3 - 8, Update the
module-level doc comment at the top of the file so it accurately describes which
tests are Linux-only and which are cross-platform: change the sentence that
currently states "All iii-init functionality is Linux-only, so every test is
gated with `#[cfg(target_os = \"linux\")]`" to reflect that only some tests are
Linux-gated while others (the tests added around Line 11 and Line 40) are
intentionally cross-platform; make the comment clearly state that Linux-specific
tests are gated with `#[cfg(target_os = "linux")]` but that other tests in this
file run on all platforms.
🧹 Nitpick comments (2)
crates/iii-worker/src/cli/project.rs (1)

151-153: Deduplicate the cargo-env guard string to avoid drift.

The same shell guard is now repeated in multiple places; extracting a shared constant keeps inferred and auto-detected Rust paths consistent over time.

Refactor sketch
+const CARGO_ENV_SOURCE_IF_PRESENT: &str = r#"[ -f "$HOME/.cargo/env" ] && . "$HOME/.cargo/env";"#;
...
-            "[ -f \"$HOME/.cargo/env\" ] && . \"$HOME/.cargo/env\"; cargo build".to_string(),
-            "[ -f \"$HOME/.cargo/env\" ] && . \"$HOME/.cargo/env\"; cargo run".to_string(),
+            format!("{CARGO_ENV_SOURCE_IF_PRESENT} cargo build"),
+            format!("{CARGO_ENV_SOURCE_IF_PRESENT} cargo run"),
...
-            install_cmd: "[ -f \"$HOME/.cargo/env\" ] && . \"$HOME/.cargo/env\"; cargo build --release".into(),
-            run_cmd: "[ -f \"$HOME/.cargo/env\" ] && . \"$HOME/.cargo/env\"; cargo run --release".into(),
+            install_cmd: format!("{CARGO_ENV_SOURCE_IF_PRESENT} cargo build --release"),
+            run_cmd: format!("{CARGO_ENV_SOURCE_IF_PRESENT} cargo run --release"),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/iii-worker/src/cli/project.rs` around lines 151 - 153, Extract the
repeated shell guard into a single constant (e.g. const CARGO_ENV_GUARD = "[ -f
\"$HOME/.cargo/env\" ] && . \"$HOME/.cargo/env\"; ") and use that constant when
constructing the install_cmd and run_cmd strings instead of repeating the
literal; update the assignments for install_cmd and run_cmd to concatenate or
format with CARGO_ENV_GUARD so the guard is defined once and reused (refer to
the install_cmd and run_cmd fields in the same struct where setup_cmd is set).
crates/iii-init/tests/init_integration.rs (1)

13-35: Source-string assertions are brittle and can false-pass.

The check at Line 33 (contains("eth0")) can pass from comments alone, and the /etc/hosts assertion depends on exact formatting text. Prefer asserting concrete call patterns (or testing a factored pure helper) to reduce fragile tests.

Targeted hardening within current approach
-    // It MUST still configure eth0.
-    assert!(
-        closure_body.contains("eth0"),
-        "configure_network must still configure eth0"
-    );
+    // It MUST still configure eth0 via concrete operations.
+    assert!(
+        closure_body.contains(r#"set_ip_address(sock, b"eth0\0", ip)"#),
+        "configure_network must set eth0 IP"
+    );
+    assert!(
+        closure_body.contains(r#"set_netmask(sock, b"eth0\0", mask)"#),
+        "configure_network must set eth0 netmask"
+    );
+    assert!(
+        closure_body.contains(r#"set_interface_up(sock, b"eth0\0")"#),
+        "configure_network must bring eth0 up"
+    );

Also applies to: 43-50

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/iii-init/tests/init_integration.rs` around lines 13 - 35, The
assertions in the test read the source as a raw string, so contains("eth0") and
similar checks are brittle and can match comments or /etc/hosts text; update the
test for function configure_network to either (A) strip Rust comments (both //
and /* */) from the included source before searching, then use precise regexes
to assert the concrete call patterns like
set_interface_up\s*\(\s*sock\s*,\s*b"eth0\\0"\s*\) and to assert absence of
set_interface_up\s*\(\s*sock\s*,\s*b"lo\\0"\s*\), or (B) factor the logic into a
pure helper function and unit-test that helper directly; apply the same stronger
check to the other assertions mentioned (the checks around lines 43-50) and
reference configure_network, closure_body, and set_interface_up when locating
the code to change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/iii-init/src/network.rs`:
- Around line 80-84: The current code calls std::fs::write("/etc/hosts", ...)
and ignores errors, which clobbers the file and swallows failures; change this
to safely update /etc/hosts by reading the existing file, preserving all other
entries, replacing any existing "localhost" line that maps to 127.0.0.1 or the
gateway, or appending a gateway->localhost line if none exists, and handle
errors instead of ignoring them (return a Result or log the error). Locate the
std::fs::write("/etc/hosts", format!("{gw}\tlocalhost\n")) call and replace it
with logic that uses std::fs::read_to_string("/etc/hosts") -> modify string
(regex or line-scan) -> write back with std::fs::write or use OpenOptions to
update atomically (write to tmp and rename), and propagate or log any io::Error
rather than discarding it.

---

Outside diff comments:
In `@crates/iii-init/tests/init_integration.rs`:
- Around line 3-8: Update the module-level doc comment at the top of the file so
it accurately describes which tests are Linux-only and which are cross-platform:
change the sentence that currently states "All iii-init functionality is
Linux-only, so every test is gated with `#[cfg(target_os = \"linux\")]`" to
reflect that only some tests are Linux-gated while others (the tests added
around Line 11 and Line 40) are intentionally cross-platform; make the comment
clearly state that Linux-specific tests are gated with `#[cfg(target_os =
"linux")]` but that other tests in this file run on all platforms.

---

Nitpick comments:
In `@crates/iii-init/tests/init_integration.rs`:
- Around line 13-35: The assertions in the test read the source as a raw string,
so contains("eth0") and similar checks are brittle and can match comments or
/etc/hosts text; update the test for function configure_network to either (A)
strip Rust comments (both // and /* */) from the included source before
searching, then use precise regexes to assert the concrete call patterns like
set_interface_up\s*\(\s*sock\s*,\s*b"eth0\\0"\s*\) and to assert absence of
set_interface_up\s*\(\s*sock\s*,\s*b"lo\\0"\s*\), or (B) factor the logic into a
pure helper function and unit-test that helper directly; apply the same stronger
check to the other assertions mentioned (the checks around lines 43-50) and
reference configure_network, closure_body, and set_interface_up when locating
the code to change.

In `@crates/iii-worker/src/cli/project.rs`:
- Around line 151-153: Extract the repeated shell guard into a single constant
(e.g. const CARGO_ENV_GUARD = "[ -f \"$HOME/.cargo/env\" ] && .
\"$HOME/.cargo/env\"; ") and use that constant when constructing the install_cmd
and run_cmd strings instead of repeating the literal; update the assignments for
install_cmd and run_cmd to concatenate or format with CARGO_ENV_GUARD so the
guard is defined once and reused (refer to the install_cmd and run_cmd fields in
the same struct where setup_cmd is set).
🪄 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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 29a128ce-9bb8-41fa-8184-7f2584c92fe1

📥 Commits

Reviewing files that changed from the base of the PR and between a0d2891 and ec71f5d.

📒 Files selected for processing (6)
  • crates/iii-init/src/network.rs
  • crates/iii-init/tests/init_integration.rs
  • crates/iii-worker/src/cli/local_worker.rs
  • crates/iii-worker/src/cli/project.rs
  • crates/iii-worker/src/cli/worker_manager/libkrun.rs
  • crates/iii-worker/tests/vm_args_integration.rs

Comment thread crates/iii-init/src/network.rs
…ding

The `let _ =` pattern swallowed io::Error, making failures invisible.
Use eprintln warning consistent with the write_resolv_conf pattern.
…line command arguments

Changed the script path for the local worker from `/tmp/iii-dev-run.sh` to `/opt/iii/dev-run.sh` and adjusted the directory structure accordingly. Additionally, streamlined the command argument formatting in the `run_dev` function for improved readability.
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