]> ###2026.05.31 - Packaged release: web files now ship as a .txz that Unraid reinstalls to RAM on every boot - Survives reboots with zero manual steps (no symlink, no go script) — fixes plugin vanishing after OS upgrades - Scripts are git-cloned to appdata on first install; web files stay on flash (~200KB) - Updates handled in-UI (git pull); the plugin no longer pulls on every boot ###2026.05.30 - First-run setup wizard: auto-detects hostname, creates master.conf + host conf from templates - Scheduler setup mode: after wizard, master.conf and host conf open sequentially with forced save flow - Partnership tab: Onboard button highlighted on arrival from wizard; disabled until partner is configured - HOST2 install paths: state-file pull, master.conf push detection, conf-only flow - Onboard Step 9: master.conf automatically pushed to all listed hosts on onboard completion - Graceful pre-onboard state: neutral banners instead of error warnings before SSH is configured - GitHub link in tab bar and Settings page; Community Apps support URL ###2026.05.28 - Initial release: Monitor, Scheduler, Docker, Watchdog, Partnership, Fallback, Arrs tabs - Mutual container fallback with tiered escalation and strike-confirmed handback - Partnership lifecycle: onboard, offboard, transfer - Rsync profile system with per-share container stops and writeback - Watchdog: Tier 1 (explicit) + Tier 2 (global scan) container monitoring - master.conf push-on-save to all configured partners via SSH https://github.com/FailedProxy/Varaverk/releases/download/&version;/&pkg; &sha256; "$CFG_FILE" <<'CFGEOF' SCRIPTS_DIR="/boot/config/plugins/varaverk" GITEA_CONTAINER="Gitea" GITEA_REPO_PATH="FailedProxy/Varaverk.git" GITEA_SSH_KEY="/root/.ssh/unraid_gitea" SSH_PORT="221" CFGEOF log "seeded varaverk.cfg" fi # Read Gitea settings from varaverk.cfg (allows override without editing .plg). _read_cfg() { grep -oP "(?<=^${1}=\")[^\"]*" "$CFG_FILE" 2>/dev/null || echo "${2}"; } GITEA_CONTAINER=$(_read_cfg GITEA_CONTAINER "Gitea") GITEA_REPO_PATH=$(_read_cfg GITEA_REPO_PATH "FailedProxy/Varaverk.git") GITEA_SSH_KEY=$(_read_cfg GITEA_SSH_KEY "/root/.ssh/unraid_gitea") SSH_PORT=$(_read_cfg SSH_PORT "221") # Clone on first install only; never auto-pull (updates via the UI git pull). if [[ ! -d "$SCRIPTS_DIR/.git" ]]; then log "initialising repo in $SCRIPTS_DIR ($BRANCH)..." # Locate Gitea: local container → local IP; else Tailscale; else fall back to GitHub. GITEA_IP="" if command -v docker >/dev/null 2>&1 && \ docker ps --format "{{.Names}}" 2>/dev/null | grep -q "^${GITEA_CONTAINER}$"; then GITEA_IP=$(hostname -I | awk '{print $1}') log "Gitea running locally — using $GITEA_IP" elif command -v tailscale >/dev/null 2>&1; then # Try each known peer until we find one hosting Gitea while IFS= read -r peer_ip; do if ssh -i "$GITEA_SSH_KEY" -p "$SSH_PORT" \ -o ConnectTimeout=3 -o StrictHostKeyChecking=no \ -o BatchMode=yes "git@${peer_ip}" info 2>/dev/null | grep -q "varaverk\|Gitea\|gitea"; then GITEA_IP="$peer_ip" log "Gitea found on Tailscale peer $GITEA_IP" break fi done < <(tailscale status --json 2>/dev/null | \ python3 -c "import json,sys; d=json.load(sys.stdin); \ [print(v['TailscaleIPs'][0]) for v in d.get('Peer',{}).values() \ if v.get('TailscaleIPs')]" 2>/dev/null) fi # init-in-place — git clone would fail because the dir already has files. git -C "$SCRIPTS_DIR" init >> "$LOG" 2>&1 CLONED=false if [[ -n "$GITEA_IP" && -f "$GITEA_SSH_KEY" ]]; then GITEA_URL="ssh://git@${GITEA_IP}:${SSH_PORT}/${GITEA_REPO_PATH}" log "trying Gitea: $GITEA_URL" git -C "$SCRIPTS_DIR" remote add origin "$GITEA_URL" >> "$LOG" 2>&1 if GIT_SSH_COMMAND="ssh -i $GITEA_SSH_KEY -p $SSH_PORT -o StrictHostKeyChecking=no" \ GIT_TERMINAL_PROMPT=0 \ git -C "$SCRIPTS_DIR" fetch --depth=1 origin "$BRANCH" >> "$LOG" 2>&1; then git -C "$SCRIPTS_DIR" reset --hard FETCH_HEAD >> "$LOG" 2>&1 git -C "$SCRIPTS_DIR" branch -M "$BRANCH" >> "$LOG" 2>&1 log "scripts installed from Gitea ($GITEA_IP)" CLONED=true else log "Gitea fetch failed — falling back to GitHub" git -C "$SCRIPTS_DIR" remote remove origin >> "$LOG" 2>&1 || true fi fi if [[ "$CLONED" == false ]]; then log "trying GitHub: $GITHUB" git -C "$SCRIPTS_DIR" remote add origin "$GITHUB" >> "$LOG" 2>&1 if GIT_TERMINAL_PROMPT=0 \ git -C "$SCRIPTS_DIR" fetch --depth=1 origin "$BRANCH" >> "$LOG" 2>&1; then git -C "$SCRIPTS_DIR" reset --hard FETCH_HEAD >> "$LOG" 2>&1 git -C "$SCRIPTS_DIR" branch -M "$BRANCH" >> "$LOG" 2>&1 log "scripts installed from GitHub" CLONED=true else log "WARNING: both Gitea and GitHub failed — scripts not installed, retry when network is up" exit 0 fi fi else log "repo present — leaving scripts untouched (update from the UI)" fi # Seed master.conf from template if absent. mkdir -p "$CONF_DIR" if [[ ! -f "$CONF_DIR/master.conf" && -f "$SCRIPTS_DIR/Deployment/conf_templates/master.conf" ]]; then cp "$SCRIPTS_DIR/Deployment/conf_templates/master.conf" "$CONF_DIR/master.conf" log "seeded master.conf from template" fi log "install step complete" ]]> /dev/null) SCRIPTS_DIR="${_sd:-$CFG_DIR}" # Stop continuous background scripts. if [[ -f "$SCRIPTS_DIR/Fallback/fallback.sh" ]]; then bash "$SCRIPTS_DIR/Fallback/fallback.sh" --stop 2>/dev/null && log "fallback.sh stopped" || true fi pkill -f "run_job.sh" 2>/dev/null || true pkill -f "watchdog_orchestrator.sh" 2>/dev/null || true # Remove cron entries. if [[ -f "$CRON_FILE" ]]; then rm -f "$CRON_FILE" /usr/local/sbin/update_cron 2>/dev/null || true log "cron removed" fi rm -f /etc/cron.d/varaverk # Remove the installed package (and its RAM files). removepkg "$PLUGIN" 2>/dev/null || true [[ -L "$WEB_DIR" ]] && rm -f "$WEB_DIR" [[ -d "$WEB_DIR" ]] && rm -rf "$WEB_DIR" log "web files removed" # Remove flash config (incl. cached .txz). rm -rf "$CFG_DIR" log "flash config removed" log "done — scripts/conf in $SCRIPTS_DIR preserved (delete manually for full wipe)" ]]>