From de12847cf163a8c7e263182b4e8ccf9e0c53b541 Mon Sep 17 00:00:00 2001 From: Sienna Meridian Satterwhite Date: Tue, 3 Mar 2026 14:23:42 +0000 Subject: [PATCH] feat: add impress image mirroring and docs secret seeding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit images.py: extend AMD64_ONLY_IMAGES with the three impress (La Suite Docs) images — impress-backend, impress-frontend, impress-y-provider. Always pull the amd64 manifest + layers by digest unconditionally before the blob check; the prior guard skipped the pull when the index blob was present but layers were missing, causing the OCI import to fail on arm64 hosts. secrets.py: add docs KV path (django-secret-key, collaboration-secret) to _seed_openbao so a fresh sunbeam seed generates all required credentials for the impress deployment. --- sunbeam/images.py | 30 ++++++++++++++++++------------ sunbeam/secrets.py | 7 ++++++- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/sunbeam/images.py b/sunbeam/images.py index bfb5e14..bed5b24 100644 --- a/sunbeam/images.py +++ b/sunbeam/images.py @@ -15,8 +15,11 @@ MANAGED_NS = ["data", "devtools", "ingress", "lasuite", "media", "ory", "storage "vault-secrets-operator"] AMD64_ONLY_IMAGES = [ - ("docker.io/lasuite/people-backend:latest", "studio", "people-backend", "latest"), - ("docker.io/lasuite/people-frontend:latest", "studio", "people-frontend", "latest"), + ("docker.io/lasuite/people-backend:latest", "studio", "people-backend", "latest"), + ("docker.io/lasuite/people-frontend:latest", "studio", "people-frontend", "latest"), + ("docker.io/lasuite/impress-backend:latest", "studio", "impress-backend", "latest"), + ("docker.io/lasuite/impress-frontend:latest", "studio", "impress-frontend", "latest"), + ("docker.io/lasuite/impress-y-provider:latest","studio", "impress-y-provider","latest"), ] _MIRROR_SCRIPT_BODY = r''' @@ -137,17 +140,20 @@ def process(src, tgt, user, pwd): amd64_hex = amd64["digest"].replace("sha256:", "") + # Always pull by digest with --platform linux/amd64 to ensure all layer + # blobs are downloaded to the content store (the index pull in step 1 only + # fetches the manifest blob, not the layers, on an arm64 host). + print(" pulling amd64 manifest + layers by digest...") + repo_base = src.rsplit(":", 1)[0] + subprocess.run( + ["ctr", "-n", "k8s.io", "images", "pull", + "--platform", "linux/amd64", + f"{repo_base}@sha256:{amd64_hex}"], + capture_output=True, + ) if not blob_exists(amd64_hex): - print(" pulling amd64 manifest + layers by digest...") - repo_base = src.rsplit(":", 1)[0] - subprocess.run( - ["ctr", "-n", "k8s.io", "images", "pull", - f"{repo_base}@sha256:{amd64_hex}"], - capture_output=True, - ) - if not blob_exists(amd64_hex): - print(" failed: amd64 manifest blob missing after pull") - return + print(" failed: amd64 manifest blob missing after pull") + return amd64_bytes = read_blob(amd64_hex) diff --git a/sunbeam/secrets.py b/sunbeam/secrets.py index c3c842a..39a0310 100644 --- a/sunbeam/secrets.py +++ b/sunbeam/secrets.py @@ -170,6 +170,10 @@ def _seed_openbao() -> dict: "csrf-cookie-secret": rand, "admin-identity-ids": lambda: ""}) + docs = get_or_create("docs", + **{"django-secret-key": rand, + "collaboration-secret": rand}) + # Write all secrets to KV (idempotent -- puts same values back) bao(f"BAO_ADDR=http://127.0.0.1:8200 BAO_TOKEN='{root_token}' sh -c '" f"bao kv put secret/hydra system-secret=\"{hydra['system-secret']}\" cookie-secret=\"{hydra['cookie-secret']}\" pairwise-salt=\"{hydra['pairwise-salt']}\" && " @@ -180,7 +184,8 @@ def _seed_openbao() -> dict: f"bao kv put secret/livekit api-key=\"{livekit['api-key']}\" api-secret=\"{livekit['api-secret']}\" && " f"bao kv put secret/people django-secret-key=\"{people['django-secret-key']}\" && " f"bao kv put secret/login-ui cookie-secret=\"{login_ui['cookie-secret']}\" csrf-cookie-secret=\"{login_ui['csrf-cookie-secret']}\" && " - f"bao kv put secret/kratos-admin cookie-secret=\"{kratos_admin['cookie-secret']}\" csrf-cookie-secret=\"{kratos_admin['csrf-cookie-secret']}\" admin-identity-ids=\"{kratos_admin['admin-identity-ids']}\"" + f"bao kv put secret/kratos-admin cookie-secret=\"{kratos_admin['cookie-secret']}\" csrf-cookie-secret=\"{kratos_admin['csrf-cookie-secret']}\" admin-identity-ids=\"{kratos_admin['admin-identity-ids']}\" && " + f"bao kv put secret/docs django-secret-key=\"{docs['django-secret-key']}\" collaboration-secret=\"{docs['collaboration-secret']}\"" f"'") # Configure Kubernetes auth method so VSO can authenticate with OpenBao