Build the fleet image by hand¶
Nerthus.Core (until cutover). This page describes the frozen system that runs today and is deleted at cutover. Replaced by: none, retired with Core.
The package job did not produce an image, and a fleet still needs a digest to pin. This page
builds one from a workstation and proposes the pin the job would have proposed.
Set up pipelines owns the pipeline this stands in for; Fleet
owns the upgrade wave a merged pin drives.
How you know you are in it¶
packageis red onci_quota_exceeded, or it never started because the branch is neithermainnormulti-host-infra.- No
deploy/<shortsha>merge request exists on the consumer fleet repo, and itsversions.lockstill pins the previous digest.
A hand build spends no CI minutes, which is usually the reason you are here. It also builds on whatever architecture the workstation is, which is what the two flags in step 1 are for.
Build and push¶
-
Cross-build for amd64 from a module checkout at the commit you intend to ship, logged in to the registry:
docker login registry.gitlab.com docker buildx build --platform linux/amd64 --provenance=false \ -f docker/Dockerfile -t registry.gitlab.com/margonem/nerthus/it/nerthus.core:main --push .--provenance=falseis load-bearingWithout it buildx publishes an OCI image index carrying the amd64 manifest plus an
unknown/unknownattestation, and a digest that names an index makes docker select by host platform. Every arm64 host then answersno matching manifest for linux/arm64/v8and stops converging. A single-platformmanifest.v2+jsondigest is fetched as named whatever the host is, which is what lets one amd64 image run on an arm64 machine under emulation. -
Read the digest back and check what you published:
It must report
linux/amd64and one manifest, not an index. The digest it prints is the value the pin carries. -
Prove the image runs before you propose it. Pull it by digest on a device and let it boot against a lore clone: it should report the schema version
versions.lockexpects and answer/health. Nothing downstream re-checks it, and a merged pin reaches every replica before anyone looks.
Propose the pin¶
Run the same publisher the package job runs, from the module checkout, with the digest and the
source commit:
./vm/Publish-NerthusImagePin.ps1 -SourceSha 61fa712 -WhatIf `
-ImageRef registry.gitlab.com/margonem/nerthus/it/nerthus.core@sha256:85a125a52553d13586da5a20ef5e453863f49cd861684cbf2e005a7e8e71e4ed
It rewrites the consumer's image: line and its Built from … @ <sha> provenance comment and
nothing else, opens deploy/<shortsha>, and stops. It reads the consumer path from
NERTHUS_INFRA_PROJECT_PATH and pushes with NERTHUS_INFRA_PUSH_TOKEN, so pass -WhatIf first and
confirm the rewrite it previews. Editing versions.lock in a merge request by hand is the same
deploy; record in the comment above the line that this digest was cross-built, why, and what step 3
verified.
How you know you are out of it¶
The merge request is merged, versions.lock names your digest, and the hosts take it in wave order:
replicas first, the primary primary_lag_minutes later. The sweep reports skew between the two
while the wave runs, which is the wave working.
See also¶
- Set up pipelines — the
packageandpublish:image-pinjobs this replaces - Fleet — digest pinning and the upgrade wave
- Check the quota — the CI-minute budget that sends you here
- Recover a diverged host — when a host will not take the new digest