FlotillasGPS - Sistema completo de monitoreo de flotillas GPS
Sistema completo para monitoreo y gestion de flotas de vehiculos con: - Backend FastAPI con PostgreSQL/TimescaleDB - Frontend React con TypeScript y TailwindCSS - App movil React Native con Expo - Soporte para dispositivos GPS, Meshtastic y celulares - Video streaming en vivo con MediaMTX - Geocercas, alertas, viajes y reportes - Autenticacion JWT y WebSockets en tiempo real Documentacion completa y guias de usuario incluidas.
This commit is contained in:
485
deploy/scripts/update.sh
Normal file
485
deploy/scripts/update.sh
Normal file
@@ -0,0 +1,485 @@
|
||||
#!/bin/bash
|
||||
# ============================================
|
||||
# Sistema de Flotillas - Script de Actualizacion
|
||||
# ============================================
|
||||
# Actualiza la aplicacion a la ultima version
|
||||
#
|
||||
# Uso: ./update.sh [--branch BRANCH] [--force] [--no-backup]
|
||||
#
|
||||
# Opciones:
|
||||
# --branch Branch a usar (default: main)
|
||||
# --force Forzar actualizacion (descartar cambios locales)
|
||||
# --no-backup No crear backup antes de actualizar
|
||||
# --backend Solo actualizar backend
|
||||
# --frontend Solo actualizar frontend
|
||||
# ============================================
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
# ---------------------------------------------
|
||||
# Colores
|
||||
# ---------------------------------------------
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
# ---------------------------------------------
|
||||
# Variables
|
||||
# ---------------------------------------------
|
||||
INSTALL_DIR="${INSTALL_DIR:-/opt/flotillas}"
|
||||
REPO_BRANCH="${REPO_BRANCH:-main}"
|
||||
BACKUP_BEFORE_UPDATE=true
|
||||
FORCE_UPDATE=false
|
||||
UPDATE_BACKEND=true
|
||||
UPDATE_FRONTEND=true
|
||||
|
||||
# Cargar variables de entorno
|
||||
if [[ -f "$INSTALL_DIR/.env" ]]; then
|
||||
export $(grep -v '^#' "$INSTALL_DIR/.env" | xargs)
|
||||
fi
|
||||
|
||||
# ---------------------------------------------
|
||||
# Funciones
|
||||
# ---------------------------------------------
|
||||
log_info() {
|
||||
echo -e "${BLUE}[$(date '+%H:%M:%S')] [INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}[$(date '+%H:%M:%S')] [OK]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[$(date '+%H:%M:%S')] [WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[$(date '+%H:%M:%S')] [ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# ---------------------------------------------
|
||||
# Parsear argumentos
|
||||
# ---------------------------------------------
|
||||
parse_args() {
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--branch)
|
||||
REPO_BRANCH="$2"
|
||||
shift 2
|
||||
;;
|
||||
--force)
|
||||
FORCE_UPDATE=true
|
||||
shift
|
||||
;;
|
||||
--no-backup)
|
||||
BACKUP_BEFORE_UPDATE=false
|
||||
shift
|
||||
;;
|
||||
--backend)
|
||||
UPDATE_FRONTEND=false
|
||||
shift
|
||||
;;
|
||||
--frontend)
|
||||
UPDATE_BACKEND=false
|
||||
shift
|
||||
;;
|
||||
--help|-h)
|
||||
echo "Uso: $0 [--branch BRANCH] [--force] [--no-backup]"
|
||||
echo ""
|
||||
echo "Opciones:"
|
||||
echo " --branch Branch a usar (default: main)"
|
||||
echo " --force Forzar (descartar cambios locales)"
|
||||
echo " --no-backup No crear backup antes de actualizar"
|
||||
echo " --backend Solo actualizar backend"
|
||||
echo " --frontend Solo actualizar frontend"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
log_error "Opcion desconocida: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# ---------------------------------------------
|
||||
# Verificar requisitos
|
||||
# ---------------------------------------------
|
||||
check_requirements() {
|
||||
log_info "Verificando requisitos..."
|
||||
|
||||
# Verificar directorio
|
||||
if [[ ! -d "$INSTALL_DIR" ]]; then
|
||||
log_error "Directorio de instalacion no encontrado: $INSTALL_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verificar git
|
||||
if [[ ! -d "$INSTALL_DIR/.git" ]]; then
|
||||
log_error "No es un repositorio git"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verificar conexion
|
||||
if ! ping -c 1 github.com &> /dev/null; then
|
||||
log_error "Sin conexion a internet"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_success "Requisitos OK"
|
||||
}
|
||||
|
||||
# ---------------------------------------------
|
||||
# Crear backup
|
||||
# ---------------------------------------------
|
||||
create_backup() {
|
||||
if [[ "$BACKUP_BEFORE_UPDATE" != "true" ]]; then
|
||||
log_warn "Saltando backup (--no-backup)"
|
||||
return
|
||||
fi
|
||||
|
||||
log_info "Creando backup antes de actualizar..."
|
||||
|
||||
if [[ -f "$INSTALL_DIR/deploy/scripts/backup.sh" ]]; then
|
||||
bash "$INSTALL_DIR/deploy/scripts/backup.sh" || log_warn "Backup fallo, continuando..."
|
||||
else
|
||||
log_warn "Script de backup no encontrado"
|
||||
fi
|
||||
}
|
||||
|
||||
# ---------------------------------------------
|
||||
# Obtener version actual
|
||||
# ---------------------------------------------
|
||||
get_current_version() {
|
||||
cd "$INSTALL_DIR"
|
||||
|
||||
# Intentar obtener version de git tag
|
||||
local version=$(git describe --tags --always 2>/dev/null || echo "unknown")
|
||||
|
||||
# O del commit
|
||||
local commit=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
|
||||
|
||||
echo "${version} (${commit})"
|
||||
}
|
||||
|
||||
# ---------------------------------------------
|
||||
# Verificar cambios locales
|
||||
# ---------------------------------------------
|
||||
check_local_changes() {
|
||||
cd "$INSTALL_DIR"
|
||||
|
||||
if [[ -n $(git status --porcelain) ]]; then
|
||||
if [[ "$FORCE_UPDATE" == "true" ]]; then
|
||||
log_warn "Descartando cambios locales..."
|
||||
git reset --hard HEAD
|
||||
git clean -fd
|
||||
else
|
||||
log_error "Hay cambios locales sin commitear"
|
||||
log_error "Usa --force para descartarlos"
|
||||
git status --short
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# ---------------------------------------------
|
||||
# Actualizar codigo
|
||||
# ---------------------------------------------
|
||||
update_code() {
|
||||
log_info "Actualizando codigo desde repositorio..."
|
||||
|
||||
cd "$INSTALL_DIR"
|
||||
|
||||
# Guardar version actual
|
||||
local old_version=$(get_current_version)
|
||||
|
||||
# Fetch
|
||||
log_info "Obteniendo cambios..."
|
||||
git fetch origin
|
||||
|
||||
# Verificar si hay actualizaciones
|
||||
local local_hash=$(git rev-parse HEAD)
|
||||
local remote_hash=$(git rev-parse origin/${REPO_BRANCH})
|
||||
|
||||
if [[ "$local_hash" == "$remote_hash" ]]; then
|
||||
log_success "Ya estas en la version mas reciente"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Mostrar cambios pendientes
|
||||
log_info "Cambios disponibles:"
|
||||
git log --oneline HEAD..origin/${REPO_BRANCH} | head -10
|
||||
|
||||
# Actualizar
|
||||
log_info "Aplicando cambios..."
|
||||
git reset --hard origin/${REPO_BRANCH}
|
||||
|
||||
local new_version=$(get_current_version)
|
||||
|
||||
log_success "Codigo actualizado: $old_version -> $new_version"
|
||||
|
||||
return 1 # Indica que hubo cambios
|
||||
}
|
||||
|
||||
# ---------------------------------------------
|
||||
# Actualizar backend
|
||||
# ---------------------------------------------
|
||||
update_backend() {
|
||||
if [[ "$UPDATE_BACKEND" != "true" ]]; then
|
||||
log_info "Saltando actualizacion de backend"
|
||||
return
|
||||
fi
|
||||
|
||||
log_info "Actualizando backend..."
|
||||
|
||||
cd "$INSTALL_DIR/backend"
|
||||
|
||||
# Activar entorno virtual
|
||||
source venv/bin/activate
|
||||
|
||||
# Actualizar dependencias
|
||||
log_info "Instalando dependencias Python..."
|
||||
|
||||
if [[ -f "requirements.txt" ]]; then
|
||||
pip install -r requirements.txt -q --upgrade
|
||||
elif [[ -f "pyproject.toml" ]]; then
|
||||
pip install -e . -q --upgrade
|
||||
fi
|
||||
|
||||
# Ejecutar migraciones
|
||||
log_info "Ejecutando migraciones..."
|
||||
|
||||
if [[ -d "alembic" ]]; then
|
||||
alembic upgrade head 2>/dev/null || log_warn "Sin migraciones pendientes"
|
||||
fi
|
||||
|
||||
deactivate
|
||||
|
||||
log_success "Backend actualizado"
|
||||
}
|
||||
|
||||
# ---------------------------------------------
|
||||
# Actualizar frontend
|
||||
# ---------------------------------------------
|
||||
update_frontend() {
|
||||
if [[ "$UPDATE_FRONTEND" != "true" ]]; then
|
||||
log_info "Saltando actualizacion de frontend"
|
||||
return
|
||||
fi
|
||||
|
||||
log_info "Actualizando frontend..."
|
||||
|
||||
cd "$INSTALL_DIR/frontend"
|
||||
|
||||
# Verificar package.json
|
||||
if [[ ! -f "package.json" ]]; then
|
||||
log_warn "No hay package.json en frontend"
|
||||
return
|
||||
fi
|
||||
|
||||
# Instalar dependencias
|
||||
log_info "Instalando dependencias Node.js..."
|
||||
|
||||
if command -v pnpm &> /dev/null; then
|
||||
pnpm install --frozen-lockfile 2>/dev/null || pnpm install
|
||||
else
|
||||
npm ci 2>/dev/null || npm install
|
||||
fi
|
||||
|
||||
# Build
|
||||
log_info "Compilando frontend..."
|
||||
|
||||
if command -v pnpm &> /dev/null; then
|
||||
pnpm build
|
||||
else
|
||||
npm run build
|
||||
fi
|
||||
|
||||
log_success "Frontend actualizado"
|
||||
}
|
||||
|
||||
# ---------------------------------------------
|
||||
# Reiniciar servicios
|
||||
# ---------------------------------------------
|
||||
restart_services() {
|
||||
log_info "Reiniciando servicios..."
|
||||
|
||||
if [[ "$UPDATE_BACKEND" == "true" ]]; then
|
||||
systemctl restart flotillas-api 2>/dev/null && log_success "flotillas-api reiniciado" || log_warn "flotillas-api no existe"
|
||||
fi
|
||||
|
||||
if [[ "$UPDATE_FRONTEND" == "true" ]]; then
|
||||
systemctl restart flotillas-web 2>/dev/null && log_success "flotillas-web reiniciado" || log_warn "flotillas-web no existe"
|
||||
fi
|
||||
}
|
||||
|
||||
# ---------------------------------------------
|
||||
# Verificar servicios
|
||||
# ---------------------------------------------
|
||||
verify_services() {
|
||||
log_info "Verificando servicios..."
|
||||
|
||||
local all_ok=true
|
||||
|
||||
# Esperar a que inicien
|
||||
sleep 3
|
||||
|
||||
if [[ "$UPDATE_BACKEND" == "true" ]]; then
|
||||
if systemctl is-active --quiet flotillas-api; then
|
||||
log_success "flotillas-api: activo"
|
||||
else
|
||||
log_error "flotillas-api: inactivo"
|
||||
all_ok=false
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$UPDATE_FRONTEND" == "true" ]]; then
|
||||
if systemctl is-active --quiet flotillas-web; then
|
||||
log_success "flotillas-web: activo"
|
||||
else
|
||||
log_error "flotillas-web: inactivo"
|
||||
all_ok=false
|
||||
fi
|
||||
fi
|
||||
|
||||
# Verificar API health
|
||||
if [[ "$UPDATE_BACKEND" == "true" ]]; then
|
||||
local api_port="${API_PORT:-8000}"
|
||||
if curl -s "http://localhost:${api_port}/health" > /dev/null 2>&1; then
|
||||
log_success "API health check: OK"
|
||||
else
|
||||
log_warn "API health check: no responde (puede estar iniciando)"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$all_ok" == "false" ]]; then
|
||||
log_error "Algunos servicios fallaron. Revisa los logs:"
|
||||
echo " journalctl -u flotillas-api -n 50"
|
||||
echo " journalctl -u flotillas-web -n 50"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# ---------------------------------------------
|
||||
# Limpiar cache
|
||||
# ---------------------------------------------
|
||||
clean_cache() {
|
||||
log_info "Limpiando cache..."
|
||||
|
||||
# Python cache
|
||||
find "$INSTALL_DIR/backend" -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
|
||||
find "$INSTALL_DIR/backend" -type f -name "*.pyc" -delete 2>/dev/null || true
|
||||
|
||||
# Node cache
|
||||
rm -rf "$INSTALL_DIR/frontend/.next/cache" 2>/dev/null || true
|
||||
|
||||
log_success "Cache limpiado"
|
||||
}
|
||||
|
||||
# ---------------------------------------------
|
||||
# Rollback
|
||||
# ---------------------------------------------
|
||||
rollback() {
|
||||
local previous_commit="$1"
|
||||
|
||||
log_warn "Ejecutando rollback a: $previous_commit"
|
||||
|
||||
cd "$INSTALL_DIR"
|
||||
git reset --hard "$previous_commit"
|
||||
|
||||
update_backend
|
||||
update_frontend
|
||||
restart_services
|
||||
|
||||
log_success "Rollback completado"
|
||||
}
|
||||
|
||||
# ---------------------------------------------
|
||||
# Mostrar resumen
|
||||
# ---------------------------------------------
|
||||
show_summary() {
|
||||
echo ""
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo -e "${GREEN} ACTUALIZACION COMPLETADA${NC}"
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo ""
|
||||
echo "Version actual: $(get_current_version)"
|
||||
echo "Branch: $REPO_BRANCH"
|
||||
echo ""
|
||||
echo "Servicios:"
|
||||
systemctl is-active flotillas-api 2>/dev/null && echo " - flotillas-api: activo" || echo " - flotillas-api: inactivo"
|
||||
systemctl is-active flotillas-web 2>/dev/null && echo " - flotillas-web: activo" || echo " - flotillas-web: inactivo"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# ---------------------------------------------
|
||||
# Main
|
||||
# ---------------------------------------------
|
||||
main() {
|
||||
parse_args "$@"
|
||||
|
||||
echo ""
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE} ACTUALIZANDO SISTEMA DE FLOTILLAS${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo ""
|
||||
echo "Branch: $REPO_BRANCH"
|
||||
echo "Force: $FORCE_UPDATE"
|
||||
echo "Backup: $BACKUP_BEFORE_UPDATE"
|
||||
echo ""
|
||||
|
||||
# Guardar commit actual para posible rollback
|
||||
cd "$INSTALL_DIR"
|
||||
PREVIOUS_COMMIT=$(git rev-parse HEAD)
|
||||
|
||||
check_requirements
|
||||
create_backup
|
||||
check_local_changes
|
||||
|
||||
# Intentar actualizar
|
||||
if update_code; then
|
||||
log_info "No hay actualizaciones disponibles"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Actualizar componentes
|
||||
update_backend || {
|
||||
log_error "Fallo en backend, haciendo rollback..."
|
||||
rollback "$PREVIOUS_COMMIT"
|
||||
exit 1
|
||||
}
|
||||
|
||||
update_frontend || {
|
||||
log_error "Fallo en frontend, haciendo rollback..."
|
||||
rollback "$PREVIOUS_COMMIT"
|
||||
exit 1
|
||||
}
|
||||
|
||||
clean_cache
|
||||
restart_services
|
||||
|
||||
# Verificar
|
||||
if ! verify_services; then
|
||||
echo ""
|
||||
read -p "Hacer rollback? (y/N): " -n 1 -r
|
||||
echo
|
||||
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
rollback "$PREVIOUS_COMMIT"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
show_summary
|
||||
}
|
||||
|
||||
# Manejo de errores
|
||||
trap 'log_error "Error en linea $LINENO"; exit 1' ERR
|
||||
|
||||
# Ejecutar
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user