darroyo 63e0b5146a fix: tolerate duplicate column errors in migration runner
The previous SAVEPOINT approach failed because Go's tx.Exec() stops at
the first error and never reaches the ROLLBACK TO statements. This caused
every subsequent startup to re-run migration 0002, fail on the first
ALTER (column already exists from a prior partial run), and crash.

Fix runMigration() to:
- Execute migrations without a wrapping transaction (DDL in SQLite is
  auto-commit anyway)
- Treat "duplicate column name" / "already exists" errors as success
  and record the migration anyway, covering cases where a previous
  failed attempt already partially modified the schema

Also simplify 0002_nfs_structured.sql back to plain ALTER TABLE
statements (no SAVEPOINT needed with the new Go-level tolerance).

Bump VERSION 0.1.9 -> 0.1.10
2026-07-06 00:05:02 -04:00

nasctl

Sistema NAS monolítico en Go, gestionable vía interfaz web, distribuido como un único binario estático.

Requisitos

  • Go 1.22+
  • Linux (para aplicar configuración Samba/NFS en producción)

Requisitos de build

  • Go 1.22+
  • Node.js 18+ y npm (solo para compilar el frontend embebido)

Build

make build      # compila frontend (npm) + binario Go con assets embebidos

Binario generado en bin/nasctl. Si ya tienes internal/web/dist compilado, make build-go compila solo el binario.

Ejecución local

make run

Levanta en http://localhost:8080. Credenciales iniciales por defecto admin / admin (cámbialas con las variables de entorno o tras el primer login).

Para desarrollo del frontend con hot-reload:

cd web && npm run dev   # Vite en :5173, proxya /api a :8080

Variables de entorno útiles:

Variable Default Descripción
NASCTL_ADDR :8080 Dirección HTTP
NASCTL_DB /var/lib/nasctl/nasctl.db Ruta SQLite
NASCTL_SMB_CONF /etc/samba/smb.conf Destino de smb.conf generado
NASCTL_EXPORTS /etc/exports Destino de /etc/exports generado
NASCTL_EXEC_SYSTEM true Ejecutar comandos reales del sistema (reload servicios, useradd, smbpasswd...)
NASCTL_ALLOWED_ROOTS (vacío) Directorios raíz permitidos para paths de shares/exports, separados por coma
NASCTL_ADMIN_USER admin Usuario admin inicial (solo si no existe ninguno)
NASCTL_ADMIN_PASSWORD admin Contraseña admin inicial (solo si no existe ninguno)
NASCTL_IMPORT_ON_BOOT false true para importar smb.conf y /etc/exports existentes al primer arranque

En desarrollo, make run usa ./.data/ y NASCTL_EXEC_SYSTEM=false (no toca el sistema real).

API

Autenticación (cookie de sesión firmada, httpOnly):

  • POST /api/auth/login{username, password} → cookie de sesión
  • POST /api/auth/logout
  • GET /api/auth/status

El resto de endpoints requieren sesión válida:

  • GET /api/dirty — módulos con cambios pendientes
  • POST /api/apply — aplica configuración pendiente
  • GET /api/apply/log — historial de aplicaciones
  • GET /api/system/status — uso de disco y estado de servicios
  • GET/POST/PUT/DELETE /api/samba/shares — CRUD de shares Samba
  • GET/POST/PUT/DELETE /api/nfs/exports — CRUD de exports NFS
  • GET/POST/PUT/DELETE /api/users — CRUD de usuarios del sistema
  • GET /api/import/status — estado del import (done, counts)
  • POST /api/import/samba — re-importa shares desde smb.conf
  • POST /api/import/nfs — re-importa exports desde /etc/exports

Todos los cambios marcan el módulo como dirty y NO se aplican al sistema hasta POST /api/apply.

Flujo dirty → apply

  1. Los cambios se guardan solo en SQLite.
  2. Se marca el módulo correspondiente como dirty.
  3. El usuario pulsa "Aplicar cambios" (POST /api/apply).
  4. El motor regenera archivos de configuración desde templates y recarga servicios.

Importar configuración existente

Si el host ya tiene smb.conf o /etc/exports configurados, nasctl puede importarlos al primer arranque:

NASCTL_IMPORT_ON_BOOT=true ./nasctl

El import:

  1. Detecta shares en smb.conf y exports en /etc/exports.
  2. Los importa a SQLite (marca el módulo como dirty).
  3. No sobreescribe los archivos automáticamente — el usuario revisa y pulsa Apply.
  4. Antes del primer Apply, hace backup de los archivos originales en <path>.nasctl.bak.<timestamp>.
  5. Los flags import.samba.done/import.nfs.done en la base de datos evitan re-importar en cada arranque.

Para re-escanear manualmente después de editar los archivos en disco:

  • POST /api/import/samba — reimporta shares desde smb.conf
  • POST /api/import/nfs — reimporta exports desde /etc/exports
  • GET /api/import/status — estado del import

Empaquetado

make package

Genera dist/nasctl_0.1.0_amd64.deb.

Estado

Implementado: módulos Samba, NFS y usuarios (con flujo dirty→apply), autenticación web (bcrypt + cookie de sesión firmada), validación de paths permitidos, dashboard con estado del sistema y frontend React + Vite + Tailwind embebido en el binario.

Próximas mejoras posibles

  • Gestión de admins web desde la UI (cambio de contraseña)
  • Polkit para delegar acciones puntuales sin correr como root
  • Métricas e histórico más detallados en el dashboard
S
Description
No description provided
Readme 604 KiB
Languages
Go 51.4%
TypeScript 45.4%
CSS 1.1%
JavaScript 1%
Makefile 0.5%
Other 0.5%