1. fix(install_nfqws): добавлены libmnl-dev и zlib1g-dev для всех дистрибутивов - Ubuntu/Debian: libmnl-dev zlib1g-dev - Arch: libmnl zlib - Fedora: libmnl-devel zlib-devel - Alpine: libmnl-dev zlib-dev Исправляет fatal error: libmnl/libmnl.h и zlib.h при сборке nfqws. 2. fix(test_zapret): исправлен вывод результатов теста - было: Results: / passed (всегда 1/1) - стало: Results: / passed (реальные цифры) 3. fix(autotest): cleanup_firewall перед каждым тестом стратегии - Убирает остатки iptables/nftables от предыдущего теста 4. fix(install): корректная обработка exit 2 от sync_from_upstream.sh - exit 2 = успешный sync + флаг rebuild, не ошибка - Теперь не пишет '[!] Sync failed' при нормальном обновлении 5. fix(service): убран рекурсивный вызов bash $0 remove_services - Используется прямой вызов функции service_remove() 6. fix(update): корректная запись версии в .service/version.txt - Убран префикс LOCAL_VERSION= из записи - Добавлена очистка кавычек через sed/tr 7. fix(service): проверка $DISPLAY перед xdg-open в check_for_updates - Предотвращает ошибки 'cannot open display' на headless/SSH
223 lines
6.2 KiB
Bash
223 lines
6.2 KiB
Bash
#!/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
|