Skip to content

feat: let the catalog declare a device, fixing Mysterium's missing TUN (CashPilot-6rv) - #157

Merged
GeiserX merged 1 commit into
mainfrom
feat/catalog-device-support
Aug 2, 2026
Merged

feat: let the catalog declare a device, fixing Mysterium's missing TUN (CashPilot-6rv)#157
GeiserX merged 1 commit into
mainfrom
feat/catalog-device-support

Conversation

@GeiserX

@GeiserX GeiserX commented Aug 2, 2026

Copy link
Copy Markdown
Owner

Closes the P1 behind the MystNodes failure documented in #155.

The gap

A service could declare cap_add but not a device, and the orchestrator had no device support at all. Mysterium needs /dev/net/tun to carry wireguard/dvpn traffic. Without it the node starts, registers, advertises itself to the network — and carries nothing.

Every view CashPilot had of it looked healthy. It took a provider email to surface. That is precisely the "running is not earning" case.

The fix

Service YAML now supports devices:, and mysterium.yml declares /dev/net/tun.

Deliberately not a passthrough

A device is a direct line to the kernel, so:

  • A hard allow-list in the worker (_ALLOWED_DEVICES) that the catalog cannot widen. Adding an entry is a maintainer decision in code, not something a service YAML can do on its own.
  • Per-slug scoping, the same rule already used for cap_add: a service may only request what its own YAML declares. With a union, one service declaring a device would grant it to the other 49.
  • Unknown slug → empty set — deny, never fall back to the union.
  • A host-path remap is judged on the host path, so /dev/mem:/dev/net/tun is refused rather than smuggled through on its container-side name.

Tests target the refusals

/dev/mem, /dev/kmsg, raw block devices, /dev/mapper/control, /dev/kvm, a traversal attempt, and the remap above — plus two structural guards:

  • the catalog can never declare a device outside the ceiling (fails if someone adds one to a YAML)
  • deploy_raw actually forwards it — a declaration nothing forwards would protect nobody

Verification

  • ruff check . && ruff format --check . — clean
  • pytest --cov=app --cov-fail-under=901470 passed, coverage 94.90%
  • The guide's manual-workaround note is updated to say this is fixed, rather than leaving stale instructions behind.

…N (CashPilot-6rv)

A service could declare cap_add but not a device, and the orchestrator had
no device support at all. Mysterium needs /dev/net/tun to carry
wireguard/dvpn traffic; without it the node starts, registers, advertises
itself to the network and carries nothing. Every view CashPilot had of it
looked healthy, so it took a provider email to surface - the exact
"running is not earning" case.

Service YAML now supports `devices:`, and mysterium.yml declares
/dev/net/tun.

A device is a direct line to the kernel, so this is deliberately not a
passthrough:

- The worker holds a hard allow-list (_ALLOWED_DEVICES) that the catalog
  cannot widen. Adding an entry is a maintainer decision in code, not
  something a service YAML can do on its own.
- Requests are scoped per-slug, the same rule already used for cap_add: a
  service may only ask for what its OWN yaml declares. With a union, one
  service declaring a device would grant it to the other 49.
- An unknown slug gets the empty set - deny, never fall back to the union.
- A host-path remap is judged on the HOST path, so /dev/mem:/dev/net/tun
  is refused rather than smuggled through on its container-side name.

Tests cover the refusals rather than just the happy path, including
/dev/mem, /dev/kmsg, raw block devices, /dev/kvm, a traversal attempt, and
the remap above. One test asserts the catalog can never declare a device
outside the ceiling, and another that deploy_raw actually forwards it -
a declaration nothing forwards would protect nobody.
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@GeiserX, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 36 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: a00282c5-27ae-4451-937b-893222aaadae

📥 Commits

Reviewing files that changed from the base of the PR and between fad13ec and 6826f62.

📒 Files selected for processing (8)
  • CHANGELOG.md
  • app/main.py
  • app/orchestrator.py
  • app/worker_api.py
  • docs/guides/mysterium.md
  • services/_schema.yml
  • services/bandwidth/mysterium.yml
  • tests/test_catalog_devices.py

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.

@codecov

codecov Bot commented Aug 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.11765% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 94.23%. Comparing base (fad13ec) to head (6826f62).

Files with missing lines Patch % Lines
app/worker_api.py 94.11% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #157      +/-   ##
==========================================
- Coverage   94.23%   94.23%   -0.01%     
==========================================
  Files          36       36              
  Lines        4475     4492      +17     
==========================================
+ Hits         4217     4233      +16     
- Misses        258      259       +1     
Files with missing lines Coverage Δ
app/main.py 96.85% <ø> (ø)
app/orchestrator.py 75.98% <ø> (ø)
app/worker_api.py 87.53% <94.11%> (+0.31%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@GeiserX
GeiserX merged commit 58e7968 into main Aug 2, 2026
8 checks passed
@GeiserX
GeiserX deleted the feat/catalog-device-support branch August 2, 2026 12:03
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