Files
OpenCode Agent 62ec6c5749 fix(core): critical fixes for service menu, autotest, strategy runner, dependencies
- service.sh: split service_remove into internal (no prompts) and interactive
  versions to prevent 'eternal wait' when installing new strategy.
  Install now calls service_remove_internal > /dev/null instead of service_remove.
  Also filter strategy list to general*.sh only to avoid clutter.
  Systemd ExecStart now points to run_strategy.sh <name> consistently.

- run_strategy.sh: add SIGTERM/SIGINT trap cleanup_strategy() that kills nfqws
  and cleans up firewall. Prevents stale nfqws/firewall rules after autotest kill.
  Also handles nfqws exit gracefully with final cleanup.

- autotest.sh: rewritten to test strategies by config name (not wrapper filename).
  Stop now sends SIGTERM to wrapper (which triggers trap cleanup) instead of
  bare kill. Added extra sleep after stop to let trap fire.
  Auto-install ExecStart fixed to run_strategy.sh <strategy>.

- setup.sh: added libmnl-dev and zlib1g-dev to Ubuntu/Debian dependency install
  to prevent build failures (missing libmnl/libmnl.h and zlib.h).

- general*.sh: removed UTF-8 BOM (0xEF 0xBB 0xBF) that caused 'exec format error'
  when running scripts on Linux. All 19 wrappers cleaned.

- ensure_wrappers.sh: always rewrite wrappers to ensure no stale BOM or paths.

Fixes: eternal wait on menu option 1, nfqws build failure, stale processes after test.
2026-05-10 22:47:48 +04:00

223 lines
6.2 KiB
Bash
Executable File

#!/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 <<EOF
Usage: sudo ./update.sh [OPTIONS]
Full pipeline: sync upstream lists/hosts/version → rebuild nfqws → test → install.
Options:
--auto, -a Non-interactive (for cron/systemd timers)
--force, -f Force rebuild even if versions match
--full-auto Same as --auto --force (always rebuild + re-test)
--help, -h Show this help
Examples:
sudo ./update.sh # interactive prompt
sudo ./update.sh --full-auto # headless, always rebuild
sudo ./update.sh --auto # headless, only if upstream changed
EOF
exit 0
;;
*) echo "Unknown: $1"; exit 1 ;;
esac
done
if [[ "$MODE" == "auto" ]]; then
if [[ "$FORCE" == "yes" ]]; then
full_pipeline auto yes
else
auto_mode
fi
else
full_pipeline interactive "$FORCE"
fi