feat(scripts): add --build — build + push sunbeam-proxy to Gitea and redeploy

build_proxy() authenticates Docker with the Gitea registry, runs
`docker buildx build --platform linux/arm64 --push`, then applies
manifests and rolls the pingora deployment to pull the fresh image.

The Gitea admin password is read from the gitea-admin-credentials K8s
Secret (written by VSO) so --build works independently of --seed.
This commit is contained in:
2026-03-02 18:55:03 +00:00
parent cc2d4e6cbd
commit fae889addc

View File

@@ -13,6 +13,7 @@ Usage:
./scripts/sunbeam.py --restart # restart services only ./scripts/sunbeam.py --restart # restart services only
./scripts/sunbeam.py --status # show pod health across all namespaces ./scripts/sunbeam.py --status # show pod health across all namespaces
./scripts/sunbeam.py --verify # E2E test VSO → OpenBao integration ./scripts/sunbeam.py --verify # E2E test VSO → OpenBao integration
./scripts/sunbeam.py --build # Build + push sunbeam-proxy to Gitea; redeploy
Requires: limactl mkcert kubectl kustomize linkerd jq yq Requires: limactl mkcert kubectl kustomize linkerd jq yq
""" """
@@ -32,6 +33,7 @@ from pathlib import Path
SCRIPT_DIR = Path(__file__).parent.resolve() SCRIPT_DIR = Path(__file__).parent.resolve()
REPO_ROOT = SCRIPT_DIR.parent REPO_ROOT = SCRIPT_DIR.parent
SECRETS_DIR = REPO_ROOT / "secrets" / "local" SECRETS_DIR = REPO_ROOT / "secrets" / "local"
PROXY_DIR = REPO_ROOT.parent / "proxy"
# ── Config ──────────────────────────────────────────────────────────────────── # ── Config ────────────────────────────────────────────────────────────────────
LIMA_VM = "sunbeam" LIMA_VM = "sunbeam"
@@ -1460,6 +1462,56 @@ spec:
ok("VSO E2E verification passed.") ok("VSO E2E verification passed.")
# ── 18. Build + push sunbeam-proxy ───────────────────────────────────────────
def build_proxy(domain, admin_pass):
"""Build sunbeam-proxy for linux/arm64 and push to our Gitea registry.
Requires Docker (buildx) on the host. The mkcert CA must already be trusted
by Docker (docker-desktop uses the macOS Keychain, so `mkcert -install` is
sufficient). After pushing, applies manifests so the Deployment picks up
the updated image reference, then rolls the pingora pod to trigger a pull.
"""
if not shutil.which("docker"):
die("docker not found — install Docker Desktop to use --build.")
if not PROXY_DIR.is_dir():
die(f"Proxy source not found at {PROXY_DIR}")
registry = f"src.{domain}"
image = f"{registry}/studio/sunbeam-proxy:latest"
step(f"Building sunbeam-proxy → {image} ...")
# Authenticate Docker with Gitea before the build so --push succeeds.
ok("Logging in to Gitea registry...")
r = subprocess.run(
["docker", "login", registry,
"--username", GITEA_ADMIN_USER, "--password-stdin"],
input=admin_pass, text=True, capture_output=True,
)
if r.returncode != 0:
die(f"docker login failed:\n{r.stderr.strip()}")
ok(f"Building image (linux/arm64, push)...")
run(["docker", "buildx", "build",
"--platform", "linux/arm64",
"--push",
"-t", image,
str(PROXY_DIR)])
ok(f"Pushed {image}")
# Apply manifests so the Deployment spec reflects the Gitea image ref.
apply_manifests(domain)
# Roll the pingora pod — imagePullPolicy: Always ensures it pulls fresh.
ok("Rolling pingora deployment...")
kube("rollout", "restart", "deployment/pingora", "-n", "ingress")
kube("rollout", "status", "deployment/pingora", "-n", "ingress",
"--timeout=120s")
ok("Pingora redeployed.")
# ── Main ────────────────────────────────────────────────────────────────────── # ── Main ──────────────────────────────────────────────────────────────────────
def main(): def main():
parser = argparse.ArgumentParser(description="Sunbeam local dev stack manager") parser = argparse.ArgumentParser(description="Sunbeam local dev stack manager")
@@ -1469,6 +1521,7 @@ def main():
parser.add_argument("--restart", action="store_true", help="Restart services only") parser.add_argument("--restart", action="store_true", help="Restart services only")
parser.add_argument("--status", action="store_true", help="Show pod health across all namespaces") parser.add_argument("--status", action="store_true", help="Show pod health across all namespaces")
parser.add_argument("--verify", action="store_true", help="E2E test VSO → OpenBao integration") parser.add_argument("--verify", action="store_true", help="E2E test VSO → OpenBao integration")
parser.add_argument("--build", action="store_true", help="Build + push sunbeam-proxy to Gitea; redeploy")
args = parser.parse_args() args = parser.parse_args()
check_prerequisites() check_prerequisites()
@@ -1482,6 +1535,19 @@ def main():
verify_vso() verify_vso()
return return
if args.build:
ip = get_lima_ip()
domain = f"{ip}.sslip.io"
admin_pass_b64 = kube_out(
"-n", "devtools", "get", "secret", "gitea-admin-credentials",
"-o=jsonpath={.data.password}",
)
if not admin_pass_b64:
die("gitea-admin-credentials secret not found — run --seed first.")
admin_pass = base64.b64decode(admin_pass_b64).decode()
build_proxy(domain, admin_pass)
return
if args.apply or args.gitea or args.seed or args.restart: if args.apply or args.gitea or args.seed or args.restart:
ip = get_lima_ip() ip = get_lima_ip()
domain = f"{ip}.sslip.io" domain = f"{ip}.sslip.io"