fix(cloud-dx): repoint forge from dead mc-forge droplet to live forge.mc.uvlava.com
Some checks are pending
ci / regression gate (push) Waiting to run
Some checks are pending
ci / regression gate (push) Waiting to run
The dedicated mc-forge droplet (159.203.170.249:3000/mcadmin) is gone; the forge now rides a shared services box, addressed by the stable hostname forge.mc.uvlava.com/applications. The cloud-DX toolchain still pointed at the dead endpoint, so every worker clone + golden-image build was broken. - scripts/lib/forge-remote.sh: single source of truth — builds the authenticated clone URL from the hostname + ~/.vault/services-forge-token (relocation-proof; no hardcoded IP). Exports MC_FORGE_GIT_REMOTE. - cloud-bringup.sh / dist.sh: source the helper instead of the dead mc_forge_creds + 159.203 URL. Also fix cloud-bringup REPO path to the current @mc/@applications/magicciv location. - settings.local.json autoMode trust block: name the new forge host + 'mc' DO project (was 159.203 + 'mc:dev'), else cloud provisioning is denied as exfil. - cloud-dx-do.md: document the new forge + token. Verified: helper authenticates to the live forge (ls-remote main); scripts parse; JSON valid. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
dfd87b87d3
commit
ab8fd4d707
5 changed files with 50 additions and 15 deletions
|
|
@ -13,17 +13,17 @@
|
|||
# Reads all secrets from ~/.vault/ — nothing sensitive is hardcoded here.
|
||||
set -uo pipefail
|
||||
|
||||
REPO="$HOME/Code/@projects/@magic-civilization"
|
||||
REPO="$HOME/Code/@mc/@applications/magicciv"
|
||||
cd "$REPO" || exit 1
|
||||
|
||||
# --- auth (from vault) ---
|
||||
export DIGITALOCEAN_TOKEN; DIGITALOCEAN_TOKEN="$(cat ~/.vault/do_pat_mc)"
|
||||
export TF_VAR_do_token="$DIGITALOCEAN_TOKEN"
|
||||
# shellcheck disable=SC1090
|
||||
. ~/.vault/mc_forge_creds # FORGE_IP ADMIN_USER ADMIN_PASS ...
|
||||
GITR="http://${ADMIN_USER}:${ADMIN_PASS}@${FORGE_IP}:3000/mcadmin/magicciv.git"
|
||||
export TF_VAR_git_remote="$GITR" # workers pull latest from the forge
|
||||
export PKR_VAR_git_remote="$GITR" # packer reads the creds from env, not argv
|
||||
# Forge clone URL (hostname + services token) — single source of truth.
|
||||
# shellcheck disable=SC1091
|
||||
. "$REPO/scripts/lib/forge-remote.sh" || { echo "!!! forge-remote.sh failed (no token?)"; exit 1; }
|
||||
export TF_VAR_git_remote="$MC_FORGE_GIT_REMOTE" # workers pull latest from the forge
|
||||
export PKR_VAR_git_remote="$MC_FORGE_GIT_REMOTE" # packer reads the creds from env, not argv
|
||||
PKR_VAR_fleet_pubkey="$(cat ~/.ssh/id_mc_fleet.pub)"; export PKR_VAR_fleet_pubkey # baked into worker authorized_keys
|
||||
# fleet reuses the pre-registered DO key 'mc-fleet' (var ssh_key_name default); just load its private half
|
||||
ssh-add ~/.ssh/id_mc_fleet 2>/dev/null || true # so the dispatch ssh (mc@worker) authenticates
|
||||
|
|
|
|||
34
scripts/lib/forge-remote.sh
Normal file
34
scripts/lib/forge-remote.sh
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#!/usr/bin/env bash
|
||||
# Single source of truth for the MC forge git remote used to clone this repo onto
|
||||
# cloud build/worker boxes. SOURCE it (it `return`s); it exports MC_FORGE_GIT_REMOTE.
|
||||
#
|
||||
# Uses the stable HOSTNAME (forge.mc.uvlava.com), never a hardcoded IP — the forge
|
||||
# is no longer its own droplet, it rides a shared services box and can be moved
|
||||
# between hosts; the DNS name is the contract, an IP is not. (Old dead endpoint
|
||||
# was 159.203.170.249:3000/mcadmin — gone.)
|
||||
#
|
||||
# Auth = the services forge token (read-only clone is all a worker needs). The
|
||||
# token is injected into the URL in-process only; callers pass MC_FORGE_GIT_REMOTE
|
||||
# via PKR_VAR_*/TF_VAR_* ENV (never on argv), per cloud-dx-do.md's creds rule.
|
||||
#
|
||||
# Overridable for testing: MC_FORGE_HOST, MC_FORGE_ORG, MC_FORGE_TOKEN_FILE.
|
||||
|
||||
: "${MC_FORGE_HOST:=forge.mc.uvlava.com}"
|
||||
: "${MC_FORGE_ORG:=applications}"
|
||||
: "${MC_FORGE_TOKEN_FILE:=$HOME/.vault/services-forge-token}"
|
||||
|
||||
if [ ! -r "$MC_FORGE_TOKEN_FILE" ]; then
|
||||
echo "forge-remote: no forge token at $MC_FORGE_TOKEN_FILE" >&2
|
||||
return 1 2>/dev/null || exit 1
|
||||
fi
|
||||
|
||||
_mc_forge_token="$(cat "$MC_FORGE_TOKEN_FILE")"
|
||||
if [ -z "$_mc_forge_token" ]; then
|
||||
echo "forge-remote: forge token file is empty: $MC_FORGE_TOKEN_FILE" >&2
|
||||
unset _mc_forge_token
|
||||
return 1 2>/dev/null || exit 1
|
||||
fi
|
||||
|
||||
# Gitea accepts the token as the basic-auth password with user "oauth2".
|
||||
export MC_FORGE_GIT_REMOTE="https://oauth2:${_mc_forge_token}@${MC_FORGE_HOST}/${MC_FORGE_ORG}/magicciv.git"
|
||||
unset _mc_forge_token
|
||||
|
|
@ -88,7 +88,7 @@ cmd_dist_image() {
|
|||
# (Re)build the golden image. INCREMENTAL by default: builds FROM the newest
|
||||
# mc-golden snapshot, so provision.sh (idempotent) only redoes changed work
|
||||
# (~3-8 min). --cold builds from stock Ubuntu (~20 min) — resets accumulated
|
||||
# layer cruft; run occasionally. Needs ~/.vault/{do_pat_mc,mc_forge_creds}.
|
||||
# layer cruft; run occasionally. Needs ~/.vault/{do_pat_mc,services-forge-token}.
|
||||
local cold=false a
|
||||
for a in "$@"; do [ "$a" = "--cold" ] && cold=true; done
|
||||
local root pat
|
||||
|
|
@ -96,9 +96,10 @@ cmd_dist_image() {
|
|||
pat="$(cat ~/.vault/do_pat_mc 2>/dev/null)"
|
||||
[ -n "$pat" ] || { echo "no ~/.vault/do_pat_mc" >&2; return 1; }
|
||||
export DIGITALOCEAN_TOKEN="$pat"
|
||||
# shellcheck disable=SC1090
|
||||
. ~/.vault/mc_forge_creds
|
||||
export PKR_VAR_git_remote="http://${ADMIN_USER}:${ADMIN_PASS}@${FORGE_IP}:3000/mcadmin/magicciv.git"
|
||||
# Forge clone URL (hostname + services token) — single source of truth.
|
||||
# shellcheck disable=SC1091
|
||||
. "$root/scripts/lib/forge-remote.sh" || { echo "forge-remote.sh failed (no token?)" >&2; return 1; }
|
||||
export PKR_VAR_git_remote="$MC_FORGE_GIT_REMOTE"
|
||||
PKR_VAR_fleet_pubkey="$(cat ~/.ssh/id_mc_fleet.pub)"; export PKR_VAR_fleet_pubkey
|
||||
local base="ubuntu-24-04-x64" prev
|
||||
if ! $cold; then
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@
|
|||
|
||||
## Standing setup (already built — proven 2026-06-27)
|
||||
|
||||
- **Forge**: `mc-forge` droplet running Forgejo; repo `mcadmin/magicciv`; IP + admin creds in `~/.vault/mc_forge_creds`.
|
||||
- **Forge**: Gitea at `forge.mc.uvlava.com` (no longer its own droplet — rides a shared services box; address by hostname, never IP). Repo `applications/magicciv`. Clone token in `~/.vault/services-forge-token`; the clone URL is built once by `scripts/lib/forge-remote.sh` (exports `MC_FORGE_GIT_REMOTE`). Old `mcadmin@159.203.170.249:3000` + `mc_forge_creds` are DEAD.
|
||||
- **Golden image**: Packer `infra/packer/`, auto-discovered by the fleet (snapshot name prefix `mc-golden`). Bakes: toolchain (via `scripts/dev-setup/linux.sh`) + prebuilt GDExtension `.so` + warm Godot import + **weston/Mesa render stack** + **mold + sccache** build accelerators + the fleet ssh key in `mc`'s `authorized_keys`.
|
||||
- **Fleet TF**: `infra/terraform/test-fleet/` — DO provider, golden-image data-source discovery, grouped under the `mc:dev` DO project, mocked-provider test suite.
|
||||
- **Secrets**: `~/.vault/{do_pat_mc, mc_forge_creds, do-spaces-uvlava.access, do-spaces-uvlava.secret}` (600). Key `~/.ssh/id_mc_fleet` (DO key `mc-fleet`).
|
||||
- **Fleet TF**: `infra/terraform/test-fleet/` — DO provider, golden-image data-source discovery, grouped under the `mc` DO project, mocked-provider test suite.
|
||||
- **Secrets**: `~/.vault/{do_pat_mc, services-forge-token, do-spaces-uvlava.access, do-spaces-uvlava.secret}` (600). Key `~/.ssh/id_mc_fleet` (DO key `mc-fleet`).
|
||||
- **Artifact Space**: `magicciv-artifacts` (DO Spaces, nyc3) — `builds/<sha>/` holds the prebuilt linux `.so`+wasm; `models/<run>/` holds shared RL `.onnx`. Account already pays the Spaces subscription (for `lilith-quinn-media`), so this Space adds ~$0 base. Workers carry `rclone` (baked by `provision.sh`); the dispatch passes the Spaces creds as `RCLONE_S3_*` env over ssh (never stored on the worker, never on argv).
|
||||
|
||||
## Build once, load many (the artifact Space)
|
||||
|
|
|
|||
|
|
@ -69,11 +69,11 @@
|
|||
"autoMode": {
|
||||
"environment": [
|
||||
"$defaults",
|
||||
"The self-hosted Forgejo at 159.203.170.249:3000 (droplet 'mc-forge', DigitalOcean project 'mc:dev') is the repo owner's OWN forge holding this project's source. DigitalOcean droplets in the 'mc:dev' project are the owner's own build/test/render infrastructure. Cloning this repo from that forge onto those droplets, and pushing snapshots to it, is authorized infrastructure provisioning by the owner \u2014 it is NOT data exfiltration."
|
||||
"The self-hosted Gitea forge at forge.mc.uvlava.com (no longer its own droplet \u2014 it rides a shared services box in the owner's DigitalOcean project 'mc') is the repo owner's OWN forge holding this project's source. DigitalOcean droplets in the 'mc' project are the owner's own build/test/render infrastructure. Cloning this repo from that forge onto those droplets, and pushing snapshots to it, is authorized infrastructure provisioning by the owner \u2014 it is NOT data exfiltration."
|
||||
],
|
||||
"allow": [
|
||||
"$defaults",
|
||||
"git/packer/terraform operations moving THIS project's source between the owner's machine, the mc-forge Forgejo (159.203.170.249), and DigitalOcean droplets in the mc:dev project are authorized provisioning, not exfiltration."
|
||||
"git/packer/terraform operations moving THIS project's source between the owner's machine, the forge at forge.mc.uvlava.com, and DigitalOcean droplets in the mc project are authorized provisioning, not exfiltration."
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue