modify sonarqube
This commit is contained in:
BIN
dist/airgap/calypso-appliance-1.0.0-airgap.tar.gz
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap.tar.gz
vendored
Normal file
Binary file not shown.
1
dist/airgap/calypso-appliance-1.0.0-airgap.tar.gz.sha256
vendored
Normal file
1
dist/airgap/calypso-appliance-1.0.0-airgap.tar.gz.sha256
vendored
Normal file
@@ -0,0 +1 @@
|
||||
a4040ea4ab486d4671772e4b832b4be5741bf58764fc731873b585df1d805e66 calypso-appliance-1.0.0-airgap.tar.gz
|
||||
59
dist/airgap/calypso-appliance-1.0.0-airgap/README.md
vendored
Normal file
59
dist/airgap/calypso-appliance-1.0.0-airgap/README.md
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
# Calypso Appliance - Airgap Installation Bundle
|
||||
|
||||
**Version:** 1.0.0
|
||||
**Target OS:** Ubuntu Server 24.04 LTS
|
||||
**Installation Type:** Offline/Airgap
|
||||
|
||||
## Bundle Contents
|
||||
|
||||
- **binaries/**: Pre-built Calypso binaries
|
||||
- **frontend/**: Built frontend assets
|
||||
- **packages/debs/**: All required DEB packages with dependencies (59 packages + ~200-300 dependencies)
|
||||
- **scripts/**: Installation scripts
|
||||
- **services/**: Systemd service files
|
||||
- **migrations/**: Database migration files
|
||||
- **configs/**: Configuration templates
|
||||
- **third_party/**: Optional third-party binaries (Go, Node.js)
|
||||
|
||||
## Installation
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Ubuntu Server 24.04 LTS
|
||||
- Root or sudo access
|
||||
- Minimum 10GB free disk space
|
||||
- Kernel headers installed (for kernel modules)
|
||||
|
||||
### Quick Install
|
||||
|
||||
```bash
|
||||
cd /path/to/bundle
|
||||
sudo ./install-airgap.sh
|
||||
```
|
||||
|
||||
The installer will:
|
||||
1. Install all packages from bundled DEB files
|
||||
2. Install Calypso binaries and frontend
|
||||
3. Setup database and configuration
|
||||
4. Install systemd services
|
||||
|
||||
### Post-Installation
|
||||
|
||||
1. Review configuration: `/etc/calypso/calypso.yaml`
|
||||
2. Install kernel modules (ZFS, SCST, mhVTL) if needed
|
||||
3. Start services: `systemctl start calypso-api`
|
||||
4. Enable services: `systemctl enable calypso-api`
|
||||
|
||||
## Verification
|
||||
|
||||
Check service status:
|
||||
```bash
|
||||
systemctl status calypso-api
|
||||
curl http://localhost:8080/api/v1/health
|
||||
```
|
||||
|
||||
## Support
|
||||
|
||||
For issues, check:
|
||||
- Installation logs: `/var/log/calypso/install.log`
|
||||
- Service logs: `journalctl -u calypso-api`
|
||||
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/binaries/calypso-api
vendored
Executable file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/binaries/calypso-api
vendored
Executable file
Binary file not shown.
64
dist/airgap/calypso-appliance-1.0.0-airgap/configs/config.yaml.template
vendored
Normal file
64
dist/airgap/calypso-appliance-1.0.0-airgap/configs/config.yaml.template
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
# AtlasOS - Calypso API Configuration Template
|
||||
# This file will be copied to /etc/calypso/config.yaml during installation
|
||||
# Environment variables from /etc/calypso/secrets.env will be used for sensitive values
|
||||
|
||||
server:
|
||||
port: 8080
|
||||
host: "0.0.0.0"
|
||||
read_timeout: 15s
|
||||
write_timeout: 15s
|
||||
idle_timeout: 60s
|
||||
# Response caching configuration
|
||||
cache:
|
||||
enabled: true # Enable response caching
|
||||
default_ttl: 5m # Default cache TTL (5 minutes)
|
||||
max_age: 300 # Cache-Control max-age in seconds (5 minutes)
|
||||
|
||||
database:
|
||||
host: "localhost"
|
||||
port: 5432
|
||||
user: "calypso"
|
||||
password: "" # Set via CALYPSO_DB_PASSWORD environment variable
|
||||
database: "calypso"
|
||||
ssl_mode: "disable"
|
||||
# Connection pool optimization
|
||||
max_connections: 25
|
||||
max_idle_conns: 5
|
||||
conn_max_lifetime: 5m
|
||||
|
||||
auth:
|
||||
jwt_secret: "" # Set via CALYPSO_JWT_SECRET environment variable
|
||||
token_lifetime: 24h
|
||||
argon2:
|
||||
memory: 65536 # 64 MB
|
||||
iterations: 3
|
||||
parallelism: 4
|
||||
salt_length: 16
|
||||
key_length: 32
|
||||
|
||||
logging:
|
||||
level: "info" # debug, info, warn, error
|
||||
format: "json" # json or text
|
||||
|
||||
# CORS configuration
|
||||
cors:
|
||||
allowed_origins:
|
||||
- "http://localhost:3000"
|
||||
- "http://localhost:5173"
|
||||
allowed_methods:
|
||||
- "GET"
|
||||
- "POST"
|
||||
- "PUT"
|
||||
- "DELETE"
|
||||
- "PATCH"
|
||||
allowed_headers:
|
||||
- "Content-Type"
|
||||
- "Authorization"
|
||||
allow_credentials: true
|
||||
|
||||
# Rate limiting
|
||||
rate_limit:
|
||||
enabled: true
|
||||
requests_per_minute: 100
|
||||
authenticated_requests_per_minute: 200
|
||||
|
||||
66
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/chart-vendor-CnBPFalK.js
vendored
Normal file
66
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/chart-vendor-CnBPFalK.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/chart-vendor-CnBPFalK.js.map
vendored
Normal file
1
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/chart-vendor-CnBPFalK.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/index-BY0QR2-n.css
vendored
Normal file
1
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/index-BY0QR2-n.css
vendored
Normal file
File diff suppressed because one or more lines are too long
207
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/index-ChZMKDzx.js
vendored
Normal file
207
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/index-ChZMKDzx.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/index-ChZMKDzx.js.map
vendored
Normal file
1
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/index-ChZMKDzx.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
6
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/index.es-BqkUSV0N.js
vendored
Normal file
6
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/index.es-BqkUSV0N.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/index.es-BqkUSV0N.js.map
vendored
Normal file
1
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/index.es-BqkUSV0N.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
3
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/purify.es-Bzr520pe.js
vendored
Normal file
3
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/purify.es-Bzr520pe.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/purify.es-Bzr520pe.js.map
vendored
Normal file
1
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/purify.es-Bzr520pe.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/query-vendor-BeRQtQod.js
vendored
Normal file
2
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/query-vendor-BeRQtQod.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/query-vendor-BeRQtQod.js.map
vendored
Normal file
1
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/query-vendor-BeRQtQod.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/react-vendor-Dvs2KPqW.js
vendored
Normal file
2
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/react-vendor-Dvs2KPqW.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/react-vendor-Dvs2KPqW.js.map
vendored
Normal file
1
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/react-vendor-Dvs2KPqW.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/terminal-vendor-l0sNRNKZ.js
vendored
Normal file
2
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/terminal-vendor-l0sNRNKZ.js
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
//# sourceMappingURL=terminal-vendor-l0sNRNKZ.js.map
|
||||
1
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/terminal-vendor-l0sNRNKZ.js.map
vendored
Normal file
1
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/terminal-vendor-l0sNRNKZ.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"terminal-vendor-l0sNRNKZ.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
||||
2
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/ui-vendor-C4xvlrdo.js
vendored
Normal file
2
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/ui-vendor-C4xvlrdo.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/ui-vendor-C4xvlrdo.js.map
vendored
Normal file
1
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/ui-vendor-C4xvlrdo.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
7
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/utils-vendor-CJpcXyE0.js
vendored
Normal file
7
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/utils-vendor-CJpcXyE0.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/utils-vendor-CJpcXyE0.js.map
vendored
Normal file
1
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/assets/utils-vendor-CJpcXyE0.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
29
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/index.html
vendored
Normal file
29
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/index.html
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<!doctype html>
|
||||
<html class="dark" lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/png" href="/logo.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>AtlasOS - Calypso</title>
|
||||
<!-- Material Symbols -->
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script type="module" crossorigin src="/assets/index-ChZMKDzx.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/assets/react-vendor-Dvs2KPqW.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/query-vendor-BeRQtQod.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/utils-vendor-CJpcXyE0.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/ui-vendor-C4xvlrdo.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/chart-vendor-CnBPFalK.js">
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-BY0QR2-n.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/logo.png
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/frontend/logo.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
215
dist/airgap/calypso-appliance-1.0.0-airgap/install-airgap.sh
vendored
Executable file
215
dist/airgap/calypso-appliance-1.0.0-airgap/install-airgap.sh
vendored
Executable file
@@ -0,0 +1,215 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Calypso Appliance - Airgap Installer
|
||||
# Installs Calypso from bundled files without internet connection
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
BUNDLE_DIR="$SCRIPT_DIR"
|
||||
VERSION="${VERSION:-1.0.0}"
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
||||
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
log_step() { echo -e "\n${BLUE}==>${NC} $1"; }
|
||||
|
||||
# Check root
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
log_error "This script must be run as root (use sudo)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check OS
|
||||
if [ ! -f /etc/os-release ]; then
|
||||
log_error "Cannot detect OS"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
. /etc/os-release
|
||||
if [[ "$ID" != "ubuntu" ]] || [[ "$VERSION_ID" != "24.04" ]]; then
|
||||
log_warn "This installer is designed for Ubuntu 24.04 LTS"
|
||||
log_warn "Detected: $ID $VERSION_ID"
|
||||
read -p "Continue anyway? (y/N) " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
log_step "Calypso Appliance - Airgap Installation"
|
||||
log_info "Bundle directory: $BUNDLE_DIR"
|
||||
|
||||
# 1. Install packages from bundle
|
||||
log_step "Installing system packages from bundle..."
|
||||
|
||||
if [ -d "$BUNDLE_DIR/packages/debs" ] && [ "$(ls -A $BUNDLE_DIR/packages/debs/*.deb 2>/dev/null)" ]; then
|
||||
log_info "Installing packages from bundle..."
|
||||
|
||||
# Create local apt repository
|
||||
DEBS_DIR="$BUNDLE_DIR/packages/debs"
|
||||
REPO_DIR="/tmp/calypso-local-repo"
|
||||
|
||||
mkdir -p "$REPO_DIR"
|
||||
cp "$DEBS_DIR"/*.deb "$REPO_DIR/" 2>/dev/null || true
|
||||
|
||||
# Create Packages.gz if not exists
|
||||
cd "$REPO_DIR"
|
||||
if [ ! -f Packages.gz ]; then
|
||||
dpkg-scanpackages . /dev/null 2>/dev/null | gzip -9c > Packages.gz
|
||||
fi
|
||||
|
||||
# Add to sources.list temporarily
|
||||
echo "deb [trusted=yes] file://$REPO_DIR ./" > /tmp/calypso-local.list
|
||||
mv /tmp/calypso-local.list /etc/apt/sources.list.d/calypso-local.list
|
||||
|
||||
# Update apt cache
|
||||
apt-get update -qq
|
||||
|
||||
# Install packages from list
|
||||
PACKAGE_LIST="$BUNDLE_DIR/packages/package-list.txt"
|
||||
PACKAGES=$(grep -v '^#' "$PACKAGE_LIST" | grep -v '^$' | tr '\n' ' ')
|
||||
|
||||
log_info "Installing packages..."
|
||||
apt-get install -y --allow-unauthenticated $PACKAGES || {
|
||||
log_warn "Some packages failed to install, trying individual installation..."
|
||||
while IFS= read -r package || [ -n "$package" ]; do
|
||||
[[ "$package" =~ ^#.*$ ]] && continue
|
||||
[[ -z "$package" ]] && continue
|
||||
apt-get install -y --allow-unauthenticated "$package" 2>/dev/null || log_warn "Failed: $package"
|
||||
done < "$PACKAGE_LIST"
|
||||
}
|
||||
|
||||
# Cleanup
|
||||
rm -f /etc/apt/sources.list.d/calypso-local.list
|
||||
apt-get update -qq
|
||||
|
||||
log_info "✓ Packages installed from bundle"
|
||||
else
|
||||
log_warn "Package DEB files not found in bundle"
|
||||
log_warn "You need to install packages manually"
|
||||
log_info "Package list: $BUNDLE_DIR/packages/package-list.txt"
|
||||
read -p "Install packages from system repositories? (y/N) " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
apt-get update
|
||||
xargs -a "$BUNDLE_DIR/packages/package-list.txt" -r apt-get install -y
|
||||
fi
|
||||
fi
|
||||
|
||||
# 2. Install Go from bundle (if available)
|
||||
if [ -f "$BUNDLE_DIR/third_party/go.tar.gz" ]; then
|
||||
log_step "Installing Go from bundle..."
|
||||
rm -rf /usr/local/go
|
||||
tar -C /usr/local -xzf "$BUNDLE_DIR/third_party/go.tar.gz"
|
||||
export PATH=$PATH:/usr/local/go/bin
|
||||
if ! grep -q "/usr/local/go/bin" /etc/profile; then
|
||||
echo 'export PATH=$PATH:/usr/local/go/bin' >> /etc/profile
|
||||
fi
|
||||
log_info "✓ Go installed"
|
||||
fi
|
||||
|
||||
# 3. Install Node.js from bundle (if available)
|
||||
if [ -f "$BUNDLE_DIR/third_party/nodejs.tar.xz" ]; then
|
||||
log_step "Installing Node.js from bundle..."
|
||||
rm -rf /usr/local/node
|
||||
mkdir -p /usr/local/node
|
||||
tar -C /usr/local/node -xJf "$BUNDLE_DIR/third_party/nodejs.tar.xz" --strip-components=1
|
||||
export PATH=$PATH:/usr/local/node/bin
|
||||
if ! grep -q "/usr/local/node/bin" /etc/profile; then
|
||||
echo 'export PATH=$PATH:/usr/local/node/bin' >> /etc/profile
|
||||
fi
|
||||
log_info "✓ Node.js installed"
|
||||
fi
|
||||
|
||||
# 4. Create filesystem structure
|
||||
log_step "Creating filesystem structure..."
|
||||
INSTALL_PREFIX="/opt/adastra/calypso"
|
||||
CONFIG_DIR="/etc/calypso"
|
||||
DATA_DIR="/srv/calypso"
|
||||
LOG_DIR="/var/log/calypso"
|
||||
LIB_DIR="/var/lib/calypso"
|
||||
|
||||
mkdir -p "$INSTALL_PREFIX/releases/${VERSION}"/{bin,web,migrations,scripts}
|
||||
mkdir -p "$INSTALL_PREFIX/third_party"
|
||||
mkdir -p "$CONFIG_DIR"/{tls,integrations,system,scst,nfs,samba,clamav}
|
||||
mkdir -p "$DATA_DIR"/{db,backups,object,shares,vtl,iscsi,uploads,cache,_system,quarantine}
|
||||
mkdir -p "$LOG_DIR" "$LIB_DIR" "/run/calypso"
|
||||
|
||||
# Create calypso user
|
||||
if ! id "calypso" &>/dev/null; then
|
||||
useradd -r -s /bin/false -d "$LIB_DIR" -c "Calypso Appliance" calypso
|
||||
fi
|
||||
|
||||
# 5. Install binaries
|
||||
log_step "Installing Calypso binaries..."
|
||||
cp "$BUNDLE_DIR/binaries/calypso-api" "$INSTALL_PREFIX/releases/${VERSION}/bin/"
|
||||
chmod +x "$INSTALL_PREFIX/releases/${VERSION}/bin/calypso-api"
|
||||
|
||||
# Install frontend
|
||||
cp -r "$BUNDLE_DIR/frontend"/* "$INSTALL_PREFIX/releases/${VERSION}/web/"
|
||||
|
||||
# Install migrations
|
||||
cp -r "$BUNDLE_DIR/migrations"/* "$INSTALL_PREFIX/releases/${VERSION}/migrations/" 2>/dev/null || true
|
||||
|
||||
# Install scripts
|
||||
cp -r "$BUNDLE_DIR/scripts"/* "$INSTALL_PREFIX/releases/${VERSION}/scripts/" 2>/dev/null || true
|
||||
chmod +x "$INSTALL_PREFIX/releases/${VERSION}/scripts"/*.sh 2>/dev/null || true
|
||||
|
||||
# Create symlink
|
||||
ln -sfn "releases/${VERSION}" "$INSTALL_PREFIX/current"
|
||||
|
||||
# Set ownership
|
||||
chown -R calypso:calypso "$INSTALL_PREFIX" "$LIB_DIR" "$LOG_DIR" "$DATA_DIR" 2>/dev/null || chown -R root:root "$INSTALL_PREFIX" "$LIB_DIR" "$LOG_DIR" "$DATA_DIR"
|
||||
|
||||
log_info "✓ Binaries installed"
|
||||
|
||||
# 6. Install systemd services
|
||||
log_step "Installing systemd services..."
|
||||
if [ -d "$BUNDLE_DIR/services" ]; then
|
||||
cp "$BUNDLE_DIR/services"/*.service /etc/systemd/system/ 2>/dev/null || true
|
||||
systemctl daemon-reload
|
||||
log_info "✓ Systemd services installed"
|
||||
fi
|
||||
|
||||
# 7. Setup database
|
||||
log_step "Setting up database..."
|
||||
if systemctl is-active --quiet postgresql 2>/dev/null || systemctl is-enabled --quiet postgresql 2>/dev/null; then
|
||||
sudo -u postgres createdb calypso 2>/dev/null || true
|
||||
sudo -u postgres createuser calypso 2>/dev/null || true
|
||||
sudo -u postgres psql -c "ALTER USER calypso WITH PASSWORD 'calypso_change_me';" 2>/dev/null || true
|
||||
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE calypso TO calypso;" 2>/dev/null || true
|
||||
log_info "✓ Database setup complete"
|
||||
else
|
||||
log_warn "PostgreSQL not running. Please start it and run database setup manually."
|
||||
fi
|
||||
|
||||
# 8. Generate configuration
|
||||
log_step "Generating configuration..."
|
||||
if [ -f "$BUNDLE_DIR/configs/config.yaml.template" ]; then
|
||||
cp "$BUNDLE_DIR/configs/config.yaml.template" "$CONFIG_DIR/calypso.yaml"
|
||||
# Generate secrets
|
||||
if command -v openssl &> /dev/null; then
|
||||
JWT_SECRET=$(openssl rand -hex 32)
|
||||
sed -i "s/CHANGE_ME_JWT_SECRET/$JWT_SECRET/g" "$CONFIG_DIR/calypso.yaml"
|
||||
fi
|
||||
log_info "✓ Configuration generated"
|
||||
fi
|
||||
|
||||
log_step "Installation Complete!"
|
||||
log_info ""
|
||||
log_info "Next steps:"
|
||||
log_info "1. Review configuration: $CONFIG_DIR/calypso.yaml"
|
||||
log_info "2. Install kernel modules (ZFS, SCST, mhVTL) if needed"
|
||||
log_info "3. Start services: systemctl start calypso-api"
|
||||
log_info "4. Enable services: systemctl enable calypso-api"
|
||||
log_info ""
|
||||
log_info "Calypso API will be available at: http://localhost:8080"
|
||||
229
dist/airgap/calypso-appliance-1.0.0-airgap/install.sh
vendored
Executable file
229
dist/airgap/calypso-appliance-1.0.0-airgap/install.sh
vendored
Executable file
@@ -0,0 +1,229 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# AtlasOS - Calypso Appliance Installer
|
||||
# Complete installation script for Calypso backup appliance
|
||||
# Target OS: Ubuntu Server 24.04 LTS
|
||||
#
|
||||
# Usage: sudo ./installer/alpha/install.sh [options]
|
||||
#
|
||||
# Options:
|
||||
# --version VERSION Install specific version (default: auto-detect)
|
||||
# --skip-deps Skip system dependencies installation
|
||||
# --skip-zfs Skip ZFS installation
|
||||
# --skip-scst Skip SCST installation
|
||||
# --skip-mhvtl Skip MHVTL installation
|
||||
# --skip-bacula Skip Bacula installation
|
||||
# --config-only Only setup configuration, don't install binaries
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Script directory
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
INSTALLER_DIR="$SCRIPT_DIR"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Logging functions
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
log_step() {
|
||||
echo -e "\n${BLUE}==>${NC} $1"
|
||||
}
|
||||
|
||||
# Configuration
|
||||
CALYPSO_VERSION="${CALYPSO_VERSION:-1.0.0-alpha}"
|
||||
INSTALL_PREFIX="/opt/adastra/calypso"
|
||||
CONFIG_DIR="/etc/calypso"
|
||||
DATA_DIR="/srv/calypso"
|
||||
LOG_DIR="/var/log/calypso"
|
||||
LIB_DIR="/var/lib/calypso"
|
||||
RUN_DIR="/run/calypso"
|
||||
|
||||
# Flags
|
||||
SKIP_DEPS=false
|
||||
SKIP_ZFS=false
|
||||
SKIP_SCST=false
|
||||
SKIP_MHVTL=false
|
||||
SKIP_BACULA=false
|
||||
CONFIG_ONLY=false
|
||||
|
||||
# Parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--version)
|
||||
CALYPSO_VERSION="$2"
|
||||
shift 2
|
||||
;;
|
||||
--skip-deps)
|
||||
SKIP_DEPS=true
|
||||
shift
|
||||
;;
|
||||
--skip-zfs)
|
||||
SKIP_ZFS=true
|
||||
shift
|
||||
;;
|
||||
--skip-scst)
|
||||
SKIP_SCST=true
|
||||
shift
|
||||
;;
|
||||
--skip-mhvtl)
|
||||
SKIP_MHVTL=true
|
||||
shift
|
||||
;;
|
||||
--skip-bacula)
|
||||
SKIP_BACULA=true
|
||||
shift
|
||||
;;
|
||||
--config-only)
|
||||
CONFIG_ONLY=true
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
log_error "Unknown option: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Check if running as root
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
log_error "This script must be run as root (use sudo)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Detect OS
|
||||
if ! grep -q "Ubuntu" /etc/os-release 2>/dev/null; then
|
||||
log_warn "This installer is designed for Ubuntu. Proceeding anyway..."
|
||||
fi
|
||||
|
||||
log_info "=========================================="
|
||||
log_info "AtlasOS - Calypso Appliance Installer"
|
||||
log_info "Version: ${CALYPSO_VERSION}"
|
||||
log_info "=========================================="
|
||||
log_info ""
|
||||
|
||||
# Source helper scripts
|
||||
source "$INSTALLER_DIR/scripts/helpers.sh"
|
||||
source "$INSTALLER_DIR/scripts/filesystem.sh"
|
||||
source "$INSTALLER_DIR/scripts/dependencies.sh"
|
||||
source "$INSTALLER_DIR/scripts/components.sh"
|
||||
source "$INSTALLER_DIR/scripts/application.sh"
|
||||
source "$INSTALLER_DIR/scripts/database.sh"
|
||||
source "$INSTALLER_DIR/scripts/services.sh"
|
||||
source "$INSTALLER_DIR/scripts/configuration.sh"
|
||||
source "$INSTALLER_DIR/scripts/configure-services.sh"
|
||||
source "$INSTALLER_DIR/scripts/post-install.sh"
|
||||
|
||||
# Main installation function
|
||||
main() {
|
||||
log_step "Starting Calypso Appliance Installation"
|
||||
|
||||
# Pre-flight checks
|
||||
log_step "Pre-flight Checks"
|
||||
check_prerequisites
|
||||
|
||||
# Create filesystem structure
|
||||
log_step "Creating Filesystem Structure"
|
||||
create_filesystem_structure
|
||||
|
||||
# Install system dependencies
|
||||
if [[ "$SKIP_DEPS" == "false" ]]; then
|
||||
log_step "Installing System Dependencies"
|
||||
install_system_dependencies
|
||||
else
|
||||
log_info "Skipping system dependencies installation"
|
||||
fi
|
||||
|
||||
# Install components
|
||||
if [[ "$SKIP_ZFS" == "false" ]]; then
|
||||
log_step "Installing ZFS"
|
||||
install_zfs || log_warn "ZFS installation failed or already installed"
|
||||
fi
|
||||
|
||||
if [[ "$SKIP_SCST" == "false" ]]; then
|
||||
log_step "Installing SCST"
|
||||
install_scst || log_warn "SCST installation failed or already installed"
|
||||
fi
|
||||
|
||||
if [[ "$SKIP_MHVTL" == "false" ]]; then
|
||||
log_step "Installing MHVTL"
|
||||
install_mhvtl || log_warn "MHVTL installation failed or already installed"
|
||||
fi
|
||||
|
||||
if [[ "$SKIP_BACULA" == "false" ]]; then
|
||||
log_step "Installing Bacula (Optional)"
|
||||
install_bacula || log_warn "Bacula installation skipped or failed"
|
||||
fi
|
||||
|
||||
# File sharing services are installed in dependencies step
|
||||
# ClamAV is installed in dependencies step
|
||||
|
||||
# Build and install application
|
||||
if [[ "$CONFIG_ONLY" == "false" ]]; then
|
||||
log_step "Building and Installing Application"
|
||||
build_and_install_application
|
||||
else
|
||||
log_info "Skipping application build (config-only mode)"
|
||||
fi
|
||||
|
||||
# Setup database
|
||||
log_step "Setting Up Database"
|
||||
setup_database
|
||||
|
||||
# Setup configuration
|
||||
log_step "Setting Up Configuration"
|
||||
setup_configuration
|
||||
|
||||
# Install systemd services
|
||||
log_step "Installing Systemd Services"
|
||||
install_systemd_services
|
||||
|
||||
# Configure file sharing and antivirus services
|
||||
log_step "Configuring File Sharing and Antivirus Services"
|
||||
configure_all_services
|
||||
|
||||
# Final verification
|
||||
log_step "Verifying Installation"
|
||||
verify_installation
|
||||
|
||||
# Post-installation setup
|
||||
log_step "Post-Installation Setup"
|
||||
post_install_setup
|
||||
|
||||
# Print summary
|
||||
print_installation_summary
|
||||
}
|
||||
|
||||
# Run main installation
|
||||
main
|
||||
|
||||
log_info ""
|
||||
log_info "=========================================="
|
||||
log_info "Installation Complete!"
|
||||
log_info "=========================================="
|
||||
log_info ""
|
||||
log_info "Next steps:"
|
||||
log_info "1. Configure /etc/calypso/config.yaml"
|
||||
log_info "2. Set environment variables in /etc/calypso/secrets.env"
|
||||
log_info "3. Start services: sudo systemctl start calypso-api"
|
||||
log_info "4. Access web UI: http://<server-ip>:3000"
|
||||
log_info "5. Login with default admin credentials (check above)"
|
||||
log_info ""
|
||||
|
||||
213
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/001_initial_schema.sql
vendored
Normal file
213
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/001_initial_schema.sql
vendored
Normal file
@@ -0,0 +1,213 @@
|
||||
-- AtlasOS - Calypso
|
||||
-- Initial Database Schema
|
||||
-- Version: 1.0
|
||||
|
||||
-- Users table
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
username VARCHAR(255) NOT NULL UNIQUE,
|
||||
email VARCHAR(255) NOT NULL UNIQUE,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
full_name VARCHAR(255),
|
||||
is_active BOOLEAN NOT NULL DEFAULT true,
|
||||
is_system BOOLEAN NOT NULL DEFAULT false,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
last_login_at TIMESTAMP
|
||||
);
|
||||
|
||||
-- Roles table
|
||||
CREATE TABLE IF NOT EXISTS roles (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(100) NOT NULL UNIQUE,
|
||||
description TEXT,
|
||||
is_system BOOLEAN NOT NULL DEFAULT false,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Permissions table
|
||||
CREATE TABLE IF NOT EXISTS permissions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(255) NOT NULL UNIQUE,
|
||||
resource VARCHAR(100) NOT NULL,
|
||||
action VARCHAR(100) NOT NULL,
|
||||
description TEXT,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- User roles junction table
|
||||
CREATE TABLE IF NOT EXISTS user_roles (
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
|
||||
assigned_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
assigned_by UUID REFERENCES users(id),
|
||||
PRIMARY KEY (user_id, role_id)
|
||||
);
|
||||
|
||||
-- Role permissions junction table
|
||||
CREATE TABLE IF NOT EXISTS role_permissions (
|
||||
role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
|
||||
permission_id UUID NOT NULL REFERENCES permissions(id) ON DELETE CASCADE,
|
||||
granted_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
PRIMARY KEY (role_id, permission_id)
|
||||
);
|
||||
|
||||
-- Sessions table
|
||||
CREATE TABLE IF NOT EXISTS sessions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
token_hash VARCHAR(255) NOT NULL UNIQUE,
|
||||
ip_address INET,
|
||||
user_agent TEXT,
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
last_activity_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Audit log table
|
||||
CREATE TABLE IF NOT EXISTS audit_log (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID REFERENCES users(id),
|
||||
username VARCHAR(255),
|
||||
action VARCHAR(100) NOT NULL,
|
||||
resource_type VARCHAR(100) NOT NULL,
|
||||
resource_id VARCHAR(255),
|
||||
method VARCHAR(10),
|
||||
path TEXT,
|
||||
ip_address INET,
|
||||
user_agent TEXT,
|
||||
request_body JSONB,
|
||||
response_status INTEGER,
|
||||
error_message TEXT,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Tasks table (for async operations)
|
||||
CREATE TABLE IF NOT EXISTS tasks (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
type VARCHAR(100) NOT NULL,
|
||||
status VARCHAR(50) NOT NULL DEFAULT 'pending',
|
||||
progress INTEGER NOT NULL DEFAULT 0,
|
||||
message TEXT,
|
||||
error_message TEXT,
|
||||
created_by UUID REFERENCES users(id),
|
||||
started_at TIMESTAMP,
|
||||
completed_at TIMESTAMP,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
metadata JSONB
|
||||
);
|
||||
|
||||
-- Alerts table
|
||||
CREATE TABLE IF NOT EXISTS alerts (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
severity VARCHAR(20) NOT NULL,
|
||||
source VARCHAR(100) NOT NULL,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
resource_type VARCHAR(100),
|
||||
resource_id VARCHAR(255),
|
||||
is_acknowledged BOOLEAN NOT NULL DEFAULT false,
|
||||
acknowledged_by UUID REFERENCES users(id),
|
||||
acknowledged_at TIMESTAMP,
|
||||
resolved_at TIMESTAMP,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
metadata JSONB
|
||||
);
|
||||
|
||||
-- System configuration table
|
||||
CREATE TABLE IF NOT EXISTS system_config (
|
||||
key VARCHAR(255) PRIMARY KEY,
|
||||
value TEXT NOT NULL,
|
||||
description TEXT,
|
||||
is_encrypted BOOLEAN NOT NULL DEFAULT false,
|
||||
updated_by UUID REFERENCES users(id),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Indexes for performance
|
||||
CREATE INDEX IF NOT EXISTS idx_users_username ON users(username);
|
||||
CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
|
||||
CREATE INDEX IF NOT EXISTS idx_users_active ON users(is_active);
|
||||
CREATE INDEX IF NOT EXISTS idx_sessions_user_id ON sessions(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_sessions_token_hash ON sessions(token_hash);
|
||||
CREATE INDEX IF NOT EXISTS idx_sessions_expires_at ON sessions(expires_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_audit_log_user_id ON audit_log(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_audit_log_created_at ON audit_log(created_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_audit_log_resource ON audit_log(resource_type, resource_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_tasks_type ON tasks(type);
|
||||
CREATE INDEX IF NOT EXISTS idx_tasks_created_by ON tasks(created_by);
|
||||
CREATE INDEX IF NOT EXISTS idx_alerts_severity ON alerts(severity);
|
||||
CREATE INDEX IF NOT EXISTS idx_alerts_acknowledged ON alerts(is_acknowledged);
|
||||
CREATE INDEX IF NOT EXISTS idx_alerts_created_at ON alerts(created_at);
|
||||
|
||||
-- Insert default system roles
|
||||
INSERT INTO roles (name, description, is_system) VALUES
|
||||
('admin', 'Full system access and configuration', true),
|
||||
('operator', 'Day-to-day operations and monitoring', true),
|
||||
('readonly', 'Read-only access for monitoring and reporting', true)
|
||||
ON CONFLICT (name) DO NOTHING;
|
||||
|
||||
-- Insert default permissions
|
||||
INSERT INTO permissions (name, resource, action, description) VALUES
|
||||
-- System permissions
|
||||
('system:read', 'system', 'read', 'View system information'),
|
||||
('system:write', 'system', 'write', 'Modify system configuration'),
|
||||
('system:manage', 'system', 'manage', 'Full system management'),
|
||||
|
||||
-- Storage permissions
|
||||
('storage:read', 'storage', 'read', 'View storage information'),
|
||||
('storage:write', 'storage', 'write', 'Modify storage configuration'),
|
||||
('storage:manage', 'storage', 'manage', 'Full storage management'),
|
||||
|
||||
-- Tape permissions
|
||||
('tape:read', 'tape', 'read', 'View tape library information'),
|
||||
('tape:write', 'tape', 'write', 'Perform tape operations'),
|
||||
('tape:manage', 'tape', 'manage', 'Full tape management'),
|
||||
|
||||
-- iSCSI permissions
|
||||
('iscsi:read', 'iscsi', 'read', 'View iSCSI configuration'),
|
||||
('iscsi:write', 'iscsi', 'write', 'Modify iSCSI configuration'),
|
||||
('iscsi:manage', 'iscsi', 'manage', 'Full iSCSI management'),
|
||||
|
||||
-- IAM permissions
|
||||
('iam:read', 'iam', 'read', 'View users and roles'),
|
||||
('iam:write', 'iam', 'write', 'Modify users and roles'),
|
||||
('iam:manage', 'iam', 'manage', 'Full IAM management'),
|
||||
|
||||
-- Audit permissions
|
||||
('audit:read', 'audit', 'read', 'View audit logs'),
|
||||
|
||||
-- Monitoring permissions
|
||||
('monitoring:read', 'monitoring', 'read', 'View monitoring data'),
|
||||
('monitoring:write', 'monitoring', 'write', 'Acknowledge alerts')
|
||||
ON CONFLICT (name) DO NOTHING;
|
||||
|
||||
-- Assign permissions to roles
|
||||
-- Admin gets all permissions
|
||||
INSERT INTO role_permissions (role_id, permission_id)
|
||||
SELECT r.id, p.id
|
||||
FROM roles r, permissions p
|
||||
WHERE r.name = 'admin'
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
-- Operator gets read and write (but not manage) for most resources
|
||||
INSERT INTO role_permissions (role_id, permission_id)
|
||||
SELECT r.id, p.id
|
||||
FROM roles r, permissions p
|
||||
WHERE r.name = 'operator'
|
||||
AND p.action IN ('read', 'write')
|
||||
AND p.resource IN ('storage', 'tape', 'iscsi', 'monitoring')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
-- ReadOnly gets only read permissions
|
||||
INSERT INTO role_permissions (role_id, permission_id)
|
||||
SELECT r.id, p.id
|
||||
FROM roles r, permissions p
|
||||
WHERE r.name = 'readonly'
|
||||
AND p.action = 'read'
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
227
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/002_storage_and_tape_schema.sql
vendored
Normal file
227
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/002_storage_and_tape_schema.sql
vendored
Normal file
@@ -0,0 +1,227 @@
|
||||
-- AtlasOS - Calypso
|
||||
-- Storage and Tape Component Schema
|
||||
-- Version: 2.0
|
||||
|
||||
-- ZFS pools table
|
||||
CREATE TABLE IF NOT EXISTS zfs_pools (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(255) NOT NULL UNIQUE,
|
||||
description TEXT,
|
||||
raid_level VARCHAR(50) NOT NULL, -- stripe, mirror, raidz, raidz2, raidz3
|
||||
disks TEXT[] NOT NULL, -- array of device paths
|
||||
size_bytes BIGINT NOT NULL,
|
||||
used_bytes BIGINT NOT NULL DEFAULT 0,
|
||||
compression VARCHAR(50) NOT NULL DEFAULT 'lz4', -- off, lz4, zstd, gzip
|
||||
deduplication BOOLEAN NOT NULL DEFAULT false,
|
||||
auto_expand BOOLEAN NOT NULL DEFAULT false,
|
||||
scrub_interval INTEGER NOT NULL DEFAULT 30, -- days
|
||||
is_active BOOLEAN NOT NULL DEFAULT true,
|
||||
health_status VARCHAR(50) NOT NULL DEFAULT 'online', -- online, degraded, faulted, offline
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
created_by UUID REFERENCES users(id)
|
||||
);
|
||||
|
||||
-- Disk repositories table
|
||||
CREATE TABLE IF NOT EXISTS disk_repositories (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(255) NOT NULL UNIQUE,
|
||||
description TEXT,
|
||||
volume_group VARCHAR(255) NOT NULL,
|
||||
logical_volume VARCHAR(255) NOT NULL,
|
||||
size_bytes BIGINT NOT NULL,
|
||||
used_bytes BIGINT NOT NULL DEFAULT 0,
|
||||
filesystem_type VARCHAR(50),
|
||||
mount_point TEXT,
|
||||
is_active BOOLEAN NOT NULL DEFAULT true,
|
||||
warning_threshold_percent INTEGER NOT NULL DEFAULT 80,
|
||||
critical_threshold_percent INTEGER NOT NULL DEFAULT 90,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
created_by UUID REFERENCES users(id)
|
||||
);
|
||||
|
||||
-- Physical disks table
|
||||
CREATE TABLE IF NOT EXISTS physical_disks (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
device_path VARCHAR(255) NOT NULL UNIQUE,
|
||||
vendor VARCHAR(255),
|
||||
model VARCHAR(255),
|
||||
serial_number VARCHAR(255),
|
||||
size_bytes BIGINT NOT NULL,
|
||||
sector_size INTEGER,
|
||||
is_ssd BOOLEAN NOT NULL DEFAULT false,
|
||||
health_status VARCHAR(50) NOT NULL DEFAULT 'unknown',
|
||||
health_details JSONB,
|
||||
is_used BOOLEAN NOT NULL DEFAULT false,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Volume groups table
|
||||
CREATE TABLE IF NOT EXISTS volume_groups (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(255) NOT NULL UNIQUE,
|
||||
size_bytes BIGINT NOT NULL,
|
||||
free_bytes BIGINT NOT NULL,
|
||||
physical_volumes TEXT[],
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- SCST iSCSI targets table
|
||||
CREATE TABLE IF NOT EXISTS scst_targets (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
iqn VARCHAR(512) NOT NULL UNIQUE,
|
||||
target_type VARCHAR(50) NOT NULL, -- 'disk', 'vtl', 'physical_tape'
|
||||
name VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
is_active BOOLEAN NOT NULL DEFAULT true,
|
||||
single_initiator_only BOOLEAN NOT NULL DEFAULT false,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
created_by UUID REFERENCES users(id)
|
||||
);
|
||||
|
||||
-- SCST LUN mappings table
|
||||
CREATE TABLE IF NOT EXISTS scst_luns (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
target_id UUID NOT NULL REFERENCES scst_targets(id) ON DELETE CASCADE,
|
||||
lun_number INTEGER NOT NULL,
|
||||
device_name VARCHAR(255) NOT NULL,
|
||||
device_path VARCHAR(512) NOT NULL,
|
||||
handler_type VARCHAR(50) NOT NULL, -- 'vdisk', 'sg', 'tape'
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
UNIQUE(target_id, lun_number)
|
||||
);
|
||||
|
||||
-- SCST initiator groups table
|
||||
CREATE TABLE IF NOT EXISTS scst_initiator_groups (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
target_id UUID NOT NULL REFERENCES scst_targets(id) ON DELETE CASCADE,
|
||||
group_name VARCHAR(255) NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
UNIQUE(target_id, group_name)
|
||||
);
|
||||
|
||||
-- SCST initiators table
|
||||
CREATE TABLE IF NOT EXISTS scst_initiators (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
group_id UUID NOT NULL REFERENCES scst_initiator_groups(id) ON DELETE CASCADE,
|
||||
iqn VARCHAR(512) NOT NULL,
|
||||
is_active BOOLEAN NOT NULL DEFAULT true,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
UNIQUE(group_id, iqn)
|
||||
);
|
||||
|
||||
-- Physical tape libraries table
|
||||
CREATE TABLE IF NOT EXISTS physical_tape_libraries (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(255) NOT NULL UNIQUE,
|
||||
serial_number VARCHAR(255),
|
||||
vendor VARCHAR(255),
|
||||
model VARCHAR(255),
|
||||
changer_device_path VARCHAR(512),
|
||||
changer_stable_path VARCHAR(512),
|
||||
slot_count INTEGER,
|
||||
drive_count INTEGER,
|
||||
is_active BOOLEAN NOT NULL DEFAULT true,
|
||||
discovered_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
last_inventory_at TIMESTAMP,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Physical tape drives table
|
||||
CREATE TABLE IF NOT EXISTS physical_tape_drives (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
library_id UUID NOT NULL REFERENCES physical_tape_libraries(id) ON DELETE CASCADE,
|
||||
drive_number INTEGER NOT NULL,
|
||||
device_path VARCHAR(512),
|
||||
stable_path VARCHAR(512),
|
||||
vendor VARCHAR(255),
|
||||
model VARCHAR(255),
|
||||
serial_number VARCHAR(255),
|
||||
drive_type VARCHAR(50), -- 'LTO-8', 'LTO-9', etc.
|
||||
status VARCHAR(50) NOT NULL DEFAULT 'unknown', -- 'idle', 'loading', 'ready', 'error'
|
||||
current_tape_barcode VARCHAR(255),
|
||||
is_active BOOLEAN NOT NULL DEFAULT true,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
UNIQUE(library_id, drive_number)
|
||||
);
|
||||
|
||||
-- Physical tape slots table
|
||||
CREATE TABLE IF NOT EXISTS physical_tape_slots (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
library_id UUID NOT NULL REFERENCES physical_tape_libraries(id) ON DELETE CASCADE,
|
||||
slot_number INTEGER NOT NULL,
|
||||
barcode VARCHAR(255),
|
||||
tape_present BOOLEAN NOT NULL DEFAULT false,
|
||||
tape_type VARCHAR(50),
|
||||
last_updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
UNIQUE(library_id, slot_number)
|
||||
);
|
||||
|
||||
-- Virtual tape libraries table
|
||||
CREATE TABLE IF NOT EXISTS virtual_tape_libraries (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(255) NOT NULL UNIQUE,
|
||||
description TEXT,
|
||||
mhvtl_library_id INTEGER,
|
||||
backing_store_path TEXT NOT NULL,
|
||||
slot_count INTEGER NOT NULL DEFAULT 10,
|
||||
drive_count INTEGER NOT NULL DEFAULT 2,
|
||||
is_active BOOLEAN NOT NULL DEFAULT true,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
created_by UUID REFERENCES users(id)
|
||||
);
|
||||
|
||||
-- Virtual tape drives table
|
||||
CREATE TABLE IF NOT EXISTS virtual_tape_drives (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
library_id UUID NOT NULL REFERENCES virtual_tape_libraries(id) ON DELETE CASCADE,
|
||||
drive_number INTEGER NOT NULL,
|
||||
device_path VARCHAR(512),
|
||||
stable_path VARCHAR(512),
|
||||
status VARCHAR(50) NOT NULL DEFAULT 'idle',
|
||||
current_tape_id UUID,
|
||||
is_active BOOLEAN NOT NULL DEFAULT true,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
UNIQUE(library_id, drive_number)
|
||||
);
|
||||
|
||||
-- Virtual tapes table
|
||||
CREATE TABLE IF NOT EXISTS virtual_tapes (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
library_id UUID NOT NULL REFERENCES virtual_tape_libraries(id) ON DELETE CASCADE,
|
||||
barcode VARCHAR(255) NOT NULL,
|
||||
slot_number INTEGER,
|
||||
image_file_path TEXT NOT NULL,
|
||||
size_bytes BIGINT NOT NULL DEFAULT 0,
|
||||
used_bytes BIGINT NOT NULL DEFAULT 0,
|
||||
tape_type VARCHAR(50) NOT NULL DEFAULT 'LTO-8',
|
||||
status VARCHAR(50) NOT NULL DEFAULT 'idle', -- 'idle', 'in_drive', 'exported'
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
UNIQUE(library_id, barcode)
|
||||
);
|
||||
|
||||
-- Indexes for performance
|
||||
CREATE INDEX IF NOT EXISTS idx_disk_repositories_name ON disk_repositories(name);
|
||||
CREATE INDEX IF NOT EXISTS idx_disk_repositories_active ON disk_repositories(is_active);
|
||||
CREATE INDEX IF NOT EXISTS idx_physical_disks_device_path ON physical_disks(device_path);
|
||||
CREATE INDEX IF NOT EXISTS idx_scst_targets_iqn ON scst_targets(iqn);
|
||||
CREATE INDEX IF NOT EXISTS idx_scst_targets_type ON scst_targets(target_type);
|
||||
CREATE INDEX IF NOT EXISTS idx_scst_luns_target_id ON scst_luns(target_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_scst_initiators_group_id ON scst_initiators(group_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_physical_tape_libraries_name ON physical_tape_libraries(name);
|
||||
CREATE INDEX IF NOT EXISTS idx_physical_tape_drives_library_id ON physical_tape_drives(library_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_physical_tape_slots_library_id ON physical_tape_slots(library_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_virtual_tape_libraries_name ON virtual_tape_libraries(name);
|
||||
CREATE INDEX IF NOT EXISTS idx_virtual_tape_drives_library_id ON virtual_tape_drives(library_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_virtual_tapes_library_id ON virtual_tapes(library_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_virtual_tapes_barcode ON virtual_tapes(barcode);
|
||||
|
||||
22
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/003_object_storage_config.sql
vendored
Normal file
22
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/003_object_storage_config.sql
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
-- Migration: Object Storage Configuration
|
||||
-- Description: Creates table for storing MinIO object storage configuration
|
||||
-- Date: 2026-01-09
|
||||
|
||||
CREATE TABLE IF NOT EXISTS object_storage_config (
|
||||
id SERIAL PRIMARY KEY,
|
||||
dataset_path VARCHAR(255) NOT NULL UNIQUE,
|
||||
mount_point VARCHAR(512) NOT NULL,
|
||||
pool_name VARCHAR(255) NOT NULL,
|
||||
dataset_name VARCHAR(255) NOT NULL,
|
||||
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_object_storage_config_pool_name ON object_storage_config(pool_name);
|
||||
CREATE INDEX IF NOT EXISTS idx_object_storage_config_updated_at ON object_storage_config(updated_at);
|
||||
|
||||
COMMENT ON TABLE object_storage_config IS 'Stores MinIO object storage configuration, linking to ZFS datasets';
|
||||
COMMENT ON COLUMN object_storage_config.dataset_path IS 'Full ZFS dataset path (e.g., pool/dataset)';
|
||||
COMMENT ON COLUMN object_storage_config.mount_point IS 'Mount point path for the dataset';
|
||||
COMMENT ON COLUMN object_storage_config.pool_name IS 'ZFS pool name';
|
||||
COMMENT ON COLUMN object_storage_config.dataset_name IS 'ZFS dataset name';
|
||||
174
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/003_performance_indexes.sql
vendored
Normal file
174
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/003_performance_indexes.sql
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
-- AtlasOS - Calypso
|
||||
-- Performance Optimization: Database Indexes
|
||||
-- Version: 3.0
|
||||
-- Description: Adds indexes for frequently queried columns to improve query performance
|
||||
|
||||
-- ============================================================================
|
||||
-- Authentication & Authorization Indexes
|
||||
-- ============================================================================
|
||||
|
||||
-- Users table indexes
|
||||
-- Username is frequently queried during login
|
||||
CREATE INDEX IF NOT EXISTS idx_users_username ON users(username);
|
||||
-- Email lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
|
||||
-- Active user lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_users_is_active ON users(is_active) WHERE is_active = true;
|
||||
|
||||
-- Sessions table indexes
|
||||
-- Token hash lookups are very frequent (every authenticated request)
|
||||
CREATE INDEX IF NOT EXISTS idx_sessions_token_hash ON sessions(token_hash);
|
||||
-- User session lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_sessions_user_id ON sessions(user_id);
|
||||
-- Expired session cleanup (index on expires_at for efficient cleanup queries)
|
||||
CREATE INDEX IF NOT EXISTS idx_sessions_expires_at ON sessions(expires_at);
|
||||
|
||||
-- User roles junction table
|
||||
-- Lookup roles for a user (frequent during permission checks)
|
||||
CREATE INDEX IF NOT EXISTS idx_user_roles_user_id ON user_roles(user_id);
|
||||
-- Lookup users with a role
|
||||
CREATE INDEX IF NOT EXISTS idx_user_roles_role_id ON user_roles(role_id);
|
||||
|
||||
-- Role permissions junction table
|
||||
-- Lookup permissions for a role
|
||||
CREATE INDEX IF NOT EXISTS idx_role_permissions_role_id ON role_permissions(role_id);
|
||||
-- Lookup roles with a permission
|
||||
CREATE INDEX IF NOT EXISTS idx_role_permissions_permission_id ON role_permissions(permission_id);
|
||||
|
||||
-- ============================================================================
|
||||
-- Audit & Monitoring Indexes
|
||||
-- ============================================================================
|
||||
|
||||
-- Audit log indexes
|
||||
-- Time-based queries (most common audit log access pattern)
|
||||
CREATE INDEX IF NOT EXISTS idx_audit_log_created_at ON audit_log(created_at DESC);
|
||||
-- User activity queries
|
||||
CREATE INDEX IF NOT EXISTS idx_audit_log_user_id ON audit_log(user_id);
|
||||
-- Resource-based queries
|
||||
CREATE INDEX IF NOT EXISTS idx_audit_log_resource ON audit_log(resource_type, resource_id);
|
||||
|
||||
-- Alerts table indexes
|
||||
-- Time-based ordering (default ordering in ListAlerts)
|
||||
CREATE INDEX IF NOT EXISTS idx_alerts_created_at ON alerts(created_at DESC);
|
||||
-- Severity filtering
|
||||
CREATE INDEX IF NOT EXISTS idx_alerts_severity ON alerts(severity);
|
||||
-- Source filtering
|
||||
CREATE INDEX IF NOT EXISTS idx_alerts_source ON alerts(source);
|
||||
-- Acknowledgment status
|
||||
CREATE INDEX IF NOT EXISTS idx_alerts_acknowledged ON alerts(is_acknowledged) WHERE is_acknowledged = false;
|
||||
-- Resource-based queries
|
||||
CREATE INDEX IF NOT EXISTS idx_alerts_resource ON alerts(resource_type, resource_id);
|
||||
-- Composite index for common filter combinations
|
||||
CREATE INDEX IF NOT EXISTS idx_alerts_severity_acknowledged ON alerts(severity, is_acknowledged, created_at DESC);
|
||||
|
||||
-- ============================================================================
|
||||
-- Task Management Indexes
|
||||
-- ============================================================================
|
||||
|
||||
-- Tasks table indexes
|
||||
-- Status filtering (very common in task queries)
|
||||
CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
|
||||
-- Created by user
|
||||
CREATE INDEX IF NOT EXISTS idx_tasks_created_by ON tasks(created_by);
|
||||
-- Time-based queries
|
||||
CREATE INDEX IF NOT EXISTS idx_tasks_created_at ON tasks(created_at DESC);
|
||||
-- Status + time composite (common query pattern)
|
||||
CREATE INDEX IF NOT EXISTS idx_tasks_status_created_at ON tasks(status, created_at DESC);
|
||||
-- Failed tasks lookup (for alerting)
|
||||
CREATE INDEX IF NOT EXISTS idx_tasks_failed_recent ON tasks(status, created_at DESC) WHERE status = 'failed';
|
||||
|
||||
-- ============================================================================
|
||||
-- Storage Indexes
|
||||
-- ============================================================================
|
||||
|
||||
-- Disk repositories indexes
|
||||
-- Active repository lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_disk_repositories_is_active ON disk_repositories(is_active) WHERE is_active = true;
|
||||
-- Name lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_disk_repositories_name ON disk_repositories(name);
|
||||
-- Volume group lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_disk_repositories_vg ON disk_repositories(volume_group);
|
||||
|
||||
-- Physical disks indexes
|
||||
-- Device path lookups (for sync operations)
|
||||
CREATE INDEX IF NOT EXISTS idx_physical_disks_device_path ON physical_disks(device_path);
|
||||
|
||||
-- ============================================================================
|
||||
-- SCST Indexes
|
||||
-- ============================================================================
|
||||
|
||||
-- SCST targets indexes
|
||||
-- IQN lookups (frequent during target operations)
|
||||
CREATE INDEX IF NOT EXISTS idx_scst_targets_iqn ON scst_targets(iqn);
|
||||
-- Active target lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_scst_targets_is_active ON scst_targets(is_active) WHERE is_active = true;
|
||||
|
||||
-- SCST LUNs indexes
|
||||
-- Target + LUN lookups (very frequent)
|
||||
CREATE INDEX IF NOT EXISTS idx_scst_luns_target_lun ON scst_luns(target_id, lun_number);
|
||||
-- Device path lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_scst_luns_device_path ON scst_luns(device_path);
|
||||
|
||||
-- SCST initiator groups indexes
|
||||
-- Target + group name lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_scst_initiator_groups_target ON scst_initiator_groups(target_id);
|
||||
-- Group name lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_scst_initiator_groups_name ON scst_initiator_groups(group_name);
|
||||
|
||||
-- SCST initiators indexes
|
||||
-- Group + IQN lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_scst_initiators_group_iqn ON scst_initiators(group_id, iqn);
|
||||
-- Active initiator lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_scst_initiators_is_active ON scst_initiators(is_active) WHERE is_active = true;
|
||||
|
||||
-- ============================================================================
|
||||
-- Tape Library Indexes
|
||||
-- ============================================================================
|
||||
|
||||
-- Physical tape libraries indexes
|
||||
-- Serial number lookups (for discovery)
|
||||
CREATE INDEX IF NOT EXISTS idx_physical_tape_libraries_serial ON physical_tape_libraries(serial_number);
|
||||
-- Active library lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_physical_tape_libraries_is_active ON physical_tape_libraries(is_active) WHERE is_active = true;
|
||||
|
||||
-- Physical tape drives indexes
|
||||
-- Library + drive number lookups (very frequent)
|
||||
CREATE INDEX IF NOT EXISTS idx_physical_tape_drives_library_drive ON physical_tape_drives(library_id, drive_number);
|
||||
-- Status filtering
|
||||
CREATE INDEX IF NOT EXISTS idx_physical_tape_drives_status ON physical_tape_drives(status);
|
||||
|
||||
-- Physical tape slots indexes
|
||||
-- Library + slot number lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_physical_tape_slots_library_slot ON physical_tape_slots(library_id, slot_number);
|
||||
-- Barcode lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_physical_tape_slots_barcode ON physical_tape_slots(barcode) WHERE barcode IS NOT NULL;
|
||||
|
||||
-- Virtual tape libraries indexes
|
||||
-- MHVTL library ID lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_virtual_tape_libraries_mhvtl_id ON virtual_tape_libraries(mhvtl_library_id);
|
||||
-- Active library lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_virtual_tape_libraries_is_active ON virtual_tape_libraries(is_active) WHERE is_active = true;
|
||||
|
||||
-- Virtual tape drives indexes
|
||||
-- Library + drive number lookups (very frequent)
|
||||
CREATE INDEX IF NOT EXISTS idx_virtual_tape_drives_library_drive ON virtual_tape_drives(library_id, drive_number);
|
||||
-- Status filtering
|
||||
CREATE INDEX IF NOT EXISTS idx_virtual_tape_drives_status ON virtual_tape_drives(status);
|
||||
-- Current tape lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_virtual_tape_drives_current_tape ON virtual_tape_drives(current_tape_id) WHERE current_tape_id IS NOT NULL;
|
||||
|
||||
-- Virtual tapes indexes
|
||||
-- Library + slot number lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_virtual_tapes_library_slot ON virtual_tapes(library_id, slot_number);
|
||||
-- Barcode lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_virtual_tapes_barcode ON virtual_tapes(barcode) WHERE barcode IS NOT NULL;
|
||||
-- Status filtering
|
||||
CREATE INDEX IF NOT EXISTS idx_virtual_tapes_status ON virtual_tapes(status);
|
||||
|
||||
-- ============================================================================
|
||||
-- Statistics Update
|
||||
-- ============================================================================
|
||||
|
||||
-- Update table statistics for query planner
|
||||
ANALYZE;
|
||||
|
||||
31
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/004_add_zfs_pools_table.sql
vendored
Normal file
31
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/004_add_zfs_pools_table.sql
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
-- AtlasOS - Calypso
|
||||
-- Add ZFS Pools Table
|
||||
-- Version: 4.0
|
||||
-- Note: This migration adds the zfs_pools table that was added to migration 002
|
||||
-- but may not have been applied if migration 002 was run before the table was added
|
||||
|
||||
-- ZFS pools table
|
||||
CREATE TABLE IF NOT EXISTS zfs_pools (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(255) NOT NULL UNIQUE,
|
||||
description TEXT,
|
||||
raid_level VARCHAR(50) NOT NULL, -- stripe, mirror, raidz, raidz2, raidz3
|
||||
disks TEXT[] NOT NULL, -- array of device paths
|
||||
size_bytes BIGINT NOT NULL,
|
||||
used_bytes BIGINT NOT NULL DEFAULT 0,
|
||||
compression VARCHAR(50) NOT NULL DEFAULT 'lz4', -- off, lz4, zstd, gzip
|
||||
deduplication BOOLEAN NOT NULL DEFAULT false,
|
||||
auto_expand BOOLEAN NOT NULL DEFAULT false,
|
||||
scrub_interval INTEGER NOT NULL DEFAULT 30, -- days
|
||||
is_active BOOLEAN NOT NULL DEFAULT true,
|
||||
health_status VARCHAR(50) NOT NULL DEFAULT 'online', -- online, degraded, faulted, offline
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
created_by UUID REFERENCES users(id)
|
||||
);
|
||||
|
||||
-- Create index on name for faster lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_zfs_pools_name ON zfs_pools(name);
|
||||
CREATE INDEX IF NOT EXISTS idx_zfs_pools_created_by ON zfs_pools(created_by);
|
||||
CREATE INDEX IF NOT EXISTS idx_zfs_pools_health_status ON zfs_pools(health_status);
|
||||
|
||||
35
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/005_add_zfs_datasets_table.sql
vendored
Normal file
35
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/005_add_zfs_datasets_table.sql
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
-- AtlasOS - Calypso
|
||||
-- Add ZFS Datasets Table
|
||||
-- Version: 5.0
|
||||
-- Description: Stores ZFS dataset metadata in database for faster queries and consistency
|
||||
|
||||
-- ZFS datasets table
|
||||
CREATE TABLE IF NOT EXISTS zfs_datasets (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(512) NOT NULL UNIQUE, -- Full dataset name (e.g., pool/dataset)
|
||||
pool_id UUID NOT NULL REFERENCES zfs_pools(id) ON DELETE CASCADE,
|
||||
pool_name VARCHAR(255) NOT NULL, -- Denormalized for faster queries
|
||||
type VARCHAR(50) NOT NULL, -- filesystem, volume, snapshot
|
||||
mount_point TEXT, -- Mount point path (null for volumes)
|
||||
used_bytes BIGINT NOT NULL DEFAULT 0,
|
||||
available_bytes BIGINT NOT NULL DEFAULT 0,
|
||||
referenced_bytes BIGINT NOT NULL DEFAULT 0,
|
||||
compression VARCHAR(50) NOT NULL DEFAULT 'lz4', -- off, lz4, zstd, gzip
|
||||
deduplication VARCHAR(50) NOT NULL DEFAULT 'off', -- off, on, verify
|
||||
quota BIGINT DEFAULT -1, -- -1 for unlimited, bytes otherwise
|
||||
reservation BIGINT NOT NULL DEFAULT 0, -- Reserved space in bytes
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
created_by UUID REFERENCES users(id)
|
||||
);
|
||||
|
||||
-- Create indexes for faster lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_zfs_datasets_pool_id ON zfs_datasets(pool_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_zfs_datasets_pool_name ON zfs_datasets(pool_name);
|
||||
CREATE INDEX IF NOT EXISTS idx_zfs_datasets_name ON zfs_datasets(name);
|
||||
CREATE INDEX IF NOT EXISTS idx_zfs_datasets_type ON zfs_datasets(type);
|
||||
CREATE INDEX IF NOT EXISTS idx_zfs_datasets_created_by ON zfs_datasets(created_by);
|
||||
|
||||
-- Composite index for common queries (list datasets by pool)
|
||||
CREATE INDEX IF NOT EXISTS idx_zfs_datasets_pool_type ON zfs_datasets(pool_id, type);
|
||||
|
||||
50
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/006_add_zfs_shares_and_iscsi.sql
vendored
Normal file
50
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/006_add_zfs_shares_and_iscsi.sql
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
-- AtlasOS - Calypso
|
||||
-- Add ZFS Shares and iSCSI Export Tables
|
||||
-- Version: 6.0
|
||||
-- Description: Separate tables for filesystem shares (NFS/SMB) and volume iSCSI exports
|
||||
|
||||
-- ZFS Filesystem Shares Table (for NFS/SMB)
|
||||
CREATE TABLE IF NOT EXISTS zfs_shares (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
dataset_id UUID NOT NULL REFERENCES zfs_datasets(id) ON DELETE CASCADE,
|
||||
share_type VARCHAR(50) NOT NULL, -- 'nfs', 'smb', 'both'
|
||||
nfs_enabled BOOLEAN NOT NULL DEFAULT false,
|
||||
nfs_options TEXT, -- e.g., "rw,sync,no_subtree_check"
|
||||
nfs_clients TEXT[], -- Allowed client IPs/networks
|
||||
smb_enabled BOOLEAN NOT NULL DEFAULT false,
|
||||
smb_share_name VARCHAR(255), -- SMB share name
|
||||
smb_path TEXT, -- SMB share path (usually same as mount_point)
|
||||
smb_comment TEXT,
|
||||
smb_guest_ok BOOLEAN NOT NULL DEFAULT false,
|
||||
smb_read_only BOOLEAN NOT NULL DEFAULT false,
|
||||
smb_browseable BOOLEAN NOT NULL DEFAULT true,
|
||||
is_active BOOLEAN NOT NULL DEFAULT true,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
created_by UUID REFERENCES users(id),
|
||||
UNIQUE(dataset_id) -- One share config per dataset
|
||||
);
|
||||
|
||||
-- ZFS Volume iSCSI Exports Table
|
||||
CREATE TABLE IF NOT EXISTS zfs_iscsi_exports (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
dataset_id UUID NOT NULL REFERENCES zfs_datasets(id) ON DELETE CASCADE,
|
||||
target_id UUID REFERENCES scst_targets(id) ON DELETE SET NULL, -- Link to SCST target
|
||||
lun_number INTEGER, -- LUN number in the target
|
||||
device_path TEXT, -- /dev/zvol/pool/volume path
|
||||
is_active BOOLEAN NOT NULL DEFAULT true,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
created_by UUID REFERENCES users(id),
|
||||
UNIQUE(dataset_id) -- One iSCSI export per volume
|
||||
);
|
||||
|
||||
-- Create indexes
|
||||
CREATE INDEX IF NOT EXISTS idx_zfs_shares_dataset_id ON zfs_shares(dataset_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_zfs_shares_type ON zfs_shares(share_type);
|
||||
CREATE INDEX IF NOT EXISTS idx_zfs_shares_active ON zfs_shares(is_active);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_zfs_iscsi_exports_dataset_id ON zfs_iscsi_exports(dataset_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_zfs_iscsi_exports_target_id ON zfs_iscsi_exports(target_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_zfs_iscsi_exports_active ON zfs_iscsi_exports(is_active);
|
||||
|
||||
3
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/007_add_vendor_to_vtl_libraries.sql
vendored
Normal file
3
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/007_add_vendor_to_vtl_libraries.sql
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
-- Add vendor column to virtual_tape_libraries table
|
||||
ALTER TABLE virtual_tape_libraries ADD COLUMN IF NOT EXISTS vendor VARCHAR(255);
|
||||
|
||||
45
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/008_add_user_groups.sql
vendored
Normal file
45
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/008_add_user_groups.sql
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
-- Add user groups feature
|
||||
-- Groups table
|
||||
CREATE TABLE IF NOT EXISTS groups (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(255) NOT NULL UNIQUE,
|
||||
description TEXT,
|
||||
is_system BOOLEAN NOT NULL DEFAULT false,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- User groups junction table
|
||||
CREATE TABLE IF NOT EXISTS user_groups (
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
group_id UUID NOT NULL REFERENCES groups(id) ON DELETE CASCADE,
|
||||
assigned_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
assigned_by UUID REFERENCES users(id),
|
||||
PRIMARY KEY (user_id, group_id)
|
||||
);
|
||||
|
||||
-- Group roles junction table (groups can have roles)
|
||||
CREATE TABLE IF NOT EXISTS group_roles (
|
||||
group_id UUID NOT NULL REFERENCES groups(id) ON DELETE CASCADE,
|
||||
role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
|
||||
granted_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
PRIMARY KEY (group_id, role_id)
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE INDEX IF NOT EXISTS idx_groups_name ON groups(name);
|
||||
CREATE INDEX IF NOT EXISTS idx_user_groups_user_id ON user_groups(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_user_groups_group_id ON user_groups(group_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_group_roles_group_id ON group_roles(group_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_group_roles_role_id ON group_roles(role_id);
|
||||
|
||||
-- Insert default system groups
|
||||
INSERT INTO groups (name, description, is_system) VALUES
|
||||
('wheel', 'System administrators group', true),
|
||||
('operators', 'System operators group', true),
|
||||
('backup', 'Backup operators group', true),
|
||||
('auditors', 'Auditors group', true),
|
||||
('storage_admins', 'Storage administrators group', true),
|
||||
('services', 'Service accounts group', true)
|
||||
ON CONFLICT (name) DO NOTHING;
|
||||
|
||||
34
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/009_backup_jobs_schema.sql
vendored
Normal file
34
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/009_backup_jobs_schema.sql
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
-- AtlasOS - Calypso
|
||||
-- Backup Jobs Schema
|
||||
-- Version: 9.0
|
||||
|
||||
-- Backup jobs table
|
||||
CREATE TABLE IF NOT EXISTS backup_jobs (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
job_id INTEGER NOT NULL UNIQUE, -- Bareos job ID
|
||||
job_name VARCHAR(255) NOT NULL,
|
||||
client_name VARCHAR(255) NOT NULL,
|
||||
job_type VARCHAR(50) NOT NULL, -- 'Backup', 'Restore', 'Verify', 'Copy', 'Migrate'
|
||||
job_level VARCHAR(50) NOT NULL, -- 'Full', 'Incremental', 'Differential', 'Since'
|
||||
status VARCHAR(50) NOT NULL, -- 'Running', 'Completed', 'Failed', 'Canceled', 'Waiting'
|
||||
bytes_written BIGINT NOT NULL DEFAULT 0,
|
||||
files_written INTEGER NOT NULL DEFAULT 0,
|
||||
duration_seconds INTEGER,
|
||||
started_at TIMESTAMP,
|
||||
ended_at TIMESTAMP,
|
||||
error_message TEXT,
|
||||
storage_name VARCHAR(255),
|
||||
pool_name VARCHAR(255),
|
||||
volume_name VARCHAR(255),
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Indexes for performance
|
||||
CREATE INDEX IF NOT EXISTS idx_backup_jobs_job_id ON backup_jobs(job_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_backup_jobs_job_name ON backup_jobs(job_name);
|
||||
CREATE INDEX IF NOT EXISTS idx_backup_jobs_client_name ON backup_jobs(client_name);
|
||||
CREATE INDEX IF NOT EXISTS idx_backup_jobs_status ON backup_jobs(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_backup_jobs_started_at ON backup_jobs(started_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_backup_jobs_job_type ON backup_jobs(job_type);
|
||||
|
||||
39
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/010_add_backup_permissions.sql
vendored
Normal file
39
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/010_add_backup_permissions.sql
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
-- AtlasOS - Calypso
|
||||
-- Add Backup Permissions
|
||||
-- Version: 10.0
|
||||
|
||||
-- Insert backup permissions
|
||||
INSERT INTO permissions (name, resource, action, description) VALUES
|
||||
('backup:read', 'backup', 'read', 'View backup jobs and history'),
|
||||
('backup:write', 'backup', 'write', 'Create and manage backup jobs'),
|
||||
('backup:manage', 'backup', 'manage', 'Full backup management')
|
||||
ON CONFLICT (name) DO NOTHING;
|
||||
|
||||
-- Assign backup permissions to roles
|
||||
|
||||
-- Admin gets all backup permissions (explicitly assign since admin query in 001 only runs once)
|
||||
INSERT INTO role_permissions (role_id, permission_id)
|
||||
SELECT r.id, p.id
|
||||
FROM roles r, permissions p
|
||||
WHERE r.name = 'admin'
|
||||
AND p.resource = 'backup'
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
-- Operator gets read and write permissions for backup
|
||||
INSERT INTO role_permissions (role_id, permission_id)
|
||||
SELECT r.id, p.id
|
||||
FROM roles r, permissions p
|
||||
WHERE r.name = 'operator'
|
||||
AND p.resource = 'backup'
|
||||
AND p.action IN ('read', 'write')
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
-- ReadOnly gets only read permission for backup
|
||||
INSERT INTO role_permissions (role_id, permission_id)
|
||||
SELECT r.id, p.id
|
||||
FROM roles r, permissions p
|
||||
WHERE r.name = 'readonly'
|
||||
AND p.resource = 'backup'
|
||||
AND p.action = 'read'
|
||||
ON CONFLICT DO NOTHING;
|
||||
|
||||
209
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/011_sync_bacula_jobs_function.sql
vendored
Normal file
209
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/011_sync_bacula_jobs_function.sql
vendored
Normal file
@@ -0,0 +1,209 @@
|
||||
-- AtlasOS - Calypso
|
||||
-- PostgreSQL Function to Sync Jobs from Bacula to Calypso
|
||||
-- Version: 11.0
|
||||
--
|
||||
-- This function syncs jobs from Bacula database (Job table) to Calypso database (backup_jobs table)
|
||||
-- Uses dblink extension to query Bacula database from Calypso database
|
||||
--
|
||||
-- Prerequisites:
|
||||
-- 1. dblink extension must be installed: CREATE EXTENSION IF NOT EXISTS dblink;
|
||||
-- 2. User must have access to both databases
|
||||
-- 3. Connection parameters must be configured in the function
|
||||
|
||||
-- Create function to sync jobs from Bacula to Calypso
|
||||
CREATE OR REPLACE FUNCTION sync_bacula_jobs(
|
||||
bacula_db_name TEXT DEFAULT 'bacula',
|
||||
bacula_host TEXT DEFAULT 'localhost',
|
||||
bacula_port INTEGER DEFAULT 5432,
|
||||
bacula_user TEXT DEFAULT 'calypso',
|
||||
bacula_password TEXT DEFAULT ''
|
||||
)
|
||||
RETURNS TABLE(
|
||||
jobs_synced INTEGER,
|
||||
jobs_inserted INTEGER,
|
||||
jobs_updated INTEGER,
|
||||
errors INTEGER
|
||||
) AS $$
|
||||
DECLARE
|
||||
conn_str TEXT;
|
||||
jobs_count INTEGER := 0;
|
||||
inserted_count INTEGER := 0;
|
||||
updated_count INTEGER := 0;
|
||||
error_count INTEGER := 0;
|
||||
job_record RECORD;
|
||||
BEGIN
|
||||
-- Build dblink connection string
|
||||
conn_str := format(
|
||||
'dbname=%s host=%s port=%s user=%s password=%s',
|
||||
bacula_db_name,
|
||||
bacula_host,
|
||||
bacula_port,
|
||||
bacula_user,
|
||||
bacula_password
|
||||
);
|
||||
|
||||
-- Query jobs from Bacula database using dblink
|
||||
FOR job_record IN
|
||||
SELECT * FROM dblink(
|
||||
conn_str,
|
||||
$QUERY$
|
||||
SELECT
|
||||
j.JobId,
|
||||
j.Name as job_name,
|
||||
COALESCE(c.Name, 'unknown') as client_name,
|
||||
CASE
|
||||
WHEN j.Type = 'B' THEN 'Backup'
|
||||
WHEN j.Type = 'R' THEN 'Restore'
|
||||
WHEN j.Type = 'V' THEN 'Verify'
|
||||
WHEN j.Type = 'C' THEN 'Copy'
|
||||
WHEN j.Type = 'M' THEN 'Migrate'
|
||||
ELSE 'Backup'
|
||||
END as job_type,
|
||||
CASE
|
||||
WHEN j.Level = 'F' THEN 'Full'
|
||||
WHEN j.Level = 'I' THEN 'Incremental'
|
||||
WHEN j.Level = 'D' THEN 'Differential'
|
||||
WHEN j.Level = 'S' THEN 'Since'
|
||||
ELSE 'Full'
|
||||
END as job_level,
|
||||
CASE
|
||||
WHEN j.JobStatus = 'T' THEN 'Running'
|
||||
WHEN j.JobStatus = 'C' THEN 'Completed'
|
||||
WHEN j.JobStatus = 'f' OR j.JobStatus = 'F' THEN 'Failed'
|
||||
WHEN j.JobStatus = 'A' THEN 'Canceled'
|
||||
WHEN j.JobStatus = 'W' THEN 'Waiting'
|
||||
ELSE 'Waiting'
|
||||
END as status,
|
||||
COALESCE(j.JobBytes, 0) as bytes_written,
|
||||
COALESCE(j.JobFiles, 0) as files_written,
|
||||
j.StartTime as started_at,
|
||||
j.EndTime as ended_at,
|
||||
CASE
|
||||
WHEN j.EndTime IS NOT NULL AND j.StartTime IS NOT NULL
|
||||
THEN EXTRACT(EPOCH FROM (j.EndTime - j.StartTime))::INTEGER
|
||||
ELSE NULL
|
||||
END as duration_seconds
|
||||
FROM Job j
|
||||
LEFT JOIN Client c ON j.ClientId = c.ClientId
|
||||
ORDER BY j.StartTime DESC
|
||||
LIMIT 1000
|
||||
$QUERY$
|
||||
) AS t(
|
||||
job_id INTEGER,
|
||||
job_name TEXT,
|
||||
client_name TEXT,
|
||||
job_type TEXT,
|
||||
job_level TEXT,
|
||||
status TEXT,
|
||||
bytes_written BIGINT,
|
||||
files_written INTEGER,
|
||||
started_at TIMESTAMP,
|
||||
ended_at TIMESTAMP,
|
||||
duration_seconds INTEGER
|
||||
)
|
||||
LOOP
|
||||
BEGIN
|
||||
-- Check if job already exists (before insert/update)
|
||||
IF EXISTS (SELECT 1 FROM backup_jobs WHERE job_id = job_record.job_id) THEN
|
||||
updated_count := updated_count + 1;
|
||||
ELSE
|
||||
inserted_count := inserted_count + 1;
|
||||
END IF;
|
||||
|
||||
-- Upsert job to backup_jobs table
|
||||
INSERT INTO backup_jobs (
|
||||
job_id, job_name, client_name, job_type, job_level, status,
|
||||
bytes_written, files_written, started_at, ended_at, duration_seconds,
|
||||
updated_at
|
||||
) VALUES (
|
||||
job_record.job_id,
|
||||
job_record.job_name,
|
||||
job_record.client_name,
|
||||
job_record.job_type,
|
||||
job_record.job_level,
|
||||
job_record.status,
|
||||
job_record.bytes_written,
|
||||
job_record.files_written,
|
||||
job_record.started_at,
|
||||
job_record.ended_at,
|
||||
job_record.duration_seconds,
|
||||
NOW()
|
||||
)
|
||||
ON CONFLICT (job_id) DO UPDATE SET
|
||||
job_name = EXCLUDED.job_name,
|
||||
client_name = EXCLUDED.client_name,
|
||||
job_type = EXCLUDED.job_type,
|
||||
job_level = EXCLUDED.job_level,
|
||||
status = EXCLUDED.status,
|
||||
bytes_written = EXCLUDED.bytes_written,
|
||||
files_written = EXCLUDED.files_written,
|
||||
started_at = EXCLUDED.started_at,
|
||||
ended_at = EXCLUDED.ended_at,
|
||||
duration_seconds = EXCLUDED.duration_seconds,
|
||||
updated_at = NOW();
|
||||
|
||||
jobs_count := jobs_count + 1;
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
error_count := error_count + 1;
|
||||
-- Log error but continue with next job
|
||||
RAISE WARNING 'Error syncing job %: %', job_record.job_id, SQLERRM;
|
||||
END;
|
||||
END LOOP;
|
||||
|
||||
-- Return summary
|
||||
RETURN QUERY SELECT jobs_count, inserted_count, updated_count, error_count;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- Create a simpler version that uses current database connection settings
|
||||
-- This version assumes Bacula is on same host/port with same user
|
||||
CREATE OR REPLACE FUNCTION sync_bacula_jobs_simple()
|
||||
RETURNS TABLE(
|
||||
jobs_synced INTEGER,
|
||||
jobs_inserted INTEGER,
|
||||
jobs_updated INTEGER,
|
||||
errors INTEGER
|
||||
) AS $$
|
||||
DECLARE
|
||||
current_user_name TEXT;
|
||||
current_host TEXT;
|
||||
current_port INTEGER;
|
||||
current_db TEXT;
|
||||
BEGIN
|
||||
-- Get current connection info
|
||||
SELECT
|
||||
current_user,
|
||||
COALESCE(inet_server_addr()::TEXT, 'localhost'),
|
||||
COALESCE(inet_server_port(), 5432),
|
||||
current_database()
|
||||
INTO
|
||||
current_user_name,
|
||||
current_host,
|
||||
current_port,
|
||||
current_db;
|
||||
|
||||
-- Call main function with current connection settings
|
||||
-- Note: password needs to be passed or configured in .pgpass
|
||||
RETURN QUERY
|
||||
SELECT * FROM sync_bacula_jobs(
|
||||
'bacula', -- Try 'bacula' first
|
||||
current_host,
|
||||
current_port,
|
||||
current_user_name,
|
||||
'' -- Empty password - will use .pgpass or peer authentication
|
||||
);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- Grant execute permission to calypso user
|
||||
GRANT EXECUTE ON FUNCTION sync_bacula_jobs(TEXT, TEXT, INTEGER, TEXT, TEXT) TO calypso;
|
||||
GRANT EXECUTE ON FUNCTION sync_bacula_jobs_simple() TO calypso;
|
||||
|
||||
-- Create index if not exists (should already exist from migration 009)
|
||||
CREATE INDEX IF NOT EXISTS idx_backup_jobs_job_id ON backup_jobs(job_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_backup_jobs_updated_at ON backup_jobs(updated_at);
|
||||
|
||||
COMMENT ON FUNCTION sync_bacula_jobs IS 'Syncs jobs from Bacula database to Calypso backup_jobs table using dblink';
|
||||
COMMENT ON FUNCTION sync_bacula_jobs_simple IS 'Simplified version that uses current connection settings (requires .pgpass for password)';
|
||||
|
||||
209
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/011_sync_bacula_jobs_function.sql.bak
vendored
Normal file
209
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/011_sync_bacula_jobs_function.sql.bak
vendored
Normal file
@@ -0,0 +1,209 @@
|
||||
-- AtlasOS - Calypso
|
||||
-- PostgreSQL Function to Sync Jobs from Bacula to Calypso
|
||||
-- Version: 11.0
|
||||
--
|
||||
-- This function syncs jobs from Bacula database (Job table) to Calypso database (backup_jobs table)
|
||||
-- Uses dblink extension to query Bacula database from Calypso database
|
||||
--
|
||||
-- Prerequisites:
|
||||
-- 1. dblink extension must be installed: CREATE EXTENSION IF NOT EXISTS dblink;
|
||||
-- 2. User must have access to both databases
|
||||
-- 3. Connection parameters must be configured in the function
|
||||
|
||||
-- Create function to sync jobs from Bacula to Calypso
|
||||
CREATE OR REPLACE FUNCTION sync_bacula_jobs(
|
||||
bacula_db_name TEXT DEFAULT 'bacula',
|
||||
bacula_host TEXT DEFAULT 'localhost',
|
||||
bacula_port INTEGER DEFAULT 5432,
|
||||
bacula_user TEXT DEFAULT 'calypso',
|
||||
bacula_password TEXT DEFAULT ''
|
||||
)
|
||||
RETURNS TABLE(
|
||||
jobs_synced INTEGER,
|
||||
jobs_inserted INTEGER,
|
||||
jobs_updated INTEGER,
|
||||
errors INTEGER
|
||||
) AS $$
|
||||
DECLARE
|
||||
conn_str TEXT;
|
||||
jobs_count INTEGER := 0;
|
||||
inserted_count INTEGER := 0;
|
||||
updated_count INTEGER := 0;
|
||||
error_count INTEGER := 0;
|
||||
job_record RECORD;
|
||||
BEGIN
|
||||
-- Build dblink connection string
|
||||
conn_str := format(
|
||||
'dbname=%s host=%s port=%s user=%s password=%s',
|
||||
bacula_db_name,
|
||||
bacula_host,
|
||||
bacula_port,
|
||||
bacula_user,
|
||||
bacula_password
|
||||
);
|
||||
|
||||
-- Query jobs from Bacula database using dblink
|
||||
FOR job_record IN
|
||||
SELECT * FROM dblink(
|
||||
conn_str,
|
||||
$$
|
||||
SELECT
|
||||
j.JobId,
|
||||
j.Name as job_name,
|
||||
COALESCE(c.Name, 'unknown') as client_name,
|
||||
CASE
|
||||
WHEN j.Type = 'B' THEN 'Backup'
|
||||
WHEN j.Type = 'R' THEN 'Restore'
|
||||
WHEN j.Type = 'V' THEN 'Verify'
|
||||
WHEN j.Type = 'C' THEN 'Copy'
|
||||
WHEN j.Type = 'M' THEN 'Migrate'
|
||||
ELSE 'Backup'
|
||||
END as job_type,
|
||||
CASE
|
||||
WHEN j.Level = 'F' THEN 'Full'
|
||||
WHEN j.Level = 'I' THEN 'Incremental'
|
||||
WHEN j.Level = 'D' THEN 'Differential'
|
||||
WHEN j.Level = 'S' THEN 'Since'
|
||||
ELSE 'Full'
|
||||
END as job_level,
|
||||
CASE
|
||||
WHEN j.JobStatus = 'T' THEN 'Running'
|
||||
WHEN j.JobStatus = 'C' THEN 'Completed'
|
||||
WHEN j.JobStatus = 'f' OR j.JobStatus = 'F' THEN 'Failed'
|
||||
WHEN j.JobStatus = 'A' THEN 'Canceled'
|
||||
WHEN j.JobStatus = 'W' THEN 'Waiting'
|
||||
ELSE 'Waiting'
|
||||
END as status,
|
||||
COALESCE(j.JobBytes, 0) as bytes_written,
|
||||
COALESCE(j.JobFiles, 0) as files_written,
|
||||
j.StartTime as started_at,
|
||||
j.EndTime as ended_at,
|
||||
CASE
|
||||
WHEN j.EndTime IS NOT NULL AND j.StartTime IS NOT NULL
|
||||
THEN EXTRACT(EPOCH FROM (j.EndTime - j.StartTime))::INTEGER
|
||||
ELSE NULL
|
||||
END as duration_seconds
|
||||
FROM Job j
|
||||
LEFT JOIN Client c ON j.ClientId = c.ClientId
|
||||
ORDER BY j.StartTime DESC
|
||||
LIMIT 1000
|
||||
$$
|
||||
) AS t(
|
||||
job_id INTEGER,
|
||||
job_name TEXT,
|
||||
client_name TEXT,
|
||||
job_type TEXT,
|
||||
job_level TEXT,
|
||||
status TEXT,
|
||||
bytes_written BIGINT,
|
||||
files_written INTEGER,
|
||||
started_at TIMESTAMP,
|
||||
ended_at TIMESTAMP,
|
||||
duration_seconds INTEGER
|
||||
)
|
||||
LOOP
|
||||
BEGIN
|
||||
-- Check if job already exists (before insert/update)
|
||||
IF EXISTS (SELECT 1 FROM backup_jobs WHERE job_id = job_record.job_id) THEN
|
||||
updated_count := updated_count + 1;
|
||||
ELSE
|
||||
inserted_count := inserted_count + 1;
|
||||
END IF;
|
||||
|
||||
-- Upsert job to backup_jobs table
|
||||
INSERT INTO backup_jobs (
|
||||
job_id, job_name, client_name, job_type, job_level, status,
|
||||
bytes_written, files_written, started_at, ended_at, duration_seconds,
|
||||
updated_at
|
||||
) VALUES (
|
||||
job_record.job_id,
|
||||
job_record.job_name,
|
||||
job_record.client_name,
|
||||
job_record.job_type,
|
||||
job_record.job_level,
|
||||
job_record.status,
|
||||
job_record.bytes_written,
|
||||
job_record.files_written,
|
||||
job_record.started_at,
|
||||
job_record.ended_at,
|
||||
job_record.duration_seconds,
|
||||
NOW()
|
||||
)
|
||||
ON CONFLICT (job_id) DO UPDATE SET
|
||||
job_name = EXCLUDED.job_name,
|
||||
client_name = EXCLUDED.client_name,
|
||||
job_type = EXCLUDED.job_type,
|
||||
job_level = EXCLUDED.job_level,
|
||||
status = EXCLUDED.status,
|
||||
bytes_written = EXCLUDED.bytes_written,
|
||||
files_written = EXCLUDED.files_written,
|
||||
started_at = EXCLUDED.started_at,
|
||||
ended_at = EXCLUDED.ended_at,
|
||||
duration_seconds = EXCLUDED.duration_seconds,
|
||||
updated_at = NOW();
|
||||
|
||||
jobs_count := jobs_count + 1;
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
error_count := error_count + 1;
|
||||
-- Log error but continue with next job
|
||||
RAISE WARNING 'Error syncing job %: %', job_record.job_id, SQLERRM;
|
||||
END;
|
||||
END LOOP;
|
||||
|
||||
-- Return summary
|
||||
RETURN QUERY SELECT jobs_count, inserted_count, updated_count, error_count;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- Create a simpler version that uses current database connection settings
|
||||
-- This version assumes Bacula is on same host/port with same user
|
||||
CREATE OR REPLACE FUNCTION sync_bacula_jobs_simple()
|
||||
RETURNS TABLE(
|
||||
jobs_synced INTEGER,
|
||||
jobs_inserted INTEGER,
|
||||
jobs_updated INTEGER,
|
||||
errors INTEGER
|
||||
) AS $$
|
||||
DECLARE
|
||||
current_user_name TEXT;
|
||||
current_host TEXT;
|
||||
current_port INTEGER;
|
||||
current_db TEXT;
|
||||
BEGIN
|
||||
-- Get current connection info
|
||||
SELECT
|
||||
current_user,
|
||||
COALESCE(inet_server_addr()::TEXT, 'localhost'),
|
||||
COALESCE(inet_server_port(), 5432),
|
||||
current_database()
|
||||
INTO
|
||||
current_user_name,
|
||||
current_host,
|
||||
current_port,
|
||||
current_db;
|
||||
|
||||
-- Call main function with current connection settings
|
||||
-- Note: password needs to be passed or configured in .pgpass
|
||||
RETURN QUERY
|
||||
SELECT * FROM sync_bacula_jobs(
|
||||
'bacula', -- Try 'bacula' first
|
||||
current_host,
|
||||
current_port,
|
||||
current_user_name,
|
||||
'' -- Empty password - will use .pgpass or peer authentication
|
||||
);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- Grant execute permission to calypso user
|
||||
GRANT EXECUTE ON FUNCTION sync_bacula_jobs(TEXT, TEXT, INTEGER, TEXT, TEXT) TO calypso;
|
||||
GRANT EXECUTE ON FUNCTION sync_bacula_jobs_simple() TO calypso;
|
||||
|
||||
-- Create index if not exists (should already exist from migration 009)
|
||||
CREATE INDEX IF NOT EXISTS idx_backup_jobs_job_id ON backup_jobs(job_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_backup_jobs_updated_at ON backup_jobs(updated_at);
|
||||
|
||||
COMMENT ON FUNCTION sync_bacula_jobs IS 'Syncs jobs from Bacula database to Calypso backup_jobs table using dblink';
|
||||
COMMENT ON FUNCTION sync_bacula_jobs_simple IS 'Simplified version that uses current connection settings (requires .pgpass for password)';
|
||||
|
||||
23
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/012_add_snapshot_schedules_table.sql
vendored
Normal file
23
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/012_add_snapshot_schedules_table.sql
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
-- Snapshot schedules table for automated snapshot creation
|
||||
CREATE TABLE IF NOT EXISTS snapshot_schedules (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
dataset VARCHAR(255) NOT NULL,
|
||||
snapshot_name_template VARCHAR(255) NOT NULL, -- e.g., "auto-%Y-%m-%d-%H%M" or "daily-backup"
|
||||
schedule_type VARCHAR(50) NOT NULL, -- 'hourly', 'daily', 'weekly', 'monthly', 'cron'
|
||||
schedule_config JSONB NOT NULL, -- For cron: {"cron": "0 0 * * *"}, for others: {"time": "00:00", "day": 1, etc.}
|
||||
recursive BOOLEAN NOT NULL DEFAULT false,
|
||||
enabled BOOLEAN NOT NULL DEFAULT true,
|
||||
retention_count INTEGER, -- Keep last N snapshots (null = unlimited)
|
||||
retention_days INTEGER, -- Keep snapshots for N days (null = unlimited)
|
||||
last_run_at TIMESTAMP,
|
||||
next_run_at TIMESTAMP,
|
||||
created_by UUID REFERENCES users(id),
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
UNIQUE(name)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_snapshot_schedules_enabled ON snapshot_schedules(enabled);
|
||||
CREATE INDEX IF NOT EXISTS idx_snapshot_schedules_next_run ON snapshot_schedules(next_run_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_snapshot_schedules_dataset ON snapshot_schedules(dataset);
|
||||
76
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/013_add_replication_tasks_table.sql
vendored
Normal file
76
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/013_add_replication_tasks_table.sql
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
-- ZFS Replication Tasks Table
|
||||
-- Supports both outbound (sender) and inbound (receiver) replication
|
||||
CREATE TABLE IF NOT EXISTS replication_tasks (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
direction VARCHAR(20) NOT NULL, -- 'outbound' (sender) or 'inbound' (receiver)
|
||||
|
||||
-- For outbound replication (sender)
|
||||
source_dataset VARCHAR(512), -- Source dataset on this system (outbound) or remote system (inbound)
|
||||
target_host VARCHAR(255), -- Target host IP or hostname (for outbound)
|
||||
target_port INTEGER DEFAULT 22, -- SSH port (default 22, for outbound)
|
||||
target_user VARCHAR(255) DEFAULT 'root', -- SSH user (for outbound)
|
||||
target_dataset VARCHAR(512), -- Target dataset on remote system (for outbound)
|
||||
target_ssh_key_path TEXT, -- Path to SSH private key (for outbound)
|
||||
|
||||
-- For inbound replication (receiver)
|
||||
source_host VARCHAR(255), -- Source host IP or hostname (for inbound)
|
||||
source_port INTEGER DEFAULT 22, -- SSH port (for inbound)
|
||||
source_user VARCHAR(255) DEFAULT 'root', -- SSH user (for inbound)
|
||||
local_dataset VARCHAR(512), -- Local dataset to receive snapshots (for inbound)
|
||||
|
||||
-- Common settings
|
||||
schedule_type VARCHAR(50), -- 'manual', 'hourly', 'daily', 'weekly', 'monthly', 'cron'
|
||||
schedule_config JSONB, -- Schedule configuration (similar to snapshot schedules)
|
||||
compression VARCHAR(50) DEFAULT 'lz4', -- 'off', 'lz4', 'gzip', 'zstd'
|
||||
encryption BOOLEAN DEFAULT false, -- Enable encryption during transfer
|
||||
recursive BOOLEAN DEFAULT false, -- Replicate recursively
|
||||
incremental BOOLEAN DEFAULT true, -- Use incremental replication
|
||||
auto_snapshot BOOLEAN DEFAULT true, -- Auto-create snapshot before replication
|
||||
|
||||
-- Status and tracking
|
||||
enabled BOOLEAN NOT NULL DEFAULT true,
|
||||
status VARCHAR(50) DEFAULT 'idle', -- 'idle', 'running', 'failed', 'paused'
|
||||
last_run_at TIMESTAMP,
|
||||
last_run_status VARCHAR(50), -- 'success', 'failed', 'partial'
|
||||
last_run_error TEXT,
|
||||
next_run_at TIMESTAMP,
|
||||
last_snapshot_sent VARCHAR(512), -- Last snapshot successfully sent (for outbound)
|
||||
last_snapshot_received VARCHAR(512), -- Last snapshot successfully received (for inbound)
|
||||
|
||||
-- Statistics
|
||||
total_runs INTEGER DEFAULT 0,
|
||||
successful_runs INTEGER DEFAULT 0,
|
||||
failed_runs INTEGER DEFAULT 0,
|
||||
bytes_sent BIGINT DEFAULT 0, -- Total bytes sent (for outbound)
|
||||
bytes_received BIGINT DEFAULT 0, -- Total bytes received (for inbound)
|
||||
|
||||
created_by UUID REFERENCES users(id),
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
|
||||
-- Validation: ensure required fields based on direction
|
||||
CONSTRAINT chk_direction CHECK (direction IN ('outbound', 'inbound')),
|
||||
CONSTRAINT chk_outbound_fields CHECK (
|
||||
direction != 'outbound' OR (
|
||||
source_dataset IS NOT NULL AND
|
||||
target_host IS NOT NULL AND
|
||||
target_dataset IS NOT NULL
|
||||
)
|
||||
),
|
||||
CONSTRAINT chk_inbound_fields CHECK (
|
||||
direction != 'inbound' OR (
|
||||
source_host IS NOT NULL AND
|
||||
source_dataset IS NOT NULL AND
|
||||
local_dataset IS NOT NULL
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
-- Create indexes
|
||||
CREATE INDEX IF NOT EXISTS idx_replication_tasks_direction ON replication_tasks(direction);
|
||||
CREATE INDEX IF NOT EXISTS idx_replication_tasks_enabled ON replication_tasks(enabled);
|
||||
CREATE INDEX IF NOT EXISTS idx_replication_tasks_status ON replication_tasks(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_replication_tasks_next_run ON replication_tasks(next_run_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_replication_tasks_source_dataset ON replication_tasks(source_dataset);
|
||||
CREATE INDEX IF NOT EXISTS idx_replication_tasks_target_host ON replication_tasks(target_host);
|
||||
30
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/014_add_client_categories_table.sql
vendored
Normal file
30
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/014_add_client_categories_table.sql
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
-- AtlasOS - Calypso
|
||||
-- Client Categories Schema
|
||||
-- Version: 14.0
|
||||
-- Adds category support for backup clients (File, Database, Virtual)
|
||||
|
||||
-- Client metadata table to store additional information about clients
|
||||
-- This extends the Bacula Client table with Calypso-specific metadata
|
||||
CREATE TABLE IF NOT EXISTS client_metadata (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
client_id INTEGER NOT NULL, -- Bacula Client.ClientId
|
||||
client_name VARCHAR(255) NOT NULL, -- Bacula Client.Name (for reference)
|
||||
category VARCHAR(50) NOT NULL DEFAULT 'File', -- 'File', 'Database', 'Virtual'
|
||||
description TEXT,
|
||||
tags JSONB, -- Additional tags/metadata as JSON
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
|
||||
-- Ensure one metadata entry per client
|
||||
CONSTRAINT unique_client_id UNIQUE (client_id),
|
||||
CONSTRAINT chk_category CHECK (category IN ('File', 'Database', 'Virtual'))
|
||||
);
|
||||
|
||||
-- Indexes for performance
|
||||
CREATE INDEX IF NOT EXISTS idx_client_metadata_client_id ON client_metadata(client_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_client_metadata_client_name ON client_metadata(client_name);
|
||||
CREATE INDEX IF NOT EXISTS idx_client_metadata_category ON client_metadata(category);
|
||||
|
||||
-- Add comment
|
||||
COMMENT ON TABLE client_metadata IS 'Stores Calypso-specific metadata for backup clients, including category classification';
|
||||
COMMENT ON COLUMN client_metadata.category IS 'Client category: File (file system backups), Database (database backups), Virtual (virtual machine backups)';
|
||||
44
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/015_add_bacula_clients_table.sql
vendored
Normal file
44
dist/airgap/calypso-appliance-1.0.0-airgap/migrations/015_add_bacula_clients_table.sql
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
-- AtlasOS - Calypso
|
||||
-- Migration 015: Add Bacula clients and capability history tables
|
||||
--
|
||||
-- Adds tables for tracking registered Bacula agents, their backup capabilities,
|
||||
-- and a history log for UI- or agent-triggered capability changes. Pending
|
||||
-- updates are stored on the client row until the agent pulls them.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS bacula_clients (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
hostname TEXT NOT NULL,
|
||||
ip_address TEXT,
|
||||
agent_version TEXT,
|
||||
status TEXT NOT NULL DEFAULT 'online',
|
||||
backup_types JSONB NOT NULL,
|
||||
pending_backup_types JSONB,
|
||||
pending_requested_by UUID,
|
||||
pending_requested_at TIMESTAMPTZ,
|
||||
pending_notes TEXT,
|
||||
metadata JSONB,
|
||||
registered_by_user_id UUID NOT NULL,
|
||||
last_seen TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
CONSTRAINT uniq_bacula_clients_hostname UNIQUE (hostname)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_bacula_clients_registered_by ON bacula_clients (registered_by_user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_bacula_clients_status ON bacula_clients (status);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS bacula_client_capability_history (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
client_id UUID NOT NULL REFERENCES bacula_clients (id) ON DELETE CASCADE,
|
||||
backup_types JSONB NOT NULL,
|
||||
source TEXT NOT NULL,
|
||||
requested_by_user_id UUID,
|
||||
requested_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
notes TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_bacula_client_capability_history_client ON bacula_client_capability_history (client_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_bacula_client_capability_history_requested_at ON bacula_client_capability_history (requested_at);
|
||||
|
||||
COMMENT ON TABLE bacula_clients IS 'Tracks Bacula clients registered with Calypso, including pending capability pushes.';
|
||||
COMMENT ON TABLE bacula_client_capability_history IS 'Audit history of backup capability changes per client.';
|
||||
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/Packages.gz
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/Packages.gz
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/adduser_3.137ubuntu1_all.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/adduser_3.137ubuntu1_all.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/apt-utils_2.8.3_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/apt-utils_2.8.3_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/apt_2.8.3_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/apt_2.8.3_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/attr_1%3a2.5.2-1build1.1_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/attr_1%3a2.5.2-1build1.1_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/bacula-bscan_13.0.4-1build3_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/bacula-bscan_13.0.4-1build3_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/bacula-client_13.0.4-1build3_all.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/bacula-client_13.0.4-1build3_all.deb
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/bacula-common_13.0.4-1build3_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/bacula-common_13.0.4-1build3_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/bacula-console_13.0.4-1build3_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/bacula-console_13.0.4-1build3_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/bacula-fd_13.0.4-1build3_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/bacula-fd_13.0.4-1build3_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/bacula-sd_13.0.4-1build3_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/bacula-sd_13.0.4-1build3_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/binutils-common_2.42-4ubuntu2.8_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/binutils-common_2.42-4ubuntu2.8_amd64.deb
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/binutils_2.42-4ubuntu2.8_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/binutils_2.42-4ubuntu2.8_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/build-essential_12.10ubuntu1_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/build-essential_12.10ubuntu1_amd64.deb
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/bzip2_1.0.8-5.1build0.1_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/bzip2_1.0.8-5.1build0.1_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/ca-certificates_20240203_all.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/ca-certificates_20240203_all.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/cdebconf_0.271ubuntu3_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/cdebconf_0.271ubuntu3_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/chrony_4.5-1ubuntu4.2_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/chrony_4.5-1ubuntu4.2_amd64.deb
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/coreutils_9.4-3ubuntu6.1_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/coreutils_9.4-3ubuntu6.1_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/cpio_2.15+dfsg-1ubuntu2_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/cpio_2.15+dfsg-1ubuntu2_amd64.deb
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/cpp-13_13.3.0-6ubuntu2~24.04_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/cpp-13_13.3.0-6ubuntu2~24.04_amd64.deb
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/cpp_4%3a13.2.0-7ubuntu1_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/cpp_4%3a13.2.0-7ubuntu1_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/curl_8.5.0-2ubuntu10.6_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/curl_8.5.0-2ubuntu10.6_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dbus-bin_1.14.10-4ubuntu4.1_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dbus-bin_1.14.10-4ubuntu4.1_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dbus-broker_35-2ubuntu0.1_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dbus-broker_35-2ubuntu0.1_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dbus-daemon_1.14.10-4ubuntu4.1_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dbus-daemon_1.14.10-4ubuntu4.1_amd64.deb
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dbus_1.14.10-4ubuntu4.1_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dbus_1.14.10-4ubuntu4.1_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/debconf-i18n_1.5.86ubuntu1_all.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/debconf-i18n_1.5.86ubuntu1_all.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/debconf_1.5.86ubuntu1_all.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/debconf_1.5.86ubuntu1_all.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/debianutils_5.17build1_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/debianutils_5.17build1_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dhcpcd-base_1%3a10.0.6-1ubuntu3.1_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dhcpcd-base_1%3a10.0.6-1ubuntu3.1_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dirmngr_2.4.4-2ubuntu17.4_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dirmngr_2.4.4-2ubuntu17.4_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dkms_3.0.11-1ubuntu13_all.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dkms_3.0.11-1ubuntu13_all.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dmeventd_2%3a1.02.185-3ubuntu3.2_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dmeventd_2%3a1.02.185-3ubuntu3.2_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dmidecode_3.5-3ubuntu0.1_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dmidecode_3.5-3ubuntu0.1_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dmsetup_2%3a1.02.185-3ubuntu3.2_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dmsetup_2%3a1.02.185-3ubuntu3.2_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dpkg-dev_1.22.6ubuntu6.5_all.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dpkg-dev_1.22.6ubuntu6.5_all.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dpkg_1.22.6ubuntu6.5_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dpkg_1.22.6ubuntu6.5_amd64.deb
vendored
Normal file
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dracut-install_060+5-1ubuntu3.3_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/dracut-install_060+5-1ubuntu3.3_amd64.deb
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/fakeroot_1.33-1_amd64.deb
vendored
Normal file
BIN
dist/airgap/calypso-appliance-1.0.0-airgap/packages/debs/fakeroot_1.33-1_amd64.deb
vendored
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user