#!/bin/bash # update.sh - Full auto-pipeline: sync upstream → update → build → test → install # Version: 2.0 set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/lib/functions.sh" LOCAL_VERSION_FILE="$SCRIPT_DIR/.service/version.txt" UPDATE_LOG="$SCRIPT_DIR/.service/update.log" mkdir -p "$SCRIPT_DIR/.service" log_msg() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$UPDATE_LOG" } # Check if nfqws binary is healthy verify_nfqws() { local bin="$BIN_DIR/nfqws" if [[ ! -x "$bin" ]]; then log_msg "[FAIL] nfqws binary missing or not executable: $bin" return 1 fi if ! "$bin" --help >/dev/null 2>&1; then log_msg "[FAIL] nfqws binary does not run (segfault?)" return 1 fi log_msg "[OK] nfqws binary verified." return 0 } # Rebuild nfqws rebuild_nfqws() { log_msg "[*] Rebuilding nfqws..." if bash "$SCRIPT_DIR/install_nfqws.sh"; then verify_nfqws else log_msg "[FAIL] Build script failed." return 1 fi } # Run autotest pipeline run_pipeline_autotest() { log_msg "[*] Running auto-test pipeline..." if command -v systemctl >/dev/null 2>&1; then systemctl stop zapret.service 2>/dev/null || true fi cleanup_firewall >/dev/null 2>&1 || true sleep 2 bash "$SCRIPT_DIR/autotest.sh" --auto && { log_msg "[OK] Auto-test: working strategy found and installed." return 0 } || { log_msg "[WARN] Auto-test: no working strategy found." return 1 } } # Restart systemd service restart_service() { if command -v systemctl >/dev/null 2>&1; then if systemctl is-enabled zapret.service >/dev/null 2>&1; then log_msg "[*] Restarting zapret.service..." systemctl restart zapret.service log_msg "[OK] Service restarted." fi fi } # Step 0: Sync upstream do_sync() { log_msg "[*] Step 0: Syncing upstream strategies, lists, hosts..." bash "$SCRIPT_DIR/sync_from_upstream.sh" 2>&1 | tee -a "$UPDATE_LOG" local sync_status=${PIPESTATUS[0]} case "$sync_status" in 0) log_msg "[OK] Sync complete, no rebuild needed." SYNC_REBUILD=0 ;; 2) log_msg "[OK] Sync complete, REBUILD FLAGGED (new version or lists changed)." SYNC_REBUILD=1 ;; *) log_msg "[WARN] Sync encountered errors (exit $sync_status). Continue anyway." SYNC_REBUILD=0 ;; esac } # Step 1-4: Main pipeline full_pipeline() { local mode="${1:-interactive}" local force="${2:-no}" [[ "$mode" == "interactive" ]] && { echo "" echo "==============================================" echo " Zapret Full Auto Pipeline v2.0" echo " Current: $LOCAL_VERSION" echo "==============================================" echo "" } # Step 0: Always sync upstream first do_sync # Determine if we need to rebuild local need_rebuild=0 if [[ "$force" == "yes" ]]; then log_msg "[*] Force rebuild requested." need_rebuild=1 elif [[ "${SYNC_REBUILD:-0}" -eq 1 ]]; then log_msg "[*] Rebuild flagged by sync." need_rebuild=1 fi if [[ "$need_rebuild" -eq 0 ]] && [[ "$mode" == "interactive" ]]; then read -rp "No upstream changes detected. Force rebuild + re-test? [y/N]: " ans [[ "$ans" == [yY]* ]] && need_rebuild=1 fi if [[ "$need_rebuild" -eq 0 ]]; then log_msg "[*] No rebuild needed. Exiting." exit 0 fi # Step 1: Update version marker log_msg "[*] Step 1: Updating version marker..." local upstream_ver upstream_ver=$(cat "$LOCAL_VERSION_FILE" 2>/dev/null | sed 's/LOCAL_VERSION=//' | tr -d '\\"' || echo "$LOCAL_VERSION") echo "$upstream_ver" > "$LOCAL_VERSION_FILE" # Step 2: Rebuild nfqws log_msg "[*] Step 2: Rebuilding nfqws..." if ! rebuild_nfqws; then log_msg "[CRITICAL] Build failed. Aborting." exit 1 fi # Step 3: Auto-test log_msg "[*] Step 3: Auto-testing strategies..." run_pipeline_autotest || true # Step 4: Restart log_msg "[*] Step 4: Restarting service..." restart_service log_msg "[SUCCESS] Full pipeline complete." [[ "$mode" == "interactive" ]] && { echo "" print_green "==============================================" print_green " Pipeline Complete!" print_green " Version: $(cat "$LOCAL_VERSION_FILE" 2>/dev/null || echo "$LOCAL_VERSION")" print_green "==============================================" systemctl status zapret --no-pager 2>/dev/null || true } } # Non-interactive cron mode auto_mode() { log_msg "Auto-update started..." log_msg "[*] Syncing upstream..." bash "$SCRIPT_DIR/sync_from_upstream.sh" --auto 2>&1 | tee -a "$UPDATE_LOG" local sync_status=${PIPESTATUS[0]} if [[ "$sync_status" -ne 2 ]]; then log_msg "No update needed or sync failed. Exiting." exit 0 fi log_msg "Update detected, running full pipeline..." rebuild_nfqws || { log_msg "[FAIL] Rebuild failed."; exit 1; } run_pipeline_autotest || true restart_service log_msg "Auto-update finished." } # CLI MODE="interactive" FORCE="no" while [[ $# -gt 0 ]]; do case "$1" in --auto|-a) MODE="auto"; shift ;; --force|-f) FORCE="yes"; shift ;; --full-auto) MODE="auto"; FORCE="yes"; shift ;; --help|-h) cat <