audit echo vs log across all scripts — outcomes always visible, verbose for per-item loops
This commit is contained in:
@@ -0,0 +1,256 @@
|
||||
<?xml version='1.0' standalone='yes'?>
|
||||
<!DOCTYPE PLUGIN [
|
||||
<!ENTITY name "varaverk">
|
||||
<!ENTITY author "gmer4lfe">
|
||||
<!ENTITY version "2026.05.31">
|
||||
<!ENTITY sha256 "d588470d6cc7f284601cb56039d5dfea6fb5bb1ee2c800657438a8edacafbd01">
|
||||
<!ENTITY launch "varaverk/monitor">
|
||||
<!ENTITY github "https://github.com/FailedProxy/Varaverk">
|
||||
<!ENTITY branch "main">
|
||||
<!ENTITY cfgdir "/boot/config/plugins/varaverk">
|
||||
<!ENTITY plugdir "/usr/local/emhttp/plugins/varaverk">
|
||||
<!ENTITY pkg "varaverk-&version;-noarch-1.txz">
|
||||
]>
|
||||
<PLUGIN name="&name;" author="&author;" version="&version;" launch="&launch;"
|
||||
support="https://github.com/FailedProxy/Varaverk/issues"
|
||||
icon="/plugins/varaverk/icons/varaverk.png">
|
||||
|
||||
<CHANGES>
|
||||
###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
|
||||
</CHANGES>
|
||||
|
||||
<!--
|
||||
── 1. Web files symlink (runs on every boot) ──────────────────────────────────
|
||||
Instead of extracting a .txz, we symlink the installed plugin web dir directly
|
||||
to the workspace on flash. Changes to Plugin/unraid/ are live instantly — no
|
||||
package build, no sync step. /boot is always mounted before this runs.
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
-->
|
||||
<FILE Run="/bin/bash">
|
||||
<INLINE>
|
||||
<![CDATA[
|
||||
#!/bin/bash
|
||||
WEB_DIR="/usr/local/emhttp/plugins/varaverk"
|
||||
SRC="/boot/config/plugins/varaverk/Plugin/unraid"
|
||||
[[ -L "$WEB_DIR" ]] && rm -f "$WEB_DIR"
|
||||
[[ -d "$WEB_DIR" ]] && rm -rf "$WEB_DIR"
|
||||
ln -sf "$SRC" "$WEB_DIR"
|
||||
echo "[Varaverk] web dir symlinked → $SRC"
|
||||
]]>
|
||||
</INLINE>
|
||||
</FILE>
|
||||
|
||||
<!--
|
||||
── 2. Scripts bootstrap (first install only) ──────────────────────────────────
|
||||
Clones the repo directly into the plugin config dir on flash (/boot/config/plugins/varaverk).
|
||||
No array dependency — scripts live on flash (64GB NVMe) and are available at boot.
|
||||
Uses git init+fetch+reset so the clone works into the non-empty cfgdir (varaverk.cfg,
|
||||
varaverk-*.txz etc. are already there). Never auto-pulls — updates via the UI git pull.
|
||||
|
||||
Clone source priority:
|
||||
1. Gitea (internal) — reads settings from varaverk.cfg; detects container IP at runtime
|
||||
2. GitHub (public) — HTTPS fallback if Gitea is unreachable
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
-->
|
||||
<FILE Run="/bin/bash" Method="install">
|
||||
<INLINE>
|
||||
<![CDATA[
|
||||
#!/bin/bash
|
||||
PLUGIN="varaverk"
|
||||
CFG_DIR="/boot/config/plugins/$PLUGIN"
|
||||
CFG_FILE="$CFG_DIR/varaverk.cfg"
|
||||
GITHUB="https://github.com/FailedProxy/Varaverk"
|
||||
BRANCH="main"
|
||||
LOG="$CFG_DIR/install.log"
|
||||
|
||||
mkdir -p "$CFG_DIR"
|
||||
log() { echo "[$(date '+%H:%M:%S')] $*" | tee -a "$LOG"; }
|
||||
|
||||
# Scripts live in the plugin dir on flash — no array needed.
|
||||
SCRIPTS_DIR="$CFG_DIR"
|
||||
CONF_DIR="$SCRIPTS_DIR/Configurations"
|
||||
|
||||
# ── Boot device check ─────────────────────────────────────────────────────────
|
||||
# Warn if /boot is on a USB/removable device. Varaverk is designed for internal
|
||||
# NVMe/SSD boot — git repo + state files + data writes on USB will wear it out
|
||||
# fast and may run out of space. Install proceeds but user is warned.
|
||||
_boot_dev=$(df /boot --output=source 2>/dev/null | tail -1)
|
||||
_boot_base=$(lsblk -no pkname "$_boot_dev" 2>/dev/null || basename "${_boot_dev%[0-9p]*}")
|
||||
_removable=$(cat "/sys/block/${_boot_base}/removable" 2>/dev/null || echo "0")
|
||||
if [[ "$_removable" == "1" ]]; then
|
||||
log "WARNING: /boot is on a removable/USB device ($_boot_dev)"
|
||||
log "WARNING: Varaverk is designed for internal NVMe/SSD boot."
|
||||
log "WARNING: Running from USB risks drive wear and space exhaustion."
|
||||
log "WARNING: Strongly recommend migrating boot to an internal NVMe/SSD drive."
|
||||
fi
|
||||
unset _boot_dev _boot_base _removable
|
||||
|
||||
# Seed varaverk.cfg with defaults (SCRIPTS_DIR + Gitea settings) if not present.
|
||||
# Requires internal NVMe/SSD boot — scripts live on flash, available before array mounts.
|
||||
if [[ ! -f "$CFG_FILE" ]]; then
|
||||
cat > "$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
|
||||
git -C "$SCRIPTS_DIR" branch --set-upstream-to=origin/"$BRANCH" "$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
|
||||
git -C "$SCRIPTS_DIR" branch --set-upstream-to=origin/"$BRANCH" "$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"
|
||||
]]>
|
||||
</INLINE>
|
||||
</FILE>
|
||||
|
||||
<!--
|
||||
── 3. Remove ───────────────────────────────────────────────────────────────────
|
||||
Stops background scripts, removes cron, the installed package, and flash config.
|
||||
Scripts/conf in appdata are left intact (delete manually for a full wipe).
|
||||
────────────────────────────────────────────────────────────────────────────────
|
||||
-->
|
||||
<FILE Run="/bin/bash" Method="remove">
|
||||
<INLINE>
|
||||
<![CDATA[
|
||||
#!/bin/bash
|
||||
PLUGIN="varaverk"
|
||||
CFG_DIR="/boot/config/plugins/$PLUGIN"
|
||||
CFG_FILE="$CFG_DIR/varaverk.cfg"
|
||||
CRON_FILE="$CFG_DIR/varaverk.cron"
|
||||
WEB_DIR="/usr/local/emhttp/plugins/$PLUGIN"
|
||||
log() { echo "[Varaverk remove] $*"; }
|
||||
|
||||
[[ -f "$CFG_FILE" ]] && _sd=$(grep -oP '(?<=SCRIPTS_DIR=")[^"]+' "$CFG_FILE" 2>/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)"
|
||||
]]>
|
||||
</INLINE>
|
||||
</FILE>
|
||||
|
||||
</PLUGIN>
|
||||
Reference in New Issue
Block a user