hashgraph / hashgraph/solo-weaver
feat(consensus): populate multi-registry image sources + layer hashes on consensus CRs from the deployment manifest
- Dominant language
- Go
- Stars
- 3
- Forks
- 0
- Avg merge
- 3d 5h
- Merged PRs (30d)
- 47
Description
### Summary
The deployment package manifest already carries, per component image, an ordered **list of registries** plus **layer hashes** (`pkg/manifests`: `Image{Version, Deterministic, Registries}`, `Registry{Image, LayerHashes}`, `Deterministic{Supported, LayerHashes}`, with `LayerHashes = map[platform][]string` keyed by `linux/amd64` / `linux/arm64`). But at install time we collapse it: `internal/rsl/consensus_resolve.go` (`resolveImageFromManifest`) reads only `Registries[0]`, and `internal/workflows/steps/step_consensus_capsule.go` sets a single `SoftwareVersion{Repository, ImageName, ImageTag}` — the registry list and layer hashes are parsed and then dropped.
### Proposed
Populate the multi-registry image **source** on the consensus CRs from the manifest so the operator can do registry selection/failover + layer-hash verification + digest pinning, instead of weaver hard-picking one registry.
### Status — UNBLOCKED (2026-09-16)
The operator dependency is satisfied: **solo-operator v0.7.0** landed `SoftwareVersionSource` on `ConsensusNodeContainer` and wires selection + verification + digest pinning on the capsule reconcile path (hashgraph/solo-operator#1316; keychain from namespace pull secrets in #1314/#1317). Weaver has already been bumped to v0.7.0 on the consensus branch, so the API types are vendored and this is now pure wiring — no new schema, no manifest change.
### v0.7.0 field mapping
`SoftwareVersionSource` **replaces** the single `SoftwareVersion` when set, and requires verification (layer hashes are mandatory). Map:
| Manifest | → CR (`api/v1alpha1`) |
|---|---|
| each `Image.Registries[i].Image` (split → repo / name / tag) | `SoftwareVersionSource.ImageRepositories[i].{Repository,ImageName,ImageTag}` |
| `Deterministic.LayerHashes` / per-`Registry.LayerHashes` map (`platform → hashes`) | `SoftwareVersionSource.ImageVerificationSpec[]` — one entry per platform, splitting `linux/amd64` → `{OS: linux, Architecture: amd64, LayerHashes: [...]}` |
| keychain-by-convention pull secret | `ImageRepositories[i].ImagePullSecrets` (see open question) |
| — | `SelectionStrategy` optional (`Random`/`Sequential`); leave unset to use the operator's `--registry-order` default |
**Emit `SoftwareVersionSource` only when there are multiple registries AND layer hashes.** Otherwise keep the single `SoftwareVersion` (today's `Registries[0]` interim) — the operator's source path rejects a source with no layer hashes, so a single/no-hash image must stay on `SoftwareVersion`.
**Open question (decide during implementation):** whether weaver sets per-repo `ImageRepositories[].ImagePullSecrets` on the CR, or leaves it empty and relies on the operator building its keychain from the namespace docker-registry secrets (v0.7.0 #1314). The operator supports the namespace-secrets path, so weaver may not need to set them.
### Backward compatibility
When the manifest lists a single registry (or has no layer hashes), behaviour is unchanged — weaver keeps setting the single `SoftwareVersion`.
Contributor guide
Research direction
Start in internal/rsl/consensus_resolve.go at resolveImageFromManifest and internal/workflows/steps/step_consensus_capsule.go, then inspect the manifest types under pkg/manifests and the v0.7.0 api/v1alpha1 fields. Populate SoftwareVersionSource only for images with multiple registries and layer hashes; preserve the existing SoftwareVersion path for single-registry or no-hash images, and decide how pull secrets are handled.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, kubernetes
- Domain
- backend-api-design, devops
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100