feat: hacer install.sh 100% automatico y desatendido usando config activa de PostgreSQL (.env)

This commit is contained in:
Carlos Tello
2026-09-04 23:02:02 -03:00
parent eea7adb1d0
commit 0cea3dca44
4 changed files with 32 additions and 32 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
# ============================================================================== # ==============================================================================
# Entorno Flask # Entorno Flask
FLASK_APP=app.py FLASK_APP=wsgi.py
FLASK_ENV=production FLASK_ENV=production
# Seguridad: Clave secreta para sesiones y protección CSRF # Seguridad: Clave secreta para sesiones y protección CSRF
+4 -1
View File
@@ -364,10 +364,13 @@
* **Contenido Respaldado:** 25 aulas físicas y virtuales, 206 comisiones, 206 asignaturas, 412 reservas, 24 carreras, 12 tipos de hitos, matrices de permisos RBAC y usuarios administradores. * **Contenido Respaldado:** 25 aulas físicas y virtuales, 206 comisiones, 206 asignaturas, 412 reservas, 24 carreras, 12 tipos de hitos, matrices de permisos RBAC y usuarios administradores.
* **Compatibilidad Multi-Versión:** Se sanitizó la directiva `\restrict` específica de PostgreSQL 18 para garantizar compatibilidad nativa con PostgreSQL 14, 15, 16, 17 y 18. * **Compatibilidad Multi-Versión:** Se sanitizó la directiva `\restrict` específica de PostgreSQL 18 para garantizar compatibilidad nativa con PostgreSQL 14, 15, 16, 17 y 18.
* **Actualización del Instalador del Sistema para Proxmox LXC ([install.sh](file:///c:/Workspace/admin-edu-space/install.sh)):** * **Actualización del Instalador del Sistema para Proxmox LXC ([install.sh](file:///c:/Workspace/admin-edu-space/install.sh)):**
* **Ejecución 100% Automatizada (Zero-Touch):** Se eliminaron todos los prompts interactivos (`read -rp`), permitiendo que el script corra de inicio a fin de forma totalmente desatendida.
* **Copia de Configuración Activa del Sistema:** Se configuraron como valores por defecto los parámetros reales del sistema en ejecución (`DATABASE_URL=postgresql://postgres:password@localhost:5432/classrooms_db`, usuario `postgres`, base `classrooms_db` y contraseña `password`), garantizando paridad exacta con el entorno local.
* **Compatibilidad Dual de Usuarios:** Configuración tanto del superusuario `postgres` como de `eduspace_user` con los mismos privilegios para compatibilidad inmediata ante cualquier variación de `.env`.
* **Optimización Proxmox LXC:** Compatible con contenedores Debian 11/12 y Ubuntu 20.04/22.04/24.04 en Proxmox VE. * **Optimización Proxmox LXC:** Compatible con contenedores Debian 11/12 y Ubuntu 20.04/22.04/24.04 en Proxmox VE.
* **Migración Automática de Directorio:** Si el repositorio se clona en `/root`, se traslada automáticamente a `/opt/admin-edu-space` para garantizar permisos de ejecución del usuario del servicio (`eduspace`). * **Migración Automática de Directorio:** Si el repositorio se clona en `/root`, se traslada automáticamente a `/opt/admin-edu-space` para garantizar permisos de ejecución del usuario del servicio (`eduspace`).
* **Despliegue del Motor PostgreSQL Nativo:** Instalación desatendida del motor en el LXC, inicialización dinámica del servicio y bucle de healthcheck de conexión. * **Despliegue del Motor PostgreSQL Nativo:** Instalación desatendida del motor en el LXC, inicialización dinámica del servicio y bucle de healthcheck de conexión.
* **Restauración Automatizada y Permisos:** Detección automática de `classrooms_db.sql`, recreación limpia, asignación de permisos `GRANT ALL` en el esquema `public`, todas las tablas y secuencias al usuario `eduspace_user`. * **Restauración Automatizada y Permisos:** Detección automática de `classrooms_db.sql`, recreación limpia, asignación de permisos `GRANT ALL` en el esquema `public`, todas las tablas y secuencias a `postgres` y `eduspace_user`.
* **Entorno Virtual Nativo (`venv`):** Configuración en `/opt/admin-edu-space/venv` con dependencias del sistema y `gunicorn`. * **Entorno Virtual Nativo (`venv`):** Configuración en `/opt/admin-edu-space/venv` con dependencias del sistema y `gunicorn`.
* **Servicio Systemd de Producción:** Configuración y activación de `admin-edu-space.service` en el puerto 5000. * **Servicio Systemd de Producción:** Configuración y activación de `admin-edu-space.service` en el puerto 5000.
* **Ejecución Idempotente:** Integración de `init_db.py` tras la restauración para validar la coherencia del esquema y roles. * **Ejecución Idempotente:** Integración de `init_db.py` tras la restauración para validar la coherencia del esquema y roles.
+1
View File
@@ -51,6 +51,7 @@ if [[ -f "$APP_ENV" ]]; then
fi fi
DB_USER="${DB_USER:-postgres}" DB_USER="${DB_USER:-postgres}"
DB_PASSWORD="${DB_PASSWORD:-password}"
DB_NAME="${DB_NAME:-classrooms_db}" DB_NAME="${DB_NAME:-classrooms_db}"
DB_HOST="${DB_HOST:-localhost}" DB_HOST="${DB_HOST:-localhost}"
DB_PORT="${DB_PORT:-5432}" DB_PORT="${DB_PORT:-5432}"
+26 -30
View File
@@ -129,31 +129,22 @@ fi
# ─── 5. Configurar Variables de Entorno (.env) ───────────────────────────────── # ─── 5. Configurar Variables de Entorno (.env) ─────────────────────────────────
hdr "5. Configurando variables de entorno (.env)" hdr "5. Configurando variables de entorno (.env)"
# Configuración idéntica al entorno del sistema activo (100% automático sin interacción)
DB_NAME="classrooms_db" DB_NAME="classrooms_db"
DB_USER="eduspace_user" DB_USER="postgres"
DEFAULT_DB_PASS="eduspace2024" DB_PASSWORD="password"
if [[ -f "$APP_ENV" ]]; then if [[ -f "$APP_ENV" ]]; then
ok ".env ya existe — se conserva la configuración existente" ok ".env ya existe — se preserva la configuración actual"
set -a set -a
# shellcheck disable=SC1090 # shellcheck disable=SC1090
source <(grep -v '^#' "$APP_ENV" | grep '=') source <(grep -v '^#' "$APP_ENV" | grep '=')
set +a set +a
DB_USER="${DB_USERNAME:-$DB_USER}" DB_USER="${DB_USERNAME:-$DB_USER}"
DB_PASSWORD="${DB_PASSWORD:-$DEFAULT_DB_PASS}" DB_PASSWORD="${DB_PASSWORD:-password}"
DB_NAME=$(echo "${DATABASE_URL:-}" | sed -E 's|.*/([^?]+).*|\1|') DB_NAME=$(echo "${DATABASE_URL:-}" | sed -E 's|.*/([^?]+).*|\1|')
DB_NAME="${DB_NAME:-classrooms_db}" DB_NAME="${DB_NAME:-classrooms_db}"
else else
echo ""
echo -e " ${BOLD}Credenciales para la base de datos PostgreSQL:${RESET}"
if [ -n "${NON_INTERACTIVE:-}" ] || [ ! -t 0 ]; then
DB_PASSWORD="$DEFAULT_DB_PASS"
info "Modo no interactivo: usando contraseña por defecto."
else
read -rp " Contraseña para el usuario '${DB_USER}' [default: ${DEFAULT_DB_PASS}]: " DB_PASS_INPUT
DB_PASSWORD="${DB_PASS_INPUT:-$DEFAULT_DB_PASS}"
fi
SECRET_KEY=$(python3 -c 'import secrets; print(secrets.token_hex(32))') SECRET_KEY=$(python3 -c 'import secrets; print(secrets.token_hex(32))')
cat > "$APP_ENV" <<ENVEOF cat > "$APP_ENV" <<ENVEOF
# Admin Edu-Space — Configuración de producción # Admin Edu-Space — Configuración de producción
@@ -174,23 +165,28 @@ BABEL_DEFAULT_LOCALE=es
BABEL_DEFAULT_TIMEZONE=America/Argentina/Buenos_Aires BABEL_DEFAULT_TIMEZONE=America/Argentina/Buenos_Aires
ENVEOF ENVEOF
chmod 640 "$APP_ENV" chmod 640 "$APP_ENV"
ok ".env generado exitosamente con SECRET_KEY criptográfica" ok ".env generado automáticamente con configuración de producción"
fi fi
# ─── 6. Crear Usuario y Permisos en PostgreSQL ───────────────────────────────── # ─── 6. Configurar Usuario y Base de Datos en PostgreSQL ───────────────────────
hdr "6. Configurando usuario y base de datos en PostgreSQL" hdr "6. Configurando motor PostgreSQL y credenciales de base de datos"
sudo -u postgres psql -c "CREATE USER ${DB_USER} WITH PASSWORD '${DB_PASSWORD}';" >/dev/null 2>&1 \ # Asignar contraseña al usuario postgres
|| sudo -u postgres psql -c "ALTER USER ${DB_USER} WITH PASSWORD '${DB_PASSWORD}';" >/dev/null 2>&1 \ sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD '${DB_PASSWORD}';" >/dev/null 2>&1 || true
# Crear usuario eduspace_user con la misma contraseña como alternativa
sudo -u postgres psql -c "CREATE USER eduspace_user WITH PASSWORD '${DB_PASSWORD}';" >/dev/null 2>&1 \
|| sudo -u postgres psql -c "ALTER USER eduspace_user WITH PASSWORD '${DB_PASSWORD}';" >/dev/null 2>&1 \
|| true || true
sudo -u postgres psql -c "CREATE DATABASE ${DB_NAME} OWNER ${DB_USER};" >/dev/null 2>&1 \ # Crear base de datos
sudo -u postgres psql -c "CREATE DATABASE ${DB_NAME} OWNER postgres;" >/dev/null 2>&1 \
|| info "La base de datos '${DB_NAME}' ya existía." || info "La base de datos '${DB_NAME}' ya existía."
sudo -u postgres psql -d "${DB_NAME}" -c "GRANT ALL PRIVILEGES ON DATABASE ${DB_NAME} TO ${DB_USER};" >/dev/null 2>&1 || true sudo -u postgres psql -d "${DB_NAME}" -c "GRANT ALL PRIVILEGES ON DATABASE ${DB_NAME} TO postgres, eduspace_user;" >/dev/null 2>&1 || true
sudo -u postgres psql -d "${DB_NAME}" -c "GRANT ALL ON SCHEMA public TO ${DB_USER};" >/dev/null 2>&1 || true sudo -u postgres psql -d "${DB_NAME}" -c "GRANT ALL ON SCHEMA public TO postgres, eduspace_user;" >/dev/null 2>&1 || true
ok "Usuario '${DB_USER}' y base de datos '${DB_NAME}' configurados" ok "Motor PostgreSQL configurado (usuario: ${DB_USER}, base: ${DB_NAME})"
# ─── 7. Crear Entorno Virtual e Instalar Dependencias ────────────────────────── # ─── 7. Crear Entorno Virtual e Instalar Dependencias ──────────────────────────
hdr "7. Creando virtualenv e instalando dependencias Python" hdr "7. Creando virtualenv e instalando dependencias Python"
@@ -223,7 +219,7 @@ if [[ -f "$SQL_BACKUP_FILE" ]]; then
# Recrear base de datos limpia para carga sin colisiones # Recrear base de datos limpia para carga sin colisiones
sudo -u postgres psql -c "DROP DATABASE IF EXISTS ${DB_NAME};" > /dev/null 2>&1 || true sudo -u postgres psql -c "DROP DATABASE IF EXISTS ${DB_NAME};" > /dev/null 2>&1 || true
sudo -u postgres psql -c "CREATE DATABASE ${DB_NAME} OWNER ${DB_USER};" > /dev/null 2>&1 sudo -u postgres psql -c "CREATE DATABASE ${DB_NAME} OWNER postgres;" > /dev/null 2>&1
# Restaurar backup filtrando directivas específicas de PG18 si existiesen # Restaurar backup filtrando directivas específicas de PG18 si existiesen
if sed '/^\\restrict/d' "$SQL_BACKUP_FILE" | sudo -u postgres psql -d "${DB_NAME}" > /dev/null 2>&1; then if sed '/^\\restrict/d' "$SQL_BACKUP_FILE" | sudo -u postgres psql -d "${DB_NAME}" > /dev/null 2>&1; then
@@ -233,12 +229,12 @@ if [[ -f "$SQL_BACKUP_FILE" ]]; then
fi fi
# Otorgar propiedad y permisos absolutos sobre todas las tablas y secuencias al usuario de la app # Otorgar propiedad y permisos absolutos sobre todas las tablas y secuencias al usuario de la app
info "Garantizando permisos y secuencias para '${DB_USER}'..." info "Garantizando permisos y secuencias para ${DB_USER} y eduspace_user..."
sudo -u postgres psql -d "${DB_NAME}" -c "GRANT ALL ON SCHEMA public TO ${DB_USER};" > /dev/null 2>&1 || true sudo -u postgres psql -d "${DB_NAME}" -c "GRANT ALL ON SCHEMA public TO postgres, eduspace_user;" > /dev/null 2>&1 || true
sudo -u postgres psql -d "${DB_NAME}" -c "GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO ${DB_USER};" > /dev/null 2>&1 || true sudo -u postgres psql -d "${DB_NAME}" -c "GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO postgres, eduspace_user;" > /dev/null 2>&1 || true
sudo -u postgres psql -d "${DB_NAME}" -c "GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO ${DB_USER};" > /dev/null 2>&1 || true sudo -u postgres psql -d "${DB_NAME}" -c "GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO postgres, eduspace_user;" > /dev/null 2>&1 || true
sudo -u postgres psql -d "${DB_NAME}" -c "ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO ${DB_USER};" > /dev/null 2>&1 || true sudo -u postgres psql -d "${DB_NAME}" -c "ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO postgres, eduspace_user;" > /dev/null 2>&1 || true
sudo -u postgres psql -d "${DB_NAME}" -c "ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO ${DB_USER};" > /dev/null 2>&1 || true sudo -u postgres psql -d "${DB_NAME}" -c "ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO postgres, eduspace_user;" > /dev/null 2>&1 || true
# Ejecutar init_db.py de forma idempotente para verificar roles y migraciones incrementales # Ejecutar init_db.py de forma idempotente para verificar roles y migraciones incrementales
info "Validando coherencia de modelos con init_db.py..." info "Validando coherencia de modelos con init_db.py..."