2 july 2026
This commit is contained in:
parent
7387844371
commit
5ef45ad6b4
7 changed files with 98 additions and 202 deletions
11
lib/steps.sh
11
lib/steps.sh
|
|
@ -3,20 +3,15 @@
|
||||||
|
|
||||||
TOTAL_STEPS=6
|
TOTAL_STEPS=6
|
||||||
|
|
||||||
# ─── Variables globales ───────────────────────────────────────────────────────
|
|
||||||
# Directorio base de hydra-veil
|
|
||||||
HV_BASE="$HOME/.local/share/hydra-veil"
|
HV_BASE="$HOME/.local/share/hydra-veil"
|
||||||
|
|
||||||
# Componentes
|
|
||||||
HV_CORE="$HV_BASE/core"
|
HV_CORE="$HV_BASE/core"
|
||||||
HV_CLI="$HV_BASE/cli"
|
HV_CLI="$HV_BASE/cli"
|
||||||
HV_GUI="$HV_BASE/gui"
|
HV_GUI="$HV_BASE/gui"
|
||||||
HV_ESSENTIALS="$HV_BASE/essentials"
|
HV_ESSENTIALS="$HV_BASE/essentials"
|
||||||
|
|
||||||
# Venv — siempre en el core
|
|
||||||
HV_VENV="$HV_CORE/.venv"
|
HV_VENV="$HV_CORE/.venv"
|
||||||
|
|
||||||
# XDG — INSTALL_DIR es $HOME, no el repo
|
|
||||||
INSTALL_DIR="$HOME"
|
INSTALL_DIR="$HOME"
|
||||||
HV_DATA_DIR="$HOME/data/hydra-veil"
|
HV_DATA_DIR="$HOME/data/hydra-veil"
|
||||||
HV_CONFIG_DIR="$HOME/.config/hydra-veil"
|
HV_CONFIG_DIR="$HOME/.config/hydra-veil"
|
||||||
|
|
@ -31,12 +26,10 @@ SINGBOX_CONFIG_DIR="$HV_DATA_DIR/configs"
|
||||||
SINGBOX_PID_FILE="$HV_DATA_DIR/runtime/singbox.pid"
|
SINGBOX_PID_FILE="$HV_DATA_DIR/runtime/singbox.pid"
|
||||||
SINGBOX_LOG_FILE="$HV_DATA_DIR/runtime/singbox.log"
|
SINGBOX_LOG_FILE="$HV_DATA_DIR/runtime/singbox.log"
|
||||||
|
|
||||||
# sudoers
|
|
||||||
SUDOERS_PATH="/etc/sudoers.d/hydraveil"
|
SUDOERS_PATH="/etc/sudoers.d/hydraveil"
|
||||||
|
|
||||||
# Repos
|
|
||||||
declare -A REPO_URLS=(
|
declare -A REPO_URLS=(
|
||||||
["core"]="https://git.simplifiedprivacy.com/Support/sp-hydra-veil-core "
|
["core"]="https://git.simplifiedprivacy.com/Support/sp-hydra-veil-core"
|
||||||
["cli"]="https://git.simplifiedprivacy.com/Support/sp-hydra-veil-cli"
|
["cli"]="https://git.simplifiedprivacy.com/Support/sp-hydra-veil-cli"
|
||||||
["essentials"]="https://git.simplifiedprivacy.com/Support/sp-essentials"
|
["essentials"]="https://git.simplifiedprivacy.com/Support/sp-essentials"
|
||||||
["gui"]="https://git.simplifiedprivacy.com/Support/sp-hydra-veil-gui"
|
["gui"]="https://git.simplifiedprivacy.com/Support/sp-hydra-veil-gui"
|
||||||
|
|
@ -54,8 +47,6 @@ declare -A REPO_DIRS=(
|
||||||
["essentials"]="$HV_ESSENTIALS"
|
["essentials"]="$HV_ESSENTIALS"
|
||||||
["gui"]="$HV_GUI"
|
["gui"]="$HV_GUI"
|
||||||
)
|
)
|
||||||
|
|
||||||
# ─── Importar steps atómicos ──────────────────────────────────────────────────
|
|
||||||
_STEPS_DIR="$SCRIPT_DIR/lib/steps"
|
_STEPS_DIR="$SCRIPT_DIR/lib/steps"
|
||||||
|
|
||||||
for _step in preflight repos python_env singbox wrapper sudoers; do
|
for _step in preflight repos python_env singbox wrapper sudoers; do
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# lib/steps/preflight.sh — verificaciones previas
|
# lib/steps/preflight.sh — verificaciones previas
|
||||||
|
|
||||||
step_preflight() {
|
step_preflight() {
|
||||||
print_section "Pre-flight"
|
print_section "Pre-flight"
|
||||||
log_step "System checks" 1 $TOTAL_STEPS
|
log_step "System checks" 1 $TOTAL_STEPS
|
||||||
|
|
|
||||||
|
|
@ -35,13 +35,11 @@ _create_venv() {
|
||||||
_pip_install() {
|
_pip_install() {
|
||||||
source "$HV_VENV/bin/activate"
|
source "$HV_VENV/bin/activate"
|
||||||
|
|
||||||
# Fix: la GUI puede pedir core==2.3.4 pero core puede ser 2.3.x
|
|
||||||
if [ -f "$HV_GUI/pyproject.toml" ]; then
|
if [ -f "$HV_GUI/pyproject.toml" ]; then
|
||||||
sed -i 's/sp-hydra-veil-core == [0-9.]*/sp-hydra-veil-core >= 2.3.0/' \
|
sed -i 's/sp-hydra-veil-core == [0-9.]*/sp-hydra-veil-core >= 2.3.0/' \
|
||||||
"$HV_GUI/pyproject.toml" 2>/dev/null || true
|
"$HV_GUI/pyproject.toml" 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Orden de instalación: dependencias primero
|
|
||||||
for name in essentials core cli gui; do
|
for name in essentials core cli gui; do
|
||||||
local dir
|
local dir
|
||||||
case "$name" in
|
case "$name" in
|
||||||
|
|
|
||||||
|
|
@ -70,13 +70,11 @@ _setup_env() {
|
||||||
*) _app_env="production" ;;
|
*) _app_env="production" ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# SP_API_BASE_URL_PRODUCTION
|
|
||||||
echo ""
|
echo ""
|
||||||
printf " ${BCYAN}┌─${RESET} ${BWHITE}SP_API_BASE_URL_PRODUCTION${RESET} ${DIM}e.g. https://fake.simplifiedprivacy.org/api/v1${RESET}\n"
|
printf " ${BCYAN}┌─${RESET} ${BWHITE}SP_API_BASE_URL_PRODUCTION${RESET} ${DIM}e.g. https://fake.simplifiedprivacy.org/api/v1${RESET}\n"
|
||||||
printf " ${BCYAN}›${RESET} "
|
printf " ${BCYAN}›${RESET} "
|
||||||
read -r _api_url < /dev/tty
|
read -r _api_url < /dev/tty
|
||||||
|
|
||||||
# Escribir .env
|
|
||||||
cat > "$env_file" << EOF
|
cat > "$env_file" << EOF
|
||||||
APP_ENV=${_app_env}
|
APP_ENV=${_app_env}
|
||||||
SP_API_BASE_URL_LOCAL=http://simplifiedprivacy.test/api/v1
|
SP_API_BASE_URL_LOCAL=http://simplifiedprivacy.test/api/v1
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ classifiers = [
|
||||||
]
|
]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cryptography ~= 46.0.3",
|
"cryptography ~= 46.0.3",
|
||||||
|
"python-dotenv ~= 1.0.0",
|
||||||
"dataclasses-json ~= 0.6.7",
|
"dataclasses-json ~= 0.6.7",
|
||||||
"marshmallow ~= 3.26.1",
|
"marshmallow ~= 3.26.1",
|
||||||
"pysocks ~= 1.7.1",
|
"pysocks ~= 1.7.1",
|
||||||
|
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
python-dotenv
|
|
||||||
cryptography~=46.0.3
|
|
||||||
dataclasses-json~=0.6.7
|
|
||||||
marshmallow~=3.26.1
|
|
||||||
psutil~=7.1.3
|
|
||||||
pysocks~=1.7.1
|
|
||||||
python-dateutil~=2.9.0.post0
|
|
||||||
requests~=2.32.5
|
|
||||||
annotated-types==0.7.0
|
|
||||||
certifi==2026.4.22
|
|
||||||
charset-normalizer==3.4.7
|
|
||||||
click==8.3.3
|
|
||||||
cytoolz==1.1.0
|
|
||||||
eth-hash==0.8.0
|
|
||||||
eth-typing==6.0.0
|
|
||||||
eth-utils==6.0.0
|
|
||||||
idna==3.13
|
|
||||||
packaging==26.2
|
|
||||||
pathspec==1.1.1
|
|
||||||
platformdirs==4.9.6
|
|
||||||
py-ecc==8.0.0
|
|
||||||
pydantic==2.13.3
|
|
||||||
pydantic_core==2.46.3
|
|
||||||
pydeps==3.0.6
|
|
||||||
pytokens==0.4.1
|
|
||||||
stdlib-list==0.12.0
|
|
||||||
toolz==1.1.0
|
|
||||||
typing-inspect==0.9.0
|
|
||||||
typing-inspection==0.4.2
|
|
||||||
typing_extensions==4.15.0
|
|
||||||
urllib3==2.6.3
|
|
||||||
252
uninstall.sh
252
uninstall.sh
|
|
@ -1,113 +1,93 @@
|
||||||
#!/bin/bash
|
#!/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
|
set -euo pipefail
|
||||||
|
|
||||||
# ─── Colores ──────────────────────────────────────────────────────────────────
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
RED='\033[0;31m'
|
LIB_DIR="$SCRIPT_DIR/lib"
|
||||||
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" "$*"; }
|
for _lib in ui log input steps; do
|
||||||
warn() { printf " ${YELLOW}⚠${RESET} %s\n" "$*"; }
|
_path="$LIB_DIR/${_lib}.sh"
|
||||||
info() { printf " ${CYAN}→${RESET} %s\n" "$*"; }
|
if [ ! -f "$_path" ]; then
|
||||||
err() { printf " ${RED}✖${RESET} %s\n" "$*" >&2; }
|
echo "[ERROR] Missing lib: $_path" >&2
|
||||||
hdr() { echo ""; printf "${BOLD}${CYAN}── %s ${RESET}\n" "$*"; echo ""; }
|
exit 1
|
||||||
|
fi
|
||||||
|
source "$_path"
|
||||||
|
done
|
||||||
|
|
||||||
# ─── 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
|
FULL=false
|
||||||
YES=false
|
YES=false
|
||||||
|
|
||||||
for arg in "$@"; do
|
for arg in "$@"; do
|
||||||
case "$arg" in
|
case "$arg" in
|
||||||
--full|-f) FULL=true ;;
|
--full|-f) FULL=true ;;
|
||||||
--yes|-y) YES=true ;;
|
--yes|-y) YES=true ;;
|
||||||
--help|-h)
|
--help|-h)
|
||||||
echo ""
|
echo ""
|
||||||
echo " Uso: $0 [opciones]"
|
echo " Usage: $0 [options]"
|
||||||
echo ""
|
echo ""
|
||||||
echo " Sin flags — elimina wrapper, sudoers, logs, pid, run"
|
echo " No flags — removes wrapper, sudoers, runtime"
|
||||||
echo " conserva repo, venv y configs"
|
echo " keeps repos, venv, configs and data"
|
||||||
echo ""
|
echo ""
|
||||||
echo " --full — todo lo anterior + repo completo, venv y configs"
|
echo " --full — everything above + repos, venv, configs and data"
|
||||||
echo " --yes — no pide confirmación"
|
echo " --yes — skip confirmation prompt"
|
||||||
echo ""
|
echo ""
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
err "Flag desconocido: $arg"
|
log_error "Unknown flag: $arg"
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
# ─── Banner ───────────────────────────────────────────────────────────────────
|
clear
|
||||||
echo ""
|
print_header "HYDRA-VEIL UNINSTALLER" "v2.0.0"
|
||||||
printf "${BOLD}${RED} hydra-veil — limpieza para reinstalación${RESET}\n"
|
printf " ${DIM}%s${RESET}\n" "$(date '+%Y-%m-%d %H:%M:%S') — $(uname -n)"
|
||||||
echo ""
|
print_divider
|
||||||
|
|
||||||
if $FULL; then
|
if $FULL; then
|
||||||
warn "Modo --full: se eliminará TODO incluyendo repo, venv y configs"
|
label_warn "Mode --full: everything will be removed (repos, venv, configs, data)"
|
||||||
else
|
else
|
||||||
info "Modo normal: conserva repo, venv y configs"
|
label_info "Normal mode: repos, venv, configs and data will be kept"
|
||||||
|
label_info "Use --full to remove everything"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# ─── Confirmación ─────────────────────────────────────────────────────────────
|
|
||||||
if ! $YES; then
|
if ! $YES; then
|
||||||
printf " ${YELLOW}¿Continuar?${RESET} ${DIM}[s/N]:${RESET} "
|
if ! ask_confirm "Continue with uninstall?"; then
|
||||||
read -r _confirm < /dev/tty
|
log_warn "Uninstall cancelled."
|
||||||
case "$_confirm" in
|
exit 0
|
||||||
s|S|y|Y) : ;;
|
fi
|
||||||
*)
|
|
||||||
echo ""
|
|
||||||
info "Cancelado."
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
echo ""
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ─── 1. Detener sing-box si está corriendo ────────────────────────────────────
|
print_divider
|
||||||
hdr "1. Proceso sing-box"
|
|
||||||
|
_rm() {
|
||||||
|
local target="$1"
|
||||||
|
if [ -e "$target" ]; then
|
||||||
|
rm -rf "$target"
|
||||||
|
label_ok "Removed: $target"
|
||||||
|
else
|
||||||
|
label_info "Not found: $target"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
print_section "1. sing-box process"
|
||||||
|
|
||||||
_stop_singbox() {
|
_stop_singbox() {
|
||||||
local pid=""
|
local pid=""
|
||||||
|
|
||||||
# Intentar via pidfile primero
|
|
||||||
if [ -f "$SINGBOX_PID_FILE" ]; then
|
if [ -f "$SINGBOX_PID_FILE" ]; then
|
||||||
pid=$(cat "$SINGBOX_PID_FILE" 2>/dev/null || echo "")
|
pid=$(cat "$SINGBOX_PID_FILE" 2>/dev/null || echo "")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Si no hay pidfile, buscar por nombre
|
|
||||||
if [[ -z "$pid" || ! "$pid" =~ ^[0-9]+$ ]]; then
|
if [[ -z "$pid" || ! "$pid" =~ ^[0-9]+$ ]]; then
|
||||||
pid=$(pgrep -x sing-box 2>/dev/null | head -1 || echo "")
|
pid=$(pgrep -x sing-box 2>/dev/null | head -1 || echo "")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -n "$pid" && "$pid" =~ ^[0-9]+$ ]] && kill -0 "$pid" 2>/dev/null; then
|
if [[ -n "$pid" && "$pid" =~ ^[0-9]+$ ]] && kill -0 "$pid" 2>/dev/null; then
|
||||||
info "Deteniendo sing-box PID $pid..."
|
log_info "Stopping sing-box PID $pid..."
|
||||||
kill -TERM "$pid" 2>/dev/null || true
|
kill -TERM "$pid" 2>/dev/null || true
|
||||||
local elapsed=0
|
local elapsed=0
|
||||||
while kill -0 "$pid" 2>/dev/null && (( elapsed < 16 )); do
|
while kill -0 "$pid" 2>/dev/null && (( elapsed < 16 )); do
|
||||||
|
|
@ -117,149 +97,109 @@ _stop_singbox() {
|
||||||
if kill -0 "$pid" 2>/dev/null; then
|
if kill -0 "$pid" 2>/dev/null; then
|
||||||
kill -KILL "$pid" 2>/dev/null || true
|
kill -KILL "$pid" 2>/dev/null || true
|
||||||
sleep 0.3
|
sleep 0.3
|
||||||
ok "sing-box eliminado (SIGKILL)"
|
label_ok "sing-box killed (SIGKILL)"
|
||||||
else
|
else
|
||||||
ok "sing-box detenido (SIGTERM)"
|
label_ok "sing-box stopped (SIGTERM)"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
info "sing-box no está corriendo"
|
label_info "sing-box is not running"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Intentar via wrapper si existe, sino directo
|
if [ -x "$SINGBOX_WRAPPER" ]; then
|
||||||
if [ -x "$WRAPPER_PATH" ]; then
|
sudo "$SINGBOX_WRAPPER" "" stop 2>/dev/null && label_ok "Stopped via wrapper" || _stop_singbox
|
||||||
sudo "$WRAPPER_PATH" "" stop 2>/dev/null && ok "Detenido via wrapper" || _stop_singbox
|
|
||||||
else
|
else
|
||||||
_stop_singbox
|
_stop_singbox
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Eliminar interfaz tun0 si existe
|
|
||||||
if ip link show tun0 &>/dev/null 2>&1; then
|
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"
|
sudo ip link delete tun0 2>/dev/null && label_ok "tun0 removed" || label_warn "Could not remove tun0"
|
||||||
else
|
else
|
||||||
info "tun0 no existe"
|
label_info "tun0 not found"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ─── 2. Wrapper ───────────────────────────────────────────────────────────────
|
print_divider
|
||||||
hdr "2. Wrapper"
|
print_section "2. Wrapper"
|
||||||
|
|
||||||
if [ -f "$WRAPPER_PATH" ]; then
|
if [ -f "$SINGBOX_WRAPPER" ]; then
|
||||||
sudo rm -f "$WRAPPER_PATH"
|
sudo rm -f "$SINGBOX_WRAPPER"
|
||||||
ok "Eliminado: $WRAPPER_PATH"
|
label_ok "Removed: $SINGBOX_WRAPPER"
|
||||||
else
|
else
|
||||||
info "No existe: $WRAPPER_PATH"
|
label_info "Not found: $SINGBOX_WRAPPER"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ─── 3. Sudoers ───────────────────────────────────────────────────────────────
|
print_divider
|
||||||
hdr "3. Sudoers"
|
print_section "3. Sudoers"
|
||||||
|
|
||||||
if [ -f "$SUDOERS_PATH" ]; then
|
if [ -f "$SUDOERS_PATH" ]; then
|
||||||
sudo rm -f "$SUDOERS_PATH"
|
sudo rm -f "$SUDOERS_PATH"
|
||||||
ok "Eliminado: $SUDOERS_PATH"
|
label_ok "Removed: $SUDOERS_PATH"
|
||||||
else
|
else
|
||||||
info "No existe: $SUDOERS_PATH"
|
label_info "Not found: $SUDOERS_PATH"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Verificar que no haya entradas huérfanas en sudoers.d
|
|
||||||
_orphans=$(sudo grep -rl "hydraveil" /etc/sudoers.d/ 2>/dev/null || true)
|
_orphans=$(sudo grep -rl "hydraveil" /etc/sudoers.d/ 2>/dev/null || true)
|
||||||
if [ -n "$_orphans" ]; then
|
if [ -n "$_orphans" ]; then
|
||||||
warn "Entradas huérfanas de hydraveil encontradas:"
|
label_warn "Orphaned sudoers entries found:"
|
||||||
echo "$_orphans" | while read -r f; do
|
echo "$_orphans" | while read -r f; do
|
||||||
warn " $f"
|
sudo rm -f "$f" && label_ok " Removed: $f"
|
||||||
sudo rm -f "$f" && ok " Eliminado: $f"
|
|
||||||
done
|
done
|
||||||
else
|
else
|
||||||
info "Sin entradas huérfanas en sudoers.d"
|
label_info "No orphaned entries in sudoers.d"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ─── 4. PID file y runtime ────────────────────────────────────────────────────
|
print_divider
|
||||||
hdr "4. Runtime (pid / run)"
|
print_section "4. Runtime"
|
||||||
|
|
||||||
if [ -f "$SINGBOX_PID_FILE" ]; then
|
_rm "$SINGBOX_PID_FILE"
|
||||||
rm -f "$SINGBOX_PID_FILE"
|
_rm "$SINGBOX_LOG_FILE"
|
||||||
ok "Eliminado PID file: $SINGBOX_PID_FILE"
|
_rm "$HV_DATA_DIR/runtime"
|
||||||
else
|
|
||||||
info "Sin PID file"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -d "$HV_RUN_DIR" ]; then
|
print_divider
|
||||||
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
|
if $FULL; then
|
||||||
hdr "6. Limpieza completa (--full)"
|
print_section "5. Data"
|
||||||
|
_rm "$HV_DATA_DIR"
|
||||||
|
|
||||||
# Configs
|
print_section "6. Configs"
|
||||||
if [ -d "$HV_CONFIG_DIR" ]; then
|
_rm "$HV_CONFIG_DIR"
|
||||||
rm -rf "$HV_CONFIG_DIR"
|
_rm "$HV_CACHE_DIR"
|
||||||
ok "Eliminado: $HV_CONFIG_DIR"
|
_rm "$HV_STATE_DIR"
|
||||||
else
|
|
||||||
info "No existe: $HV_CONFIG_DIR"
|
print_section "7. Venv"
|
||||||
|
_rm "$HV_VENV"
|
||||||
|
|
||||||
|
print_section "8. Repos"
|
||||||
|
for _dir in "$HV_CORE" "$HV_CLI" "$HV_GUI" "$HV_ESSENTIALS"; do
|
||||||
|
_rm "$_dir"
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -d "$HV_BASE" ] && [ -z "$(ls -A "$HV_BASE" 2>/dev/null)" ]; then
|
||||||
|
rmdir "$HV_BASE"
|
||||||
|
label_ok "Empty base directory removed: $HV_BASE"
|
||||||
fi
|
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
|
if [ -L "$SINGBOX_BIN" ]; then
|
||||||
sudo rm -f "$SINGBOX_BIN"
|
sudo rm -f "$SINGBOX_BIN"
|
||||||
ok "Eliminado symlink sing-box: $SINGBOX_BIN"
|
label_ok "sing-box symlink removed: $SINGBOX_BIN"
|
||||||
else
|
else
|
||||||
info "sing-box no es symlink — conservado: $SINGBOX_BIN"
|
label_info "sing-box is not a symlink — kept: $SINGBOX_BIN"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
print_divider
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ─── Resumen ──────────────────────────────────────────────────────────────────
|
|
||||||
echo ""
|
echo ""
|
||||||
printf "${BOLD}${GREEN} ✔ Limpieza completa.${RESET}"
|
label_ok "Uninstall complete"
|
||||||
|
|
||||||
if $FULL; then
|
if $FULL; then
|
||||||
printf " ${DIM}(modo --full)${RESET}\n"
|
label_ok "Mode --full: everything removed"
|
||||||
else
|
else
|
||||||
printf "\n"
|
|
||||||
echo ""
|
echo ""
|
||||||
printf " ${DIM}Conservados: repo, venv, configs${RESET}\n"
|
label_info "Kept: repos, venv, configs, data"
|
||||||
printf " ${DIM}Para eliminar todo: %s --full${RESET}\n" "$0"
|
label_info "To remove everything: $0 --full"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
info "Podés correr el installer nuevamente sin conflictos."
|
print_divider
|
||||||
echo ""
|
echo ""
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue