feat(registry-manifest): phase 1 — orchestrator consumes manifests from signed catalog
Workstream B phase 1 (node-side consume). The signed app-catalog can now carry a full manifest per entry; the orchestrator overlays it over the disk manifest (origin-wins) with disk as the migration fallback. Moves apps toward registry-distributed manifests with no OTA-shipped disk file. - app_catalog: `manifest: Option<Value>` on AppCatalogEntry (forward-compatible, covered by the existing release-root signature over the raw JSON); `catalog_manifest_values()` accessor. - prod_orchestrator: `load_manifests` overlays catalog manifests after the disk walk; `catalog_manifest_to_overlay()` returns None (→ disk fallback) on unparseable value / app-id mismatch / failed validate() / build source (build contexts aren't registry-distributed yet — phase 1 is image-only). - manifest_dir stays PathBuf (build-only field); image-only apps never read it. - 6 unit tests; compiles clean. No-op until a catalog embeds a manifest, so existing nodes are unaffected. See docs/registry-manifest-design.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
192238cbb8
commit
220666d3a9
@@ -83,17 +83,22 @@ Extend (not replace) the disk walk:
|
||||
4. A catalog manifest that fails parse/validate is logged and skipped → disk
|
||||
fallback used (one bad entry never blocks the fleet, same as the disk walk).
|
||||
|
||||
### `manifest_dir` for registry manifests
|
||||
### `manifest_dir` for registry manifests — IMPLEMENTED
|
||||
|
||||
`LoadedManifest.manifest_dir` is used for **build contexts** and **generated files**
|
||||
(`GeneratedFile`) that live next to a disk manifest. Registry manifests have no dir.
|
||||
`LoadedManifest.manifest_dir` is used **only** in the `ResolvedSource::Build` branch
|
||||
(relative `container.build.context` resolution — two call sites). Image-only apps
|
||||
(`ResolvedSource::Pull`) never read it.
|
||||
|
||||
- **Phase 1 scope = image-only apps** (no `build:`, no `generated_files:` needing a
|
||||
source dir). immich, grafana, the fedimint apps, postgres/redis all qualify.
|
||||
- Represent the absent dir explicitly: `manifest_dir: Option<PathBuf>` (or a
|
||||
sentinel under `<data_dir>/registry-apps/<app_id>/` materialized on demand).
|
||||
Companion build apps (bitcoin-ui, …) keep their disk path until a later phase
|
||||
teaches the catalog to carry build contexts (content-addressed, per the DHT plan).
|
||||
**Decision (phase 1, shipped):** keep `manifest_dir: PathBuf` (no `Option` ripple
|
||||
through the codebase). A catalog manifest with a **build source is skipped** so its
|
||||
disk manifest stays in effect — build contexts aren't registry-distributed until a
|
||||
later phase (content-addressed, per the DHT plan). For an accepted (image-only)
|
||||
catalog manifest, `manifest_dir` = the disk app dir if the app also exists on disk,
|
||||
else a sentinel `<manifests_dir>/<app_id>` (never read for image-only apps).
|
||||
|
||||
This is enforced by `catalog_manifest_to_overlay(app_id, value) -> Option<AppManifest>`
|
||||
in `prod_orchestrator.rs`, which returns `None` (→ disk fallback) for: unparseable
|
||||
value, embedded-id ≠ catalog-key, failed `validate()`, or a build source.
|
||||
|
||||
## 5. Publishing (publish-side generator)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user