Supply-Chain-Scan (Go) / govulncheck (push) Canceled after 0s
deploy/install.sh: idempotenter Installer fuer Debian/systemd. Legt Systembenutzer 'nexarch', Postgres-Rolle+Registry-DB an, baut alle 7 Core-Binaries (cmd/core + *-devserver), wendet Registry-Migrationen an (nur bei leerer DB), generiert Secrets (Audit-Admin-Token, Ed25519- Lizenzschluesselpaar) nach /etc/nexarch/core.env (0600), installiert und startet je Dienst einen systemd-Service. Tatsaechlich auf 192.168.1.131 ausgefuehrt und verifiziert: alle 7 Dienste laufen (systemctl active), alle Health-Endpunkte antworten 200. Zweiter Installer-Lauf bestaetigt Idempotenz (ueberspringt bestehende Rolle/DB/ Secrets/Migrationen, Dienste bleiben durchgehend aktiv). Hinweis: kein unified Server (siehe QA-05/AUD-06-Befund) - weiterhin 7 getrennte Binaries/Ports, dieser Installer deployt sie so wie sie sind. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HhgFcLS8tYMhDJpP74C6AQ
151 lines
6.4 KiB
Bash
Executable File
151 lines
6.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# NEXARCH Core – Installer/Deployer fuer eine Debian/systemd-Zielumgebung.
|
||
#
|
||
# Baut alle Core-Binaries (cmd/core + die *-devserver), legt Postgres-Rolle
|
||
# und Registry-Datenbank an (falls nicht vorhanden), wendet die
|
||
# Registry-Migrationen an, generiert Secrets (falls nicht vorhanden) und
|
||
# installiert+startet jeden Dienst als eigenen systemd-Service.
|
||
#
|
||
# Idempotent: mehrfacher Aufruf ist sicher — vorhandene Rolle/DB/Secrets
|
||
# werden nicht ueberschrieben, Migrationen nur angewendet, wenn die
|
||
# Registry-DB noch leer ist (siehe Abschnitt "Migrationen" unten).
|
||
#
|
||
# Aufruf (als root): ./deploy/install.sh
|
||
#
|
||
# Ueberschreibbar per Umgebungsvariable:
|
||
# NEXARCH_INSTALL_DIR (Default: /opt/nexarch-core)
|
||
# NEXARCH_PG_ROLE (Default: nexarch_core)
|
||
# NEXARCH_PG_REGISTRY_DB (Default: nexarch_registry)
|
||
# NEXARCH_BRANCH (Default: aktueller Branch dieses Checkouts)
|
||
set -euo pipefail
|
||
|
||
INSTALL_DIR="${NEXARCH_INSTALL_DIR:-/opt/nexarch-core}"
|
||
PG_ROLE="${NEXARCH_PG_ROLE:-nexarch_core}"
|
||
PG_DB="${NEXARCH_PG_REGISTRY_DB:-nexarch_registry}"
|
||
ENV_FILE=/etc/nexarch/core.env
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||
|
||
if [ "$(id -u)" -ne 0 ]; then
|
||
echo "Bitte als root ausfuehren (legt Systembenutzer, systemd-Units und Postgres-Rolle an)." >&2
|
||
exit 1
|
||
fi
|
||
|
||
echo "== 1. Systembenutzer =="
|
||
if ! id nexarch >/dev/null 2>&1; then
|
||
useradd --system --no-create-home --shell /usr/sbin/nologin nexarch
|
||
echo "Benutzer 'nexarch' angelegt."
|
||
else
|
||
echo "Benutzer 'nexarch' existiert bereits."
|
||
fi
|
||
|
||
echo "== 2. Postgres-Rolle und Registry-Datenbank =="
|
||
if ! sudo -u postgres psql -tAc "SELECT 1 FROM pg_roles WHERE rolname = '${PG_ROLE}'" | grep -q 1; then
|
||
PG_PASSWORD="$(openssl rand -hex 24)"
|
||
sudo -u postgres psql -v ON_ERROR_STOP=1 -c "CREATE ROLE ${PG_ROLE} WITH LOGIN PASSWORD '${PG_PASSWORD}';"
|
||
echo "Rolle '${PG_ROLE}' angelegt."
|
||
else
|
||
echo "Rolle '${PG_ROLE}' existiert bereits — Passwort wird NICHT neu gesetzt (siehe ${ENV_FILE} fuer das vorhandene)."
|
||
PG_PASSWORD=""
|
||
fi
|
||
|
||
if ! sudo -u postgres psql -tAc "SELECT 1 FROM pg_database WHERE datname = '${PG_DB}'" | grep -q 1; then
|
||
sudo -u postgres psql -v ON_ERROR_STOP=1 -c "CREATE DATABASE ${PG_DB} OWNER ${PG_ROLE};"
|
||
echo "Datenbank '${PG_DB}' angelegt."
|
||
else
|
||
echo "Datenbank '${PG_DB}' existiert bereits."
|
||
fi
|
||
# Fuer Tenant-Provisioning (CREATE DATABASE pro Mandant, Modell C) braucht
|
||
# die Rolle CREATEDB-Recht auf der physischen Postgres-Instanz.
|
||
sudo -u postgres psql -v ON_ERROR_STOP=1 -c "ALTER ROLE ${PG_ROLE} WITH CREATEDB;" >/dev/null
|
||
|
||
echo "== 3. Secrets/Konfiguration =="
|
||
mkdir -p /etc/nexarch
|
||
if [ ! -f "$ENV_FILE" ]; then
|
||
if [ -z "${PG_PASSWORD}" ]; then
|
||
echo "FEHLER: Rolle existierte bereits, aber ${ENV_FILE} fehlt — Passwort kann nicht rekonstruiert werden." >&2
|
||
echo "Entweder ${ENV_FILE} von Hand mit dem bekannten Passwort anlegen, oder die Rolle droppen und erneut installieren." >&2
|
||
exit 1
|
||
fi
|
||
|
||
AUDIT_ADMIN_TOKEN="$(openssl rand -hex 32)"
|
||
|
||
# Ed25519-Schluesselpaar fuer die Lizenzsignatur (LIC-01/LIC-04):
|
||
# licadmin-devserver prueft Lizenzen nur mit dem OEFFENTLICHEN Schluessel,
|
||
# der private Schluessel wird NICHT deployt, sondern separat fuer das
|
||
# (noch zu bauende) offline Lizenz-Ausstellungswerkzeug aufbewahrt.
|
||
KEYPAIR_DIR=/etc/nexarch/license-signing
|
||
mkdir -p "$KEYPAIR_DIR"
|
||
chmod 700 "$KEYPAIR_DIR"
|
||
if [ ! -f "$KEYPAIR_DIR/private.b64" ]; then
|
||
go run "$SCRIPT_DIR/gen-ed25519-keypair.go" > "$KEYPAIR_DIR/keypair.txt"
|
||
grep '^PRIVATE=' "$KEYPAIR_DIR/keypair.txt" | cut -d= -f2 > "$KEYPAIR_DIR/private.b64"
|
||
grep '^PUBLIC=' "$KEYPAIR_DIR/keypair.txt" | cut -d= -f2 > "$KEYPAIR_DIR/public.b64"
|
||
chmod 600 "$KEYPAIR_DIR"/*.b64 "$KEYPAIR_DIR/keypair.txt"
|
||
rm -f "$KEYPAIR_DIR/keypair.txt"
|
||
fi
|
||
LICENSE_PUBLIC_KEY="$(cat "$KEYPAIR_DIR/public.b64")"
|
||
|
||
cat > "$ENV_FILE" <<EOF
|
||
# Automatisch generiert von deploy/install.sh am $(date -Iseconds).
|
||
# NICHT ins Repository committen — enthaelt Zugangsdaten/Secrets.
|
||
NEXARCH_REGISTRY_DSN=postgresql://${PG_ROLE}:${PG_PASSWORD}@localhost:5432/${PG_DB}?sslmode=disable
|
||
NEXARCH_ADMIN_DSN=postgresql://${PG_ROLE}:${PG_PASSWORD}@localhost:5432/postgres?sslmode=disable
|
||
NEXARCH_TENANT_DSN_TEMPLATE=postgresql://${PG_ROLE}:${PG_PASSWORD}@localhost:5432/%s?sslmode=disable
|
||
NEXARCH_TENANT_SCHEMA_PATH=${INSTALL_DIR}/migrations/tenant
|
||
NEXARCH_LISTEN_ADDR=:8080
|
||
NEXARCH_AUDIT_ADMIN_TOKEN=${AUDIT_ADMIN_TOKEN}
|
||
NEXARCH_LICENSE_PUBLIC_KEY=${LICENSE_PUBLIC_KEY}
|
||
EOF
|
||
chmod 600 "$ENV_FILE"
|
||
chown nexarch:nexarch "$ENV_FILE"
|
||
echo "${ENV_FILE} angelegt (Secrets generiert)."
|
||
else
|
||
echo "${ENV_FILE} existiert bereits — wird nicht ueberschrieben."
|
||
fi
|
||
|
||
echo "== 4. Build =="
|
||
mkdir -p "$INSTALL_DIR/bin"
|
||
cd "$REPO_ROOT"
|
||
for svc in core auditlog-devserver licadmin-devserver metrics-devserver secheaders-devserver statuspage-devserver tenantadmin-devserver; do
|
||
go build -o "$INSTALL_DIR/bin/${svc}" "./cmd/${svc}"
|
||
echo "gebaut: ${svc}"
|
||
done
|
||
cp -r migrations "$INSTALL_DIR/migrations"
|
||
chown -R nexarch:nexarch "$INSTALL_DIR"
|
||
|
||
echo "== 5. Registry-Migrationen =="
|
||
# shellcheck disable=SC1090
|
||
source "$ENV_FILE"
|
||
ALREADY_MIGRATED=$(sudo -u postgres psql -tAc "SELECT to_regclass('public.tenants') IS NOT NULL" -d "${PG_DB}")
|
||
if [ "$ALREADY_MIGRATED" = "t" ]; then
|
||
echo "Registry-Datenbank hat bereits Tabellen — Migrationen werden uebersprungen (nicht idempotent, siehe Skript-Kommentar)."
|
||
else
|
||
for f in $(find "$INSTALL_DIR/migrations" -maxdepth 1 -name '*.up.sql' | sort); do
|
||
sudo -u postgres psql -v ON_ERROR_STOP=1 -d "${PG_DB}" -f "$f" >/dev/null
|
||
echo "angewendet: $(basename "$f")"
|
||
done
|
||
fi
|
||
|
||
echo "== 6. systemd-Units =="
|
||
for tmpl in "$SCRIPT_DIR"/systemd/*.service.tmpl; do
|
||
name="$(basename "$tmpl" .service.tmpl)"
|
||
sed "s#__INSTALL_DIR__#${INSTALL_DIR}#g" "$tmpl" > "/etc/systemd/system/${name}.service"
|
||
done
|
||
systemctl daemon-reload
|
||
for tmpl in "$SCRIPT_DIR"/systemd/*.service.tmpl; do
|
||
name="$(basename "$tmpl" .service.tmpl)"
|
||
systemctl enable --now "${name}.service"
|
||
done
|
||
|
||
echo "== Fertig =="
|
||
echo "Status pruefen mit: systemctl status 'nexarch-*'"
|
||
echo "Health-Checks:"
|
||
echo " curl -s http://localhost:8080/healthz"
|
||
echo " curl -s http://localhost:8081/healthz # licadmin"
|
||
echo " curl -s http://localhost:8082/healthz # tenantadmin"
|
||
echo " curl -s http://localhost:8083/healthz # auditlog"
|
||
echo " curl -s http://localhost:8084/healthz # statuspage"
|
||
echo " curl -s http://localhost:8085/healthz # metrics"
|
||
echo " curl -s http://localhost:8086/unprotected # secheaders (kein /healthz)"
|