#!/usr/bin/env bash # install.sh — Instalador inteligente del agente usite-agent # Se adapta automáticamente al entorno: VPS root, contenedor, usuario sin root, etc. # # Uso: # curl -sL https://admin.u-site.app/agent/install.sh | bash -s -- --token=TU_TOKEN --url=https://admin.u-site.app # bash install.sh --token=TU_TOKEN --url=https://admin.u-site.app [--interval=30] [--dir=/opt/usite-agent] set -euo pipefail RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m' info() { echo -e "${BLUE}[INFO]${NC} $*"; } ok() { echo -e "${GREEN}[OK]${NC} $*"; } warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; } TOKEN="" API_URL="" INTERVAL=30 INSTALL_DIR="" CPU_THRESHOLD=90 RENICE_ENABLED=true RENICE_CONSECUTIVE=2 for arg in "$@"; do case $arg in --token=*) TOKEN="${arg#*=}" ;; --url=*) API_URL="${arg#*=}" ;; --interval=*) INTERVAL="${arg#*=}" ;; --dir=*) INSTALL_DIR="${arg#*=}" ;; --cpu-threshold=*) CPU_THRESHOLD="${arg#*=}" ;; --renice=*) RENICE_ENABLED="${arg#*=}" ;; --renice-consecutive=*) RENICE_CONSECUTIVE="${arg#*=}" ;; esac done [[ -z "$TOKEN" ]] && error "Falta --token=TU_TOKEN" [[ -z "$API_URL" ]] && error "Falta --url=https://admin.u-site.app" OS="$(uname -s | tr '[:upper:]' '[:lower:]')" ARCH="$(uname -m)" case $ARCH in x86_64) ARCH="amd64" ;; aarch64) ARCH="arm64" ;; armv7l) ARCH="arm" ;; *) error "Arquitectura no soportada: $ARCH" ;; esac BINARY_NAME="usite-agent-${OS}-${ARCH}" DOWNLOAD_URL="${API_URL}/agent/download/${BINARY_NAME}" IS_ROOT=0 [[ "$(id -u)" == "0" ]] && IS_ROOT=1 # ── Detectar entorno ────────────────────────────────────────────────────────── ENV_TYPE="vps" IS_CONTAINER=0 if [[ -f "/run/.containerenv" ]] || [[ -f "/.dockerenv" ]]; then IS_CONTAINER=1; ENV_TYPE="contenedor" fi if [[ -n "${DOCKER_HOST:-}" ]] || [[ -n "${KUBERNETES_SERVICE_HOST:-}" ]]; then IS_CONTAINER=1; ENV_TYPE="contenedor" fi if [[ "$IS_ROOT" == 0 ]]; then ENV_TYPE="usuario" fi # ── Directorio ───────────────────────────────────────────────────────────────── if [[ -z "$INSTALL_DIR" ]]; then if [[ "$IS_ROOT" == 1 ]]; then INSTALL_DIR="/opt/usite-agent" else INSTALL_DIR="${HOME}/.usite-agent" fi fi info "Entorno: ${ENV_TYPE}${IS_CONTAINER:+(contenedor)}" info "Sistema: ${OS}/${ARCH}" info "Directorio: ${INSTALL_DIR}" info "Intervalo: ${INTERVAL}s" # ── Instalar binario ────────────────────────────────────────────────────────── mkdir -p "$INSTALL_DIR" || error "No se pudo crear directorio ${INSTALL_DIR} (¿permisos?)" # Verificar espacio disponible (necesita al menos 20 MB) AVAIL_KB=$(df -k "$INSTALL_DIR" 2>/dev/null | awk 'NR==2 {print $4}') if [[ -n "$AVAIL_KB" && "$AVAIL_KB" -lt 20480 ]]; then error "Espacio insuficiente en ${INSTALL_DIR}: solo ${AVAIL_KB} KB disponibles (se necesitan ≥20 MB)" fi info "Descargando agente desde ${DOWNLOAD_URL}..." DEST="${INSTALL_DIR}/usite-agent" TMP_DEST="/tmp/usite-agent-download-$$" if command -v curl &>/dev/null; then curl -fsSL "$DOWNLOAD_URL" -o "$TMP_DEST" 2>/tmp/curl_err || { CURL_ERR=$(cat /tmp/curl_err 2>/dev/null) rm -f "$TMP_DEST" error "No se pudo descargar: ${CURL_ERR}" } elif command -v wget &>/dev/null; then wget -q "$DOWNLOAD_URL" -O "$TMP_DEST" || { rm -f "$TMP_DEST"; error "No se pudo descargar con wget"; } else error "Se requiere curl o wget" fi if [[ ! -s "$TMP_DEST" ]]; then rm -f "$TMP_DEST" error "El archivo descargado está vacío" fi mv "$TMP_DEST" "$DEST" || { cp "$TMP_DEST" "$DEST" && rm -f "$TMP_DEST"; } || error "No se pudo mover el binario a ${DEST}" chmod +x "$DEST" ok "Binario descargado ($(du -sh "$DEST" | cut -f1))" # ── Configuración ───────────────────────────────────────────────────────────── cat > "${INSTALL_DIR}/agent.yml" </dev/null; then cat > /etc/systemd/system/usite-agent.service </dev/null; then cat > /etc/init.d/usite-agent </dev/null | grep -q "usite-agent"; then warn "Crontab ya tiene una entrada para usite-agent, se omite" else (crontab -l 2>/dev/null || true; echo "$CRON_JOB") | crontab - ok "Entrada @reboot agregada al crontab" fi nohup "${INSTALL_DIR}/usite-agent" --config="${INSTALL_DIR}/agent.yml" >/dev/null 2>&1 & ok "Agente iniciado en background (PID $!)" STARTED=1 fi # ── Resumen ──────────────────────────────────────────────────────────────────── echo "" if [[ "$STARTED" == 1 ]]; then ok "usite-agent instalado correctamente en ${INSTALL_DIR}" info "El agente reportará métricas a ${API_URL} cada ${INTERVAL}s" info "" info "Comandos útiles:" if [[ "$IS_ROOT" == 1 ]] && command -v systemctl &>/dev/null; then info " systemctl status usite-agent" info " journalctl -u usite-agent -f" fi info " ${INSTALL_DIR}/usite-agent --config=${INSTALL_DIR}/agent.yml (ejecutar manual)" info "" info "Para desinstalar:" if [[ "$IS_ROOT" == 1 ]] && command -v systemctl &>/dev/null; then info " systemctl disable usite-agent && rm /etc/systemd/system/usite-agent.service && rm -rf ${INSTALL_DIR}" elif [[ "$IS_ROOT" == 1 ]] && command -v rc-update &>/dev/null; then info " rc-update del usite-agent && rm /etc/init.d/usite-agent && rm -rf ${INSTALL_DIR}" else info " crontab -l | grep -v usite-agent | crontab - && rm -rf ${INSTALL_DIR}" fi else warn "No se pudo configurar auto-arranque. Ejecuta manualmente:" warn " ${INSTALL_DIR}/usite-agent --config=${INSTALL_DIR}/agent.yml &" fi