| 1 | #!/usr/bin/env python3 |
| 2 | import json |
| 3 | import os |
| 4 | import secrets |
| 5 | import subprocess |
| 6 | import sys |
| 7 | import tempfile |
| 8 | import urllib.error |
| 9 | import urllib.request |
| 10 | |
| 11 | from api import instance |
| 12 | |
| 13 | |
| 14 | data = json.load(sys.stdin) |
| 15 | container, address = instance(data["serviceId"]) |
| 16 | script = """ |
| 17 | IFS= read -r password |
| 18 | cd /app/gitea |
| 19 | su-exec git /usr/local/bin/gitea admin user create \ |
| 20 | --username studio-automation --email studio-automation@users.invalid \ |
| 21 | --password "$password" --must-change-password=false >/dev/null 2>&1 || true |
| 22 | su-exec git /usr/local/bin/gitea admin user change-password \ |
| 23 | --username studio-automation --password "$password" >/dev/null |
| 24 | su-exec git /usr/local/bin/gitea admin user must-change-password \ |
| 25 | --unset studio-automation >/dev/null |
| 26 | """ |
| 27 | result = subprocess.run( |
| 28 | ["podman", "--url", "unix:///run/podman/podman.sock", "exec", "-i", container, |
| 29 | "/bin/sh", "-ec", script], |
| 30 | input=data["automation_password"] + "\n", text=True, capture_output=True, |
| 31 | ) |
| 32 | if result.returncode: |
| 33 | raise RuntimeError("could not prepare Forgejo automation account") |
| 34 | |
| 35 | path = "nomad/jobs/" + data["serviceId"] |
| 36 | request = urllib.request.Request( |
| 37 | "http://127.0.0.1:4646/v1/var/" + path, |
| 38 | headers={"X-Nomad-Token": os.environ["NOMAD_TOKEN"]}, |
| 39 | ) |
| 40 | with urllib.request.urlopen(request, timeout=5) as response: |
| 41 | variable = json.load(response) |
| 42 | current = variable["Items"].get("automation_token") |
| 43 | if current: |
| 44 | check = urllib.request.Request(address + "/api/v1/user", headers={"Authorization": "token " + current}) |
| 45 | try: |
| 46 | with urllib.request.urlopen(check, timeout=5) as response: |
| 47 | response.read() |
| 48 | except urllib.error.HTTPError as error: |
| 49 | if error.code not in (401, 403): |
| 50 | raise |
| 51 | current = None |
| 52 | if not current: |
| 53 | generated = subprocess.run( |
| 54 | ["podman", "--url", "unix:///run/podman/podman.sock", "exec", container, |
| 55 | "/bin/sh", "-ec", "cd /app/gitea; su-exec git /usr/local/bin/gitea admin user generate-access-token --username studio-automation --token-name studio-" + secrets.token_hex(8) + " --raw"], |
| 56 | check=True, capture_output=True, text=True, |
| 57 | ).stdout.strip() |
| 58 | if len(generated) < 20: |
| 59 | raise ValueError("Forgejo did not generate an automation token") |
| 60 | with tempfile.NamedTemporaryFile("w", suffix=".nv.hcl", delete=False) as file: |
| 61 | file.write("items {\n" + "".join( |
| 62 | f" {key} = {json.dumps(value)}\n" |
| 63 | for key, value in {**variable["Items"], "automation_token": generated}.items() |
| 64 | ) + "}\n") |
| 65 | filename = file.name |
| 66 | try: |
| 67 | subprocess.run(["nomad", "var", "put", "-in=hcl", "-out=none", |
| 68 | f"-check-index={variable['ModifyIndex']}", path, "@" + filename], check=True) |
| 69 | finally: |
| 70 | os.unlink(filename) |