From 6e231f79c649eb7f789548e70acb2eca768af1da Mon Sep 17 00:00:00 2001 From: npub128x7j3pwgm4vs8yra3c42fcgcwcvh94g3luwzkqa376du2q6l0esqcrwch <51cde9442e46eac81c83ec71552708c3b0cb96a88ff8e1581d8fb4de281afbf3@buzz.block.builderlab.xyz> Date: Fri, 31 Jul 2026 19:46:17 -0400 Subject: [PATCH] docs(media): document staged key migration Keep self-hosted upgrades on legacy writes by default, expose the write-layout gate through Helm and Compose, and document the explicit legacy-to-dual-to-sharded migration sequence. Co-authored-by: npub128x7j3pwgm4vs8yra3c42fcgcwcvh94g3luwzkqa376du2q6l0esqcrwch <51cde9442e46eac81c83ec71552708c3b0cb96a88ff8e1581d8fb4de281afbf3@buzz.block.builderlab.xyz> Signed-off-by: npub128x7j3pwgm4vs8yra3c42fcgcwcvh94g3luwzkqa376du2q6l0esqcrwch <51cde9442e46eac81c83ec71552708c3b0cb96a88ff8e1581d8fb4de281afbf3@buzz.block.builderlab.xyz> --- .env.example | 7 +++++++ deploy/charts/buzz/README.md | 19 +++++++++++++++++++ deploy/charts/buzz/templates/deployment.yaml | 1 + deploy/charts/buzz/values.schema.json | 1 + deploy/charts/buzz/values.yaml | 3 +++ deploy/compose/.env.example | 3 +++ 6 files changed, 34 insertions(+) diff --git a/.env.example b/.env.example index b9bfcada0..a26b1bb2a 100644 --- a/.env.example +++ b/.env.example @@ -95,6 +95,13 @@ BUZZ_S3_BUCKET=buzz-media BUZZ_S3_REGION=us-east-1 BUZZ_S3_ADDRESSING_STYLE=path +# Media payload write migration. Unset defaults to legacy, so upgrades preserve +# existing flat-only writes and do not duplicate objects automatically. +# Stages: legacy (flat only) -> dual (sharded + flat rollback copy) -> sharded. +# Deploy compatibility readers everywhere and backfill/reconcile objects before +# advancing; do not roll sharded writers back to a version without sharded reads. +# BUZZ_MEDIA_KEY_LAYOUT=legacy + # ----------------------------------------------------------------------------- # Media Upload Admission # ----------------------------------------------------------------------------- diff --git a/deploy/charts/buzz/README.md b/deploy/charts/buzz/README.md index b2778df28..b1d06c5e8 100644 --- a/deploy/charts/buzz/README.md +++ b/deploy/charts/buzz/README.md @@ -94,6 +94,25 @@ disables that probe through `relay.extraEnv`, `/_readiness` does not test object storage; configuration is still parsed strictly, but reachability and addressing errors surface on the first storage operation. +## Media object-key migration + +Media writes stay on the flat legacy layout after an upgrade unless the operator +explicitly advances `BUZZ_MEDIA_KEY_LAYOUT` (or Helm +`relay.mediaKeyLayout`). The supported stages are: + +1. `legacy` (default): write only existing flat keys. Deploy this release first + so every relay can read both layouts; upgrading alone does **not** double-write. +2. `dual`: after all readers are compatible, write the sharded key and a flat + rollback copy. Monitor `buzz_media_s3_read_resolutions_total`, + `buzz_media_s3_read_fallbacks_total`, and the storage duplicate-layout gauges. +3. `sharded`: after backfill/reconciliation and a full rollback window, stop + writing flat copies. Keep compatibility readers deployed while legacy objects + are migrated and verified. + +Do not roll `sharded` writers back to a Buzz version that predates sharded reads. +Returning from `sharded` to `dual` does not retroactively recreate legacy copies; +run and verify the backfill before relying on old-version rollback. + ## Relay Pod extensions The chart exposes narrow extension points for init containers, volumes, relay diff --git a/deploy/charts/buzz/templates/deployment.yaml b/deploy/charts/buzz/templates/deployment.yaml index 67a93138c..8fb1a7154 100644 --- a/deploy/charts/buzz/templates/deployment.yaml +++ b/deploy/charts/buzz/templates/deployment.yaml @@ -131,6 +131,7 @@ spec: - { name: BUZZ_REQUIRE_AUTH_TOKEN, value: {{ .Values.relay.requireAuthToken | quote }} } - { name: BUZZ_REQUIRE_RELAY_MEMBERSHIP, value: {{ .Values.relay.requireRelayMembership | quote }} } - { name: BUZZ_REQUIRE_MEDIA_GET_AUTH, value: {{ .Values.relay.requireMediaGetAuth | quote }} } + - { name: BUZZ_MEDIA_KEY_LAYOUT, value: {{ .Values.relay.mediaKeyLayout | quote }} } - { name: BUZZ_ALLOW_NIP_OA_AUTH, value: {{ .Values.relay.allowNipOaAuth | quote }} } - { name: BUZZ_PUBKEY_ALLOWLIST, value: {{ .Values.relay.pubkeyAllowlist | quote }} } {{- if .Values.relay.corsOrigins }} diff --git a/deploy/charts/buzz/values.schema.json b/deploy/charts/buzz/values.schema.json index 9cb6a02c9..a644d33f2 100644 --- a/deploy/charts/buzz/values.schema.json +++ b/deploy/charts/buzz/values.schema.json @@ -62,6 +62,7 @@ "requireAuthToken": { "type": "boolean" }, "requireRelayMembership": { "type": "boolean" }, "requireMediaGetAuth": { "type": "boolean" }, + "mediaKeyLayout": { "type": "string", "enum": ["legacy", "dual", "sharded"] }, "allowNipOaAuth": { "type": "boolean" }, "huddleAudioAvailable": { "type": ["boolean", "null"], diff --git a/deploy/charts/buzz/values.yaml b/deploy/charts/buzz/values.yaml index 810f8a965..b6d39cae3 100644 --- a/deploy/charts/buzz/values.yaml +++ b/deploy/charts/buzz/values.yaml @@ -113,6 +113,9 @@ relay: # local development or fully public communities — desktop, mobile, and CLI # clients all attach read auth. requireMediaGetAuth: true + # Media payload write migration: legacy -> dual -> sharded. The upgrade-safe + # default is legacy, so installing a new release never starts duplicate writes. + mediaKeyLayout: legacy allowNipOaAuth: true pubkeyAllowlist: false corsOrigins: [] diff --git a/deploy/compose/.env.example b/deploy/compose/.env.example index f6ab4fcab..eef3f7fb6 100644 --- a/deploy/compose/.env.example +++ b/deploy/compose/.env.example @@ -35,6 +35,9 @@ BUZZ_S3_SECRET_KEY=CHANGE_ME_RANDOM_SECRET_KEY BUZZ_S3_BUCKET=buzz-media # Bundled MinIO uses path-style URLs; deploy/compose/compose.yml pins this. BUZZ_S3_ADDRESSING_STYLE=path +# Safe upgrade default: legacy writes only. Migrate explicitly in stages: +# legacy -> dual -> sharded, after compatibility readers and backfill are ready. +BUZZ_MEDIA_KEY_LAYOUT=legacy # Optional host ports. Base compose publishes the relay directly on BUZZ_HTTP_PORT. BUZZ_HTTP_PORT=3000