Remove Claude tooling from repo — personal setup moved to standalone /boot/config/claude_startup.sh
This commit is contained in:
@@ -4,7 +4,6 @@
|
||||
Configurations/host*.conf
|
||||
Configurations/master.conf
|
||||
Configurations/*.bak
|
||||
.claude
|
||||
.vscode
|
||||
|
||||
# ── Runtime state, data, logs ─────────────────────────────────────────────────
|
||||
@@ -28,9 +27,6 @@ varaverk-*.txz
|
||||
# .txz packages are attached to GitHub releases, not committed to the repo.
|
||||
Plugin/dist/
|
||||
|
||||
# ── Claude Code installation (lives alongside repo on flash, not source) ──────
|
||||
claude-bin/
|
||||
claude-data/
|
||||
|
||||
# ── OS / editor ───────────────────────────────────────────────────────────────
|
||||
.DS_Store
|
||||
|
||||
@@ -1,162 +0,0 @@
|
||||
# Varaverk — Claude Code Context
|
||||
|
||||
## Working Rules (read first)
|
||||
|
||||
- **Dev workspace** — `/mnt/cloud-storage/Important Shit/Git/Development/Varaverk/`. All editing happens here.
|
||||
- **Prod** — `/boot/config/plugins/varaverk/`. Never edited directly. Only updated via `git pull` (daily orchestrator or the pull button in the UI).
|
||||
- **No Co-Authored-By** in commit messages unless explicitly asked.
|
||||
- **No comments** unless the WHY is genuinely non-obvious.
|
||||
|
||||
### Current workflow: dev/prod split
|
||||
|
||||
Edit in dev, push to Gitea, pull prod when ready (daily orchestrator or manual UI trigger).
|
||||
Push is the only bridge — no deploy hooks, no rsync-on-save, no direct path references between dev and prod.
|
||||
|
||||
`plugin_setup.sh` stays pointing at the prod path. Dev never touches `/boot/` directly.
|
||||
|
||||
### Hard limits — do not cross these
|
||||
|
||||
- **Never create or modify `.claude/settings.json`** in this repo. No workspace hooks, ever. The stale hook that existed here previously fired `Deployment/deploy.sh` (now deleted) on every file edit and caused unintended deploys. If you think a hook would help, ask first.
|
||||
- **Never change `HOST1_STORAGE_MODE_INTERNAL`** in `host1.conf`. Claude data belongs in `/mnt/user/appdata/claude-code/` — not inside this repo.
|
||||
- **Never move files between `Configurations/` and `Deployment/`** without explicit instruction. `Configurations/` = live runtime confs (gitignored). `Deployment/` = templates and setup tooling (tracked).
|
||||
|
||||
---
|
||||
|
||||
## Project: What Varaverk Is
|
||||
|
||||
Self-healing, self-maintaining, mutually-redundant two-server Unraid home media ecosystem.
|
||||
One codebase runs on both servers. No primary/standby — both run independently and cover each other.
|
||||
|
||||
**HOST1 — unRAID-Gmer4Lfe** (`gmer4lfe@gmail.com`)
|
||||
- Hardware: Threadripper 1950X, 128 GB RAM, ZFS cache pools
|
||||
- Domain: Gmer4Lfe.com
|
||||
- Runs: full arr stack (Sonarr/Radarr/Lidarr), auth stack (source of truth), Emby primary
|
||||
|
||||
**HOST2 — unRAID-Jayred365**
|
||||
- Hardware: Intel i5 10th gen, 64 GB RAM
|
||||
- Domain: Gmer4Lfe.us
|
||||
- Status: being rebuilt — most host2.conf sections scaffolded, not yet fully online
|
||||
|
||||
Networking between hosts: Tailscale mesh. No hardcoded IPs — hostnames resolve via Tailscale.
|
||||
|
||||
---
|
||||
|
||||
## Configuration System (three-file model)
|
||||
|
||||
Every script sources all three at startup:
|
||||
|
||||
```
|
||||
master.conf ← shared: thresholds, toggles, profiles, orchestrator job lists
|
||||
host1.conf ← HOST1 credentials, shares, container names, keys
|
||||
host2.conf ← HOST2 credentials, shares, container names, keys
|
||||
```
|
||||
|
||||
Sparse checkout (git) means each server only pulls its own `host*.conf`.
|
||||
HOST1 never sees HOST2 credentials and vice versa.
|
||||
|
||||
**Rule:** thresholds/toggles → `master.conf`; credentials/paths/container names → `host*.conf`.
|
||||
|
||||
`detect_hosts()` in `common.sh` matches `$(hostname)` against `HOST1`/`HOST2` in `master.conf`
|
||||
and sets `MY_ID` / `REMOTE_ID` for the rest of the script.
|
||||
|
||||
---
|
||||
|
||||
## Platform Adapter Layer
|
||||
|
||||
`Plugin/unraid/adapter.sh` isolates all OS-specific calls.
|
||||
Scripts never branch on OS directly — always call adapter functions.
|
||||
This is intentional architecture — don't bypass it.
|
||||
|
||||
---
|
||||
|
||||
## Key Paths
|
||||
|
||||
| Path | Purpose |
|
||||
|------|---------|
|
||||
| `master.conf` | Shared config — all thresholds, toggles, profiles |
|
||||
| `host1.conf` / `host2.conf` | Per-host credentials, shares, container lists |
|
||||
| `common.sh` | Shared functions — `detect_hosts()`, `log()`, `notify()`, etc. |
|
||||
| `load_config.sh` | Sources all three conf files + common.sh |
|
||||
| `State_Files/` | Runtime state (watchdogs, fallback, transcode) — survives reboots |
|
||||
| `data/` | Historical logs and stats |
|
||||
| `Plugin/unraid/` | Unraid WebGUI plugin (PHP pages, API endpoints, adapter) |
|
||||
| `Orchestrators/` | Top-level schedulers (array_started, daily, weekly, watchdog) |
|
||||
| `Watchdogs/` | docker_watchdog, system_watchdog, resource_watchdog, stability |
|
||||
| `Fallback/` | Mutual container failover logic |
|
||||
| `Rsync/` | rsync.sh + profile system |
|
||||
| `Media/` | Arr cleanup, discovery, permissions, play state sync |
|
||||
| `Tools/` | Manual one-off tools including `claude_startup.sh` |
|
||||
|
||||
---
|
||||
|
||||
## Orchestrator Schedule
|
||||
|
||||
| When | What |
|
||||
|------|------|
|
||||
| Array start | `Orchestrators/array_started.sh` → runs `ARRAY_START_SCRIPTS` |
|
||||
| Every minute | `watchdog_orchestrator.sh` → resource → docker → system → stability watchdogs |
|
||||
| Every 30 min | `critical_sync_maintenance.sh` → downloaders_reset, play_state_sync, critical rsync |
|
||||
| Every 4 hours | `intermediate_sync_maintenance.sh` → arr_sync, arrs_failed_stalled_recovery |
|
||||
| Daily 1am | `daily_sync_maintenance.sh` → git pull, permissions, cleaners, arr cleanup, docker updates |
|
||||
| Sunday 2:30am | `weekly_sync_maintenance.sh` → full Emby + Critical-Data sync, weekly restarts |
|
||||
| Sunday 3am+ | `monthly_maintenance.sh` (self-gated on 30-day uptime) → ZFS scrub, SMART tests |
|
||||
| Sunday 7am | `sunday_morning_coffee_report.sh` → ZFS, SMART, certs, backup verify, bandwidth, Emby report |
|
||||
|
||||
---
|
||||
|
||||
## Rsync Toggle State (current)
|
||||
|
||||
```bash
|
||||
RSYNC_ENABLED=true
|
||||
CRITICAL_RSYNC_ENABLED=true
|
||||
INTERMEDIATE_RSYNC_ENABLED=true
|
||||
DAILY_RSYNC_ENABLED=true
|
||||
WEEKLY_RSYNC_ENABLED=true
|
||||
FALLBACK_RSYNC_ENABLED=true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Fallback System
|
||||
|
||||
`fallback.sh` runs continuously from array start.
|
||||
States: `NORMAL | FALLBACK | NO_INTERNET | DARK`
|
||||
|
||||
DDNS rules are absolute:
|
||||
- Internet loss → stop own DDNS immediately
|
||||
- Failover → start remote's DDNS as Tier 1 first
|
||||
- Handback → stop remote DDNS → rsync → start containers → start local DDNS last
|
||||
|
||||
Tier delays before activating higher tiers are in `host*.conf` (`HOST1_TIER*_DELAY`, `HOST2_TIER*_DELAY`).
|
||||
|
||||
---
|
||||
|
||||
## Port Notes
|
||||
|
||||
- **NPM admin API (`HOST1_NPM_URL`)** — port **7818**. Port 81 is the partnership WebUI port (`HOST1_PARTNERSHIP_AUTH_WEBUIS`), not the API. Easy to confuse.
|
||||
- **HOST1_NETWORK_WATCHDOG_NPM_URL** — external HTTPS domain, completely separate from the admin API.
|
||||
|
||||
## Known Gaps / Active Work
|
||||
|
||||
- HOST2 NPM/lldap credentials (`HOST2_NPM_USER`, `HOST2_NPM_PASS`, `HOST2_LLDAP_PASS`) are empty in `host2.conf` — fill in when HOST2 is back online.
|
||||
- `PARTNERSHIP_ENABLED=false` — not yet active.
|
||||
- `FALLBACK_ENABLED=true` — fallback is running.
|
||||
|
||||
---
|
||||
|
||||
## Claude Code Persistence on Unraid
|
||||
|
||||
`/root` is a RAM filesystem — wiped on every reboot.
|
||||
`Tools/claude_startup.sh` runs at array start (via `ARRAY_START_SCRIPTS`) and:
|
||||
- Symlinks `/root/.claude` → `/mnt/user/appdata/claude-code/.claude`
|
||||
- Symlinks `/root/.local/share/claude` → `/mnt/user/appdata/claude-code/local/share/claude`
|
||||
- Symlinks `/root/CLAUDE.md` → `/boot/config/plugins/varaverk/CLAUDE.md` (this file)
|
||||
|
||||
This file lives on `/boot` (USB flash) and is always available regardless of array state.
|
||||
|
||||
---
|
||||
|
||||
## Commit Style
|
||||
|
||||
Plain, concise messages. No Co-Authored-By trailers. No bullet-point summaries in the body.
|
||||
One sentence on the why, not the what.
|
||||
@@ -1,181 +0,0 @@
|
||||
#!/bin/bash
|
||||
# ==============================================================================================
|
||||
# ================================= Claude Code Startup ========================================
|
||||
# ==============================================================================================
|
||||
#
|
||||
# PURPOSE
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# Restores Claude Code's persistent data after an Unraid reboot.
|
||||
# /root is RAM — wiped on every boot. This script re-creates symlinks so
|
||||
# Claude's memory, sessions, settings, and binary survive across reboots.
|
||||
#
|
||||
# Storage mode is read from the host conf file:
|
||||
#
|
||||
# HOST*_STORAGE_MODE_INTERNAL=true → Internal (boot) mode
|
||||
# .claude data → /boot/config/claude
|
||||
# binary → /boot/config/claude-bin
|
||||
# No array dependency — runs even before array mounts.
|
||||
#
|
||||
# HOST*_STORAGE_MODE_INTERNAL=false → Appdata mode
|
||||
# .claude data → /mnt/user/appdata/claude-code/.claude
|
||||
# binary → /mnt/user/appdata/claude-code/local/share/claude
|
||||
# Requires array to be mounted.
|
||||
#
|
||||
# On first run in either mode, migrates any existing live data to persistent
|
||||
# storage. Subsequent runs only re-create the symlinks.
|
||||
#
|
||||
# Standalone script — no common.sh dependency. Safe to run directly from
|
||||
# terminal or from array_started.sh.
|
||||
#
|
||||
# ==============================================================================================
|
||||
# DESIGN PRINCIPLES
|
||||
# ==============================================================================================
|
||||
#
|
||||
# Mode-Aware Paths
|
||||
# Storage mode is read from host*.conf before any symlink is created. Internal
|
||||
# mode (boot) requires no array — symlinks resolve immediately. Appdata mode
|
||||
# requires the array to be mounted before symlinks are useful.
|
||||
#
|
||||
# Migrate on First Run
|
||||
# If live data already exists at /root/.claude and the persistent store is
|
||||
# empty, the live data is moved to persistent storage on first run. Subsequent
|
||||
# runs only re-create the symlinks — migration is one-time.
|
||||
#
|
||||
# No common.sh Dependency
|
||||
# Runs before load_config.sh is available (early in ARRAY_START_SCRIPTS).
|
||||
# All logic is self-contained — no ecosystem functions used.
|
||||
#
|
||||
# ==============================================================================================
|
||||
# OPERATIONAL SAFEGUARDS
|
||||
# ==============================================================================================
|
||||
#
|
||||
# Conf probe — reads storage mode from Configurations/host*.conf directly
|
||||
# Migration guard — only migrates if persistent store is empty; never overwrites
|
||||
# Symlink-safe — removes existing symlink before re-creating; won't error on re-run
|
||||
#
|
||||
# ==============================================================================================
|
||||
# RUNTIME MODES
|
||||
# ==============================================================================================
|
||||
#
|
||||
# claude_startup.sh
|
||||
# Set up persistent symlinks only — default, used by array_started.sh on boot.
|
||||
#
|
||||
# claude_startup.sh --launch
|
||||
# Set up persistent symlinks and launch Claude interactively.
|
||||
#
|
||||
# ==============================================================================================
|
||||
|
||||
LAUNCH=false
|
||||
[[ "$1" == "--launch" ]] && LAUNCH=true
|
||||
|
||||
_log() { echo " ✅ $*"; }
|
||||
_warn() { echo " ⚠️ $*"; }
|
||||
_err() { echo " ❌ $*" >&2; }
|
||||
|
||||
echo ""
|
||||
echo "━━━ Claude Code Startup ━━━"
|
||||
echo ""
|
||||
|
||||
# ── Detect storage mode ───────────────────────────────────────────────────────────────────────
|
||||
CONF_DIR="/boot/config/plugins/varaverk/Configurations"
|
||||
STORAGE_INTERNAL=false
|
||||
for _conf in "$CONF_DIR"/host*.conf; do
|
||||
[[ -f "$_conf" ]] || continue
|
||||
if grep -q "_STORAGE_MODE_INTERNAL=true" "$_conf" 2>/dev/null; then
|
||||
STORAGE_INTERNAL=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "$STORAGE_INTERNAL" == true ]]; then
|
||||
CLAUDE_DATA="/boot/config/plugins/varaverk/claude-data"
|
||||
CLAUDE_BIN="/boot/config/plugins/varaverk/claude-bin"
|
||||
_log "Storage mode: internal boot"
|
||||
else
|
||||
PERSIST_DIR="/mnt/user/appdata/claude-code"
|
||||
CLAUDE_DATA="$PERSIST_DIR/.claude"
|
||||
CLAUDE_BIN="$PERSIST_DIR/local/share/claude"
|
||||
_log "Storage mode: appdata"
|
||||
fi
|
||||
|
||||
# ── Array check (appdata mode only) ──────────────────────────────────────────────────────────
|
||||
if [[ "$STORAGE_INTERNAL" == false ]]; then
|
||||
if ! mountpoint -q /mnt/user 2>/dev/null; then
|
||||
_err "Array not mounted — /mnt/user not available (required for appdata mode)"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── Create persistent dirs ────────────────────────────────────────────────────────────────────
|
||||
mkdir -p "$CLAUDE_DATA" "$CLAUDE_BIN"
|
||||
|
||||
# ── Migrate from old /boot/config/claude location (internal mode only) ───────────────────────
|
||||
if [[ "$STORAGE_INTERNAL" == true && -d /boot/config/claude && "$CLAUDE_DATA" != "/boot/config/claude" ]]; then
|
||||
if [[ -z "$(ls -A "$CLAUDE_DATA" 2>/dev/null)" ]]; then
|
||||
_warn "Migrating old /boot/config/claude → $CLAUDE_DATA"
|
||||
cp -a /boot/config/claude/. "$CLAUDE_DATA/"
|
||||
_log "Migrated .claude data from old location"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── Migrate .claude on first run ──────────────────────────────────────────────────────────────
|
||||
if [[ ! -L /root/.claude && -d /root/.claude ]]; then
|
||||
_warn "First run — migrating /root/.claude → $CLAUDE_DATA"
|
||||
cp -a /root/.claude/. "$CLAUDE_DATA/"
|
||||
rm -rf /root/.claude
|
||||
_log "Migrated .claude (memory, sessions, settings)"
|
||||
elif [[ -z "$(ls -A "$CLAUDE_DATA" 2>/dev/null)" && -d /root/.claude ]]; then
|
||||
_warn "Persistent storage empty — copying current .claude data"
|
||||
cp -a /root/.claude/. "$CLAUDE_DATA/"
|
||||
_log "Copied .claude data to persistent storage"
|
||||
fi
|
||||
|
||||
# ── Migrate Claude binaries on first run ──────────────────────────────────────────────────────
|
||||
if [[ ! -L /root/.local/share/claude && -d /root/.local/share/claude ]]; then
|
||||
_warn "First run — migrating Claude binaries → $CLAUDE_BIN"
|
||||
cp -a /root/.local/share/claude/. "$CLAUDE_BIN/"
|
||||
_log "Migrated Claude binaries"
|
||||
fi
|
||||
|
||||
# ── Create symlinks ───────────────────────────────────────────────────────────────────────────
|
||||
mkdir -p /root/.local/share /root/.local/bin
|
||||
|
||||
[[ -d /root/.claude && ! -L /root/.claude ]] && rm -rf /root/.claude
|
||||
ln -sfn "$CLAUDE_DATA" /root/.claude
|
||||
_log ".claude → $CLAUDE_DATA"
|
||||
|
||||
[[ -d /root/.local/share/claude && ! -L /root/.local/share/claude ]] && rm -rf /root/.local/share/claude
|
||||
ln -sfn "$CLAUDE_BIN" /root/.local/share/claude
|
||||
_log "claude binary → $CLAUDE_BIN"
|
||||
|
||||
# ── Symlink CLAUDE.md ─────────────────────────────────────────────────────────────────────────
|
||||
CLAUDE_MD="/boot/config/plugins/varaverk/CLAUDE.md"
|
||||
if [[ -f "$CLAUDE_MD" ]]; then
|
||||
ln -sfn "$CLAUDE_MD" /root/CLAUDE.md
|
||||
_log "CLAUDE.md → $CLAUDE_MD"
|
||||
else
|
||||
_warn "CLAUDE.md not found at $CLAUDE_MD — skipping symlink"
|
||||
fi
|
||||
|
||||
# ── Point the claude binary at the latest installed version ───────────────────────────────────
|
||||
LATEST=$(ls "$CLAUDE_BIN/versions/" 2>/dev/null | sort -V | tail -1)
|
||||
if [[ -z "$LATEST" ]]; then
|
||||
_err "No Claude versions found in $CLAUDE_BIN/versions/"
|
||||
_err "Install Claude Code first: npm install -g @anthropic-ai/claude-code"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ln -sfn "$CLAUDE_BIN/versions/$LATEST" /root/.local/bin/claude
|
||||
_log "claude v$LATEST ready"
|
||||
|
||||
echo ""
|
||||
|
||||
if [[ "$LAUNCH" == false ]]; then
|
||||
_log "Setup complete — run 'claude' to start"
|
||||
echo ""
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# ── Launch ────────────────────────────────────────────────────────────────────────────────────
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
exec claude
|
||||
Reference in New Issue
Block a user