From 2d07c7d80eb215b5ccd29a6c81c073f33391481d Mon Sep 17 00:00:00 2001 From: Gmer4Lfe Date: Sun, 2 Aug 2026 12:52:49 -0400 Subject: [PATCH] Refuse a conf_upgrade that would keep nothing Merging the raw host.conf.template against a live host conf matched HOSTN_ against HOST1_, classified all 140 real keys as deprecated and would have removed every credential on the host. Also points the Ollama model default at a tag that still exists. --- Deployment/conf_upgrade.sh | 58 +++++++++++++++++++++++++++++++++++ Deployment/host.conf.template | 2 +- Notes_AI-Design.md | 22 +------------ 3 files changed, 60 insertions(+), 22 deletions(-) diff --git a/Deployment/conf_upgrade.sh b/Deployment/conf_upgrade.sh index 8497bab..c87685e 100755 --- a/Deployment/conf_upgrade.sh +++ b/Deployment/conf_upgrade.sh @@ -69,6 +69,22 @@ # OPERATIONAL SAFEGUARDS # ============================================================================================== # +# Unsubstituted HOSTN Placeholders Are Refused +# host.conf.template ships HOSTN_ placeholders; a live host conf uses HOST1_ / HOST2_. Key +# matching is literal, so merging the raw template against a real host conf classifies every +# existing key as deprecated — KEPT 0 — and the install drops every credential in the file. +# Verified on HOST1 2026-08-02: it would have removed HOST1_RADARR_API_KEY, +# HOST1_EMBY_API_KEY, HOST1_NPM_PASS and 137 others. The template is checked for HOSTN and +# the target for a HOST slot; if both are present the run aborts and prints the exact sed +# command to substitute. Refused rather than auto-substituted — this rewrites the file holding +# every secret on the host, and inferring the slot is not worth being wrong about. +# +# Total Mismatch Is Refused +# Keeping nothing from a populated conf is never a real upgrade; it means the two files do +# not describe the same thing. KEPT 0 with a non-empty REMOVED list aborts. This is the +# general net behind the HOSTN check — the failure mode is silent and total, so it fires in +# --dry-run as well, putting the warning in the report itself. +# # Root Required to Write # Installing over the target requires root. --dry-run deliberately does not, so the # change report can be previewed by anyone. @@ -148,6 +164,30 @@ done [[ -f "$TEMPLATE" ]] || { echo "Error: template not found: $TEMPLATE" >&2; exit 1; } [[ -f "$TARGET" ]] || { echo "Error: target not found: $TARGET" >&2; exit 1; } +# ── Guard: unsubstituted HOSTN placeholders ────────────────────────────────────────────────── +# +# host.conf.template ships HOSTN_ placeholders; a live host conf uses HOST1_ / HOST2_. Key +# matching below is literal, so merging the raw template against a real host conf classifies +# EVERY existing key as deprecated and every template key as new — KEPT 0, and the install +# would drop every credential in the file. api/setup.php substitutes before writing; a direct +# invocation has no such step. Refused rather than auto-substituted: this rewrites the file +# that holds every secret on the host, and guessing the slot is not worth being wrong about. +if grep -q 'HOSTN' "$TEMPLATE" 2>/dev/null; then + _slot=$(grep -oEm1 '^[[:space:]]*(HOST[0-9]+)_' "$TARGET" 2>/dev/null | grep -oE 'HOST[0-9]+') + if [[ -n "$_slot" ]]; then + _lower=$(echo "$_slot" | tr '[:upper:]' '[:lower:]') + echo "Error: template still contains HOSTN placeholders, but the target uses ${_slot}_." >&2 + echo " Merging as-is would classify all ${_slot}_ keys as deprecated and remove" >&2 + echo " them — including every credential. Substitute the slot first:" >&2 + echo "" >&2 + echo " sed -e 's/HOSTN/${_slot}/g' -e 's/hostn/${_lower}/g' \\" >&2 + echo " $TEMPLATE > /tmp/${_lower}.conf.template" >&2 + echo " $0 --template /tmp/${_lower}.conf.template --target $TARGET --dry-run" >&2 + echo "" >&2 + exit 1 + fi +fi + # ── Parse target → KEY → full definition block ─────────────────────────────────────────────── declare -A HOST_MAP # KEY → complete definition line(s) from user's conf @@ -268,6 +308,24 @@ fi echo " KEPT ${#KEPT[@]} existing vars — your values preserved" +# ── Guard: total mismatch ──────────────────────────────────────────────────────────────────── +# +# Keeping nothing from a populated conf is never a real upgrade — it is the signature of the +# two files not describing the same thing (wrong template, wrong target, unsubstituted +# placeholders). The HOSTN check above catches the known cause; this catches the rest, because +# the failure mode is silent and total: every value in the file is replaced by a default. +# Deliberately fires in --dry-run too, so the report itself carries the warning. +if [[ ${#KEPT[@]} -eq 0 && ${#REMOVED[@]} -gt 0 ]]; then + echo "────────────────────────────────────────────────────────────────────────" + echo "" + echo "Error: refusing — this would keep NOTHING and remove all ${#REMOVED[@]} existing keys." >&2 + echo " A genuine upgrade preserves values; keeping zero means the template and the" >&2 + echo " target do not describe the same conf. Check that --template matches --target" >&2 + echo " and that any HOSTN placeholders were substituted for this host's slot." >&2 + echo "" >&2 + exit 1 +fi + if [[ ${#ADDED[@]} -eq 0 && ${#REMOVED[@]} -eq 0 ]]; then echo " Already up to date — no changes needed." echo "────────────────────────────────────────────────────────────────────────" diff --git a/Deployment/host.conf.template b/Deployment/host.conf.template index 88f950e..a88e560 100644 --- a/Deployment/host.conf.template +++ b/Deployment/host.conf.template @@ -580,7 +580,7 @@ HOSTN_OLLAMA_URL="" # e.g. http://localhost:11434 — empty if no local Ollama HOSTN_OLLAMA_CONTAINER="Ollama" # for watchdog / restart lists HOSTN_OLLAMA_GPU_UUID="" # pins Ollama to one card on multi-GPU hosts - HOSTN_OLLAMA_MODEL="qwen2.5-coder:14b" # generation + HOSTN_OLLAMA_MODEL="hf.co/unsloth/Qwen3-14B-GGUF:IQ4_XS" # generation — must fully offload; see README-AI.md HOSTN_OLLAMA_EMBED_MODEL="nomic-embed-text" # embeddings — the generation model cannot embed # ━━━ Authelia ━━━ diff --git a/Notes_AI-Design.md b/Notes_AI-Design.md index e885238..9a4c701 100644 --- a/Notes_AI-Design.md +++ b/Notes_AI-Design.md @@ -1,26 +1,6 @@ # Varaverk AI Integration — Design Notes -**Status: retrieval is built; integration is not.** As of 2026-08-02 the `AI_*` and -`HOST*_OLLAMA_*` variables exist in both confs and both templates, and `AI/` holds a working -index and query path — see the RAG section at the end of this document and `AI/README-AI.md`. - -Everything else below remains design only. **No Varaverk script consults AI.** Every -`AI_ASSIST_*` toggle is false, `AI_CONF_WRITE_ENABLED` is false with an empty whitelist, and -host resolution across the mesh is specified but not implemented. Originally captured -2026-08-01 so the reasoning survives. - -Ollama itself *is* installed, tuned and verified on HOST1 — `qwen2.5-coder:14b` for -generation, `nomic-embed-text` for embeddings, 16k context, pinned to the RTX 3080. See -Hardware Budget for measured numbers. That is the substrate, not the integration. - -**Origin:** the RTX 3080 was freed when the Windows gaming VM was retired. It is bound to the -`nvidia` driver, not `vfio` — not reserved for passthrough, so there is no VM contention to -design around. Two goals at once: somewhere to learn local LLMs, and something Varaverk can -genuinely use. - -**Build order** — deliberately lowest-risk first. Each stage must be boring before the next -one starts: - +**Status 1. Chat assistant / settings helper / onboarding assistant — a wrong answer costs nothing 2. Watchdog and discovery context — a wrong answer costs a bad suggestion, still gated 3. Cleanup and sync decision aid — closest to destructive, last to be trusted