feat: Initial commit for OnEver Drive centralized backup system with Windows PyQt6 agent and Proxmox LXC deployment
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
# OnEver Drive — Referencia de API REST & WebSockets
|
||||
|
||||
Base URL: `/api`
|
||||
|
||||
---
|
||||
|
||||
## 1. Autenticación
|
||||
|
||||
### `POST /api/auth/login`
|
||||
Inicia sesión de usuario administrativo.
|
||||
- **Body**:
|
||||
```json
|
||||
{
|
||||
"email": "admin@oneverdrive.local",
|
||||
"password": "Admin1234!"
|
||||
}
|
||||
```
|
||||
- **Response**:
|
||||
```json
|
||||
{
|
||||
"access_token": "eyJhbGciOi...",
|
||||
"token_type": "bearer",
|
||||
"user": { "id": 1, "email": "admin@oneverdrive.local", "role": "ADMIN" }
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Clientes Windows
|
||||
|
||||
### `POST /api/clients/registration-code`
|
||||
Genera un código temporal de un solo uso para registrar un nuevo agente Windows.
|
||||
- **Auth**: Bearer Token (ADMIN)
|
||||
- **Body**: `{ "client_name_hint": "SQL Server Prod", "expires_in_hours": 48 }`
|
||||
- **Response**: `{ "code": "OED-4A2F-9B1C", "expires_at": "2026-08-15T12:00:00Z" }`
|
||||
|
||||
### `POST /api/clients/register`
|
||||
Invocado por el agente Windows con el código de registro para obtener credenciales únicas.
|
||||
- **Body**:
|
||||
```json
|
||||
{
|
||||
"registration_code": "OED-4A2F-9B1C",
|
||||
"name": "SQL Server Prod",
|
||||
"hostname": "WIN-SRV-2022",
|
||||
"os_info": "Windows Server 2022 Datacenter",
|
||||
"agent_version": "1.0.0"
|
||||
}
|
||||
```
|
||||
- **Response**:
|
||||
```json
|
||||
{
|
||||
"client_code": "CLIENT-0001",
|
||||
"device_id": "8f3b4d7c-3b1a-4d2e-9c1a-8f3b4d7c3b1a",
|
||||
"device_token": "oed_sec_a8b9c0d1...",
|
||||
"name": "SQL Server Prod",
|
||||
"server_time": "2026-08-13T16:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### `GET /api/clients`
|
||||
Lista todos los clientes registrados.
|
||||
|
||||
### `POST /api/clients/{id}/revoke`
|
||||
Revoca inmediatamente las credenciales de un cliente Windows.
|
||||
|
||||
---
|
||||
|
||||
## 3. Motor de Transferencia por Chunks
|
||||
|
||||
### `POST /api/upload/session`
|
||||
Inicia una nueva sesión de subida o reanuda una sesión existente incompleta.
|
||||
- **Headers**:
|
||||
`X-Device-Id: <DEVICE_ID>`
|
||||
`X-Device-Token: <DEVICE_TOKEN>`
|
||||
- **Body**:
|
||||
```json
|
||||
{
|
||||
"filename": "database_production.bak",
|
||||
"file_size": 12582912,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"chunk_size": 4194304,
|
||||
"job_id": 1
|
||||
}
|
||||
```
|
||||
- **Response**:
|
||||
```json
|
||||
{
|
||||
"session_code": "6f2e8b1a-...",
|
||||
"filename": "database_production.bak",
|
||||
"file_size": 12582912,
|
||||
"chunk_size": 4194304,
|
||||
"total_chunks": 3,
|
||||
"received_chunks": [0],
|
||||
"status": "UPLOADING"
|
||||
}
|
||||
```
|
||||
|
||||
### `POST /api/upload/{session_code}/chunk`
|
||||
Envía los bytes de un bloque específico.
|
||||
- **Headers**:
|
||||
`X-Device-Id: <DEVICE_ID>`
|
||||
`X-Device-Token: <DEVICE_TOKEN>`
|
||||
`X-Chunk-Index: 1`
|
||||
`X-Chunk-SHA256: <CHUNK_HASH>`
|
||||
- **Body**: Raw binary bytes
|
||||
- **Response**:
|
||||
```json
|
||||
{
|
||||
"chunk_index": 1,
|
||||
"is_received": true,
|
||||
"total_received": 2,
|
||||
"total_chunks": 3,
|
||||
"progress_percent": 66.67
|
||||
}
|
||||
```
|
||||
|
||||
### `GET /api/upload/{session_code}/status`
|
||||
Devuelve el estado de la sesión y la lista de chunks pendientes de subida.
|
||||
|
||||
### `POST /api/upload/{session_code}/complete`
|
||||
Solicita el ensamblado secuencial del archivo y la verificación de integridad SHA-256 total.
|
||||
- **Response**:
|
||||
```json
|
||||
{
|
||||
"session_code": "6f2e8b1a-...",
|
||||
"filename": "database_production.bak",
|
||||
"relative_path": "clients/CLIENT-0001/JOB-001/20260813_160000_database_production.bak",
|
||||
"file_size": 12582912,
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"status": "SUCCESS"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. WebSockets Telemetría en Tiempo Real
|
||||
|
||||
### Endpoint: `/ws/telemetry`
|
||||
Eventos transmitidos:
|
||||
- `UPLOAD_PROGRESS`: `{ "session_code", "filename", "client_id", "chunk_index", "received_chunks", "total_chunks", "progress_percent" }`
|
||||
- `UPLOAD_COMPLETED`: `{ "session_code", "filename", "client_id", "file_size", "sha256", "status" }`
|
||||
- `CLIENT_REGISTERED`: `{ "id", "client_code", "name", "hostname", "status" }`
|
||||
- `EVENT_LOG`: `{ "id", "timestamp", "event_type", "severity", "message" }`
|
||||
@@ -0,0 +1,97 @@
|
||||
# OnEver Drive — Arquitectura Técnica y Especificación
|
||||
|
||||
## 1. Visión General
|
||||
**OnEver Drive** es una plataforma de copia de seguridad y sincronización centralizada de nivel empresarial, diseñada para respaldar de manera desatendida y segura servidores y estaciones de trabajo Windows hacia un cluster de virtualización **Proxmox VE**.
|
||||
|
||||
La plataforma divide responsabilidades en dos capas desacopladas:
|
||||
1. **Backend API + Interfaz Web Centralizada**: Administra clientes, define trabajos de respaldo, supervisa telemetría en tiempo real y ejecuta políticas de retención.
|
||||
2. **Agente Windows (Servicio de Fondo)**: Detecta cambios en carpetas locales, valida estabilidad y bloqueo de archivos (especialmente volcados masivos `.bak` de Microsoft SQL Server), y transfiere datos mediante bloques (chunks) a través de HTTPS con capacidad de reanudación inmediata ante cortes.
|
||||
|
||||
---
|
||||
|
||||
## 2. Diagrama de Arquitectura en Proxmox VE
|
||||
|
||||
```text
|
||||
INTERNET / RED LOCAL
|
||||
│
|
||||
│ HTTPS / WebSockets
|
||||
▼
|
||||
┌───────────────────────────────────────────────┐
|
||||
│ SERVIDOR CENTRAL │
|
||||
│ PROXMOX VE │
|
||||
└───────────────────────┬───────────────────────┘
|
||||
│
|
||||
┌───────────────────────┴───────────────────────┐
|
||||
│ │
|
||||
▼ ▼
|
||||
┌───────────────────────┐ ┌───────────────────────┐
|
||||
│ LXC 1: BACKEND │ │ LXC 2: STORAGE │
|
||||
│ (Debian 12/13 CT100)│ │ (Debian 12/13 CT101)│
|
||||
│ │ │ │
|
||||
│ • FastAPI REST API │ Punto de Montaje │ • Almacenamiento ZFS │
|
||||
│ • PostgreSQL 16 Nativo│ ────────────────────► │ • Aislamiento /client │
|
||||
│ • WebSockets Engine │ │ • Directorio Temporal │
|
||||
│ • Dashboard Web UI │ │ • Deduplicación / LVM │
|
||||
└───────────┬───────────┘ └───────────────────────┘
|
||||
│
|
||||
│ HTTPS (Streaming Chunks 4MB + Hashing)
|
||||
│
|
||||
┌────────┴────────┐
|
||||
│ │
|
||||
▼ ▼
|
||||
┌──────────────┐ ┌──────────────┐
|
||||
│ Windows 11 │ │WinServer 2022│
|
||||
│ Backup Agent │ │ Backup Agent │
|
||||
└──────────────┘ └──────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Protocolo de Transferencia por Bloques (Chunks) y Reanudación
|
||||
|
||||
La transferencia de archivos grandes (ej. 50 GB) no utiliza envíos en una sola petición `POST` multipart monolítica, sino un protocolo secuenciado de subida por bloques:
|
||||
|
||||
```text
|
||||
[Archivo database.bak (12 GB)]
|
||||
│
|
||||
├── Chunk 000000 (4 MB) ──► SHA256 Chunk ──► Guardado en temp/{session}/00000000.chunk
|
||||
├── Chunk 000001 (4 MB) ──► SHA256 Chunk ──► Guardado en temp/{session}/00000001.chunk
|
||||
├── ...
|
||||
└── Chunk 003000 (4 MB) ──► SHA256 Chunk ──► Guardado en temp/{session}/00300000.chunk
|
||||
│
|
||||
▼
|
||||
[Ensamblado Secuencial]
|
||||
│
|
||||
▼
|
||||
[Validación SHA-256 Full]
|
||||
│
|
||||
▼
|
||||
/storage/backups/clients/{client}/{job}/
|
||||
```
|
||||
|
||||
### Ciclo de Vida de una Sesión de Subida
|
||||
|
||||
1. **Detección y Estabilidad (`is_file_stable`)**:
|
||||
- El agente comprueba que el archivo no posea un bloqueo exclusivo de escritura (`EACCES`/`EBUSY`) por parte de SQL Server y que su tamaño permanezca invariante durante la ventana configurada (`min_stable_time_seconds: 60s`).
|
||||
2. **Inicio o Reanudación (`POST /api/upload/session`)**:
|
||||
- El agente envía el hash SHA-256 total precalculado, tamaño en bytes y nombre.
|
||||
- El backend busca si ya existe una sesión en progreso para ese hash. Si existe, responde con `received_chunks: [0, 1, 2, ...]`.
|
||||
3. **Transmisión de Chunks Faltantes (`POST /api/upload/{session}/chunk`)**:
|
||||
- El agente transmite exclusivamente los bloques que el servidor aún no tiene.
|
||||
- El servidor almacena el bloque y valida su hash SHA-256 individual.
|
||||
- Cada bloque recibido emite un evento WebSocket `UPLOAD_PROGRESS` que actualiza el Dashboard en tiempo real.
|
||||
4. **Ensamblado y Verificación de Integridad (`POST /api/upload/{session}/complete`)**:
|
||||
- El servidor concatena los bloques en streaming hacia el volumen final.
|
||||
- Calcula el hash SHA-256 en streaming del archivo ensamblado y lo compara contra el hash declarado.
|
||||
- Si coincide: Marca el archivo como `SUCCESS`, actualiza la cuota del cliente y ejecuta la política de retención.
|
||||
- Si difiere: Elimina el archivo corrupto y solicita retransmisión.
|
||||
|
||||
---
|
||||
|
||||
## 4. Aislamiento Estricto Multicliente
|
||||
|
||||
- Cada agente Windows posee credenciales únicas revocables (`X-Device-Id` y `X-Device-Token`).
|
||||
- Los respaldos se estructuran físicamente en:
|
||||
`/storage/backups/clients/{CLIENT_CODE}/{JOB_CODE}/{TIMESTAMP}_{FILENAME}`
|
||||
- Ningún cliente puede listar, sobrescribir ni acceder a las sesiones o archivos de otro cliente (validado a nivel de base de datos y sistema de archivos).
|
||||
- La eliminación accidental de un archivo local en Windows **nunca** borra los backups remotos en el servidor.
|
||||
@@ -0,0 +1,111 @@
|
||||
# OnEver Drive — Guía de Despliegue Nativo en Proxmox VE (LXC Debian 12 / 13)
|
||||
|
||||
Este documento detalla la instalación paso a paso en **Proxmox Virtual Environment (PVE)** ejecutando la aplicación **100% nativa en contenedores Linux (LXC) sobre Debian 12 (Bookworm) o Debian 13 (Trixie)**, sin Docker ni capas intermedias.
|
||||
|
||||
---
|
||||
|
||||
## 1. Topología del Sistema en Proxmox VE
|
||||
|
||||
```text
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ PROXMOX VE HOST │
|
||||
│ │
|
||||
│ ZFS / LVM Pool: /mnt/pve/backup-pool │
|
||||
│ ├── backups/ (Repositorio de respaldos) │
|
||||
│ └── temp/ (Directorio temporal de chunks) │
|
||||
└────────────────────────────┬────────────────────────────┘
|
||||
│ Mountpoints (-mp0, -mp1)
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ CT 100 — onever-backend (Debian 12/13) │
|
||||
│ │
|
||||
│ • FastAPI Backend Service (/etc/systemd/system/...) │
|
||||
│ • PostgreSQL 15/16 Nativo (Base de datos transaccional)│
|
||||
│ • Nginx Reverse Proxy (Streaming Chunks + WebSockets) │
|
||||
│ • Frontend Web Dashboard (/var/www/onever-drive-web) │
|
||||
│ • Python Virtualenv (/opt/onever_drive/venv) │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Paso 1: Creación del Contenedor LXC en Proxmox Host
|
||||
|
||||
Ejecute en la consola Shell del nodo Proxmox VE (root):
|
||||
|
||||
```bash
|
||||
# 1. Copiar o clonar scripts de aprovisionamiento
|
||||
git clone <URL_REPOSITORIO> /tmp/onever_drive
|
||||
|
||||
# 2. Ejecutar creación automática de LXC y montaje de almacenamiento
|
||||
bash /tmp/onever_drive/deployment/proxmox/01-create-lxc-pve-host.sh
|
||||
```
|
||||
|
||||
El script:
|
||||
- Descarga la plantilla oficial `debian-12-standard` o `debian-13-standard`.
|
||||
- Crea el contenedor **CT 100** (2 GB RAM, 2 Cores, 20 GB disco del sistema).
|
||||
- Monta directamente el pool de almacenamiento del Host hacia `/storage/backups` y `/storage/temp` en el LXC.
|
||||
- Inicia el contenedor.
|
||||
|
||||
---
|
||||
|
||||
## 3. Paso 2: Instalación Nativa en el Contenedor (Debian 12 / 13)
|
||||
|
||||
Ingrese al contenedor e inicie el instalador nativo:
|
||||
|
||||
```bash
|
||||
# En el Host Proxmox:
|
||||
pct enter 100
|
||||
|
||||
# Dentro del contenedor Debian 12 / 13:
|
||||
git clone <URL_REPOSITORIO> /opt/onever_drive
|
||||
bash /opt/onever_drive/deployment/proxmox/02-install-backend-debian.sh
|
||||
```
|
||||
|
||||
El instalador automatiza todo el proceso:
|
||||
1. Instala paquetes nativos: `postgresql`, `nginx`, `python3`, `python3-venv`, `nodejs`, `npm`.
|
||||
2. Inicializa PostgreSQL y crea la base de datos `onever_drive` con el esquema DDL e índices.
|
||||
3. Configura el entorno virtual de Python y dependencias en `/opt/onever_drive/venv`.
|
||||
4. Compila la interfaz Web React y la ubica en `/var/www/onever-drive-web`.
|
||||
5. Instala el servicio `onever-backend.service` en **systemd** y lo inicia automáticamente.
|
||||
6. Configura **Nginx** con soporte para streaming de bloques por chunks ilimitados y WebSockets.
|
||||
|
||||
---
|
||||
|
||||
## 4. Paso 3: Configuración de Certificado SSL / HTTPS
|
||||
|
||||
Para habilitar HTTPS en el puerto 443:
|
||||
|
||||
```bash
|
||||
# Para dominio público con Let's Encrypt (Certbot):
|
||||
bash /opt/onever_drive/deployment/proxmox/03-configure-ssl.sh backup.midominio.com
|
||||
|
||||
# Para entorno LAN / Intranet (Certificado autofirmado 4096 bits):
|
||||
bash /opt/onever_drive/deployment/proxmox/03-configure-ssl.sh self-signed
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Paso 4: Mantenimiento y Backups del Sistema
|
||||
|
||||
Para programar el backup diario de la base de datos PostgreSQL de OnEver Drive hacia el almacenamiento persistente:
|
||||
|
||||
```bash
|
||||
# Agregar tarea en cron en CT 100:
|
||||
crontab -e
|
||||
|
||||
# Agregar línea (ejecutar diariamente a las 01:00 AM):
|
||||
0 1 * * * bash /opt/onever_drive/deployment/proxmox/04-backup-maintenance.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Comprobación y Estado de Servicios
|
||||
|
||||
Verificar que todos los servicios nativos están activos:
|
||||
|
||||
```bash
|
||||
systemctl status onever-backend.service
|
||||
systemctl status postgresql
|
||||
systemctl status nginx
|
||||
```
|
||||
@@ -0,0 +1,84 @@
|
||||
# OnEver Drive — Manual del Agente Windows (PyQt6 & System Tray)
|
||||
|
||||
## 1. Visión General
|
||||
El **Agente de Windows de OnEver Drive** es una aplicación de escritorio nativa moderna desarrollada en **PyQt6**, empaquetada como ejecutable `.exe` y diseñada para ejecutarse silenciosamente en el **Área de Notificaciones (System Tray)** de Windows con interfaz gráfica completa para:
|
||||
|
||||
1. **Apuntar y conectar con el servidor central de backup** (URL del servidor + Código de registro con test de latencia).
|
||||
2. **Elegir carpetas de backup locales visualmente** mediante el explorador de Windows (`QFileDialog`), estableciendo filtros (`*.bak`, `*.mdf`), frecuencia y estabilidad de archivos.
|
||||
3. **Monitorear transferencias por bloques (chunks de 4 MB)** en tiempo real con barras de progreso, cálculo de hash SHA-256 y notificaciones nativas de Windows.
|
||||
|
||||
---
|
||||
|
||||
## 2. Interfaz Gráfica PyQt6
|
||||
|
||||
```text
|
||||
┌────────────────────────────────────────────────────────────────────────┐
|
||||
│ OnEver Drive — Agente de Backup Windows ● Conectado │
|
||||
├────────────────────────────────────────────────────────────────────────┤
|
||||
│ [Dashboard] [Carpetas de Backup] [Servidor & Config] [Historial] │
|
||||
├────────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Transferencia en Vivo (Motor de Chunks) │
|
||||
│ Subiendo database_production.bak... │
|
||||
│ [████████████████████████████░░░░░░░░] 68.4% (17 / 25 Chunks) │
|
||||
│ Chunks: 17/25 | Velocidad: 42.1 MB/s | SHA-256: e3b0c44298fc... │
|
||||
│ │
|
||||
│ Información del Dispositivo │
|
||||
│ • Cliente ID: CLIENT-0001 (Servidor SQL Producción) │
|
||||
│ • Servidor Proxmox: https://backup.midominio.com │
|
||||
│ • Carpetas en Monitoreo: 3 carpetas locales │
|
||||
│ │
|
||||
│ [ ▶ Iniciar Sincronización Manual Ahora ] │
|
||||
└────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Pestañas y Funcionalidades
|
||||
|
||||
### 📁 Pestaña 1: Carpetas de Backup (Selector Visual)
|
||||
Permite gestionar las carpetas de Windows que el agente respaldará automáticamente:
|
||||
- **Añadir Carpeta...**: Abre el selector visual de Windows para elegir la carpeta deseada (ej. `C:\SQLBackups`, `D:\DatosEmpresa`).
|
||||
- **Configuración de la Carpeta**:
|
||||
- **Filtros de Archivo**: `*.bak,*.mdf` (o `*.*`).
|
||||
- **Frecuencia de Sondeo**: Intervalo en minutos (ej. cada 60 min).
|
||||
- **Estabilidad de Archivo (Locks)**: Ventana de seguridad en segundos (ej. 60s) para garantizar que SQL Server finalizó el volcado antes de iniciar la transferencia por bloques.
|
||||
- **Respaldar / Eliminar**: Botones dedicados para iniciar un respaldo inmediato de la carpeta o eliminarla del monitoreo.
|
||||
|
||||
### 🌐 Pestaña 2: Servidor & Configuración
|
||||
- **URL Servidor**: Ingrese la dirección del servidor Proxmox VE (ej. `http://192.168.1.100:8000` o `https://backup.midominio.com`).
|
||||
- **Probar Conexión**: Comprueba la conectividad de red con el backend y muestra la latencia en milisegundos.
|
||||
- **Código de Registro**: Ingrese el código de un solo uso generado en el Dashboard Web (`OED-XXXX-XXXX`).
|
||||
- **Registrar Dispositivo**: Vincula criptográficamente la máquina Windows generando un `Device ID` y token secreto único.
|
||||
- **Preferencias de Notificaciones (No Invasivas)**:
|
||||
- `[x] Habilitar notificaciones en el Área de Notificaciones (System Tray)`
|
||||
- `[x] Notificar únicamente cuando INICIA un proceso de respaldo`
|
||||
- `[x] Notificar únicamente cuando FINALIZA con éxito (Confirmación SHA-256)`
|
||||
- `[x] Notificar en caso de error o pérdida de conexión`
|
||||
*(Las actualizaciones de progreso intermedias se visualizan de manera silenciosa en la barra de la interfaz sin emitir globos emergentes).*
|
||||
|
||||
### 📊 Pestaña 3: Dashboard & Telemetría
|
||||
- Medidor en tiempo real del progreso de subida por bloques.
|
||||
- Notificaciones de confirmación de integridad SHA-256 tras cada ensamblado.
|
||||
|
||||
### 📜 Pestaña 4: Historial de Archivos
|
||||
- Registro histórico de todos los archivos respaldados localmente con su tamaño, fecha y checksum SHA-256.
|
||||
|
||||
---
|
||||
|
||||
## 4. Ejecutables Disponibles
|
||||
|
||||
Los ejecutables listos para su distribución se ubican en:
|
||||
- **Standalone Portable (Un solo archivo):**
|
||||
[`windows-agent/dist/OnEverDriveAgent-Standalone.exe`](file:///c:/Workspaces/onever_drive/windows-agent/dist/OnEverDriveAgent-Standalone.exe)
|
||||
- **Carpeta de Distribución:**
|
||||
[`windows-agent/dist/OnEverDriveAgent/OnEverDriveAgent.exe`](file:///c:/Workspaces/onever_drive/windows-agent/dist/OnEverDriveAgent/OnEverDriveAgent.exe)
|
||||
- **Lanzador rápido con doble clic:**
|
||||
[`windows-agent/start_tray_agent.bat`](file:///c:/Workspaces/onever_drive/windows-agent/start_tray_agent.bat)
|
||||
|
||||
---
|
||||
|
||||
## 5. Comportamiento en la Bandeja del Sistema (System Tray)
|
||||
|
||||
- Al cerrar la ventana principal (botón `X`), la aplicación se **minimiza al área de notificaciones** junto al reloj sin interrumpir las transferencias programadas.
|
||||
- Al hacer **doble clic** o clic derecho en el icono de OnEver Drive en el System Tray, se abre instantáneamente el panel de control.
|
||||
Reference in New Issue
Block a user