Commit Graph

2 Commits

Author SHA1 Message Date
Anso 60f893a81f feat(fleet): move bulk Remote OTA updates to Community tier (#1151)
Drops `requirePaid` from `POST /api/fleet/update-all` so Community admins
can dispatch bulk node updates. Per-node OTA was already Community-
reachable (admin-only); this completes the move so the full Remote OTA
surface ships at Community.

Frontend mirrors the backend: removes `canBulkUpdate` from
NodeUpdatesSheet so the "Update all (N)" affordance is purely data-
driven on `updatableRemoteCount > 0`.

Docs realigned to drop fence-spec and Skipper-only phrasing on the
Update all bulk action:
- features/licensing.mdx: Community line now lists Remote OTA (per-node
  and Update all); Skipper Fleet Actions parenthetical drops "bulk
  update all"
- features/remote-updates.mdx: Note rewritten to role-only requirement
- features/fleet-view.mdx: Update all (n) bullet drops the tier clause
- features/overview.mdx: Fleet View and Remote updates blurbs drop the
  Skipper/Admiral fences
- operations/upgrade.mdx: Note rephrased without naming tiers

Test coverage:
- fleet.test.ts: tier-gating spec flipped to assert Community access
- fleet-pilot-update.test.ts: bulk-OTA dispatch suite now spies tier
  to Community so it doubles as a regression guard
2026-05-21 23:54:45 -04:00
Anso 0b50c88eb3 fix(fleet): route remote update trigger through getProxyTarget (#1123)
POST /api/fleet/nodes/:id/update and POST /api/fleet/update-all read
node.api_url + node.api_token directly, so a pilot-agent row (which
carries neither) returned "Remote node not configured." and was
filtered out of bulk update. Both routes now resolve the target via
NodeRegistry.getProxyTarget(), which returns the loopback URL for an
active pilot tunnel and the configured api_url for proxy-mode remotes.
fetchMetaForNode replaces the direct fetchRemoteMeta call for the
self-update capability check.

self-update is removed from PILOT_DISABLED_CAPABILITIES so a
Compose-deployed pilot can advertise it; the host-console filter
stays. SelfUpdateService still gates the local-end capability on the
container actually carrying docker-compose labels, so a docker-run
pilot self-disables and the Fleet UI sees a clean 503 instead of an
ambiguous failure.

Tests: new fleet-pilot-update covers the four single-node branches
(success via loopback, null target, no self-update capability, meta
offline) and two update-all cases (mixed-fleet dispatch, all-targets-
null skip). capability-registry-pilot rewired to assert the new
filter set.
2026-05-20 03:35:39 -04:00