265 lines
8.7 KiB
Bash
Executable file
265 lines
8.7 KiB
Bash
Executable file
#!/bin/bash
|
|
# hv-clean.sh — Limpieza completa de hydra-veil para reinstalación limpia
|
|
# Elimina: wrapper, sudoers, dirs de runtime (logs/run/pid)
|
|
# Conserva: repo, venv, configs (a menos que se pase --full)
|
|
|
|
set -euo pipefail
|
|
|
|
# ─── Colores ──────────────────────────────────────────────────────────────────
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
CYAN='\033[0;36m'
|
|
DIM='\033[2m'
|
|
BOLD='\033[1m'
|
|
RESET='\033[0m'
|
|
|
|
ok() { printf " ${GREEN}✔${RESET} %s\n" "$*"; }
|
|
warn() { printf " ${YELLOW}⚠${RESET} %s\n" "$*"; }
|
|
info() { printf " ${CYAN}→${RESET} %s\n" "$*"; }
|
|
err() { printf " ${RED}✖${RESET} %s\n" "$*" >&2; }
|
|
hdr() { echo ""; printf "${BOLD}${CYAN}── %s ${RESET}\n" "$*"; echo ""; }
|
|
|
|
# ─── Paths (deben coincidir con steps.sh) ────────────────────────────────────
|
|
HV_CORE_HOME="$HOME/.local/share/hydra-veil/core"
|
|
HV_LOG_DIR="$HV_CORE_HOME/logs/hydra-veil"
|
|
HV_RUN_DIR="$HV_CORE_HOME/run"
|
|
HV_DATA_DIR="$HV_CORE_HOME/data/hydra-veil"
|
|
HV_CONFIG_DIR="$HV_DATA_DIR/configs"
|
|
HV_VENV_DIR="$HV_CORE_HOME/.venv"
|
|
|
|
SINGBOX_BIN="/usr/bin/sing-box"
|
|
SINGBOX_PID_FILE="$HV_RUN_DIR/singbox.pid"
|
|
SINGBOX_LOG_FILE="$HV_LOG_DIR/singbox.log"
|
|
|
|
WRAPPER_PATH="/usr/local/bin/hydraveil-singbox"
|
|
SUDOERS_PATH="/etc/sudoers.d/hydraveil"
|
|
|
|
# ─── Flags ────────────────────────────────────────────────────────────────────
|
|
FULL=false
|
|
YES=false
|
|
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--full|-f) FULL=true ;;
|
|
--yes|-y) YES=true ;;
|
|
--help|-h)
|
|
echo ""
|
|
echo " Uso: $0 [opciones]"
|
|
echo ""
|
|
echo " Sin flags — elimina wrapper, sudoers, logs, pid, run"
|
|
echo " conserva repo, venv y configs"
|
|
echo ""
|
|
echo " --full — todo lo anterior + repo completo, venv y configs"
|
|
echo " --yes — no pide confirmación"
|
|
echo ""
|
|
exit 0
|
|
;;
|
|
*)
|
|
err "Flag desconocido: $arg"
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# ─── Banner ───────────────────────────────────────────────────────────────────
|
|
echo ""
|
|
printf "${BOLD}${RED} hydra-veil — limpieza para reinstalación${RESET}\n"
|
|
echo ""
|
|
|
|
if $FULL; then
|
|
warn "Modo --full: se eliminará TODO incluyendo repo, venv y configs"
|
|
else
|
|
info "Modo normal: conserva repo, venv y configs"
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# ─── Confirmación ─────────────────────────────────────────────────────────────
|
|
if ! $YES; then
|
|
printf " ${YELLOW}¿Continuar?${RESET} ${DIM}[s/N]:${RESET} "
|
|
read -r _confirm < /dev/tty
|
|
case "$_confirm" in
|
|
s|S|y|Y) : ;;
|
|
*)
|
|
echo ""
|
|
info "Cancelado."
|
|
exit 0
|
|
;;
|
|
esac
|
|
echo ""
|
|
fi
|
|
|
|
# ─── 1. Detener sing-box si está corriendo ────────────────────────────────────
|
|
hdr "1. Proceso sing-box"
|
|
|
|
_stop_singbox() {
|
|
local pid=""
|
|
|
|
# Intentar via pidfile primero
|
|
if [ -f "$SINGBOX_PID_FILE" ]; then
|
|
pid=$(cat "$SINGBOX_PID_FILE" 2>/dev/null || echo "")
|
|
fi
|
|
|
|
# Si no hay pidfile, buscar por nombre
|
|
if [[ -z "$pid" || ! "$pid" =~ ^[0-9]+$ ]]; then
|
|
pid=$(pgrep -x sing-box 2>/dev/null | head -1 || echo "")
|
|
fi
|
|
|
|
if [[ -n "$pid" && "$pid" =~ ^[0-9]+$ ]] && kill -0 "$pid" 2>/dev/null; then
|
|
info "Deteniendo sing-box PID $pid..."
|
|
kill -TERM "$pid" 2>/dev/null || true
|
|
local elapsed=0
|
|
while kill -0 "$pid" 2>/dev/null && (( elapsed < 16 )); do
|
|
sleep 0.5
|
|
(( elapsed++ )) || true
|
|
done
|
|
if kill -0 "$pid" 2>/dev/null; then
|
|
kill -KILL "$pid" 2>/dev/null || true
|
|
sleep 0.3
|
|
ok "sing-box eliminado (SIGKILL)"
|
|
else
|
|
ok "sing-box detenido (SIGTERM)"
|
|
fi
|
|
else
|
|
info "sing-box no está corriendo"
|
|
fi
|
|
}
|
|
|
|
# Intentar via wrapper si existe, sino directo
|
|
if [ -x "$WRAPPER_PATH" ]; then
|
|
sudo "$WRAPPER_PATH" "" stop 2>/dev/null && ok "Detenido via wrapper" || _stop_singbox
|
|
else
|
|
_stop_singbox
|
|
fi
|
|
|
|
# Eliminar interfaz tun0 si existe
|
|
if ip link show tun0 &>/dev/null 2>&1; then
|
|
sudo ip link delete tun0 2>/dev/null && ok "tun0 eliminada" || warn "No se pudo eliminar tun0"
|
|
else
|
|
info "tun0 no existe"
|
|
fi
|
|
|
|
# ─── 2. Wrapper ───────────────────────────────────────────────────────────────
|
|
hdr "2. Wrapper"
|
|
|
|
if [ -f "$WRAPPER_PATH" ]; then
|
|
sudo rm -f "$WRAPPER_PATH"
|
|
ok "Eliminado: $WRAPPER_PATH"
|
|
else
|
|
info "No existe: $WRAPPER_PATH"
|
|
fi
|
|
|
|
# ─── 3. Sudoers ───────────────────────────────────────────────────────────────
|
|
hdr "3. Sudoers"
|
|
|
|
if [ -f "$SUDOERS_PATH" ]; then
|
|
sudo rm -f "$SUDOERS_PATH"
|
|
ok "Eliminado: $SUDOERS_PATH"
|
|
else
|
|
info "No existe: $SUDOERS_PATH"
|
|
fi
|
|
|
|
# Verificar que no haya entradas huérfanas en sudoers.d
|
|
_orphans=$(sudo grep -rl "hydraveil" /etc/sudoers.d/ 2>/dev/null || true)
|
|
if [ -n "$_orphans" ]; then
|
|
warn "Entradas huérfanas de hydraveil encontradas:"
|
|
echo "$_orphans" | while read -r f; do
|
|
warn " $f"
|
|
sudo rm -f "$f" && ok " Eliminado: $f"
|
|
done
|
|
else
|
|
info "Sin entradas huérfanas en sudoers.d"
|
|
fi
|
|
|
|
# ─── 4. PID file y runtime ────────────────────────────────────────────────────
|
|
hdr "4. Runtime (pid / run)"
|
|
|
|
if [ -f "$SINGBOX_PID_FILE" ]; then
|
|
rm -f "$SINGBOX_PID_FILE"
|
|
ok "Eliminado PID file: $SINGBOX_PID_FILE"
|
|
else
|
|
info "Sin PID file"
|
|
fi
|
|
|
|
if [ -d "$HV_RUN_DIR" ]; then
|
|
rm -rf "$HV_RUN_DIR"
|
|
ok "Eliminado: $HV_RUN_DIR"
|
|
else
|
|
info "No existe: $HV_RUN_DIR"
|
|
fi
|
|
|
|
# ─── 5. Logs ──────────────────────────────────────────────────────────────────
|
|
hdr "5. Logs"
|
|
|
|
if [ -d "$HV_LOG_DIR" ]; then
|
|
rm -rf "$HV_LOG_DIR"
|
|
ok "Eliminado: $HV_LOG_DIR"
|
|
else
|
|
info "No existe: $HV_LOG_DIR"
|
|
fi
|
|
|
|
# ─── 6. Limpieza completa (--full) ────────────────────────────────────────────
|
|
if $FULL; then
|
|
hdr "6. Limpieza completa (--full)"
|
|
|
|
# Configs
|
|
if [ -d "$HV_CONFIG_DIR" ]; then
|
|
rm -rf "$HV_CONFIG_DIR"
|
|
ok "Eliminado: $HV_CONFIG_DIR"
|
|
else
|
|
info "No existe: $HV_CONFIG_DIR"
|
|
fi
|
|
|
|
# Data dir completo
|
|
if [ -d "$HV_DATA_DIR" ]; then
|
|
rm -rf "$HV_DATA_DIR"
|
|
ok "Eliminado: $HV_DATA_DIR"
|
|
else
|
|
info "No existe: $HV_DATA_DIR"
|
|
fi
|
|
|
|
# Venv
|
|
if [ -d "$HV_VENV_DIR" ]; then
|
|
rm -rf "$HV_VENV_DIR"
|
|
ok "Eliminado venv: $HV_VENV_DIR"
|
|
else
|
|
info "No existe: $HV_VENV_DIR"
|
|
fi
|
|
|
|
# Repo completo
|
|
if [ -d "$HV_CORE_HOME/.git" ]; then
|
|
rm -rf "$HV_CORE_HOME"
|
|
ok "Eliminado repo: $HV_CORE_HOME"
|
|
elif [ -d "$HV_CORE_HOME" ]; then
|
|
rm -rf "$HV_CORE_HOME"
|
|
ok "Eliminado directorio: $HV_CORE_HOME"
|
|
else
|
|
info "No existe: $HV_CORE_HOME"
|
|
fi
|
|
|
|
# sing-box binary (solo si se instaló por el installer, no si era preexistente)
|
|
if [ -L "$SINGBOX_BIN" ]; then
|
|
sudo rm -f "$SINGBOX_BIN"
|
|
ok "Eliminado symlink sing-box: $SINGBOX_BIN"
|
|
else
|
|
info "sing-box no es symlink — conservado: $SINGBOX_BIN"
|
|
fi
|
|
fi
|
|
|
|
# ─── Resumen ──────────────────────────────────────────────────────────────────
|
|
echo ""
|
|
printf "${BOLD}${GREEN} ✔ Limpieza completa.${RESET}"
|
|
|
|
if $FULL; then
|
|
printf " ${DIM}(modo --full)${RESET}\n"
|
|
else
|
|
printf "\n"
|
|
echo ""
|
|
printf " ${DIM}Conservados: repo, venv, configs${RESET}\n"
|
|
printf " ${DIM}Para eliminar todo: %s --full${RESET}\n" "$0"
|
|
fi
|
|
|
|
echo ""
|
|
info "Podés correr el installer nuevamente sin conflictos."
|
|
echo ""
|