Skip to content

Hand over data to the estate path #661

Closed
1 of 2 issues completed
Closed

Description

@ExtraToast

Parent

Rewrite the spec and the compiler in place, release 1.0.0, and hand over every Project

What to build

The data Project leaves fleet-infra and is delivered from the estate repository, in the order #381 sets.

The estate's data file declares postgres, rabbitmq and valkey. Add platform-mongo and platform-garage. Everything stays in data-system. The live claims are kept: postgres-data, rabbitmq-data, valkey-data, and mongo-data-mongo-0, which mongo's declaration must name exactly. Garage's volumes split at handover (decided 2026-10-27): in the window, Garage stops, its metadata is copied onto the new garage-meta volume, garage-data keeps the data blocks, and Garage starts with metadata_snapshots_dir on garage-snapshots. The rest of Garage's handover (its releases, engines.s3, the live keys, bucket names, garage-asset-sync) is in the comment below. The platform-postgres serving statement leaves the handover ledger.

The estate-side changes are recorded in the estate repository's HANDOVER.md.

Acceptance criteria

  • The render's diff against the Project's hand-written objects in fleet-infra is clean, or each difference is explained.
  • The Project's Reconcile Units report Ready.
  • A consumer-visible value checks out: Every consumer still reads its database, its queue and its bucket.
  • One change flips the handover ledger entry and deletes the hand-written objects, the descriptor and the drift-check entry.

Blocked by

Activity

  1. added
    type: choreMaintenance work without intended behavior change.
    area: platformPlatform, deployment, cluster, or runtime concern.
    priority: P1High; important and should be handled in the current iteration.
    status: blockedCannot move forward until an external dependency is resolved.
    on Oct 27, 2026
  2. ExtraToast commented on Oct 27, 2026

    @ExtraToast
    ContributorAuthor

    Missing from this issue, from the #387 work (#647, JorisJonkers-dev/delivery#94):

    • Needs first: a deploy-kit release carrying feat(model): derive a bucket catalog from the edges into an object store #647, and a delivery release that publishes garage-catalog and locks it. The Platform document then gains engines.s3: {backup: file-backup, catalog: garage-catalog, catalogSurface: admin} and the serving platform-garage admin {path: secret/data/platform/garage, token: admin-token}, as the worked platform has them.
    • Keys: copy each live key from secret/data/<ns>/garage (s3.key_hex, s3.secret) to secret/data/<project>/garage/s3 (access-key-id, secret-access-key) before the catalog first runs. The catalog then imports them instead of minting new ones, so every consumer keeps its key.
    • Volumes: this issue says the live garage-data claim is kept, but the worked example declares three: garage-meta (reconstructible), garage-snapshots and garage-data (recoverable). So either split the live 20Gi claim at handover (metadata onto garage-meta, with metadata_snapshots_dir on garage-snapshots), or declare one recoverable garage-data until a quiet window. This is the maintainer's choice; it is open.
    • Each consumer's edge names its buckets (buckets: [<name>], giving <project>-<name>). Those must match the live bucket names, or the catalog creates new, empty buckets.
    • fleet-infra's garage-asset-sync CronJob also runs in data-system. Before the hand-written objects are deleted, check what it does and whether a model concept covers it.
  3. ExtraToast commented on Oct 27, 2026

    @ExtraToast
    ContributorAuthor

    Decided by the maintainer, 2026-10-27: split at handover. In the handover window, stop Garage and copy its metadata (the LMDB directory) onto the new garage-meta volume. The live garage-data claim keeps the data blocks. Start Garage with metadata_snapshots_dir on garage-snapshots. This is one short Garage outage, and the estate matches the model from the first day.

  4. ExtraToast commented on Oct 27, 2026

    @ExtraToast
    ContributorAuthor

    Resume here

    Garage specifics are in the two comments above (keys, buckets, the split, and garage-asset-sync). The releases it needs are #379 and JorisJonkers-dev/delivery#98, which locks garage-catalog.

  5. ExtraToast commented on Oct 29, 2026

    @ExtraToast
    ContributorAuthor

    #380 is closed: delivery, _canary and _estate are on the 1.0 contract (evidence in #380 (comment)).

  6. ExtraToast commented on Oct 29, 2026

    @ExtraToast
    ContributorAuthor

    Data handover PRs, refreshed 2026-10-29

    The other session's stale PRs are taken over: each has main merged in (no force-push), and the work moved onto deploy-kit 1.3.0, the version toolkit.yml pins (also checked on 1.2.0). The runbook is docs/runbooks/data-handover.md on JorisJonkers-dev/estate#215. Nothing is merged, and nothing live was written.

    Merge order

    # PR merges changes live
    D0 JorisJonkers-dev/fleet-infra#562 (new, draft) now five annotations: data-system and the claims postgres-data, rabbitmq-data, valkey-data, garage-data get prune: disabled; nothing restarts
    P0 a person: kubectl patch pv … Retain, commands in #562 now the seven data-system volumes that reclaim Delete (Postgres, RabbitMQ, Valkey, Garage, MongoDB, and both of Vault's) reclaim Retain
    A JorisJonkers-dev/estate#215, then its release before the window nothing: every artifact composes byte for byte as on main
    P1 a person: the Vault documents in pre-check 3 before the window none
    D1 JorisJonkers-dev/fleet-infra#537 before the window, or window step 1 26 objects gain the prune mark, and apps-data stops pruning; nothing restarts
    D2 JorisJonkers-dev/fleet-infra#538 (draft) window step 2 apps-data becomes apps-data-leftovers, and nothing is pruned
    G a person: Garage's split window step 3 Garage stops; its metadata is copied onto garage-meta
    B JorisJonkers-dev/estate#216 (draft), then its release window step 4 data's first pin: Postgres, RabbitMQ, Valkey and Garage are recreated in place
    D3 JorisJonkers-dev/fleet-infra#539 (draft) after the proof rabbitmq-definitions-backup retires

    What changed from the stale versions

    • Garage is declared (platform-garage), with the 2026-10-27 split: garage-meta, garage-snapshots, and the live garage-data, whose blocks stay under data/. engines.s3 and Garage's serving admin location are in A.
    • D1 and D2 carry Garage's own objects too. Its bootstrap Job, garage-asset-sync and the assets route stay in apps-data-leftovers.
    • garage-asset-sync publishes agent-kit's latest release to the assets.jorisjonkers.dev bucket every 15 minutes. A scheduled Process covers it, but its logic is a shell script, never an Asset, so it waits for an image of its own.
    • Postgres runs as live: its config_file argument, and its exporter back as a sidecar mounting its queries (deploy-kit 1.2).
    • RabbitMQ sets HOME=/tmp. kubelet applies fsGroup to these local volumes at each mount, so every file on them becomes group-readable (read on immich-postgres). In Docker, the live RabbitMQ image then exits: Cookie file … must be accessible by owner only. With HOME on a writable path, it starts.
    • B no longer deletes projects/_estate/source.yaml by hand. Composition rewrites it, dropping estate-vso-secrets.

    Render against live, in short

    The full table is in #216 and the runbook. All four Deployments are recreated, because the fixed label set changes their immutable selectors. Same claims, Service names, ports and image digests. The Assets are byte-identical.

    • Every pod runs non-root under restricted; Garage moves from root to 1000:1000, and the split chowns its claims.
    • Request equals limit: about 4.1Gi more requested on frankfurt-contabo-1, 16.7Gi of 23.5Gi.
    • priorityClassName: platform-data goes: the Platform document has no priority block yet.
    • The probes are TCP, where live runs pg_isready.
    • The Postgres catalog moves into apps-data and signs in with secret/data/data/postgres/catalog.
    • New backups: Postgres off-cluster, plus RabbitMQ and both Garage claims.

    Open blockers

    1. W2, Vault. The render reads secret/data/data/postgres/catalog (user, password), data/postgres/backup (PGUSER, PGPASSWORD) and data/rabbitmq/backup (RABBITMQ_USERNAME, RABBITMQ_PASSWORD). None exists. platform/backup/off-cluster is unverified. A person writes them.
    2. W3, the namespace's prune mark. The render writes data-system with no mark. Server-side apply by the same kustomize-controller manager will drop the mark D0 sets. After the flip, one prune of the namespace deletes Vault and MongoDB with it. This needs a deploy-kit change, or the maintainer's acceptance with every volume on Retain (P0). The rollback is ordered around it.
    3. W5, platform-mongo. It is not declared: delivery publishes no mongo-backup image, so the declaration is refused with E_NO_ENGINE_POLICY. MongoDB stays in apps-data-leftovers. Its own handover later also needs the replica set's member host moved off mongo-0.mongo.data-system.svc.cluster.local, a StatefulSet name the render does not make. The maintainer decides whether data hands over without it.
    4. W1. The observability handover (Hand over observability to the estate path #660) comes first.
    5. Garage's split is a live step for the maintainer, with a Garage outage: cutover step 3 in the runbook.
    6. Priority. Adding priority to the Platform document gives the datastores platform-data back, but also moves auth and the foundation. It is a separate decision.

    Validation

  7. added and removed
    status: blockedCannot move forward until an external dependency is resolved.
    on Oct 30, 2026
  8. ExtraToast commented on Nov 1, 2026

    @ExtraToast
    ContributorAuthor

    Data is on the estate path: Postgres, RabbitMQ, Valkey and Garage, adopted in place on their own claims. MongoDB stays on the old path and follows under #748.

    Left: two old Vault roles, and the old logical Postgres backup until the first derived backup has been read back.

    Found: the datastores' derived priority and memory requests preempted other pods on their node; one (Karakeep's browser) has no room until capacity is added.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: platformPlatform, deployment, cluster, or runtime concern.priority: P1High; important and should be handled in the current iteration.type: choreMaintenance work without intended behavior change.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions