Rename Castle -> Wild PC across the repo
Repo-side rename only (Phases 1-3 of the migration plan); the live box (~/.castle, systemd units, /data/castle, domains) is a separate cutover. - Slug `castle` -> `wildpc`: CLI command, module names (wildpc_core/cli/api), dist names, entry point `wildpc = wildpc_cli.main:main`. - Identifiers: CastleConfig/NATSClient/DirError/MDNS -> Wildpc*. - Env/constants: CASTLE_* -> WILDPC_*; ~/.castle -> ~/.wildpc, castle.yaml -> wildpc.yaml, /data/castle -> /data/wildpc. - Systemd UNIT_PREFIX castle- -> wildpc-; own programs castle-api/gateway/etc. - Display prose "Castle" -> "Wild PC" in docs, agent-guide files, README, frontend. - Package dirs and bootstrap yaml renamed via git mv; lockfiles regenerated; redundant nested uv.lock files dropped (workspace root lock is authoritative). Tests: core 273, cli 47, wildpc-api 120 all pass. Frontend type-checks + builds. Fixed a stale test fixture (secret_env_path kind arg) broken pre-rename.
This commit is contained in:
202
install.sh
202
install.sh
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# Castle Platform — Bootstrap Install
|
||||
# Wild PC Platform — Bootstrap Install
|
||||
#
|
||||
# Idempotent script that sets up the infrastructure "control layer":
|
||||
# - Docker, Caddy (system binary)
|
||||
@@ -18,16 +18,16 @@ set -euo pipefail
|
||||
# Config
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
CASTLE_HOME="${HOME}/.castle"
|
||||
CASTLE_CONF="${CASTLE_HOME}/infra.conf"
|
||||
# Program data lives on a dedicated volume, decoupled from CASTLE_HOME — must match
|
||||
# castle_core.config._resolve_data_dir (default /data/castle, override CASTLE_DATA_DIR)
|
||||
# so the data dirs + container mounts created here line up with what castle apply
|
||||
WILDPC_HOME="${HOME}/.wildpc"
|
||||
WILDPC_CONF="${WILDPC_HOME}/infra.conf"
|
||||
# Program data lives on a dedicated volume, decoupled from WILDPC_HOME — must match
|
||||
# wildpc_core.config._resolve_data_dir (default /data/wildpc, override WILDPC_DATA_DIR)
|
||||
# so the data dirs + container mounts created here line up with what wildpc apply
|
||||
# generates for the mqtt/postgres/neo4j deployments.
|
||||
DATA_DIR="${CASTLE_DATA_DIR:-/data/castle}"
|
||||
# Program source repos (default /data/repos, override CASTLE_REPOS_DIR).
|
||||
REPOS_DIR="${CASTLE_REPOS_DIR:-/data/repos}"
|
||||
CASTLE_ROOT="$(cd "$(dirname "$0")" && pwd)"
|
||||
DATA_DIR="${WILDPC_DATA_DIR:-/data/wildpc}"
|
||||
# Program source repos (default /data/repos, override WILDPC_REPOS_DIR).
|
||||
REPOS_DIR="${WILDPC_REPOS_DIR:-/data/repos}"
|
||||
WILDPC_ROOT="$(cd "$(dirname "$0")" && pwd)"
|
||||
|
||||
# Container defaults
|
||||
MQTT_IMAGE="eclipse-mosquitto:2"
|
||||
@@ -83,18 +83,18 @@ ask_yes_no() {
|
||||
|
||||
conf_get() {
|
||||
local key="$1"
|
||||
if [ -f "$CASTLE_CONF" ]; then
|
||||
grep -m1 "^${key}=" "$CASTLE_CONF" 2>/dev/null | cut -d= -f2 || true
|
||||
if [ -f "$WILDPC_CONF" ]; then
|
||||
grep -m1 "^${key}=" "$WILDPC_CONF" 2>/dev/null | cut -d= -f2 || true
|
||||
fi
|
||||
}
|
||||
|
||||
conf_set() {
|
||||
local key="$1" val="$2"
|
||||
mkdir -p "$(dirname "$CASTLE_CONF")"
|
||||
if [ -f "$CASTLE_CONF" ] && grep -q "^${key}=" "$CASTLE_CONF" 2>/dev/null; then
|
||||
sed -i "s/^${key}=.*/${key}=${val}/" "$CASTLE_CONF"
|
||||
mkdir -p "$(dirname "$WILDPC_CONF")"
|
||||
if [ -f "$WILDPC_CONF" ] && grep -q "^${key}=" "$WILDPC_CONF" 2>/dev/null; then
|
||||
sed -i "s/^${key}=.*/${key}=${val}/" "$WILDPC_CONF"
|
||||
else
|
||||
echo "${key}=${val}" >> "$CASTLE_CONF"
|
||||
echo "${key}=${val}" >> "$WILDPC_CONF"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ ensure_caddy() {
|
||||
| sudo tee /etc/apt/sources.list.d/caddy-stable.list >/dev/null
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -y -qq caddy >/dev/null
|
||||
# Disable the system-level caddy service — castle manages it via user systemd
|
||||
# Disable the system-level caddy service — wildpc manages it via user systemd
|
||||
sudo systemctl disable --now caddy 2>/dev/null || true
|
||||
log_ok
|
||||
}
|
||||
@@ -177,7 +177,7 @@ CADDY_DNS_VERSION="${CADDY_DNS_VERSION:-v2.11.4}"
|
||||
# (Let's Encrypt wildcard via DNS-01). Stock apt Caddy has no DNS modules. The
|
||||
# result goes to /usr/local/bin/caddy, which precedes /usr/bin on PATH, so the
|
||||
# gateway (a `command` runner resolving `caddy` via PATH) picks it up on the next
|
||||
# `castle apply` with no spec change. Idempotent and opt-in (--with-dns-plugin).
|
||||
# `wildpc apply` with no spec change. Idempotent and opt-in (--with-dns-plugin).
|
||||
ensure_caddy_dns_plugin() {
|
||||
local provider="${1:-cloudflare}"
|
||||
local module
|
||||
@@ -202,7 +202,7 @@ ensure_caddy_dns_plugin() {
|
||||
|| log_fail "xcaddy install failed"
|
||||
fi
|
||||
|
||||
# events-exec: lets the gateway run `castle tls reconcile` on cert issuance/
|
||||
# events-exec: lets the gateway run `wildpc tls reconcile` on cert issuance/
|
||||
# renewal (the cert_obtained hook), so certs materialized onto raw-TCP services
|
||||
# refresh automatically. See docs/tcp-exposure.md §5.
|
||||
local events_module="github.com/mholt/caddy-events-exec"
|
||||
@@ -217,12 +217,12 @@ ensure_caddy_dns_plugin() {
|
||||
|| log_fail "built caddy is missing dns.providers.$provider"
|
||||
/usr/local/bin/caddy list-modules 2>/dev/null | grep -q "events.handlers.exec" \
|
||||
|| log_fail "built caddy is missing events.handlers.exec"
|
||||
log_info "Built /usr/local/bin/caddy — run 'castle apply' to use it."
|
||||
log_info "Built /usr/local/bin/caddy — run 'wildpc apply' to use it."
|
||||
log_ok
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Castle CLI
|
||||
# Wild PC CLI
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
ensure_uv() {
|
||||
@@ -238,20 +238,20 @@ ensure_uv() {
|
||||
log_ok
|
||||
}
|
||||
|
||||
# Install the `castle` CLI from this repo as an editable uv tool, so a fresh
|
||||
# clone becomes a working `castle` command. Idempotent — reinstall is cheap and
|
||||
# Install the `wildpc` CLI from this repo as an editable uv tool, so a fresh
|
||||
# clone becomes a working `wildpc` command. Idempotent — reinstall is cheap and
|
||||
# keeps the entry point pointed at the current checkout.
|
||||
install_cli() {
|
||||
log_step "Installing the castle CLI"
|
||||
( cd "$CASTLE_ROOT" && uv tool install --editable ./cli >/dev/null 2>&1 ) \
|
||||
log_step "Installing the wildpc CLI"
|
||||
( cd "$WILDPC_ROOT" && uv tool install --editable ./cli >/dev/null 2>&1 ) \
|
||||
|| log_fail "uv tool install of ./cli failed"
|
||||
cmd_exists castle || log_info "NOTE: ensure ~/.local/bin is on your PATH to use 'castle'"
|
||||
cmd_exists wildpc || log_info "NOTE: ensure ~/.local/bin is on your PATH to use 'wildpc'"
|
||||
log_ok
|
||||
}
|
||||
|
||||
# Non-interactive/non-login shells (`ssh host cmd`, systemd units, `castle` dev verbs)
|
||||
# Non-interactive/non-login shells (`ssh host cmd`, systemd units, `wildpc` dev verbs)
|
||||
# load ~/.zshenv but NOT ~/.zshrc → ~/.zsh.d/*.sh — so tools installed there (uv,
|
||||
# castle, pnpm, nvm node) don't resolve over a bare `ssh host 'castle …'`. Mirror just
|
||||
# wildpc, pnpm, nvm node) don't resolve over a bare `ssh host 'wildpc …'`. Mirror just
|
||||
# the PATH entries into ~/.zshenv (interactive niceties stay in ~/.zsh.d). Idempotent.
|
||||
ensure_shell_path() {
|
||||
log_step "Wiring PATH for non-interactive shells"
|
||||
@@ -265,16 +265,16 @@ ensure_shell_path() {
|
||||
;;
|
||||
esac
|
||||
local zshenv="${HOME}/.zshenv"
|
||||
if [ -f "$zshenv" ] && grep -q "castle non-interactive PATH" "$zshenv"; then
|
||||
if [ -f "$zshenv" ] && grep -q "wildpc non-interactive PATH" "$zshenv"; then
|
||||
log_skip "already wired"
|
||||
return
|
||||
fi
|
||||
cat >> "$zshenv" <<'ZSHENV'
|
||||
|
||||
# >>> castle non-interactive PATH >>>
|
||||
# Non-interactive/non-login shells (ssh 'cmd', systemd, castle dev verbs) load
|
||||
# ~/.zshenv but not ~/.zshrc → ~/.zsh.d/*.sh. Mirror the PATH entries castle's
|
||||
# toolchain needs (uv/castle in ~/.local/bin, pnpm, nvm node) so they resolve there.
|
||||
# >>> wildpc non-interactive PATH >>>
|
||||
# Non-interactive/non-login shells (ssh 'cmd', systemd, wildpc dev verbs) load
|
||||
# ~/.zshenv but not ~/.zshrc → ~/.zsh.d/*.sh. Mirror the PATH entries wildpc's
|
||||
# toolchain needs (uv/wildpc in ~/.local/bin, pnpm, nvm node) so they resolve there.
|
||||
for _d in "$HOME/.local/bin" "$HOME/.local/share/pnpm"; do
|
||||
case ":$PATH:" in *":$_d:"*) ;; *) [ -d "$_d" ] && PATH="$_d:$PATH" ;; esac
|
||||
done
|
||||
@@ -283,7 +283,7 @@ for _nb in "$HOME"/.nvm/versions/node/*/bin(N); do
|
||||
done
|
||||
export PATH
|
||||
unset _d _nb
|
||||
# <<< castle non-interactive PATH <<<
|
||||
# <<< wildpc non-interactive PATH <<<
|
||||
ZSHENV
|
||||
log_ok "~/.zshenv"
|
||||
}
|
||||
@@ -295,78 +295,78 @@ ZSHENV
|
||||
create_directories() {
|
||||
log_step "Creating directory structure"
|
||||
|
||||
# ~/.castle tree — globals (castle.yaml) plus one file per program/deployment.
|
||||
mkdir -p "${CASTLE_HOME}/programs"
|
||||
mkdir -p "${CASTLE_HOME}/deployments"
|
||||
mkdir -p "${CASTLE_HOME}/artifacts/specs"
|
||||
mkdir -p "${CASTLE_HOME}/artifacts/content"
|
||||
mkdir -p "${CASTLE_HOME}/secrets" && chmod 700 "${CASTLE_HOME}/secrets"
|
||||
# ~/.wildpc tree — globals (wildpc.yaml) plus one file per program/deployment.
|
||||
mkdir -p "${WILDPC_HOME}/programs"
|
||||
mkdir -p "${WILDPC_HOME}/deployments"
|
||||
mkdir -p "${WILDPC_HOME}/artifacts/specs"
|
||||
mkdir -p "${WILDPC_HOME}/artifacts/content"
|
||||
mkdir -p "${WILDPC_HOME}/secrets" && chmod 700 "${WILDPC_HOME}/secrets"
|
||||
|
||||
# Program data volume (default /data/castle) lives outside $HOME, so on a fresh
|
||||
# Program data volume (default /data/wildpc) lives outside $HOME, so on a fresh
|
||||
# machine its parent may not be user-writable — fall back to sudo + chown so the
|
||||
# later container mounts (and castle apply) can write there.
|
||||
# later container mounts (and wildpc apply) can write there.
|
||||
if ! mkdir -p "${DATA_DIR}" 2>/dev/null; then
|
||||
log_info "creating ${DATA_DIR} (needs sudo — outside \$HOME)"
|
||||
sudo mkdir -p "${DATA_DIR}"
|
||||
sudo chown "$(id -un):$(id -gn)" "${DATA_DIR}"
|
||||
fi
|
||||
|
||||
# Seed a minimal global castle.yaml — never clobber an existing one.
|
||||
if [[ -f "${CASTLE_HOME}/castle.yaml" ]]; then
|
||||
# Seed a minimal global wildpc.yaml — never clobber an existing one.
|
||||
if [[ -f "${WILDPC_HOME}/wildpc.yaml" ]]; then
|
||||
log_ok
|
||||
else
|
||||
printf 'gateway:\n port: 9000\n' > "${CASTLE_HOME}/castle.yaml"
|
||||
log_ok "seeded ~/.castle/castle.yaml"
|
||||
printf 'gateway:\n port: 9000\n' > "${WILDPC_HOME}/wildpc.yaml"
|
||||
log_ok "seeded ~/.wildpc/wildpc.yaml"
|
||||
fi
|
||||
|
||||
# Persist the chosen roots into castle.yaml so every later `castle` (CLI, in the
|
||||
# shell) and `castle-api` (service) invocation resolves the SAME dirs from the file
|
||||
# Persist the chosen roots into wildpc.yaml so every later `wildpc` (CLI, in the
|
||||
# shell) and `wildpc-api` (service) invocation resolves the SAME dirs from the file
|
||||
# — not from a per-process env var that only one of them happens to have. Only when
|
||||
# non-default, to keep the file minimal; idempotent (grep-guarded), like repo: below.
|
||||
if [ "${DATA_DIR}" != "/data/castle" ]; then
|
||||
grep -q "^data_dir:" "${CASTLE_HOME}/castle.yaml" 2>/dev/null \
|
||||
|| printf 'data_dir: %s\n' "${DATA_DIR}" >> "${CASTLE_HOME}/castle.yaml"
|
||||
if [ "${DATA_DIR}" != "/data/wildpc" ]; then
|
||||
grep -q "^data_dir:" "${WILDPC_HOME}/wildpc.yaml" 2>/dev/null \
|
||||
|| printf 'data_dir: %s\n' "${DATA_DIR}" >> "${WILDPC_HOME}/wildpc.yaml"
|
||||
fi
|
||||
if [ "${REPOS_DIR}" != "/data/repos" ]; then
|
||||
grep -q "^repos_dir:" "${CASTLE_HOME}/castle.yaml" 2>/dev/null \
|
||||
|| printf 'repos_dir: %s\n' "${REPOS_DIR}" >> "${CASTLE_HOME}/castle.yaml"
|
||||
grep -q "^repos_dir:" "${WILDPC_HOME}/wildpc.yaml" 2>/dev/null \
|
||||
|| printf 'repos_dir: %s\n' "${REPOS_DIR}" >> "${WILDPC_HOME}/wildpc.yaml"
|
||||
fi
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Control plane (Castle's own gateway + API + dashboard)
|
||||
# Control plane (Wild PC's own gateway + API + dashboard)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Register Castle's own control-plane programs/deployments from bootstrap/ so a
|
||||
# fresh registry is not empty. Without this, `castle apply`
|
||||
# Register Wild PC's own control-plane programs/deployments from bootstrap/ so a
|
||||
# fresh registry is not empty. Without this, `wildpc apply`
|
||||
# would bring up nothing. Never clobbers existing entries (idempotent). The
|
||||
# gateway deployment carries a `__SPECS_DIR__` placeholder (the source repo has
|
||||
# no machine-specific paths) that we substitute with this machine's specs dir.
|
||||
seed_control_plane() {
|
||||
log_step "Registering Castle's control plane"
|
||||
local specs="${CASTLE_HOME}/artifacts/specs"
|
||||
log_step "Registering Wild PC's control plane"
|
||||
local specs="${WILDPC_HOME}/artifacts/specs"
|
||||
|
||||
# The `repo:` field lets `source: repo:<name>` resolve castle's own programs.
|
||||
if ! grep -q "^repo:" "${CASTLE_HOME}/castle.yaml" 2>/dev/null; then
|
||||
printf 'repo: %s\n' "$CASTLE_ROOT" >> "${CASTLE_HOME}/castle.yaml"
|
||||
# The `repo:` field lets `source: repo:<name>` resolve wildpc's own programs.
|
||||
if ! grep -q "^repo:" "${WILDPC_HOME}/wildpc.yaml" 2>/dev/null; then
|
||||
printf 'repo: %s\n' "$WILDPC_ROOT" >> "${WILDPC_HOME}/wildpc.yaml"
|
||||
fi
|
||||
|
||||
local seeded=0 f dst rel
|
||||
for f in "${CASTLE_ROOT}"/bootstrap/programs/*.yaml; do
|
||||
dst="${CASTLE_HOME}/programs/$(basename "$f")"
|
||||
for f in "${WILDPC_ROOT}"/bootstrap/programs/*.yaml; do
|
||||
dst="${WILDPC_HOME}/programs/$(basename "$f")"
|
||||
[ -f "$dst" ] || { cp "$f" "$dst"; seeded=1; }
|
||||
done
|
||||
# Deployments are seeded into the per-kind layout (deployments/<kind>/<name>.yaml),
|
||||
# mirroring bootstrap/deployments/<kind>/ — the shape the loader reads.
|
||||
for f in "${CASTLE_ROOT}"/bootstrap/deployments/*/*.yaml; do
|
||||
rel="${f#"${CASTLE_ROOT}"/bootstrap/deployments/}"
|
||||
dst="${CASTLE_HOME}/deployments/${rel}"
|
||||
for f in "${WILDPC_ROOT}"/bootstrap/deployments/*/*.yaml; do
|
||||
rel="${f#"${WILDPC_ROOT}"/bootstrap/deployments/}"
|
||||
dst="${WILDPC_HOME}/deployments/${rel}"
|
||||
mkdir -p "$(dirname "$dst")"
|
||||
[ -f "$dst" ] || { sed "s#__SPECS_DIR__#${specs}#g" "$f" > "$dst"; seeded=1; }
|
||||
done
|
||||
|
||||
if [ "$seeded" = "1" ]; then
|
||||
log_ok "castle-gateway, castle-api, castle (dashboard)"
|
||||
log_ok "wildpc-gateway, wildpc-api, wildpc (dashboard)"
|
||||
else
|
||||
log_skip "already registered"
|
||||
fi
|
||||
@@ -392,26 +392,26 @@ enable_lingering() {
|
||||
|
||||
seed_caddyfile() {
|
||||
log_step "Seeding Caddyfile"
|
||||
local caddyfile="${CASTLE_HOME}/artifacts/specs/Caddyfile"
|
||||
local caddyfile="${WILDPC_HOME}/artifacts/specs/Caddyfile"
|
||||
if [ -f "$caddyfile" ]; then
|
||||
log_skip "already exists"
|
||||
return
|
||||
fi
|
||||
cat > "$caddyfile" << 'EOF'
|
||||
:9000 {
|
||||
respond "Castle is starting. Run 'castle apply' to configure." 200
|
||||
respond "Wild PC is starting. Run 'wildpc apply' to configure." 200
|
||||
}
|
||||
EOF
|
||||
log_ok
|
||||
}
|
||||
|
||||
seed_mosquitto_config() {
|
||||
local conf="${DATA_DIR}/castle-mqtt/config/mosquitto.conf"
|
||||
local conf="${DATA_DIR}/wildpc-mqtt/config/mosquitto.conf"
|
||||
if [ -f "$conf" ]; then
|
||||
return
|
||||
fi
|
||||
mkdir -p "${DATA_DIR}/castle-mqtt/config"
|
||||
mkdir -p "${DATA_DIR}/castle-mqtt/data"
|
||||
mkdir -p "${DATA_DIR}/wildpc-mqtt/config"
|
||||
mkdir -p "${DATA_DIR}/wildpc-mqtt/data"
|
||||
cat > "$conf" << 'EOF'
|
||||
listener 1883
|
||||
allow_anonymous true
|
||||
@@ -425,13 +425,13 @@ EOF
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
migrate_old_containers() {
|
||||
# castle-eclipse-mosquitto → castle-mqtt
|
||||
if docker inspect castle-eclipse-mosquitto &>/dev/null 2>&1; then
|
||||
log_step "Migrating castle-eclipse-mosquitto → castle-mqtt"
|
||||
docker stop castle-eclipse-mosquitto 2>/dev/null || true
|
||||
docker rm castle-eclipse-mosquitto 2>/dev/null || true
|
||||
systemctl --user stop castle-castle-mqtt.service 2>/dev/null || true
|
||||
systemctl --user disable castle-castle-mqtt.service 2>/dev/null || true
|
||||
# wildpc-eclipse-mosquitto → wildpc-mqtt
|
||||
if docker inspect wildpc-eclipse-mosquitto &>/dev/null 2>&1; then
|
||||
log_step "Migrating wildpc-eclipse-mosquitto → wildpc-mqtt"
|
||||
docker stop wildpc-eclipse-mosquitto 2>/dev/null || true
|
||||
docker rm wildpc-eclipse-mosquitto 2>/dev/null || true
|
||||
systemctl --user stop wildpc-wildpc-mqtt.service 2>/dev/null || true
|
||||
systemctl --user disable wildpc-wildpc-mqtt.service 2>/dev/null || true
|
||||
log_ok
|
||||
fi
|
||||
}
|
||||
@@ -446,7 +446,7 @@ migrate_old_containers() {
|
||||
# - Ask user or auto-provision
|
||||
provision_service() {
|
||||
local name="$1" # e.g. MQTT
|
||||
local container="$2" # e.g. castle-mqtt
|
||||
local container="$2" # e.g. wildpc-mqtt
|
||||
local port="$3" # e.g. 1883
|
||||
local display="$4" # e.g. "MQTT"
|
||||
shift 4
|
||||
@@ -478,7 +478,7 @@ provision_service() {
|
||||
|
||||
# No previous choice, no existing container — detect and ask
|
||||
if port_in_use "$port"; then
|
||||
log_info "Detected: port ${port} is already in use (not a castle container)"
|
||||
log_info "Detected: port ${port} is already in use (not a wildpc container)"
|
||||
if ask_yes_no "Use existing ${display} server?"; then
|
||||
conf_set "$name" "existing"
|
||||
log_ok "using existing ${display} on localhost:${port}"
|
||||
@@ -497,16 +497,16 @@ provision_service() {
|
||||
|
||||
setup_mqtt() {
|
||||
seed_mosquitto_config
|
||||
provision_service "MQTT" "castle-mqtt" "$MQTT_PORT" "MQTT" \
|
||||
provision_service "MQTT" "wildpc-mqtt" "$MQTT_PORT" "MQTT" \
|
||||
-p "${MQTT_PORT}:1883" \
|
||||
-v "${DATA_DIR}/castle-mqtt/config:/mosquitto/config" \
|
||||
-v "${DATA_DIR}/castle-mqtt/data:/mosquitto/data" \
|
||||
-v "${DATA_DIR}/wildpc-mqtt/config:/mosquitto/config" \
|
||||
-v "${DATA_DIR}/wildpc-mqtt/data:/mosquitto/data" \
|
||||
"$MQTT_IMAGE"
|
||||
}
|
||||
|
||||
setup_postgres() {
|
||||
# Ensure password exists
|
||||
local pass_file="${CASTLE_HOME}/secrets/POSTGRES_PASSWORD"
|
||||
local pass_file="${WILDPC_HOME}/secrets/POSTGRES_PASSWORD"
|
||||
if [ ! -f "$pass_file" ]; then
|
||||
openssl rand -base64 24 > "$pass_file"
|
||||
chmod 600 "$pass_file"
|
||||
@@ -516,11 +516,11 @@ setup_postgres() {
|
||||
|
||||
mkdir -p "${DATA_DIR}/postgres/data"
|
||||
|
||||
provision_service "POSTGRES" "castle-postgres" "$POSTGRES_PORT" "Postgres" \
|
||||
provision_service "POSTGRES" "wildpc-postgres" "$POSTGRES_PORT" "Postgres" \
|
||||
-p "${POSTGRES_PORT}:5432" \
|
||||
-e "POSTGRES_USER=castle" \
|
||||
-e "POSTGRES_USER=wildpc" \
|
||||
-e "POSTGRES_PASSWORD=${pg_pass}" \
|
||||
-e "POSTGRES_DB=castle" \
|
||||
-e "POSTGRES_DB=wildpc" \
|
||||
-v "${DATA_DIR}/postgres/data:/var/lib/postgresql/data" \
|
||||
"$POSTGRES_IMAGE"
|
||||
}
|
||||
@@ -529,7 +529,7 @@ setup_neo4j() {
|
||||
mkdir -p "${DATA_DIR}/neo4j/data"
|
||||
mkdir -p "${DATA_DIR}/neo4j/logs"
|
||||
|
||||
provision_service "NEO4J" "castle-neo4j" "$NEO4J_BOLT_PORT" "Neo4j" \
|
||||
provision_service "NEO4J" "wildpc-neo4j" "$NEO4J_BOLT_PORT" "Neo4j" \
|
||||
-p "${NEO4J_HTTP_PORT}:7474" \
|
||||
-p "${NEO4J_BOLT_PORT}:7687" \
|
||||
-e "NEO4J_AUTH=neo4j/changeme" \
|
||||
@@ -565,20 +565,20 @@ maybe_setup_neo4j() {
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Build the dashboard SPA so the gateway has something to serve at :9000. The
|
||||
# `castle` program serves `app/dist/` in place; without a build there's no UI.
|
||||
# `wildpc` program serves `app/dist/` in place; without a build there's no UI.
|
||||
# Best-effort: a missing pnpm is a warning (the CLI/API still work), not a failure.
|
||||
build_dashboard() {
|
||||
log_step "Building the dashboard"
|
||||
if [ ! -d "${CASTLE_ROOT}/app" ]; then
|
||||
if [ ! -d "${WILDPC_ROOT}/app" ]; then
|
||||
log_skip "no app/ directory"
|
||||
return
|
||||
fi
|
||||
if ! cmd_exists pnpm; then
|
||||
log_skip "pnpm not found — build later with 'castle program build castle'"
|
||||
log_skip "pnpm not found — build later with 'wildpc program build wildpc'"
|
||||
return
|
||||
fi
|
||||
( cd "${CASTLE_ROOT}/app" && pnpm install --silent >/dev/null 2>&1 && pnpm build >/dev/null 2>&1 ) \
|
||||
|| { log_skip "build failed — retry later with 'castle program build castle'"; return; }
|
||||
( cd "${WILDPC_ROOT}/app" && pnpm install --silent >/dev/null 2>&1 && pnpm build >/dev/null 2>&1 ) \
|
||||
|| { log_skip "build failed — retry later with 'wildpc program build wildpc'"; return; }
|
||||
log_ok "app/dist/"
|
||||
}
|
||||
|
||||
@@ -588,7 +588,7 @@ build_dashboard() {
|
||||
|
||||
print_summary() {
|
||||
printf "\n${_bold}========================================${_reset}\n"
|
||||
printf "${_bold}Castle bootstrap complete!${_reset}\n"
|
||||
printf "${_bold}Wild PC bootstrap complete!${_reset}\n"
|
||||
printf "${_bold}========================================${_reset}\n\n"
|
||||
|
||||
printf "Infrastructure:\n"
|
||||
@@ -607,16 +607,16 @@ print_summary() {
|
||||
printf "\n"
|
||||
|
||||
printf "Directories:\n"
|
||||
printf " %-20s %s\n" "Castle home" "$CASTLE_HOME"
|
||||
printf " %-20s %s\n" "Wild PC home" "$WILDPC_HOME"
|
||||
printf " %-20s %s\n" "Repos" "$REPOS_DIR"
|
||||
printf " %-20s %s\n" "Artifacts" "${CASTLE_HOME}/artifacts"
|
||||
printf " %-20s %s\n" "Artifacts" "${WILDPC_HOME}/artifacts"
|
||||
printf " %-20s %s\n" "Data" "$DATA_DIR"
|
||||
printf " %-20s %s\n" "Secrets" "${CASTLE_HOME}/secrets"
|
||||
printf " %-20s %s\n" "Secrets" "${WILDPC_HOME}/secrets"
|
||||
printf "\n"
|
||||
|
||||
printf "Next steps:\n"
|
||||
printf " castle apply # Converge: render units/routes + start everything\n"
|
||||
printf " castle doctor # Verify setup + health (green = good to go)\n"
|
||||
printf " wildpc apply # Converge: render units/routes + start everything\n"
|
||||
printf " wildpc doctor # Verify setup + health (green = good to go)\n"
|
||||
printf " open http://localhost:9000 # the dashboard\n"
|
||||
}
|
||||
|
||||
@@ -626,7 +626,7 @@ print_summary() {
|
||||
|
||||
main() {
|
||||
printf "${_bold}========================================${_reset}\n"
|
||||
printf "${_bold}Castle Platform — Bootstrap Install${_reset}\n"
|
||||
printf "${_bold}Wild PC Platform — Bootstrap Install${_reset}\n"
|
||||
printf "${_bold}========================================${_reset}\n"
|
||||
|
||||
# Parse args
|
||||
|
||||
Reference in New Issue
Block a user