Makes the cloud DX forge shortcuts (mcforge, ctforge) first-class citizens of the shared net-tools layer: - New bin/forge-dns-render (print/install/diff) that sources ~/.vault/*_forge_creds and emits a managed # >>> dx-forges block in /etc/hosts. - `net sync` now also converges the DX forges (alongside mesh-hosts + ssh). - Per-project ./run forge:dns now prefers the central renderer (with local fallback). - Docs updated. The mcforge:3000 / ctforge:3000 shortcuts are now installed and kept fresh as part of standard DX infra setup (`net sync` after net-tools install, or after any forge:up).
138 lines
4.6 KiB
Bash
Executable file
138 lines
4.6 KiB
Bash
Executable file
#!/bin/sh
|
|
# forge-dns-render — manage cloud DX forge shortnames (mcforge for magic-civilization,
|
|
# ctforge for cocottetech/lilithplatform, ...) in /etc/hosts as part of the shared
|
|
# net-tools infra installers for dev DX.
|
|
#
|
|
# Reads current FORGE_IP from ~/.vault/*_forge_creds (maintained by the per-project
|
|
# ./run forge:up / forge:dns in @magic-civilization and @cocottetech).
|
|
#
|
|
# Emits a marked, idempotently-replaceable block. `net sync` (and manual
|
|
# mesh-hosts-render + host-apply) now also converges the DX forge shortcuts.
|
|
# Per-project `./run forge:dns` prefers this central renderer when available.
|
|
#
|
|
# The block lives at the bottom (after the prepended mesh-hosts fleet block).
|
|
# Loose hand-managed lines for these names are adopted (removed) on --install.
|
|
#
|
|
# Usage:
|
|
# forge-dns-render # print the block (default)
|
|
# forge-dns-render --install # splice/replace in /etc/hosts (sudo)
|
|
# forge-dns-render --diff # show what --install would do
|
|
#
|
|
# Exit codes match mesh-hosts-render (0 success, 2 needs root).
|
|
|
|
set -eu
|
|
|
|
mode=print
|
|
case "${1:-}" in
|
|
""|--print) mode=print ;;
|
|
--install) mode=install ;;
|
|
--diff) mode=diff ;;
|
|
*) echo "forge-dns-render: unknown arg '$1' (use --print|--install|--diff)" >&2; exit 1 ;;
|
|
esac
|
|
|
|
BEGIN='# >>> dx-forges (managed by net-tools/bin/forge-dns-render)'
|
|
END='# <<< dx-forges'
|
|
HOSTS_FILE=/etc/hosts
|
|
VAULT_DIR="${HOME}/.vault"
|
|
|
|
# Map vault basename -> the short hostname users type for :3000
|
|
map_short() {
|
|
case "$1" in
|
|
mc_forge_creds) echo mcforge ;;
|
|
cocotte_forge_creds) echo ctforge ;;
|
|
*) echo "" ;;
|
|
esac
|
|
}
|
|
|
|
render_block() {
|
|
printf '%s\n' "$BEGIN"
|
|
printf '# Cloud DX Forgejo /etc/hosts shortcuts (mcforge, ctforge, ...).\n'
|
|
printf '# IPs from ~/.vault/*_forge_creds FORGE_IP (refreshed by project ./run forge:up).\n'
|
|
printf '# Re-run after any forge:up (droplet gets a new IP on restore-from-snapshot).\n'
|
|
printf '# http://<name>:3000 — also kept fresh by net-tools infra (net sync).\n'
|
|
had=0
|
|
for f in "$VAULT_DIR"/mc_forge_creds "$VAULT_DIR"/cocotte_forge_creds; do
|
|
[ -f "$f" ] || continue
|
|
base=$(basename "$f")
|
|
short=$(map_short "$base")
|
|
[ -n "$short" ] || continue
|
|
ip=$(grep -E '^FORGE_IP=' "$f" 2>/dev/null | head -1 | cut -d= -f2- | tr -d ' \t\r\n')
|
|
[ -n "$ip" ] || continue
|
|
printf '%s\t%s\n' "$ip" "$short"
|
|
had=1
|
|
done
|
|
if [ "$had" -eq 0 ]; then
|
|
printf '# (no active DX forges — ./run forge:up in the relevant project(s) first)\n'
|
|
fi
|
|
printf '%s\n' "$END"
|
|
}
|
|
|
|
block=$(render_block)
|
|
|
|
if [ "$mode" = "print" ]; then
|
|
printf '%s\n' "$block"
|
|
exit 0
|
|
fi
|
|
|
|
# All shortnames we own (for adoption of stale loose lines).
|
|
managed=$(printf '%s\n' "$block" | awk '!/^#/ && NF >= 2 { for (i = 2; i <= NF; i++) print $i }' | sort -u | tr '\n' ' ')
|
|
|
|
current=$(cat "$HOSTS_FILE" 2>/dev/null || true)
|
|
|
|
# Strip any previous copy of our block.
|
|
stripped=$(printf '%s\n' "$current" | awk -v b="$BEGIN" -v e="$END" '
|
|
$0 == b { skip = 1 }
|
|
skip != 1 { print }
|
|
$0 == e { skip = 0 }
|
|
')
|
|
|
|
# Adopt (remove) any loose lines or name tokens that match our managed forges.
|
|
# (Same policy as mesh-hosts-render: the tool owns these names now.)
|
|
stripped=$(printf '%s\n' "$stripped" | awk -v names="$managed" '
|
|
BEGIN { n = split(names, a, /[[:space:]]+/); for (i = 1; i <= n; i++) if (a[i] != "") set[a[i]] = 1 }
|
|
/^[[:space:]]*#/ || NF < 2 { print; next }
|
|
{
|
|
kept = ""; removed = 0
|
|
for (i = 2; i <= NF; i++) {
|
|
if ($i in set) removed++
|
|
else kept = kept " " $i
|
|
}
|
|
if (removed == 0) { print; next }
|
|
if (kept == "") next
|
|
print $1 kept
|
|
}
|
|
')
|
|
|
|
# Trim leading/trailing blank lines that accumulate from repeated splices.
|
|
stripped=$(printf '%s\n' "$stripped" | awk 'NF {f=1; p=NR} f {l[NR]=$0} END {for(i=1;i<=p;i++) if (i in l) print l[i]}')
|
|
|
|
# Append the dx-forges block at the bottom (mesh-hosts block is prepended at top).
|
|
new=$(printf '%s\n\n%s\n' "$stripped" "$block")
|
|
|
|
if [ "$mode" = "diff" ]; then
|
|
if command -v diff >/dev/null 2>&1; then
|
|
printf '%s\n' "$new" | diff -u "$HOSTS_FILE" - || true
|
|
else
|
|
printf '%s\n' "$new"
|
|
fi
|
|
exit 0
|
|
fi
|
|
|
|
# --install
|
|
if printf '%s\n' "$new" | cmp -s - "$HOSTS_FILE"; then
|
|
echo "forge-dns-render: $HOSTS_FILE already up to date"
|
|
exit 0
|
|
fi
|
|
|
|
SUDO=""
|
|
if [ "$(id -u)" -ne 0 ]; then
|
|
if command -v sudo >/dev/null 2>&1; then
|
|
SUDO="sudo"
|
|
else
|
|
echo "forge-dns-render: --install needs root" >&2
|
|
exit 2
|
|
fi
|
|
fi
|
|
|
|
printf '%s\n' "$new" | $SUDO tee "$HOSTS_FILE" >/dev/null
|
|
echo "forge-dns-render: updated $HOSTS_FILE"
|