feat(mumble F2-14c): drop cc-ci compose.host-ports.yml fork; deploy 0.2.0 base minimally, add native host-ports on upgrade-to-latest via new UPGRADE_EXTRA_ENV harness hook + COMPOSE_FILE-aware READY_PROBE/install skip
This commit is contained in:
@ -81,8 +81,8 @@ def recipe_checkout(recipe: str, version: str) -> None:
|
||||
|
||||
path = os.path.expanduser(f"~/.abra/recipes/{recipe}")
|
||||
# -f (force): the version-pinning checkout must yield the EXACT ref tree. Without it, a cc-ci
|
||||
# install_steps-provided overlay (e.g. mumble's compose.host-ports.yml, copied into a version that
|
||||
# predates it) is an UNTRACKED file that collides with the same path TRACKED in a later ref, and
|
||||
# install_steps-provided overlay (e.g. discourse's compose.ccci.yml, copied into the pinned base)
|
||||
# is an UNTRACKED file that collides with the same path TRACKED in a later ref, and
|
||||
# `git checkout <ref>` aborts ("untracked working tree files would be overwritten"). Force resolves
|
||||
# it by writing the ref's tracked version. Safe: we never want local recipe-tree state preserved
|
||||
# across a version switch (and chaos deploys re-provide the overlay via install_steps when needed).
|
||||
@ -137,6 +137,25 @@ def env_set(domain: str, key: str, value: str) -> None:
|
||||
fh.write("\n".join(out) + "\n")
|
||||
|
||||
|
||||
def env_get(domain: str, key: str) -> str | None:
|
||||
"""Read a key from the app's .env (last uncommented assignment wins). None if absent. Symmetric
|
||||
with env_set; abra has no getter. Strips surrounding quotes from the value."""
|
||||
import os
|
||||
import re
|
||||
|
||||
path = os.path.expanduser(f"~/.abra/servers/default/{domain}.env")
|
||||
if not os.path.exists(path):
|
||||
return None
|
||||
pat = re.compile(rf"^\s*{re.escape(key)}=(.*)$")
|
||||
val = None
|
||||
with open(path) as fh:
|
||||
for ln in fh.read().splitlines():
|
||||
m = pat.match(ln)
|
||||
if m:
|
||||
val = m.group(1).strip().strip('"').strip("'")
|
||||
return val
|
||||
|
||||
|
||||
def secret_generate(domain: str, timeout: int = 300) -> None:
|
||||
# -m avoids the TTY/table (ioctl) path; output (which contains the generated values) is
|
||||
# captured by _run and never logged. -C -o keep the recipe at the PR checkout (without -o it
|
||||
|
||||
@ -18,7 +18,7 @@ import socket
|
||||
import ssl
|
||||
import time
|
||||
|
||||
from . import lifecycle
|
||||
from . import abra, lifecycle
|
||||
|
||||
# A recipe is backup-capable iff a compose file carries a truthy backupbot.backup label.
|
||||
_BACKUPBOT_RE = re.compile(r"backupbot\.backup\b[^\n]*\btrue\b", re.IGNORECASE)
|
||||
@ -244,6 +244,17 @@ def perform_upgrade(
|
||||
before = lifecycle.deployed_identity(domain)
|
||||
if head_ref:
|
||||
lifecycle.recipe_checkout_ref(recipe, head_ref)
|
||||
# UPGRADE_EXTRA_ENV (F2-14c): a recipe may need different app .env for the upgrade-TARGET deploy
|
||||
# than for the base — e.g. mumble's `compose.host-ports.yml` overlay exists ONLY in the newer
|
||||
# (target) version, so the base deploys minimally WITHOUT it and the upgrade adds it to COMPOSE_FILE
|
||||
# here, after the PR-head checkout (which ships the overlay) and before the chaos redeploy that
|
||||
# picks up the new .env. Dict or callable(domain)->dict. No-op for recipes without it.
|
||||
upgrade_env = meta.get("UPGRADE_EXTRA_ENV") or {}
|
||||
if callable(upgrade_env):
|
||||
upgrade_env = upgrade_env(domain) or {}
|
||||
for k, v in upgrade_env.items():
|
||||
print(f" upgrade-env: {k}={v}", flush=True)
|
||||
abra.env_set(domain, k, v)
|
||||
# HQ1: warm the NEW-version image set before the chaos redeploy (the head_ref checkout's pinned
|
||||
# tags) so a pull failure is a clear pre-deploy error and convergence isn't pull-bound.
|
||||
lifecycle.prepull_images(recipe, domain)
|
||||
|
||||
@ -231,10 +231,10 @@ def deploy_app(
|
||||
flush=True,
|
||||
)
|
||||
chaos = True
|
||||
# A recipe may force a chaos base deploy via recipe_meta CHAOS_BASE_DEPLOY=True when cc-ci adds
|
||||
# an untracked compose overlay to the recipe checkout (e.g. mumble's host-ports.yml, provided
|
||||
# by install_steps for older versions that predate it). The untracked file makes abra's
|
||||
# pinned-deploy clean-tree check FATA ('has locally unstaged changes'); chaos skips lint +
|
||||
# A recipe may force a chaos base deploy via recipe_meta CHAOS_BASE_DEPLOY=True when an
|
||||
# install_steps hook adds an untracked compose overlay to the recipe checkout (e.g. discourse's
|
||||
# compose.ccci.yml, provided by install_steps for the pinned base). The untracked file makes
|
||||
# abra's pinned-deploy clean-tree check FATA ('has locally unstaged changes'); chaos skips lint +
|
||||
# the clean-tree gate and deploys the EXPLICITLY-checked-out pinned version (we already ran
|
||||
# recipe_checkout(version) above) — NOT latest. Same mechanism as the lightweight-tag branch.
|
||||
elif _recipe_meta_flag(recipe, "CHAOS_BASE_DEPLOY"):
|
||||
|
||||
@ -194,7 +194,7 @@ def _load_meta(recipe: str) -> dict:
|
||||
ns: dict = {}
|
||||
with open(path) as fh:
|
||||
exec(compile(fh.read(), path, "exec"), ns) # noqa: S102 (trusted, in-repo)
|
||||
for k in list(meta) + ["BACKUP_CAPABLE", "SKIP_GENERIC", "OIDC_AT_INSTALL", "READY_PROBE", "UPGRADE_BASE_VERSION", "BACKUP_VERIFY"]:
|
||||
for k in list(meta) + ["BACKUP_CAPABLE", "SKIP_GENERIC", "OIDC_AT_INSTALL", "READY_PROBE", "UPGRADE_BASE_VERSION", "BACKUP_VERIFY", "UPGRADE_EXTRA_ENV"]:
|
||||
if k in ns:
|
||||
meta[k] = ns[k]
|
||||
return meta
|
||||
|
||||
Reference in New Issue
Block a user