Implement data directory configuration and ensure its existence in the main application. Update README with comprehensive features, installation instructions, and usage guidelines for the Adastra Storage Appliance.
This commit is contained in:
351
README.md
351
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 <repository-url>
|
||||
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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
13
packaging/DEBIAN/control
Executable file
13
packaging/DEBIAN/control
Executable file
@@ -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 <admin@adastra-storage.local>
|
||||
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
|
||||
|
||||
47
packaging/DEBIAN/postinst
Executable file
47
packaging/DEBIAN/postinst
Executable file
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user