Skip to content

0.9.27 — rootless: per-user lease file path#185

Merged
click0 merged 1 commit into
mainfrom
claude/release-0.9.27
May 9, 2026
Merged

0.9.27 — rootless: per-user lease file path#185
click0 merged 1 commit into
mainfrom
claude/release-0.9.27

Conversation

@click0
Copy link
Copy Markdown
Owner

@click0 click0 commented May 9, 2026

Summary

Twenty-eighth 0.9.x release. IP-lease file (network-leases.txt) moves from a single shared /var/run/crate/ location to a per-user /var/run/crate/<uid>/ subtree when crated's privops socket is detected.

What lands

lib/network_lease.cpp::effectivePath() — lazily resolves the path on first use:

const std::string &effectivePath() {
  static std::string cached;
  static bool computed = false;
  if (!computed) {
    if (g_pathOverridden) {
      cached = g_path;  // honour test override
    } else if (!PrivOpsClient::detectSocketPath().empty()) {
      cached = RuntimePathsPure::perUserRoot((uint32_t)::getuid())
             + "/network-leases.txt";
    } else {
      cached = g_path;  // legacy single-tenant
    }
    computed = true;
  }
  return cached;
}

All 7 call sites (openLocked, readAll, writeAllAtomic, leasePath) replaced g_path references with effectivePath(). Path cached for process lifetime.

Behavior

Mode Lease file path
Legacy (no socket) /var/run/crate/network-leases.txt
Rootless (socket detected) /var/run/crate/<uid>/network-leases.txt
Test override setPathForTesting-supplied path

Combined with 0.9.10's sub-CIDR allocator, alice's crate run never reads or writes bob's leases. Two operators can run a jail named web simultaneously without IP collision.

Trade-offs

  • Path locked in at process start. Cached after first call. Acceptable for short-lived crate run.
  • No auto-migration of legacy leases. Operators switching to rootless run crate clean + crate run to rebuild per-user.

Test plan

  • Suite: 1301/1301 passing (unchanged — existing tests use setPathForTesting override path)
  • lib/network_lease.cpp compiles cleanly
  • FreeBSD CI must pass

No new tests — the runtime path-detection is non-deterministic (depends on whether socket exists at test time); existing test infrastructure deliberately overrides via setPathForTesting.

Series state

CLI call-sites wired (12 in total):

  • crate retune, crate stop, full crate run chain (createJail / removeJail / ZFS attach+detach / nullfs mounts / vnet moveToVnet / setUp / disableOffload / bridge add+del / setInetAddr / createEpair)
  • crate run lease file path → per-user under /var/run/crate/<uid>/ ← this PR

Remaining:

  • 0.9.28 — RCTL umbrella application (uses 0.9.11 loginclass to apply loginclass:crate-<uid>:KEY:deny=... rules at jail-create time)
  • 0.9.29 — default flip (rootless_per_user: true becomes default in crated.conf.sample)
  • 1.0.0 — setuid bit removed from Makefile install

Files

  • lib/network_lease.cppeffectivePath() + 7 call-site updates
  • cli/args.cppcrate 0.9.27
  • CHANGELOG.md — entry

Generated by Claude Code

Twenty-eighth 0.9.x release. IP-lease file
(network-leases.txt) moves from single shared
/var/run/crate/ to per-user /var/run/crate/<uid>/ subtree
when crated's privops socket is detected.

lib/network_lease.cpp::effectivePath() — lazily resolves
the path on first use:
  - g_pathOverridden (setPathForTesting): honour override
  - privops socket detected: per-user
    /var/run/crate/<uid>/network-leases.txt
  - else: legacy /var/run/crate/network-leases.txt

All 7 call sites (openLocked, readAll, writeAllAtomic,
leasePath) replaced g_path with effectivePath(). Same path
cached for process lifetime.

Combined with 0.9.10 sub-CIDR allocator, alice's crate run
never reads or writes bob's leases. Two operators can both
run a jail named "web" simultaneously without IP collision.

Trade-offs:
  - Path locked in at process start (cached after first
    call). Acceptable for short-lived crate run.
  - No auto-migration of existing legacy leases — operator
    runs crate clean + crate run to rebuild per-user.

Suite: 1301 (unchanged — existing tests use setPathForTesting
override path).

Remaining: RCTL umbrella (0.9.28), default flip (0.9.29),
setuid removed (1.0.0).
@click0 click0 merged commit 7ba774c into main May 9, 2026
2 checks passed
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