Shared pool hosts exempt from the per-org co-location

Task 5054 · Done · Coder · created · updated

Defect (epic 4929, dev finding F5; operator decision 2026-10-06: "Exempt Shared pool"): out of the box no tenant can rent Shared and an approved trial gets no node. Both place a tenant node on an operator host marked for Shared rentals (`vnode_hosts.shared_capacity IS NOT NULL`), and the D15 isolation default refuses that unless the org holds `orgs.colocation_allowed`, which is false for every tenant/trial org. Reproduction (dev, Task 4973 report): approved trial org c8trlco44 → no trial node, note "This organization runs on dedicated nodes only..."; tenant org-b Add node → Rent Shared disabled until the operator granted org-b's exception. Cause: - `apps/api/app/rental_catalog.py:137` — Shared offering disabled (`SHARED_NOT_ALLOWED`) unless `tenant_defaults.colocation_allowed`. - `apps/api/app/vnodes.py:548-549` — `place_virtual_node` calls `tenant_defaults.require_colocation_allowed` for any host of another org (reached from `trial_node.py:303`, `rental_provisioning.py:283`, `node_orders.py:425/465`). - WORK doors too: `apps/api/app/tenant_defaults.py` `_FOREIGN_HOSTED_AMONG_SQL` (read by `placement_grants.py:215` and `vnodes.py:176`) marks such a node as taking no work — so fixing only placement would create a node that can never run a task. Fix: a node on an OPERATOR-org host that is marked for Shared rentals (`shared_capacity IS NOT NULL`) is allowed for a tenant org without the exception — at placement, in the Shared offering check, and in `foreign_hosted_among`. Single-home the rule in `app/tenant_defaults.py` (e.g. a helper "is a Shared pool host") and update its module docstring item 1. Every other cross-org co-location stays refused exactly as today. Add a risk-register entry in `docs/compliance/risk-register.md` (Shared is shared by design; tenant told so by the AC6.2 isolation sentence; tenants never see the host's name/org). No new setting. Out of scope: no change to `apps/jaahd/vnodehelper/*`, nft rules or quotas; no change to `shared_store_allowed`; no change to the operator-grant UI; do not auto-flip `colocation_allowed` on any org; no new knob. Done means: - A tenant org with `colocation_allowed=false` sees Shared enabled in GET /api/rentals/catalog when a Shared pool host has capacity — regression test. - Approving a trial for an org with `colocation_allowed=false` creates the trial node on the Shared pool host — regression test. - That trial/Shared node is NOT in `foreign_hosted_among` and is returned by `placement_grants.allowed_nodes` — regression test. - A tenant node on a NON-pool host of another org (shared_capacity NULL, or a tenant-owned host) is still refused at placement and for work — regression test asserting the existing refusal text. - `./dc check full` green.

Outcome

Shared pool hosts exempt from D15 co-location at placement, catalog and work doors (tenant_defaults.is_shared_pool_host); R-SHARED risk entry; full gate green; PR #4491 merged. Deferred: un-marking a pool host strands its nodes.

Pull request

Artifacts

Activity

  • Ready
  • Runner started
  • Runner ended (done)