Antoine Vandeplanque e57144c9b1
All checks were successful
CI / Lint, PostgreSQL tests, and package (push) Successful in 12s
CI / Build and publish tested image (push) Successful in 1m14s
run selected releases through restricted SSH instead of GitOps polling
2026-10-01 17:20:40 +02:00

48 lines
2.1 KiB
Python

"""Resolve an approved image and invoke the restricted production SSH command."""
import os
from pathlib import Path
import subprocess
import sys
import tempfile
import uuid
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "gitops"))
from request import image_digest, resolve_release # noqa: E402
def main():
os.umask(0o077)
try:
sha = resolve_release(os.environ["RELEASE"])
image = image_digest(f"gitea.vandeplanque.com/tonio/car-tracker:{sha}", sha)
# Stable across job retries; a new manual dispatch has a different run ID.
request_id = str(uuid.uuid5(uuid.NAMESPACE_URL,
"https://gitea.vandeplanque.com/tonio/car-tracker/actions/runs/"
+ os.environ["GITHUB_RUN_ID"]))
with tempfile.TemporaryDirectory(prefix="car-tracker-ssh-") as directory:
key, hosts = Path(directory) / "key", Path(directory) / "known_hosts"
key.write_text(os.environ["SSH_PRIVATE_KEY"].strip() + "\n")
hosts.write_text(os.environ["SSH_KNOWN_HOSTS"].strip() + "\n")
key.chmod(0o600)
hosts.chmod(0o600)
print(f"Running request {request_id}; revision {sha}", flush=True)
result = subprocess.run([
"ssh", "-F", "/dev/null", "-T", "-i", str(key),
"-o", "BatchMode=yes", "-o", "IdentitiesOnly=yes",
"-o", "StrictHostKeyChecking=yes", "-o", f"UserKnownHostsFile={hosts}",
"-o", "ConnectTimeout=15", "-o", "ServerAliveInterval=30",
"-o", "ServerAliveCountMax=3", "tonio@192.168.1.56",
f"run {request_id} {sha} {image}",
])
if result.returncode == 255:
print("SSH connection failed/lost. The job may still be running; inspect the host before another dispatch.")
return result.returncode if result.returncode >= 0 else 70
except (KeyError, ValueError, OSError, subprocess.SubprocessError):
print("Run failed: check release, image and SSH configuration. No completion confirmed.")
return 70
if __name__ == "__main__":
sys.exit(main())