fix(gtea): UPGRADE_SECRET_PREP hook — pre-insert lfs_jwt_secret with correct 43-char format
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
Blocker 4 fix: abra `secret generate --all` uses .env.sample for length hints; the lfs-plain-gitea PR has SECRET_LFS_JWT_SECRET_VERSION=v1 COMMENTED OUT, so abra produces a wrong-length secret. gitea requires exactly 43 chars (32 bytes base64 URL-safe); wrong length → gitea fatals trying to save the JWT secret to the read-only Docker Config app.ini → health check fails → swarm rolls back. Fix: new UPGRADE_SECRET_PREP hook (meta.py) called before `abra secret generate --all` in the upgrade path. abra's `--all` is idempotent (skips existing secrets), so the correctly pre-inserted secret survives. gitea's recipe_meta.py implements the hook using `docker secret create` directly to guarantee correct format regardless of .env.sample. Also consumes machine-docs/BUILDER-INBOX.md (Adversary Blocker 4 digest). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@ -60,6 +60,45 @@ def UPGRADE_EXTRA_ENV(ctx):
|
||||
}
|
||||
|
||||
|
||||
def UPGRADE_SECRET_PREP(ctx):
|
||||
"""Pre-insert lfs_jwt_secret with the correct 43-char base64 URL-safe format before
|
||||
`abra secret generate --all` runs. The lfs-plain-gitea PR's .env.sample has the
|
||||
SECRET_LFS_JWT_SECRET_VERSION=v1 spec COMMENTED OUT, so abra uses a wrong default length;
|
||||
gitea requires exactly 43 chars (32 bytes) or it fatals on the read-only app.ini."""
|
||||
if not _lfs_enabled():
|
||||
return
|
||||
import base64
|
||||
import subprocess
|
||||
|
||||
env_path = _os.path.expanduser(f"~/.abra/servers/default/{ctx.domain}.env")
|
||||
stack_name = None
|
||||
try:
|
||||
with open(env_path) as fh:
|
||||
for line in fh:
|
||||
if line.startswith("STACK_NAME="):
|
||||
stack_name = line.split("=", 1)[1].strip().strip('"').strip("'")
|
||||
except OSError:
|
||||
pass
|
||||
if not stack_name:
|
||||
raise RuntimeError(f"UPGRADE_SECRET_PREP: STACK_NAME not found in {env_path}")
|
||||
|
||||
docker_secret = f"{stack_name}_lfs_jwt_secret_v1"
|
||||
value = base64.urlsafe_b64encode(_os.urandom(32)).rstrip(b"=").decode()
|
||||
|
||||
subprocess.run(["docker", "secret", "rm", docker_secret], capture_output=True)
|
||||
result = subprocess.run(
|
||||
["docker", "secret", "create", docker_secret, "-"],
|
||||
input=value,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
if result.returncode != 0:
|
||||
raise RuntimeError(
|
||||
f"UPGRADE_SECRET_PREP: docker secret create {docker_secret}: {result.stderr.strip()}"
|
||||
)
|
||||
print(f" gitea upgrade: pre-created {docker_secret} (43-char lfs_jwt_secret)", flush=True)
|
||||
|
||||
|
||||
def EXTRA_ENV(ctx):
|
||||
lfs = _lfs_enabled()
|
||||
compose_file = "compose.yml:compose.sqlite3.yml"
|
||||
|
||||
Reference in New Issue
Block a user