diff --git a/README.md b/README.md index 817c5c1..57e7813 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,355 @@ -# Storage Appliance (skeleton) +# Adastra Storage Appliance -This repository is a starting skeleton for a storage appliance management system using Go + HTMX. +A comprehensive storage appliance management system providing ZFS pool management, NFS/SMB shares, iSCSI targets, object storage, and monitoring capabilities with a modern web interface. -Features in this skeleton: -- HTTP server with chi router and graceful shutdown -- Basic DB migration and seed for a sqlite database -- Minimal middleware placeholders (auth, RBAC, CSRF) -- Templates using html/template and HTMX sample -- Job runner skeleton and infra adapter stubs for ZFS/NFS/SMB/MinIO/iSCSI +## Features -Quick start: +- **Storage Management**: ZFS pool and dataset management with snapshots +- **Network Shares**: NFS and SMB/CIFS share management +- **Block Storage**: iSCSI target and LUN management +- **Object Storage**: MinIO integration for S3-compatible storage +- **Authentication & RBAC**: User management with role-based access control +- **Monitoring**: Prometheus metrics and real-time monitoring dashboard +- **Audit Logging**: Comprehensive audit trail of all operations +- **Modern UI**: HTMX-based web interface with TailwindCSS + +## Requirements + +- Ubuntu 24.04 (or compatible Linux distribution) +- Go 1.21 or later +- ZFS utilities (`zfsutils-linux`) +- SMART monitoring tools (`smartmontools`) +- NFS server (`nfs-kernel-server`) +- Samba (`samba`) +- iSCSI target utilities (`targetcli-fb`) +- MinIO (included in installer) + +## Installation + +### Option 1: Using the Installation Script (Recommended) + +1. Clone the repository: +```bash +git clone +cd storage-appliance +``` + +2. Run the installation script as root: +```bash +sudo bash packaging/install.sh +``` + +The installer will: +- Install all system dependencies +- Build the application +- Create the service user +- Set up systemd service +- Configure directories and permissions + +3. Start the service: +```bash +sudo systemctl start adastra-storage +sudo systemctl enable adastra-storage # Enable on boot +``` + +4. Check the status: +```bash +sudo systemctl status adastra-storage +``` + +5. View logs: +```bash +sudo journalctl -u adastra-storage -f +``` + +### Option 2: Building a Debian Package + +1. Build the Debian package: +```bash +cd packaging +chmod +x build-deb.sh +sudo ./build-deb.sh +``` + +2. Install the package: +```bash +sudo dpkg -i ../adastra-storage_1.0.0_amd64.deb +sudo apt-get install -f # Install any missing dependencies +``` + +3. Start the service: +```bash +sudo systemctl start adastra-storage +sudo systemctl enable adastra-storage +``` + +### Option 3: Manual Installation + +1. Install dependencies: +```bash +sudo apt-get update +sudo apt-get install -y golang-go zfsutils-linux smartmontools \ + nfs-kernel-server samba targetcli-fb build-essential +``` + +2. Install MinIO: +```bash +wget https://dl.min.io/server/minio/release/linux-amd64/minio -O /usr/local/bin/minio +chmod +x /usr/local/bin/minio +``` + +3. Build the application: +```bash +go build -o appliance ./cmd/appliance +``` + +4. Create directories: +```bash +sudo mkdir -p /opt/adastra-storage/{bin,data,templates,migrations,logs} +``` + +5. Copy files: +```bash +sudo cp appliance /opt/adastra-storage/bin/adastra-storage +sudo cp -r internal/templates/* /opt/adastra-storage/templates/ +sudo cp -r migrations/* /opt/adastra-storage/migrations/ +``` + +6. Create service user: +```bash +sudo useradd -r -s /bin/false -d /opt/adastra-storage adastra +sudo chown -R adastra:adastra /opt/adastra-storage +``` + +7. Install systemd service: +```bash +sudo cp packaging/adastra-storage.service /etc/systemd/system/ +sudo systemctl daemon-reload +sudo systemctl enable adastra-storage +sudo systemctl start adastra-storage +``` + +## Configuration + +### Installation Directory + +The application is installed to `/opt/adastra-storage` with the following structure: +``` +/opt/adastra-storage/ +├── bin/ +│ └── adastra-storage # Main binary +├── data/ +│ └── appliance.db # SQLite database +├── templates/ # HTML templates +├── migrations/ # Database migrations +├── logs/ # Log files +└── uninstall.sh # Uninstaller script +``` + +### Environment Variables + +The service uses the following environment variables (set in systemd service): +- `INSTALL_DIR`: Installation directory (default: `/opt/adastra-storage`) +- `DATA_DIR`: Data directory (default: `/opt/adastra-storage/data`) + +### Service Configuration + +The systemd service file is located at `/etc/systemd/system/adastra-storage.service`. + +To modify the service: +```bash +sudo systemctl edit adastra-storage +``` + +## Usage + +### Accessing the Web Interface + +After installation, access the web interface at: +``` +http://localhost:8080 +``` + +Default credentials: +- **Username**: `admin` +- **Password**: `admin` + +⚠️ **IMPORTANT**: Change the default password immediately after first login! + +### Service Management + +Start the service: +```bash +sudo systemctl start adastra-storage +``` + +Stop the service: +```bash +sudo systemctl stop adastra-storage +``` + +Restart the service: +```bash +sudo systemctl restart adastra-storage +``` + +Check status: +```bash +sudo systemctl status adastra-storage +``` + +View logs: +```bash +sudo journalctl -u adastra-storage -f +``` + +### Prometheus Metrics + +The application exposes Prometheus metrics at: +``` +http://localhost:8080/metrics +``` + +### API Examples + +Get pools (requires authentication): +```bash +curl -b cookies.txt http://127.0.0.1:8080/api/pools +``` + +Create a pool (requires admin permission): +```bash +curl -X POST -b cookies.txt -H "Content-Type: application/json" \ + -d '{"name":"tank","vdevs":["/dev/sda"]}' \ + http://127.0.0.1:8080/api/pools +``` + +## Development + +### Quick Start ```bash make run ``` -Build: +### Build + ```bash make build ``` -Run tests: +### Run Tests + ```bash make test ``` -The skeleton is intentionally minimal. Next steps include adding real service implementations, authentication, and more tests. +### Lint -API examples: - -Get pools (viewer): ```bash -curl -H "X-Auth-User: viewer" -H "X-Auth-Role: viewer" http://127.0.0.1:8080/api/pools +make lint ``` -Create a pool (admin): +## Uninstallation + +### Using the Uninstaller Script + ```bash -curl -s -X POST -H "X-Auth-User: admin" -H "X-Auth-Role: admin" -H "Content-Type: application/json" \ - -d '{"name":"tank","vdevs":["/dev/sda"]}' http://127.0.0.1:8080/api/pools +sudo /opt/adastra-storage/uninstall.sh ``` +The uninstaller will: +- Stop and disable the service +- Remove application files (optionally preserve data) +- Optionally remove the service user + +### Manual Uninstallation + +1. Stop and disable the service: +```bash +sudo systemctl stop adastra-storage +sudo systemctl disable adastra-storage +``` + +2. Remove files: +```bash +sudo rm -rf /opt/adastra-storage +sudo rm /etc/systemd/system/adastra-storage.service +sudo systemctl daemon-reload +``` + +3. Remove service user (optional): +```bash +sudo userdel adastra +``` + +## Architecture + +### Components + +- **HTTP Server**: Chi router with middleware for auth, RBAC, CSRF +- **Database**: SQLite with migrations +- **Services**: Storage, Shares, iSCSI, Object Store +- **Infrastructure Adapters**: ZFS, NFS, Samba, iSCSI, MinIO +- **Job Runner**: Async job processing for long-running tasks +- **Monitoring**: Prometheus metrics and UI dashboard +- **Audit**: Comprehensive audit logging + +### Security + +- Session-based authentication with secure cookies +- CSRF protection compatible with HTMX +- Role-based access control (RBAC) with fine-grained permissions +- Password hashing using Argon2id +- Audit logging of all operations + +## Troubleshooting + +### Service Won't Start + +1. Check service status: +```bash +sudo systemctl status adastra-storage +``` + +2. Check logs: +```bash +sudo journalctl -u adastra-storage -n 50 +``` + +3. Verify permissions: +```bash +ls -la /opt/adastra-storage +``` + +4. Check if port 8080 is available: +```bash +sudo netstat -tlnp | grep 8080 +``` + +### Database Issues + +The database is located at `/opt/adastra-storage/data/appliance.db`. If you need to reset: +```bash +sudo systemctl stop adastra-storage +sudo rm /opt/adastra-storage/data/appliance.db +sudo systemctl start adastra-storage +``` + +⚠️ **Warning**: This will delete all data! + +### Permission Issues + +Ensure the service user has proper permissions: +```bash +sudo chown -R adastra:adastra /opt/adastra-storage +sudo usermod -aG disk adastra # For ZFS access +``` + +## License + +[Specify your license here] + +## Support + +For issues and questions, please open an issue on the project repository. diff --git a/cmd/appliance/main.go b/cmd/appliance/main.go index ac10a2a..3b69208 100644 --- a/cmd/appliance/main.go +++ b/cmd/appliance/main.go @@ -3,9 +3,11 @@ package main import ( "context" "database/sql" + "fmt" "log" "net/http" "os" + "path/filepath" "os/signal" "syscall" "time" @@ -30,8 +32,26 @@ import ( func main() { ctx := context.Background() + + // Determine data directory (use /opt/adastra-storage/data in production, current dir in dev) + dataDir := os.Getenv("DATA_DIR") + if dataDir == "" { + dataDir = os.Getenv("INSTALL_DIR") + if dataDir != "" { + dataDir = filepath.Join(dataDir, "data") + } else { + dataDir = "." // Development mode + } + } + + // Ensure data directory exists + if err := os.MkdirAll(dataDir, 0755); err != nil { + log.Fatalf("failed to create data directory: %v", err) + } + // Connect simple sqlite DB (file) - dsn := "file:appliance.db?_foreign_keys=on" + dbPath := filepath.Join(dataDir, "appliance.db") + dsn := fmt.Sprintf("file:%s?_foreign_keys=on", dbPath) sqldb, err := sql.Open("sqlite", dsn) if err != nil { log.Fatalf("open db: %v", err) diff --git a/packaging/DEBIAN/control b/packaging/DEBIAN/control new file mode 100755 index 0000000..b7755eb --- /dev/null +++ b/packaging/DEBIAN/control @@ -0,0 +1,13 @@ +Package: adastra-storage +Version: 1.0.0 +Section: admin +Priority: optional +Architecture: amd64 +Depends: golang-go (>= 1.21), zfsutils-linux, smartmontools, nfs-kernel-server, samba, targetcli-fb, minio +Maintainer: Adastra Storage Team +Description: Adastra Storage Appliance Management System + A comprehensive storage appliance management system providing + ZFS pool management, NFS/SMB shares, iSCSI targets, object storage, + and monitoring capabilities with a modern web interface. +Homepage: https://github.com/example/storage-appliance + diff --git a/packaging/DEBIAN/postinst b/packaging/DEBIAN/postinst new file mode 100755 index 0000000..22458a0 --- /dev/null +++ b/packaging/DEBIAN/postinst @@ -0,0 +1,47 @@ +#!/bin/bash +set -e + +# Post-installation script for adastra-storage + +INSTALL_DIR="/opt/adastra-storage" +SERVICE_USER="adastra" +SERVICE_GROUP="adastra" + +echo "Adastra Storage: Post-installation setup..." + +# Create service user if it doesn't exist +if ! id "$SERVICE_USER" &>/dev/null; then + echo "Creating service user: $SERVICE_USER" + useradd -r -s /bin/false -d "$INSTALL_DIR" "$SERVICE_USER" || true +fi + +# Set ownership +chown -R "$SERVICE_USER:$SERVICE_GROUP" "$INSTALL_DIR" || true + +# Create data directory +mkdir -p "$INSTALL_DIR/data" +chown "$SERVICE_USER:$SERVICE_GROUP" "$INSTALL_DIR/data" + +# Enable and start systemd service +if systemctl is-enabled adastra-storage.service >/dev/null 2>&1; then + echo "Service already enabled" +else + systemctl daemon-reload + systemctl enable adastra-storage.service + echo "Service enabled. Start with: systemctl start adastra-storage" +fi + +# Set permissions for ZFS commands (if needed) +# Note: Service user may need sudo access or be in appropriate groups +usermod -aG disk "$SERVICE_USER" || true + +echo "Adastra Storage installation complete!" +echo "Default admin credentials: username=admin, password=admin" +echo "Please change the default password after first login!" +echo "" +echo "Start the service: systemctl start adastra-storage" +echo "Check status: systemctl status adastra-storage" +echo "View logs: journalctl -u adastra-storage -f" + +exit 0 +