Skip to content

Keep Linux LXC DHCP state service-writable - #35

Merged
gitcommit90 merged 1 commit into
mainfrom
fix/linux-lxc-dhcp-lease
Jul 29, 2026
Merged

Keep Linux LXC DHCP state service-writable#35
gitcommit90 merged 1 commit into
mainfrom
fix/linux-lxc-dhcp-lease

Conversation

@gitcommit90

@gitcommit90 gitcommit90 commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Fixes the final real-host Linux terminal blockers discovered during 0.0.25 acceptance.

  • moves dnsmasq DHCP leases into the dedicated /var/lib/1helm-lxc writable tree
  • verifies the exact DHCP process and DNS/forwarding/NAT rules
  • treats an absent partial container as a successful cleanup no-op under set -e
  • bumps the unpublished candidate to 0.0.26

Verification: typecheck, build, npm test (125 native + 112 runnable contracts), onboarding 20/20, focused site/channel-computer tests, and a hardened service-namespace DHCP/guest provisioning probe.

Summary by CodeRabbit

  • Bug Fixes

    • Improved Linux LXC networking recovery, including DHCP/DNS startup, lease handling, bridge health checks, and firewall rule verification.
    • Corrected lifecycle cleanup behavior when partial container state is missing.
    • Improved installer setup for private network and DHCP state directories.
  • Release

    • Updated the default channel machine image and package version to 0.0.26.
    • Added release documentation and changelog entries for the networking and lifecycle fixes.
  • Tests

    • Expanded coverage for installer assets, DHCP/DNS configuration, firewall rules, and cleanup behavior.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Release and LXC recovery

Layer / File(s) Summary
0.0.26 release and image pins
CHANGELOG.md, README.md, package.json, src/server/..., test/channel-computers.mjs
Release metadata and channel machine image defaults and expectations advance from 0.0.25 to 0.0.26.
Private bridge and DNSMASQ recovery
scripts/1helm-lxc-net, site/public/install-lxc-runtime.sh, test/site.mjs
LXC networking starts DNSMASQ directly, persists lease state, validates DHCP and nftables configuration, and updates installer ordering and assertions.
Incomplete-container cleanup behavior
scripts/1helm-lxc-runtime
Missing partial-container state is treated as a successful cleanup no-op and is covered by a site assertion.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Installer
  participant LXCNetwork
  participant Bridge
  participant DNSMASQ
  participant Nftables
  Installer->>LXCNetwork: create network state directories
  LXCNetwork->>Bridge: create and configure lxcbr0
  LXCNetwork->>DNSMASQ: start with DHCP range and leasefile
  LXCNetwork->>Nftables: ensure onehelm_lxc rules
  LXCNetwork->>DNSMASQ: validate runtime DHCP options
  LXCNetwork->>Nftables: validate expected rules
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the summary and verification, but it omits most required template sections such as Type of change, Release notes, and the acceptance ledger. Add the template sections: Type of change, Release notes with changelog checkbox, numbered acceptance ledger, verification checklist, and post-merge items.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly reflects the main Linux LXC DHCP-state change, even if it omits the version bump and cleanup fix.
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.
✨ 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/linux-lxc-dhcp-lease

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

@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 `@scripts/1helm-lxc-net`:
- Around line 106-127: Update rules_healthy() to verify that IPv4 forwarding is
enabled via the same net.ipv4.ip_forward setting configured by install_rules(),
returning unhealthy when it is not enabled. Add coverage for this failure case
in test/site.mjs, ensuring ensure_rules() and network_healthy() do not report
success when forwarding is disabled.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a39c037c-b06f-4145-952a-d2f0fbe7c80c

📥 Commits

Reviewing files that changed from the base of the PR and between 7f968ca and e1a53f0.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (10)
  • CHANGELOG.md
  • README.md
  • package.json
  • scripts/1helm-lxc-net
  • scripts/1helm-lxc-runtime
  • site/public/install-lxc-runtime.sh
  • src/server/channel-computers.ts
  • src/server/db.ts
  • test/channel-computers.mjs
  • test/site.mjs

Comment thread scripts/1helm-lxc-net
Comment on lines +106 to +127
rules_healthy() {
[[ -e "$RULE_MARKER" ]] || return 1
nft list chain inet onehelm_lxc input 2>/dev/null \
| grep -Eq 'iifname "lxcbr0" udp dport \{ 53, 67 \} accept' || return 1
nft list chain inet onehelm_lxc input 2>/dev/null \
| grep -Eq 'iifname "lxcbr0" tcp dport \{ 53, 67 \} accept' || return 1
nft list chain inet onehelm_lxc forward 2>/dev/null \
| grep -Fq 'iifname "lxcbr0" accept' || return 1
nft list chain inet onehelm_lxc forward 2>/dev/null \
| grep -Eq 'oifname "lxcbr0" ct state (established,related|related,established) accept' || return 1
nft list chain ip onehelm_lxc postrouting 2>/dev/null \
| grep -Eq 'ip saddr 10\.0\.3\.0/24 ip daddr != 10\.0\.3\.0/24 masquerade' || return 1
}

network_healthy() {
lease_state_writable || return 1
bridge_dns_healthy || return 1
[[ -e "$RULE_MARKER" ]] || return 1
nft list table inet onehelm_lxc >/dev/null 2>&1 || return 1
nft list table ip onehelm_lxc >/dev/null 2>&1 || return 1
rules_healthy || return 1
}

ensure_rules() {
if [[ -e "$RULE_MARKER" ]] \
&& nft list table inet onehelm_lxc >/dev/null 2>&1 \
&& nft list table ip onehelm_lxc >/dev/null 2>&1; then
if rules_healthy; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Include IPv4 forwarding in the health contract.

install_rules() enables net.ipv4.ip_forward, but rules_healthy() never verifies it. If the sysctl is reset while the nftables marker and rules remain, ensure_rules() skips rebuilding and network_healthy() reports success even though guest forwarding and outbound NAT are broken. Add the sysctl check here and cover it in test/site.mjs.

Suggested fix
 rules_healthy() {
+  [[ "$(sysctl -n net.ipv4.ip_forward 2>/dev/null)" == "1" ]] || return 1
   [[ -e "$RULE_MARKER" ]] || return 1
📝 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
rules_healthy() {
[[ -e "$RULE_MARKER" ]] || return 1
nft list chain inet onehelm_lxc input 2>/dev/null \
| grep -Eq 'iifname "lxcbr0" udp dport \{ 53, 67 \} accept' || return 1
nft list chain inet onehelm_lxc input 2>/dev/null \
| grep -Eq 'iifname "lxcbr0" tcp dport \{ 53, 67 \} accept' || return 1
nft list chain inet onehelm_lxc forward 2>/dev/null \
| grep -Fq 'iifname "lxcbr0" accept' || return 1
nft list chain inet onehelm_lxc forward 2>/dev/null \
| grep -Eq 'oifname "lxcbr0" ct state (established,related|related,established) accept' || return 1
nft list chain ip onehelm_lxc postrouting 2>/dev/null \
| grep -Eq 'ip saddr 10\.0\.3\.0/24 ip daddr != 10\.0\.3\.0/24 masquerade' || return 1
}
network_healthy() {
lease_state_writable || return 1
bridge_dns_healthy || return 1
[[ -e "$RULE_MARKER" ]] || return 1
nft list table inet onehelm_lxc >/dev/null 2>&1 || return 1
nft list table ip onehelm_lxc >/dev/null 2>&1 || return 1
rules_healthy || return 1
}
ensure_rules() {
if [[ -e "$RULE_MARKER" ]] \
&& nft list table inet onehelm_lxc >/dev/null 2>&1 \
&& nft list table ip onehelm_lxc >/dev/null 2>&1; then
if rules_healthy; then
rules_healthy() {
[[ "$(sysctl -n net.ipv4.ip_forward 2>/dev/null)" == "1" ]] || return 1
[[ -e "$RULE_MARKER" ]] || return 1
nft list chain inet onehelm_lxc input 2>/dev/null \
| grep -Eq 'iifname "lxcbr0" udp dport \{ 53, 67 \} accept' || return 1
nft list chain inet onehelm_lxc input 2>/dev/null \
| grep -Eq 'iifname "lxcbr0" tcp dport \{ 53, 67 \} accept' || return 1
nft list chain inet onehelm_lxc forward 2>/dev/null \
| grep -Fq 'iifname "lxcbr0" accept' || return 1
nft list chain inet onehelm_lxc forward 2>/dev/null \
| grep -Eq 'oifname "lxcbr0" ct state (established,related|related,established) accept' || return 1
nft list chain ip onehelm_lxc postrouting 2>/dev/null \
| grep -Eq 'ip saddr 10\.0\.3\.0/24 ip daddr != 10\.0\.3\.0/24 masquerade' || return 1
}
🤖 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 `@scripts/1helm-lxc-net` around lines 106 - 127, Update rules_healthy() to
verify that IPv4 forwarding is enabled via the same net.ipv4.ip_forward setting
configured by install_rules(), returning unhealthy when it is not enabled. Add
coverage for this failure case in test/site.mjs, ensuring ensure_rules() and
network_healthy() do not report success when forwarding is disabled.

@gitcommit90
gitcommit90 merged commit 482c1a6 into main Jul 29, 2026
6 checks passed
@gitcommit90
gitcommit90 deleted the fix/linux-lxc-dhcp-lease branch July 29, 2026 03:23
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.

1 participant