diff --git a/Configurations/host.conf.template b/Configurations/host.conf.template index 16088eb..1393590 100644 --- a/Configurations/host.conf.template +++ b/Configurations/host.conf.template @@ -68,6 +68,18 @@ # # ============================================================================================== +# ============================================================================================== +# ── STORAGE MODE ────────────────────────────────────────────────────────────────────────────── +# ============================================================================================== + +# ━━━ Storage mode ━━━ +# Controls where Varaverk stores scripts, conf, and state files. +# true = internal NVMe/SSD — /boot/config/plugins/varaverk (write-safe, git-direct) +# false = USB flash boot — /mnt/user/appdata/Varaverk (preserves flash lifetime) +# Auto-detected from boot device transport on first setup. +# To change: Settings → Storage → Migrate. + HOSTN_STORAGE_MODE_INTERNAL=true + # ============================================================================================== # ── IDENTITY & CONNECTIVITY ─────────────────────────────────────────────────────────────────── # ============================================================================================== diff --git a/Partnership/partnership_transfer.sh b/Partnership/partnership_transfer.sh index d8e6993..f50179c 100755 --- a/Partnership/partnership_transfer.sh +++ b/Partnership/partnership_transfer.sh @@ -291,11 +291,16 @@ if [[ "$DRY_RUN" == false ]]; then # Push updated master.conf to new owner so both servers agree immediately. # master.conf is shared — host-specific credentials live in host*.conf. + _REMOTE_SD=$(ssh -i "$SSH_KEY" -o ConnectTimeout=5 -o StrictHostKeyChecking=no \ + "root@${MIRROR_IP}" \ + "grep -m1 '^SCRIPTS_DIR' /boot/config/plugins/varaverk/varaverk.cfg 2>/dev/null | cut -d= -f2 | tr -d '\"'" \ + 2>/dev/null | tr -d '[:space:]') + _REMOTE_SD="${_REMOTE_SD:-/boot/config/plugins/varaverk}" scp -i "$SSH_KEY" \ -o ConnectTimeout="$SSH_TIMEOUT" \ -o StrictHostKeyChecking=no \ "$SCRIPTS_ROOT/Configurations/master.conf" \ - "root@${MIRROR_IP}:/boot/config/plugins/varaverk/Configurations/master.conf" 2>/dev/null && \ + "root@${MIRROR_IP}:${_REMOTE_SD}/Configurations/master.conf" 2>/dev/null && \ log "master.conf pushed to $NEW_OWNER ✅" || \ error "Failed to push master.conf to $NEW_OWNER — set PARTNERSHIP_OWNER_HOST=\"$NEW_OWNER_ID\" manually" else diff --git a/Plugin/unraid/Varaverk.page b/Plugin/unraid/Varaverk.page index fa7afd8..ecf8e74 100644 --- a/Plugin/unraid/Varaverk.page +++ b/Plugin/unraid/Varaverk.page @@ -24,9 +24,9 @@ unset($_master, $_h1m, $_host1_blank, $_my_hostid, $_conf_missing); // Determine active tab $tab = $_GET['tab'] ?? 'monitor'; -$validTabs = ['monitor', 'scheduler', 'docker', 'watchdog', 'partnership', 'fallback', 'arrs', 'rsync']; +$validTabs = ['monitor', 'scheduler', 'docker', 'watchdog', 'partnership', 'fallback', 'arrs', 'rsync', 'settings']; if (!in_array($tab, $validTabs)) $tab = 'monitor'; -$tabLabels = ['monitor' => 'Monitor', 'scheduler' => 'Scheduler', 'docker' => 'Docker', 'watchdog' => 'Watchdog', 'partnership' => 'Partnership', 'fallback' => 'FallBack', 'arrs' => 'Arrs', 'rsync' => 'Rsync']; +$tabLabels = ['monitor' => 'Monitor', 'scheduler' => 'Scheduler', 'docker' => 'Docker', 'watchdog' => 'Watchdog', 'partnership' => 'Partnership', 'fallback' => 'FallBack', 'arrs' => 'Arrs', 'rsync' => 'Rsync', 'settings' => 'Settings']; ?> diff --git a/Plugin/unraid/api/storage.php b/Plugin/unraid/api/storage.php new file mode 100644 index 0000000..4497af8 --- /dev/null +++ b/Plugin/unraid/api/storage.php @@ -0,0 +1,98 @@ +/dev/null") ?: ''); + if (!$part) return 'unknown'; + $disk = trim(shell_exec("lsblk -no pkname " . escapeshellarg($part) . " 2>/dev/null") ?: ''); + if (!$disk) return 'unknown'; + return strtolower(trim(shell_exec("lsblk -dno TRAN /dev/" . escapeshellarg($disk) . " 2>/dev/null") ?: 'unknown')); +} + +// ── Current mode status ─────────────────────────────────────────────────────── +if ($action === 'status') { + $transport = vv_storage_detect_transport(); + $detected = ($transport === 'usb') ? 'flash' : 'internal'; + $currentDir = SCRIPTS_DIR; + $internalDir = '/boot/config/plugins/varaverk'; + $flashDir = '/mnt/user/appdata/Varaverk'; + $currentMode = ($currentDir === $internalDir) ? 'internal' + : ($currentDir === $flashDir ? 'flash' : 'custom'); + + $myHost = vv_detect_host(); + $vars = vv_conf_vars(); + $confKey = strtoupper($myHost) . '_STORAGE_MODE_INTERNAL'; + $confVal = $vars[$confKey] ?? null; + + // Boot device name for display + $bootPart = trim(shell_exec("findmnt -n -o SOURCE /boot 2>/dev/null") ?: ''); + $bootDisk = $bootPart ? trim(shell_exec("lsblk -no pkname " . escapeshellarg($bootPart) . " 2>/dev/null") ?: '') : ''; + + echo json_encode([ + 'ok' => true, + 'current_mode' => $currentMode, + 'current_dir' => $currentDir, + 'internal_dir' => $internalDir, + 'flash_dir' => $flashDir, + 'transport' => $transport, + 'detected' => $detected, + 'boot_disk' => $bootDisk ? '/dev/' . $bootDisk : 'unknown', + 'conf_key' => $confKey, + 'conf_val' => $confVal, + 'array_started'=> is_dir('/mnt/user') && count(scandir('/mnt/user')) > 2, + ]); + exit; +} + +// ── Run migration ───────────────────────────────────────────────────────────── +if ($action === 'migrate' && $_SERVER['REQUEST_METHOD'] === 'POST') { + $to = trim($_POST['to'] ?? ''); + if (!in_array($to, ['internal', 'flash'], true)) { + echo json_encode(['ok' => false, 'error' => 'Invalid target: must be internal or flash']); + exit; + } + + $script = SCRIPTS_DIR . '/Tools/storage_migrate.sh'; + if (!file_exists($script)) { + echo json_encode(['ok' => false, 'error' => 'storage_migrate.sh not found']); + exit; + } + + set_time_limit(300); + $output = []; + $exit = 0; + exec('bash ' . escapeshellarg($script) . ' --to=' . escapeshellarg($to) . ' 2>&1', $output, $exit); + + echo json_encode([ + 'ok' => $exit === 0, + 'exit' => $exit, + 'output' => implode("\n", $output), + ]); + exit; +} + +// ── Auto-detect and write to conf ───────────────────────────────────────────── +if ($action === 'detect' && $_SERVER['REQUEST_METHOD'] === 'POST') { + $transport = vv_storage_detect_transport(); + $detected = ($transport === 'usb') ? 'false' : 'true'; + $myHost = vv_detect_host(); + $confKey = strtoupper($myHost) . '_STORAGE_MODE_INTERNAL'; + $confFile = $myHost . '.conf'; + + $results = vv_conf_write_changes([[ + 'file' => $confFile, + 'key' => $confKey, + 'value' => $detected, + 'type' => 'scalar', + ]]); + + $ok = !in_array(false, $results, true); + echo json_encode(['ok' => $ok, 'detected' => $detected, 'transport' => $transport]); + exit; +} + +echo json_encode(['ok' => false, 'error' => 'Unknown action']); diff --git a/Plugin/unraid/include/docker.php b/Plugin/unraid/include/docker.php index f0a367a..e5c1388 100644 --- a/Plugin/unraid/include/docker.php +++ b/Plugin/unraid/include/docker.php @@ -6,7 +6,7 @@ require_once __DIR__ . '/config.php'; -define('VV_DOCKER_JSON', '/boot/config/plugins/varaverk/docker_folders.json'); +define('VV_DOCKER_JSON', SCRIPTS_DIR . '/docker_folders.json'); define('VV_FV3_JSON', '/boot/config/plugins/folder.view3/docker.json'); // ── JSON helpers ────────────────────────────────────────────────────────────── diff --git a/Plugin/unraid/include/scheduler.php b/Plugin/unraid/include/scheduler.php index a324118..90103db 100644 --- a/Plugin/unraid/include/scheduler.php +++ b/Plugin/unraid/include/scheduler.php @@ -5,8 +5,8 @@ require_once __DIR__ . '/config.php'; require_once __DIR__ . '/confform.php'; -define('SCHEDULE_FILE', '/boot/config/plugins/varaverk/schedule.json'); -define('CRON_FILE', '/boot/config/plugins/varaverk/varaverk.cron'); +define('SCHEDULE_FILE', SCRIPTS_DIR . '/schedule.json'); +define('CRON_FILE', '/boot/config/plugins/varaverk/varaverk.cron'); // must stay in /boot — update_cron scans there function vv_pretty_label(string $slug): string { return ucwords(str_replace('_', ' ', $slug)); diff --git a/Plugin/unraid/pages/settings.php b/Plugin/unraid/pages/settings.php new file mode 100644 index 0000000..e28494a --- /dev/null +++ b/Plugin/unraid/pages/settings.php @@ -0,0 +1,201 @@ + + + +
+ + +
+
+ Storage Location + +
+ +
Loading…
+ +
+ +
+ Varaverk stores all scripts, configuration, state files, and the git repository in + SCRIPTS_DIR. +
+ Internal NVMe/SSD — direct access, zero write-wear concern, git pull/push from boot volume.
+ USB Flash — preserves flash lifetime. Requires array to be started. git pull syncs + Plugin/ + back to /boot/ + after each pull so the webUI always stays current. +
+ +
+ Array must be started for Varaverk to function in flash mode. The plugin tab is always accessible. +
+
+ Array is not started — cannot migrate to flash mode right now. Start the array first. +
+ +
+ + + +
+ +

+  
+ +
+ + diff --git a/Plugin/unraid/run_job.sh b/Plugin/unraid/run_job.sh index 351a400..c7c3faa 100755 --- a/Plugin/unraid/run_job.sh +++ b/Plugin/unraid/run_job.sh @@ -44,7 +44,9 @@ if [[ "$MANUAL" == false && -f "$MANUAL_TS_FILE" ]]; then # Only suppress for interval-based crons (*/N * * * *). # Static schedules like "30 2 * * 0" run at their appointed time and are never suppressed. INTERVAL=0 - SCHEDULE_FILE="/boot/config/plugins/varaverk/schedule.json" + _VV_CFG="/boot/config/plugins/varaverk/varaverk.cfg" + _SCRIPTS_DIR=$(grep -m1 '^SCRIPTS_DIR' "$_VV_CFG" 2>/dev/null | cut -d= -f2 | tr -d '"'"'" | tr -d '[:space:]') + SCHEDULE_FILE="${_SCRIPTS_DIR:-/boot/config/plugins/varaverk}/schedule.json" if [[ -f "$SCHEDULE_FILE" ]]; then CRON_EXPR=$(php -r " \$s = json_decode(file_get_contents('$SCHEDULE_FILE'), true) ?: []; diff --git a/Tools/storage_migrate.sh b/Tools/storage_migrate.sh new file mode 100755 index 0000000..cbb86f6 --- /dev/null +++ b/Tools/storage_migrate.sh @@ -0,0 +1,323 @@ +#!/bin/bash +# ============================================================================================== +# ================================= Storage Migration ========================================== +# ============================================================================================== +# +# PURPOSE +# ───────────────────────────────────────────────────────────────────────────── +# Migrates Varaverk between internal NVMe and USB flash storage modes. +# +# Internal mode: SCRIPTS_DIR = /boot/config/plugins/varaverk +# All scripts, conf, state, and git repo live on fast internal storage. +# Direct git pull/push. Zero write-wear concern. +# +# Flash mode: SCRIPTS_DIR = /mnt/user/appdata/Varaverk +# All scripts, conf, state, and git repo live in appdata. +# Preserves USB flash lifetime. Array must be started for Varaverk to function. +# git_pull_execute.sh syncs Plugin/ back to /boot/ after each pull so the +# Unraid webUI always serves current PHP files. +# +# What this script updates: +# varaverk.cfg SCRIPTS_DIR +# master.conf TARGET_DIR +# host*.conf HOST*_STORAGE_MODE_INTERNAL +# varaverk.cron rebuilt via PHP (job paths regenerated for new SCRIPTS_DIR) +# +# ============================================================================================== +# RUNTIME MODES +# ============================================================================================== +# +# storage_migrate.sh --to=internal +# Migrate to /boot/config/plugins/varaverk +# +# storage_migrate.sh --to=flash +# Migrate to /mnt/user/appdata/Varaverk +# +# storage_migrate.sh --dry-run --to= +# Show what would happen — no changes made +# +# storage_migrate.sh --status +# Show current mode, paths, and boot device info +# +# ============================================================================================== + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "$SCRIPT_DIR/../load_config.sh" + +parse_args "$@" +acquire_lock + +VV_CFG="/boot/config/plugins/varaverk/varaverk.cfg" +INTERNAL_DIR="/boot/config/plugins/varaverk" +FLASH_DIR="/mnt/user/appdata/Varaverk" + +# ────────────────────────────────────────────────────────────────────────────── +# Parse --to= from raw args (parse_args doesn't handle this flag) +TO_MODE="" +for arg in "$@"; do + case "$arg" in + --to=internal) TO_MODE="internal" ;; + --to=flash) TO_MODE="flash" ;; + esac +done + +# ────────────────────────────────────────────────────────────────────────────── +# Boot device detection +detect_boot_storage() { + local boot_part boot_disk transport + boot_part=$(findmnt -n -o SOURCE /boot 2>/dev/null) + boot_disk=$(lsblk -no pkname "$boot_part" 2>/dev/null) + transport=$(lsblk -dno TRAN "/dev/$boot_disk" 2>/dev/null | tr '[:upper:]' '[:lower:]') + echo "${transport:-unknown}" +} + +# ────────────────────────────────────────────────────────────────────────────── +# Status +if [[ "$SHOW_STATUS" == true ]]; then + TRANSPORT=$(detect_boot_storage) + DETECTED=$([[ "$TRANSPORT" == "usb" ]] && echo "flash" || echo "internal") + echo "" + echo "━━━━━ $ICON_SUMMARY STORAGE STATUS ━━━━━" + echo "$ICON_GEAR SCRIPTS_DIR: $SCRIPTS_DIR" + echo "$ICON_GEAR varaverk.cfg: $VV_CFG" + echo "$ICON_HOST Boot device: transport=$TRANSPORT → detected=$DETECTED" + echo "$ICON_GEAR Target dirs:" + echo " internal: $INTERNAL_DIR" + echo " flash: $FLASH_DIR" + CONF_MODE=$(grep -m1 "${MY_ID}_STORAGE_MODE_INTERNAL" "$CONF_FILE" 2>/dev/null | cut -d= -f2 | tr -d '"' | tr -d '[:space:]') + echo "$ICON_GEAR conf setting: ${MY_ID}_STORAGE_MODE_INTERNAL=${CONF_MODE:-not set}" + if [[ "$SCRIPTS_DIR" == "$INTERNAL_DIR" ]]; then + echo "$ICON_DONE Current mode: INTERNAL ✅" + elif [[ "$SCRIPTS_DIR" == "$FLASH_DIR" ]]; then + echo "$ICON_DONE Current mode: FLASH ✅" + else + echo "$ICON_WARN Current mode: CUSTOM ($SCRIPTS_DIR)" + fi + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + exit 0 +fi + +# ────────────────────────────────────────────────────────────────────────────── +if [[ -z "$TO_MODE" ]]; then + error "Usage: storage_migrate.sh --to=internal|flash [--dry-run] [--log]" + exit 1 +fi + +SRC="$SCRIPTS_DIR" +DST=$([[ "$TO_MODE" == "internal" ]] && echo "$INTERNAL_DIR" || echo "$FLASH_DIR") +NEW_INTERNAL=$([[ "$TO_MODE" == "internal" ]] && echo "true" || echo "false") + +echo "" +echo "━━━━━ $ICON_SYNC Storage Migration ━━━━━" +echo "$ICON_GEAR From: $SRC" +echo "$ICON_GEAR To: $DST" +echo "$ICON_GEAR Mode: $TO_MODE" +[[ "$DRY_RUN" == true ]] && warn "DRY RUN — no changes will be made" +echo "" + +# ────────────────────────────────────────────────────────────────────────────── +# Pre-flight checks +if [[ "$SRC" == "$DST" ]]; then + info "Already in $TO_MODE mode — nothing to do" + exit 0 +fi + +if [[ "$TO_MODE" == "flash" ]]; then + if ! mountpoint -q /mnt/user 2>/dev/null; then + error "Array not started — /mnt/user is not mounted. Start the array before migrating to flash." + exit 1 + fi +fi + +if [[ ! -f "$SRC/load_config.sh" ]]; then + error "Source directory looks invalid: $SRC (load_config.sh not found)" + exit 1 +fi + +# ────────────────────────────────────────────────────────────────────────────── +# Step 1: Git push — ensure remote has everything before we touch the local repo +echo "━━━ $ICON_SYNC Step 1: Git push ━━━" +if [[ "$DRY_RUN" == false ]]; then + if [[ -d "$SRC/.git" ]]; then + log "Pushing to Gitea before migration..." + if GIT_SSH_COMMAND="ssh -i $GITEA_SSH_KEY -p $SSH_PORT" \ + git -C "$SRC" push origin main 2>&1 | while IFS= read -r line; do echo " $line"; done; then + echo " Git push complete ✅" + else + warn "Git push failed — continuing (data safe locally, push manually after migration)" + fi + else + warn "No .git directory in $SRC — skipping push" + fi +else + warn "DRY RUN — would push $SRC to Gitea" +fi + +# ────────────────────────────────────────────────────────────────────────────── +# Step 2: Rsync content to destination +echo "" +echo "━━━ $ICON_SYNC Step 2: Copy files ━━━" +if [[ "$DRY_RUN" == false ]]; then + mkdir -p "$DST" + echo " rsync: $SRC/ → $DST/" + if rsync -av --delete \ + --exclude='.git' \ + "$SRC/" "$DST/" 2>&1 | \ + grep -v "/$" | \ + while IFS= read -r line; do log "$line"; done; then + echo " Files copied ✅" + else + error "rsync failed — aborting migration" + exit 1 + fi + + # Copy .git separately (rsync --exclude='.git' above skipped it) + echo " Copying .git..." + if cp -a "$SRC/.git" "$DST/.git" 2>/dev/null || \ + rsync -a "$SRC/.git/" "$DST/.git/" 2>/dev/null; then + echo " .git copied ✅" + else + error ".git copy failed — aborting" + exit 1 + fi + + # Mark git safe directory + git config --global --add safe.directory "$DST" 2>/dev/null +else + warn "DRY RUN — would rsync $SRC/ → $DST/ (including .git)" +fi + +# ────────────────────────────────────────────────────────────────────────────── +# Step 3: Update varaverk.cfg +echo "" +echo "━━━ $ICON_GEAR Step 3: Update varaverk.cfg ━━━" +if [[ "$DRY_RUN" == false ]]; then + if grep -q '^SCRIPTS_DIR' "$VV_CFG"; then + sed -i "s|^SCRIPTS_DIR=.*|SCRIPTS_DIR=\"$DST\"|" "$VV_CFG" + else + echo "SCRIPTS_DIR=\"$DST\"" >> "$VV_CFG" + fi + echo " SCRIPTS_DIR → $DST ✅" +else + warn "DRY RUN — would set SCRIPTS_DIR=\"$DST\" in $VV_CFG" +fi + +# ────────────────────────────────────────────────────────────────────────────── +# Step 4: Update TARGET_DIR in master.conf (new location) +echo "" +echo "━━━ $ICON_GEAR Step 4: Update TARGET_DIR ━━━" +NEW_MASTER="$DST/Configurations/master.conf" +if [[ "$DRY_RUN" == false ]]; then + if [[ -f "$NEW_MASTER" ]]; then + sed -i "s|^\(\s*TARGET_DIR\s*=\s*\)\"[^\"]*\"|\1\"$DST\"|" "$NEW_MASTER" + echo " TARGET_DIR → $DST ✅" + else + error "master.conf not found at $NEW_MASTER" + exit 1 + fi +else + warn "DRY RUN — would set TARGET_DIR=\"$DST\" in master.conf" +fi + +# ────────────────────────────────────────────────────────────────────────────── +# Step 5: Update STORAGE_MODE_INTERNAL in host*.conf (new location) +echo "" +echo "━━━ $ICON_GEAR Step 5: Update STORAGE_MODE_INTERNAL ━━━" +NEW_CONF="$DST/Configurations/${MY_ID,,}.conf" +if [[ "$DRY_RUN" == false ]]; then + if [[ -f "$NEW_CONF" ]]; then + if grep -q "${MY_ID}_STORAGE_MODE_INTERNAL" "$NEW_CONF"; then + sed -i "s|^\(\s*${MY_ID}_STORAGE_MODE_INTERNAL\s*=\s*\).*|\1${NEW_INTERNAL}|" "$NEW_CONF" + else + sed -i "/# ━━━ Storage mode/a\\ ${MY_ID}_STORAGE_MODE_INTERNAL=${NEW_INTERNAL}" "$NEW_CONF" + fi + echo " ${MY_ID}_STORAGE_MODE_INTERNAL → $NEW_INTERNAL ✅" + else + warn "${MY_ID,,}.conf not found at $NEW_CONF — skipping conf update" + fi +else + warn "DRY RUN — would set ${MY_ID}_STORAGE_MODE_INTERNAL=$NEW_INTERNAL" +fi + +# ────────────────────────────────────────────────────────────────────────────── +# Step 6: Rebuild cron (paths must reference new SCRIPTS_DIR) +echo "" +echo "━━━ $ICON_GEAR Step 6: Rebuild cron ━━━" +if [[ "$DRY_RUN" == false ]]; then + RESULT=$(php -r " + define('PLUGIN_CFG', '/boot/config/plugins/varaverk/varaverk.cfg'); + \$_c = @parse_ini_file(PLUGIN_CFG) ?: []; + define('SCRIPTS_DIR', \$_c['SCRIPTS_DIR'] ?? '/boot/config/plugins/varaverk'); + define('CONF_DIR', SCRIPTS_DIR . '/Configurations'); + define('DATA_DIR', SCRIPTS_DIR . '/data'); + define('STATE_DIR', SCRIPTS_DIR . '/State_Files'); + define('LOG_DIR', '/var/log/varaverk'); + define('VV_SETUP_STATE_FILE', STATE_DIR . '/varaverk_setup.db'); + require_once '/usr/local/emhttp/plugins/varaverk/include/confform.php'; + require_once '/usr/local/emhttp/plugins/varaverk/include/scheduler.php'; + \$ok = vv_cron_rebuild(vv_schedule_load()); + echo \$ok ? 'ok' : 'fail'; + " 2>/dev/null) + if [[ "$RESULT" == "ok" ]]; then + echo " Cron rebuilt ✅" + else + warn "Cron rebuild failed — run Settings → Scheduler → Save to regenerate" + fi +else + warn "DRY RUN — would rebuild cron with new SCRIPTS_DIR paths" +fi + +# ────────────────────────────────────────────────────────────────────────────── +# Step 7: Flash mode — sync Plugin/ to /boot/ so webUI is current +if [[ "$TO_MODE" == "flash" && "$DRY_RUN" == false ]]; then + echo "" + echo "━━━ $ICON_SYNC Step 7: Sync Plugin/ → /boot/ ━━━" + if rsync -a --delete "$DST/Plugin/" "/boot/config/plugins/varaverk/Plugin/" 2>/dev/null; then + echo " Plugin/ synced to /boot/ ✅" + else + warn "Plugin/ sync to /boot/ failed — webUI may be stale" + fi +fi + +# ────────────────────────────────────────────────────────────────────────────── +# Step 8: Delete old location +echo "" +echo "━━━ $ICON_GEAR Step $([[ "$TO_MODE" == "flash" ]] && echo 8 || echo 7): Clean up old location ━━━" +if [[ "$DRY_RUN" == false ]]; then + if [[ "$SRC" == "$INTERNAL_DIR" ]]; then + # Migrating internal→flash: keep varaverk.cfg and Plugin/ in /boot/, remove everything else + echo " Removing scripts/conf/state from /boot/ (keeping Plugin/ and varaverk.cfg)..." + find "$SRC" -mindepth 1 -maxdepth 1 \ + ! -name 'Plugin' \ + ! -name 'varaverk.cfg' \ + ! -name '*.plg' \ + ! -name '*.txz' \ + -exec rm -rf {} + 2>/dev/null + echo " /boot/ cleaned ✅ (Plugin/ and varaverk.cfg preserved)" + else + # Migrating flash→internal: remove appdata copy entirely + echo " Removing $SRC..." + rm -rf "$SRC" + echo " $SRC removed ✅" + fi +else + if [[ "$SRC" == "$INTERNAL_DIR" ]]; then + warn "DRY RUN — would remove scripts/conf/state from /boot/ (keeping Plugin/ and varaverk.cfg)" + else + warn "DRY RUN — would remove $SRC" + fi +fi + +# ────────────────────────────────────────────────────────────────────────────── +echo "" +echo "━━━━━ $ICON_DONE Migration complete ━━━━━" +echo "$ICON_GEAR Mode: $TO_MODE" +echo "$ICON_GEAR SCRIPTS_DIR: $DST" +if [[ "$TO_MODE" == "flash" ]]; then + echo "" + warn "IMPORTANT: Varaverk requires the array to be started to function in flash mode." + warn "The webUI plugin tab will load normally at all times (Plugin/ stays in /boot/)." +fi +echo "" +echo " Reload the Varaverk plugin tab to apply changes." +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" diff --git a/git_pull_execute.sh b/git_pull_execute.sh index eeb3956..2684cb0 100755 --- a/git_pull_execute.sh +++ b/git_pull_execute.sh @@ -255,6 +255,19 @@ else log "Setting executable permissions on all .sh files..." find "$TARGET_DIR" -type f -name "*.sh" -exec chmod +x {} \; echo " Permissions set on .sh files" + + # ── Flash mode: sync Plugin/ to /boot/ so the webUI picks up updates ───── + # In flash mode SCRIPTS_DIR is in appdata — Plugin/ lives in the repo there + # but Unraid serves PHP from /boot/. Sync after every pull to keep them in step. + if [[ "$TARGET_DIR" != "/boot/config/plugins/varaverk" ]]; then + echo "" + echo "━━━ $ICON_SYNC Flash mode: sync Plugin/ → /boot/ ━━━" + if rsync -a --delete "$TARGET_DIR/Plugin/" "/boot/config/plugins/varaverk/Plugin/" 2>/dev/null; then + echo " Plugin/ synced to /boot/ ✅" + else + warn "Plugin/ sync to /boot/ failed — webUI may be stale until next pull" + fi + fi fi END=$(date +%s)