Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
95b83bc70a | ||
|
|
f708d0ea87 |
No files matched your search
@@ -49,7 +49,7 @@ import (
|
||||
|
||||
const workerPollInterval = 2 * time.Second
|
||||
|
||||
const defaultListenAddr = "127.0.0.1:9600"
|
||||
const defaultListenAddr = "127.0.0.1:8900"
|
||||
const defaultModel = "default"
|
||||
|
||||
type config struct {
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// Command migrate wendet die offenen Postgres-Migrationen des AI-Moduls an.
|
||||
// Einmal gegen eine frische Datenbank ausfuehren, bevor ai-app startet.
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
|
||||
"gitea.perlbach24.de/scripte/nexarch/ai/internal/migrate"
|
||||
)
|
||||
|
||||
func main() {
|
||||
dsn := os.Getenv("NEXARCH_AI_APP_TENANT_DSN")
|
||||
if dsn == "" {
|
||||
log.Fatal("migrate: NEXARCH_AI_APP_TENANT_DSN ist erforderlich")
|
||||
}
|
||||
dir := "migrations"
|
||||
if len(os.Args) > 1 {
|
||||
dir = os.Args[1]
|
||||
}
|
||||
ctx := context.Background()
|
||||
pool, err := pgxpool.New(ctx, dsn)
|
||||
if err != nil {
|
||||
log.Fatalf("migrate: datenbankverbindung: %v", err)
|
||||
}
|
||||
defer pool.Close()
|
||||
|
||||
migrations, err := migrate.Load(dir)
|
||||
if err != nil {
|
||||
log.Fatalf("migrate: migrationen laden: %v", err)
|
||||
}
|
||||
applied, err := migrate.Up(ctx, pool, migrations)
|
||||
if err != nil {
|
||||
log.Fatalf("migrate: migrationen anwenden: %v", err)
|
||||
}
|
||||
log.Printf("migrate: %d migration(en) angewendet", len(applied))
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
# Betrieb: ai-app
|
||||
|
||||
Port-Bereich 8900 bis 8999 (`deploy/ports.tsv`), Routenpräfix `/api/ai/v1` (`deploy/routes.tsv`). Secrets gehören ausschließlich in die Umgebung (`/etc/nexarch/ai-app.env`, Rechte 600), nie in Code, Logs oder Dokumentation.
|
||||
|
||||
## Einrichten
|
||||
|
||||
1. Datenbank und Rolle anlegen (nicht Teil der Units).
|
||||
2. `/etc/nexarch/ai-app.env` mit den Variablen unten anlegen.
|
||||
3. Migrationen anwenden: `NEXARCH_AI_APP_TENANT_DSN=... ./migrate ai/migrations` (Fortschrittstabelle `ai_schema_migrations`).
|
||||
4. Unit aus `deploy/systemd/nexarch-ai-app.service.tmpl` installieren (`__INSTALL_DIR__` ersetzen), `systemctl enable --now nexarch-ai-app`.
|
||||
5. Health: `GET /healthz`.
|
||||
|
||||
Eine Datenbank, die vor ENG-10 mit den AI-Migrationen angelegt wurde, führte den Fortschritt in `connect_schema_migrations`. Ist sie ausschließlich AI-Datenbank, vor dem ersten Lauf `ALTER TABLE connect_schema_migrations RENAME TO ai_schema_migrations;`. Bei gemeinsamer Datenbank mit Connect nicht umbenennen, sondern die AI-Einträge von Hand in die neue Tabelle übertragen.
|
||||
|
||||
## Variablen
|
||||
|
||||
| Variable | Standard | Wirkung |
|
||||
|---|---|---|
|
||||
| `NEXARCH_AI_APP_TENANT_DSN` | Pflicht | Datenbank des AI-Moduls |
|
||||
| `NEXARCH_AI_APP_SERVICE_TOKEN` | Pflicht | Service-Token, das alle Aufrufer im Header `X-Service-Token` senden |
|
||||
| `NEXARCH_AI_APP_LISTEN_ADDR` | `127.0.0.1:8900` | Lauschadresse |
|
||||
| `NEXARCH_AI_APP_MODEL` | `default` | Modellname für Inferenzaufrufe |
|
||||
| `NEXARCH_AI_APP_POLICY_URL` / `_POLICY_SERVICE_TOKEN` | Pflicht, oder Übergangsschalter | Rechteprüfung der semantischen Suche; Token Pflicht, sobald URL gesetzt |
|
||||
| `NEXARCH_AI_APP_POLICY_DISABLED` | aus | `1` startet ohne Rechteprüfung (Übergang, Warnlog) |
|
||||
| `NEXARCH_AI_APP_MODULE_BASE_URLS` | leer | `modul=url,modul2=url2`, Basis-URLs für den Rückschreib-Push |
|
||||
| `NEXARCH_AI_APP_CORE_BASE_URL` / `_CORE_SERVICE_TOKEN` | leer | Core-Anbindung; ohne sie ist die Objekttyp-Registrierung (GOV-01) deaktiviert |
|
||||
@@ -0,0 +1,40 @@
|
||||
# ENG-10 – ai-app: Deployment-Anbindung – Prüfprotokoll
|
||||
|
||||
Datum: 2026-11-06. Host: Entwicklungshost 192.168.1.204 (Wegwerf-Rolle/DB `eng10_test`, nach Abschluss entfernt).
|
||||
|
||||
## Befund (Ausgangslage)
|
||||
|
||||
- `ai-app` lauschte standardmäßig auf `127.0.0.1:9600`, außerhalb des für `ai` reservierten Bereichs 8900 bis 8999 (`deploy/ports.tsv`). 9600 belegt außerdem `workflow-app` (`docs/BETRIEB-PORTAL.md`). `scripts/check-port-defaults.sh` erkennt nur `":NNNN"`-Literale und meldete den Verstoß nicht.
|
||||
- Kein systemd-Template für `ai-app` (Connect und DMS haben eines).
|
||||
- Kein Migrationswerkzeug für das AI-Modul; `ai/internal/migrate` führte den Fortschritt in der Tabelle `connect_schema_migrations` (Kopierfehler aus dem Connect-Modul).
|
||||
|
||||
## Umsetzung
|
||||
|
||||
- Standard-Lauschadresse `127.0.0.1:8900`.
|
||||
- `ai/cmd/migrate` (Muster `connect/cmd/migrate`, DSN aus `NEXARCH_AI_APP_TENANT_DSN`, Verzeichnis als Argument).
|
||||
- Fortschrittstabelle `ai_schema_migrations`.
|
||||
- `deploy/systemd/nexarch-ai-app.service.tmpl` nach dem Muster von `nexarch-connect-app` (gleiche Härtung).
|
||||
- `ai/docs/BETRIEB-UMGEBUNGSVARIABLEN.md` mit Einrichtungsschritten und Variablen.
|
||||
|
||||
## Akzeptanzkriterien
|
||||
|
||||
| # | Kriterium | Ergebnis |
|
||||
|---|---|---|
|
||||
| 1 | Standard-Port liegt im Bereich von `ai` | **Erfüllt.** 8900. `scripts/check-port-defaults.sh` meldet für `ai/cmd/ai-app` nichts (dort erkennt es allerdings das Format `127.0.0.1:NNNN` ohnehin nicht, siehe Einschränkungen). |
|
||||
| 2 | systemd-Template vorhanden und gehärtet | **Erfüllt.** `scripts/check-systemd-hardening.sh`: ok, 18 Dienste geprüft. Start der Unit selbst nicht getestet. |
|
||||
| 3 | Migrationen anwendbar, idempotent | **Erfüllt.** Frische DB: 16 Migrationen angewendet, zweiter Lauf 0; ohne DSN klare Fehlermeldung, Abbruch. |
|
||||
| 4 | Eigene Fortschrittstabelle | **Erfüllt.** `ai_schema_migrations` existiert, `connect_schema_migrations` nicht (`TestUp_UsesOwnTrackingTable`, echte DB). |
|
||||
|
||||
## Prüfungen vor der Abnahme
|
||||
|
||||
| # | Prüfung | Ergebnis |
|
||||
|---|---|---|
|
||||
| 1 | Migrationswerkzeug gegen frische Wegwerf-DB | **Bestanden** (siehe AK3). |
|
||||
| 2 | Bestehende Modultests | **Bestanden.** `./internal/migrate/`, `./cmd/ai-app/` grün, `go build ./...` und `go vet` sauber. |
|
||||
| 3 | Unit startet `ai-app` real | **Offen.** Template nicht auf einem Host installiert, `systemctl` nicht ausgeführt. |
|
||||
|
||||
## Einschränkungen
|
||||
|
||||
- Umbenennung der Fortschrittstabelle betrifft bestehende AI-Datenbanken; Hinweis in `BETRIEB-UMGEBUNGSVARIABLEN.md`. Eine automatische Übernahme gibt es nicht.
|
||||
- Nicht Teil der Kachel: Aufnahme in `deploy/rollout-131-*.sh` (Host-131-Rollout), Provisionierung von DB, Rolle und Secrets.
|
||||
- Weitere Port-Verstöße außerhalb von `ai`, die beim Prüfen auffielen und nicht behoben wurden: `workflow-app` und `tasks-a11y-fixture` auf 9600 (Bereich 8800 bis 8899), Connect-Fixtures doppelt auf 9500, mehrere Fixtures und `verapdf-sidecar` außerhalb ihrer Bereiche. `check-port-defaults.sh` erkennt `127.0.0.1:NNNN`-Literale nicht; eine Erweiterung würde diese Verstöße sichtbar machen und braucht eine eigene Entscheidung.
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
type Migration = cmigrate.Migration
|
||||
|
||||
const TrackingTable = "connect_schema_migrations"
|
||||
const TrackingTable = "ai_schema_migrations"
|
||||
|
||||
var migrator = cmigrate.MustNew(TrackingTable)
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package migrate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"gitea.perlbach24.de/scripte/nexarch/common/testdb"
|
||||
)
|
||||
|
||||
func TestUp_UsesOwnTrackingTable(t *testing.T) {
|
||||
dsn := os.Getenv("TEST_TENANT_DSN")
|
||||
if dsn == "" {
|
||||
t.Skip("TEST_TENANT_DSN nicht gesetzt, Integrationstest uebersprungen")
|
||||
}
|
||||
pool := testdb.Pool(t, dsn)
|
||||
dir, err := filepath.Abs("../../migrations")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
migrations, err := Load(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ctx := context.Background()
|
||||
if _, err := Up(ctx, pool, migrations); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
again, err := Up(ctx, pool, migrations)
|
||||
if err != nil || len(again) != 0 {
|
||||
t.Fatalf("zweiter lauf soll nichts anwenden: %v %v", again, err)
|
||||
}
|
||||
var own, foreign bool
|
||||
if err := pool.QueryRow(ctx, `SELECT to_regclass('ai_schema_migrations') IS NOT NULL, to_regclass('connect_schema_migrations') IS NOT NULL`).Scan(&own, &foreign); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !own || foreign {
|
||||
t.Fatalf("fortschrittstabelle: ai=%v connect=%v", own, foreign)
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ REPO_DIR="${NEXARCH_ROLLOUT_REPO_DIR:-/root/nexarch-code}"
|
||||
ENV_DIR=/etc/nexarch
|
||||
DMS_INSTALL_DIR="${NEXARCH_DMS_INSTALL_DIR:-/opt/nexarch-dms}"
|
||||
CONNECT_INSTALL_DIR="${NEXARCH_CONNECT_INSTALL_DIR:-/opt/nexarch-connect}"
|
||||
AI_INSTALL_DIR="${NEXARCH_AI_INSTALL_DIR:-/opt/nexarch-ai}"
|
||||
DMS_STORAGE_DIR="${NEXARCH_DMS_STORAGE_DIR:-/var/lib/nexarch-dms/storage}"
|
||||
DMS_STAGING_DIR="${NEXARCH_DMS_STAGING_DIR:-/var/lib/nexarch-dms/staging}"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
@@ -50,10 +51,18 @@ require_set() {
|
||||
return 0
|
||||
}
|
||||
|
||||
echo "== 1. Pruefe die 5 echten TODO-Werte =="
|
||||
echo "== 1. Pruefe die echten TODO-Werte =="
|
||||
missing=0
|
||||
require_set "$ENV_DIR/connect-app.env" NEXARCH_CONNECT_APP_LISTEN_ADDR || missing=1
|
||||
require_set "$ENV_DIR/connect-app.env" NEXARCH_CONNECT_APP_TENANT_DSN || missing=1
|
||||
require_set "$ENV_DIR/ai-app.env" NEXARCH_AI_APP_LISTEN_ADDR || missing=1
|
||||
require_set "$ENV_DIR/ai-app.env" NEXARCH_AI_APP_TENANT_DSN || missing=1
|
||||
require_set "$ENV_DIR/ai-app.env" NEXARCH_AI_APP_SERVICE_TOKEN || missing=1
|
||||
if ! require_set "$ENV_DIR/ai-app.env" NEXARCH_AI_APP_POLICY_URL 2>/dev/null \
|
||||
&& ! grep -q '^NEXARCH_AI_APP_POLICY_DISABLED=1' "$ENV_DIR/ai-app.env" 2>/dev/null; then
|
||||
echo "OFFEN: NEXARCH_AI_APP_POLICY_URL (mit _POLICY_SERVICE_TOKEN) oder NEXARCH_AI_APP_POLICY_DISABLED=1 in $ENV_DIR/ai-app.env" >&2
|
||||
missing=1
|
||||
fi
|
||||
require_set "$ENV_DIR/dms-app.env" NEXARCH_DMS_APP_CORE_SERVICE_TOKEN || missing=1
|
||||
require_set "$ENV_DIR/dms-app.env" NEXARCH_DMS_APP_KEK_CLIENT_ID || missing=1
|
||||
require_set "$ENV_DIR/dms-app.env" NEXARCH_DMS_APP_KEK_CLIENT_SECRET || missing=1
|
||||
@@ -63,10 +72,10 @@ if [ "$missing" -eq 1 ]; then
|
||||
echo "Trage die fehlenden Werte von Hand in die genannten Dateien ein und starte das Skript erneut." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Alle 5 TODO-Werte sind gesetzt."
|
||||
echo "Alle TODO-Werte sind gesetzt."
|
||||
|
||||
echo "== 2. Build (falls rollout-131-sync.sh das noch nicht getan hat) =="
|
||||
for mod in dms connect; do
|
||||
for mod in dms connect ai; do
|
||||
if [ -f "$REPO_DIR/$mod/go.mod" ]; then
|
||||
( cd "$REPO_DIR/$mod" && go build ./... && go vet ./... )
|
||||
echo "gebaut/verifiziert: $mod"
|
||||
@@ -77,14 +86,16 @@ for mod in dms connect; do
|
||||
done
|
||||
|
||||
echo "== 3. Binaries kopieren =="
|
||||
mkdir -p "$DMS_INSTALL_DIR/bin" "$CONNECT_INSTALL_DIR/bin"
|
||||
mkdir -p "$DMS_INSTALL_DIR/bin" "$CONNECT_INSTALL_DIR/bin" "$AI_INSTALL_DIR/bin"
|
||||
( cd "$REPO_DIR/dms" && go build -o "$DMS_INSTALL_DIR/bin/dms-app" ./cmd/app )
|
||||
( cd "$REPO_DIR/dms" && go build -o "$DMS_INSTALL_DIR/bin/dms-worker" ./cmd/worker )
|
||||
( cd "$REPO_DIR/connect" && go build -o "$CONNECT_INSTALL_DIR/bin/connect-app" ./cmd/connect-app )
|
||||
echo "Binaries liegen unter ${DMS_INSTALL_DIR}/bin und ${CONNECT_INSTALL_DIR}/bin."
|
||||
( cd "$REPO_DIR/ai" && go build -o "$AI_INSTALL_DIR/bin/ai-app" ./cmd/ai-app )
|
||||
( cd "$REPO_DIR/ai" && go build -o "$AI_INSTALL_DIR/bin/ai-migrate" ./cmd/migrate )
|
||||
echo "Binaries liegen unter ${DMS_INSTALL_DIR}/bin, ${CONNECT_INSTALL_DIR}/bin und ${AI_INSTALL_DIR}/bin."
|
||||
|
||||
if id nexarch >/dev/null 2>&1; then
|
||||
chown -R nexarch:nexarch "$DMS_INSTALL_DIR" "$CONNECT_INSTALL_DIR"
|
||||
chown -R nexarch:nexarch "$DMS_INSTALL_DIR" "$CONNECT_INSTALL_DIR" "$AI_INSTALL_DIR"
|
||||
else
|
||||
echo "WARNUNG: Systembenutzer 'nexarch' existiert nicht -- Units werden trotzdem als User=nexarch geschrieben (wie bei Core/Archive ueblich), legen den Benutzer aber nicht an. Falls er fehlt, vor dem Start anlegen: useradd --system --no-create-home --shell /usr/sbin/nologin nexarch" >&2
|
||||
fi
|
||||
@@ -129,7 +140,15 @@ else
|
||||
echo "${ENV_DIR}/dms-worker.env existiert bereits -- wird nicht ueberschrieben."
|
||||
fi
|
||||
|
||||
echo "== 5b. AI-Migrationen anwenden =="
|
||||
AI_DSN="$(grep '^NEXARCH_AI_APP_TENANT_DSN=' "$ENV_DIR/ai-app.env" | head -n1 | cut -d= -f2-)"
|
||||
NEXARCH_AI_APP_TENANT_DSN="$AI_DSN" "$AI_INSTALL_DIR/bin/ai-migrate" "$REPO_DIR/ai/migrations"
|
||||
unset AI_DSN
|
||||
|
||||
echo "== 6. systemd-Units installieren =="
|
||||
sed -e "s#__INSTALL_DIR__#${AI_INSTALL_DIR}#g" \
|
||||
"$SCRIPT_DIR/systemd/nexarch-ai-app.service.tmpl" > /etc/systemd/system/nexarch-ai-app.service
|
||||
|
||||
sed -e "s#__INSTALL_DIR__#${CONNECT_INSTALL_DIR}#g" \
|
||||
"$SCRIPT_DIR/systemd/nexarch-connect-app.service.tmpl" > /etc/systemd/system/nexarch-connect-app.service
|
||||
|
||||
@@ -142,7 +161,7 @@ sed -e "s#__INSTALL_DIR__#${DMS_INSTALL_DIR}#g" \
|
||||
-e "s#__STORAGE_DIR__#${DMS_STORAGE_DIR}#g" \
|
||||
"$SCRIPT_DIR/systemd/nexarch-dms-worker.service.tmpl" > /etc/systemd/system/nexarch-dms-worker.service
|
||||
|
||||
echo "Units geschrieben: nexarch-connect-app, nexarch-dms-app, nexarch-dms-worker"
|
||||
echo "Units geschrieben: nexarch-ai-app, nexarch-connect-app, nexarch-dms-app, nexarch-dms-worker"
|
||||
|
||||
echo "== 7. daemon-reload =="
|
||||
systemctl daemon-reload
|
||||
@@ -167,7 +186,8 @@ if [ "$ok" -ne 1 ]; then
|
||||
fi
|
||||
echo "account-api liefert /auth/module-jwks."
|
||||
|
||||
echo "== 9. connect-app, dms-app, dms-worker aktivieren und starten =="
|
||||
echo "== 9. ai-app, connect-app, dms-app, dms-worker aktivieren und starten =="
|
||||
systemctl enable --now nexarch-ai-app.service
|
||||
systemctl enable --now nexarch-connect-app.service
|
||||
systemctl enable --now nexarch-dms-app.service
|
||||
systemctl enable --now nexarch-dms-worker.service
|
||||
|
||||
@@ -37,6 +37,7 @@ DMS_APP_ADDR=$(listen_addr "$ENV_DIR/dms-app.env" NEXARCH_DMS_APP_LISTEN_ADDR "1
|
||||
DMS_WORKER_METRICS_ADDR=$(listen_addr "$ENV_DIR/dms-worker.env" NEXARCH_DMS_WORKER_METRICS_ADDR "127.0.0.1:8601")
|
||||
DMS_KOSIT_ADDR=$(listen_addr "$ENV_DIR/dms-worker.env" NEXARCH_DMS_WORKER_KOSIT_ADDR "127.0.0.1:8610")
|
||||
CONNECT_APP_ADDR=$(listen_addr "$ENV_DIR/connect-app.env" NEXARCH_CONNECT_APP_LISTEN_ADDR "127.0.0.1:9500")
|
||||
AI_APP_ADDR=$(listen_addr "$ENV_DIR/ai-app.env" NEXARCH_AI_APP_LISTEN_ADDR "127.0.0.1:8900")
|
||||
|
||||
echo "== Core (bereits laufend erwartet) =="
|
||||
check "nexarch-core" "http://127.0.0.1:8080/healthz"
|
||||
@@ -53,6 +54,9 @@ check "dms-kosit-sidecar" "http://${DMS_KOSIT_ADDR}/healthz"
|
||||
echo "== Connect (Erstinstallation durch diesen Rollout) =="
|
||||
check "connect-app" "http://${CONNECT_APP_ADDR}/healthz"
|
||||
|
||||
echo "== AI =="
|
||||
check "ai-app" "http://${AI_APP_ADDR}/healthz"
|
||||
|
||||
echo
|
||||
echo "Hinweis: Adressen werden aus den echten Env-Dateien gelesen"
|
||||
echo "(NEXARCH_*_LISTEN_ADDR); ohne gesetzten Wert greift der Platzhalter aus"
|
||||
|
||||
@@ -13,6 +13,7 @@ set -euo pipefail
|
||||
CONNECT_ENV=/etc/nexarch/connect-app.env
|
||||
DMS_ENV=/etc/nexarch/dms-app.env
|
||||
CORE_ENV=/etc/nexarch/core.env
|
||||
AI_ENV=/etc/nexarch/ai-app.env
|
||||
|
||||
if [ ! -f "$CONNECT_ENV" ] || [ ! -f "$DMS_ENV" ] || [ ! -f "$CORE_ENV" ]; then
|
||||
echo "Abbruch: eine der Env-Dateien fehlt ($CONNECT_ENV, $DMS_ENV, $CORE_ENV)." >&2
|
||||
@@ -50,6 +51,42 @@ else
|
||||
echo "Uebersprungen: NEXARCH_CONNECT_APP_LISTEN_ADDR ist schon gesetzt."
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "== 1b. AI-DB (Rolle + Datenbank) =="
|
||||
if [ ! -f "$AI_ENV" ]; then
|
||||
echo "Uebersprungen: $AI_ENV fehlt (rollout-131-sync.sh zuerst ausfuehren)."
|
||||
else
|
||||
if grep -q '^NEXARCH_AI_APP_TENANT_DSN=.*TODO' "$AI_ENV" 2>/dev/null || ! grep -q '^NEXARCH_AI_APP_TENANT_DSN=' "$AI_ENV"; then
|
||||
PW=$(openssl rand -hex 20)
|
||||
sudo -u postgres psql -v ON_ERROR_STOP=1 <<SQL
|
||||
DO \$\$
|
||||
BEGIN
|
||||
IF EXISTS (SELECT FROM pg_roles WHERE rolname = 'ai_app') THEN
|
||||
ALTER ROLE ai_app WITH PASSWORD '${PW}';
|
||||
ELSE
|
||||
CREATE ROLE ai_app LOGIN PASSWORD '${PW}';
|
||||
END IF;
|
||||
END
|
||||
\$\$;
|
||||
SELECT 'CREATE DATABASE ai_app_tenant OWNER ai_app'
|
||||
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'ai_app_tenant')\gexec
|
||||
SQL
|
||||
sed -i '/^NEXARCH_AI_APP_TENANT_DSN=/d' "$AI_ENV"
|
||||
echo "NEXARCH_AI_APP_TENANT_DSN=postgresql://ai_app:${PW}@localhost:5432/ai_app_tenant?sslmode=disable" >> "$AI_ENV"
|
||||
echo "OK: NEXARCH_AI_APP_TENANT_DSN gesetzt."
|
||||
else
|
||||
echo "Uebersprungen: NEXARCH_AI_APP_TENANT_DSN ist schon gesetzt."
|
||||
fi
|
||||
if grep -q '^NEXARCH_AI_APP_LISTEN_ADDR=.*TODO' "$AI_ENV" 2>/dev/null || ! grep -q '^NEXARCH_AI_APP_LISTEN_ADDR=' "$AI_ENV"; then
|
||||
sed -i '/^NEXARCH_AI_APP_LISTEN_ADDR=/d' "$AI_ENV"
|
||||
echo "NEXARCH_AI_APP_LISTEN_ADDR=127.0.0.1:8900" >> "$AI_ENV"
|
||||
echo "OK: NEXARCH_AI_APP_LISTEN_ADDR gesetzt (127.0.0.1:8900)."
|
||||
else
|
||||
echo "Uebersprungen: NEXARCH_AI_APP_LISTEN_ADDR ist schon gesetzt."
|
||||
fi
|
||||
echo "OFFEN: NEXARCH_AI_APP_SERVICE_TOKEN und Policy-Anbindung (POLICY_URL/_POLICY_SERVICE_TOKEN oder POLICY_DISABLED=1) setzt der Betreiber von Hand."
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "== 2. KEK-Client fuer DMS registrieren =="
|
||||
if grep -q '^NEXARCH_DMS_APP_KEK_CLIENT_ID=.*TODO' "$DMS_ENV" 2>/dev/null; then
|
||||
@@ -135,3 +172,4 @@ echo
|
||||
echo "== Zusammenfassung =="
|
||||
grep -c TODO "$CONNECT_ENV" | xargs -I{} echo "connect-app.env: {} offene TODOs"
|
||||
grep -c TODO "$DMS_ENV" | xargs -I{} echo "dms-app.env: {} offene TODOs"
|
||||
[ -f "$AI_ENV" ] && { grep -c TODO "$AI_ENV" | xargs -I{} echo "ai-app.env: {} offene TODOs" || true; }
|
||||
@@ -17,10 +17,12 @@ REPO_DIR="${NEXARCH_ROLLOUT_REPO_DIR:-/root/nexarch-code}"
|
||||
ENV_DIR=/etc/nexarch
|
||||
DMS_INSTALL_DIR="${NEXARCH_DMS_INSTALL_DIR:-/opt/nexarch-dms}"
|
||||
CONNECT_INSTALL_DIR="${NEXARCH_CONNECT_INSTALL_DIR:-/opt/nexarch-connect}"
|
||||
AI_INSTALL_DIR="${NEXARCH_AI_INSTALL_DIR:-/opt/nexarch-ai}"
|
||||
DMS_STORAGE_DIR="${NEXARCH_DMS_STORAGE_DIR:-/var/lib/nexarch-dms/storage}"
|
||||
DMS_STAGING_DIR="${NEXARCH_DMS_STAGING_DIR:-/var/lib/nexarch-dms/staging}"
|
||||
CONNECT_ENV="$ENV_DIR/connect-app.env"
|
||||
DMS_ENV="$ENV_DIR/dms-app.env"
|
||||
AI_ENV="$ENV_DIR/ai-app.env"
|
||||
CORE_ENV="$ENV_DIR/core.env"
|
||||
MAX_ATTEMPTS=10
|
||||
|
||||
@@ -93,7 +95,7 @@ while [ "$attempt" -lt "$MAX_ATTEMPTS" ]; do
|
||||
fi
|
||||
|
||||
for pair in "$CONNECT_ENV:NEXARCH_CONNECT_APP_TENANT_DSN" "$CONNECT_ENV:NEXARCH_CONNECT_APP_LISTEN_ADDR" \
|
||||
"$DMS_ENV:NEXARCH_DMS_APP_CORE_SERVICE_TOKEN" "$DMS_ENV:NEXARCH_DMS_APP_KEK_CLIENT_ID" "$DMS_ENV:NEXARCH_DMS_APP_KEK_CLIENT_SECRET"; do
|
||||
"$AI_ENV:NEXARCH_AI_APP_TENANT_DSN" "$AI_ENV:NEXARCH_AI_APP_LISTEN_ADDR" "$AI_ENV:NEXARCH_AI_APP_SERVICE_TOKEN" "$DMS_ENV:NEXARCH_DMS_APP_CORE_SERVICE_TOKEN" "$DMS_ENV:NEXARCH_DMS_APP_KEK_CLIENT_ID" "$DMS_ENV:NEXARCH_DMS_APP_KEK_CLIENT_SECRET"; do
|
||||
f="${pair%%:*}"; n="${pair#*:}"
|
||||
if is_open "$f" "$n"; then
|
||||
blockers+=("${n} in ${f} ist weiterhin offen -- braucht einen externen Wert, den nur der Nutzer kennt (kein Konfigurationsfehler, den dieses Skript loesen darf).")
|
||||
@@ -125,7 +127,7 @@ while [ "$attempt" -lt "$MAX_ATTEMPTS" ]; do
|
||||
done
|
||||
|
||||
log "== Zielverzeichnisse pruefen =="
|
||||
for d in "$DMS_INSTALL_DIR/bin" "$CONNECT_INSTALL_DIR/bin" "$DMS_STORAGE_DIR" "$DMS_STAGING_DIR"; do
|
||||
for d in "$DMS_INSTALL_DIR/bin" "$CONNECT_INSTALL_DIR/bin" "$AI_INSTALL_DIR/bin" "$DMS_STORAGE_DIR" "$DMS_STAGING_DIR"; do
|
||||
if [ ! -d "$d" ]; then
|
||||
mkdir -p "$d"
|
||||
log "repariert: Verzeichnis $d angelegt."
|
||||
@@ -133,13 +135,15 @@ while [ "$attempt" -lt "$MAX_ATTEMPTS" ]; do
|
||||
fi
|
||||
done
|
||||
if id nexarch >/dev/null 2>&1; then
|
||||
chown -R nexarch:nexarch "$DMS_INSTALL_DIR" "$CONNECT_INSTALL_DIR" "$DMS_STORAGE_DIR" "$DMS_STAGING_DIR" 2>/dev/null || true
|
||||
chown -R nexarch:nexarch "$DMS_INSTALL_DIR" "$CONNECT_INSTALL_DIR" "$AI_INSTALL_DIR" "$DMS_STORAGE_DIR" "$DMS_STAGING_DIR" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
log "== Binaries pruefen (nachbauen falls sie fehlen) =="
|
||||
for triple in "$DMS_INSTALL_DIR/bin/dms-app:$REPO_DIR/dms:./cmd/app" \
|
||||
"$DMS_INSTALL_DIR/bin/dms-worker:$REPO_DIR/dms:./cmd/worker" \
|
||||
"$CONNECT_INSTALL_DIR/bin/connect-app:$REPO_DIR/connect:./cmd/connect-app"; do
|
||||
"$CONNECT_INSTALL_DIR/bin/connect-app:$REPO_DIR/connect:./cmd/connect-app" \
|
||||
"$AI_INSTALL_DIR/bin/ai-app:$REPO_DIR/ai:./cmd/ai-app" \
|
||||
"$AI_INSTALL_DIR/bin/ai-migrate:$REPO_DIR/ai:./cmd/migrate"; do
|
||||
bin="${triple%%:*}"; rest="${triple#*:}"; moddir="${rest%%:*}"; pkg="${rest#*:}"
|
||||
if [ ! -x "$bin" ]; then
|
||||
if [ -f "$moddir/go.mod" ]; then
|
||||
@@ -190,7 +194,7 @@ while [ "$attempt" -lt "$MAX_ATTEMPTS" ]; do
|
||||
fi
|
||||
|
||||
log "== systemd-Unit-Dateien pruefen (nur Datei-Kopie, kein systemctl) =="
|
||||
for unit in nexarch-connect-app nexarch-dms-app nexarch-dms-worker; do
|
||||
for unit in nexarch-ai-app nexarch-connect-app nexarch-dms-app nexarch-dms-worker; do
|
||||
tmpl="$SCRIPT_DIR/systemd/${unit}.service.tmpl"
|
||||
dest="/etc/systemd/system/${unit}.service"
|
||||
if [ ! -f "$tmpl" ]; then
|
||||
@@ -199,6 +203,9 @@ while [ "$attempt" -lt "$MAX_ATTEMPTS" ]; do
|
||||
fi
|
||||
if [ ! -f "$dest" ] || grep -q '__INSTALL_DIR__\|__STORAGE_DIR__\|__STAGING_DIR__' "$dest" 2>/dev/null; then
|
||||
case "$unit" in
|
||||
nexarch-ai-app)
|
||||
sed -e "s#__INSTALL_DIR__#${AI_INSTALL_DIR}#g" "$tmpl" > "$dest"
|
||||
;;
|
||||
nexarch-connect-app)
|
||||
sed -e "s#__INSTALL_DIR__#${CONNECT_INSTALL_DIR}#g" "$tmpl" > "$dest"
|
||||
;;
|
||||
@@ -234,7 +241,7 @@ if [ "$ready" -eq 1 ]; then
|
||||
echo " systemctl daemon-reload"
|
||||
echo " systemctl restart nexarch-account-api"
|
||||
echo " sleep 3 && curl -sf http://127.0.0.1:8099/auth/module-jwks && echo OK"
|
||||
echo " systemctl enable --now nexarch-connect-app nexarch-dms-app nexarch-dms-worker"
|
||||
echo " systemctl enable --now nexarch-ai-app nexarch-connect-app nexarch-dms-app nexarch-dms-worker"
|
||||
echo " $SCRIPT_DIR/rollout-131-healthcheck.sh"
|
||||
echo
|
||||
echo "(Alternativ deckt deploy/rollout-131-apply.sh genau diese Schritte in einem Lauf ab.)"
|
||||
|
||||
@@ -67,6 +67,12 @@ echo "-- connect-app.env (neu, Connect API-02) --"
|
||||
ensure_var "$ENV_DIR/connect-app.env" NEXARCH_CONNECT_APP_LISTEN_ADDR "z.B. 127.0.0.1:9500"
|
||||
ensure_var "$ENV_DIR/connect-app.env" NEXARCH_CONNECT_APP_TENANT_DSN "Postgres-DSN fuer den Connect-Mandanten"
|
||||
|
||||
echo "-- ai-app.env (neu, ENG-10) --"
|
||||
ensure_var "$ENV_DIR/ai-app.env" NEXARCH_AI_APP_LISTEN_ADDR "z.B. 127.0.0.1:8900"
|
||||
ensure_var "$ENV_DIR/ai-app.env" NEXARCH_AI_APP_TENANT_DSN "Postgres-DSN fuer die AI-Datenbank"
|
||||
ensure_var "$ENV_DIR/ai-app.env" NEXARCH_AI_APP_SERVICE_TOKEN "Token, das alle Aufrufer im Header X-Service-Token senden -- muss zu den Aufrufern passen"
|
||||
ensure_var "$ENV_DIR/ai-app.env" NEXARCH_AI_APP_POLICY_URL "policy-api-Adresse fuer die Rechtepruefung der Suche (alternativ NEXARCH_AI_APP_POLICY_DISABLED=1 als Uebergang)"
|
||||
|
||||
echo "-- dms-app.env (Ergaenzungen aus dieser Session gehaerteter Konfiguration) --"
|
||||
# Pflicht zum Start ueberhaupt (TENANT_DSN/TENANT_SLUG waren auf 131 bei der
|
||||
# Bestandsaufnahme bereits gesetzt, hier nur zur Vollstaendigkeit abgesichert):
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
[Unit]
|
||||
Description=NEXARCH AI - ai-app (ENG-10)
|
||||
After=network.target postgresql.service
|
||||
Wants=postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=nexarch
|
||||
Group=nexarch
|
||||
EnvironmentFile=/etc/nexarch/ai-app.env
|
||||
ExecStart=__INSTALL_DIR__/bin/ai-app
|
||||
Restart=on-failure
|
||||
RestartSec=3
|
||||
WorkingDirectory=__INSTALL_DIR__
|
||||
# QA-15 F-13/OPS-08: reiner Netzwerkdienst (HTTP + Postgres-DSN aus
|
||||
# EnvironmentFile), keine eigene Schreibarbeit im Dateisystem.
|
||||
NoNewPrivileges=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
PrivateTmp=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Reference in new issue
Block a user