Files
Varaverk/Plugin/unraid/Tools/remote_arr_cache_writer.sh
T
Gmer4Lfe 9c3ace95a7 Auth stack certs tab, arrs db fallbacks, cert monitor cache, conf parser fix
- Auth stack: fold cert monitor into Auth Stack page as fourth tab (Certs);
  remove standalone cert page and top-level tab
- cert_monitor.sh: write JSON status cache to State_Files/cert_status.json
  after each run; expose per-domain days/expiry via _CERT_DAYS/_CERT_EXPIRY globals
- api/cert.php: new — serves cached cert status; falls back to configured
  domains as UNKN when no cache exists; POST action=run triggers live check
- arrs db fallbacks: vv_arr_cleanup_stats/discovery_stats/recovery_stats now
  read from data/*.db files when log JSON files don't yet exist
- config.php vv_conf_vars(): unescape bash \$ → $ so passwords with dollar
  signs read correctly from conf files
- host1.conf: fill in HOST1_NPM_USER/PASS and HOST1_LLDAP_USER/PASS
- Partnership adapter pattern: Unraid-specific container logic extracted to
  Plugin/unraid/Partnership/; platform-agnostic structure stays in Partnership/
- First-run wizard: uniform multi-step flow for all hosts; HOST2 pull moved
  to checklist; auto SSH keygen and API key creation on save
- api/checklist.php: live setup checklist with pull_master action
- Fullscreen toggle: hide Unraid header/menu; state persists via localStorage
2026-06-05 23:17:30 -04:00

143 lines
5.3 KiB
Bash
Executable File

#!/bin/bash
# ==============================================================================================
# ============================= Remote Arr Cache Writer ========================================
# ==============================================================================================
#
# PURPOSE
# ─────────────────────────────────────────────────────────────────────────────
# SSHes to each remote partner host, calls vv_arrs_local_node() on their PHP
# stack, and caches the result locally in /tmp/vv_cache/arrs_remote_hostN.json.
#
# The arrs page reads these files for instant initial load without hitting the
# remote arr APIs on every page view. This script runs every 2 hours so remote
# library counts stay reasonably current without hammering the network.
#
# Accepts --host=HOST2 to refresh a single host (used by the UI refresh button).
#
# ==============================================================================================
# USAGE
# ==============================================================================================
#
# remote_arr_cache_writer.sh — refresh all remote hosts
# remote_arr_cache_writer.sh --host=HOST2 — refresh one host only
# remote_arr_cache_writer.sh --dry-run — show what would happen
# remote_arr_cache_writer.sh --log — verbose output
#
# ==============================================================================================
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../../../load_config.sh"
parse_args "$@"
acquire_lock
detect_hosts
# Parse --host= from raw args
TARGET_HOST=""
for arg in "$@"; do
case "$arg" in --host=*) TARGET_HOST="${arg#--host=}" ;; esac
done
mkdir -p "$VV_CACHE_DIR"
log "$ICON_GEAR Config: target=${TARGET_HOST:-all hosts} ssh-key=${SSH_KEY}"
FETCH_OK=0
FETCH_FAIL=0
FETCH_SKIP=0
echo ""
echo "━━━ $ICON_SYNC Remote Arr Cache Writer ━━━"
[[ "$DRY_RUN" == true ]] && warn "DRY RUN — no changes will be made"
[[ -n "$TARGET_HOST" ]] && echo " Target: $TARGET_HOST"
echo ""
for host_var in HOST1 HOST2 HOST3 HOST4 HOST5 HOST6 HOST7 HOST8; do
[[ "$host_var" == "$MY_ID" ]] && continue
hostname="${!host_var:-}"
[[ -z "$hostname" ]] && continue
# If targeting a specific host, skip others
if [[ -n "$TARGET_HOST" ]]; then
[[ "${host_var,,}" != "${TARGET_HOST,,}" && "$host_var" != "$TARGET_HOST" ]] && continue
fi
host_id="${host_var,,}" # host1, host2, …
cache_file="$VV_CACHE_DIR/arrs_remote_${host_id}.json"
echo " $host_var ($hostname)…"
if [[ "$DRY_RUN" == true ]]; then
warn " DRY RUN — would SSH to $hostname and cache arr data"
(( FETCH_SKIP++ ))
continue
fi
# Resolve Tailscale IP
REMOTE_IP=$(resolve_tailscale_ip "$hostname")
if [[ -z "$REMOTE_IP" ]]; then
warn " $host_var: cannot resolve Tailscale IP for $hostname — skipping"
(( FETCH_FAIL++ ))
continue
fi
log " $host_var: resolved $hostname$REMOTE_IP"
# Single SSH connection — fetch arrs + monitor stats together
RESULT=$(ssh -i "$SSH_KEY" \
-o ConnectTimeout=10 \
-o StrictHostKeyChecking=no \
-o BatchMode=yes \
"root@${REMOTE_IP}" \
"php -r \"
require_once '/usr/local/emhttp/plugins/varaverk/include/arrs.php';
require_once '/usr/local/emhttp/plugins/varaverk/include/unraid_api.php';
echo json_encode([
'arrs' => vv_arrs_local_node(),
'monitor' => vv_local_host_stats(),
]);
\"" 2>/dev/null)
if [[ -z "$RESULT" ]]; then
warn " $host_var: empty SSH response — skipping"
(( FETCH_FAIL++ ))
continue
fi
# Validate combined JSON
if ! echo "$RESULT" | php -r "
\$d = json_decode(file_get_contents('php://stdin'), true);
exit(!is_array(\$d) || !isset(\$d['arrs'], \$d['monitor']) ? 1 : 0);
" 2>/dev/null; then
warn " $host_var: invalid JSON — skipping"
log " Response: ${RESULT:0:200}"
(( FETCH_FAIL++ ))
continue
fi
# Save arr cache
echo "$RESULT" | php -r "
\$d = json_decode(file_get_contents('php://stdin'), true);
file_put_contents('$cache_file', json_encode(\$d['arrs']));
" 2>/dev/null
# Save monitor cache
MONITOR_CACHE="$VV_CACHE_DIR/monitor_remote_${host_id}.json"
echo "$RESULT" | php -r "
\$d = json_decode(file_get_contents('php://stdin'), true);
file_put_contents('$MONITOR_CACHE', json_encode(\$d['monitor']));
" 2>/dev/null
CACHED_TYPES=$(echo "$RESULT" | php -r "
\$d = json_decode(file_get_contents('php://stdin'), true);
echo implode(', ', array_column(\$d['arrs']['arrs'] ?? [], 'type'));
" 2>/dev/null)
echo " $host_var: arrs [${CACHED_TYPES:-none}] + monitor stats cached ✅"
(( FETCH_OK++ ))
done
echo ""
echo "━━━━━ $ICON_SUMMARY Cache Writer Summary ━━━━━"
echo " $FETCH_OK updated · $FETCH_FAIL failed · $FETCH_SKIP skipped"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"