112 lines
3.3 KiB
Nix
112 lines
3.3 KiB
Nix
{ config, pkgs, lib, ... }:
|
|
|
|
with lib;
|
|
|
|
let
|
|
cfg = config.services.naxos.gitops;
|
|
|
|
# Safe switch script with canary validation and automatic rollback
|
|
naxosRebuildWrapper = pkgs.writeShellScriptBin "naxos-rebuild-safe" ''
|
|
set -euo pipefail
|
|
CONFIG_DIR="''${CONFIG_DIR:-/etc/naxos/repo}"
|
|
LOG_FILE="/var/log/naxos-rebuild.log"
|
|
|
|
echo "[$(date -Iseconds)] Starting NaxOS declarative rebuild..." | tee -a "$LOG_FILE"
|
|
|
|
cd "$CONFIG_DIR"
|
|
|
|
# Pre-flight check with nix flake check / nixos-rebuild dry-build
|
|
echo "Running dry build validation..."
|
|
if ! nixos-rebuild build --flake .#naxos 2>&1 | tee -a "$LOG_FILE"; then
|
|
echo "Dry-build failed! Configuration aborted without changing running system." | tee -a "$LOG_FILE"
|
|
exit 1
|
|
fi
|
|
|
|
# Record current generation
|
|
PREV_GEN=$(readlink -f /nix/var/nix/profiles/system)
|
|
|
|
echo "Applying system switch..."
|
|
if nixos-rebuild switch --flake .#naxos 2>&1 | tee -a "$LOG_FILE"; then
|
|
echo "System switch succeeded." | tee -a "$LOG_FILE"
|
|
|
|
# Canary health check: verify management daemon and storage pools are responsive
|
|
if systemctl is-active --quiet naxos-api.service; then
|
|
echo "Canary verification passed: NaxOS daemon active." | tee -a "$LOG_FILE"
|
|
exit 0
|
|
else
|
|
echo "WARNING: NaxOS daemon failed canary test! Initiating safe automatic rollback..." | tee -a "$LOG_FILE"
|
|
"$PREV_GEN/bin/switch-to-configuration" switch
|
|
exit 2
|
|
fi
|
|
else
|
|
echo "Switch command failed! Rolling back to $PREV_GEN..." | tee -a "$LOG_FILE"
|
|
"$PREV_GEN/bin/switch-to-configuration" switch
|
|
exit 3
|
|
fi
|
|
'';
|
|
|
|
# Automated remote push/pull service
|
|
naxosGitSync = pkgs.writeShellScriptBin "naxos-git-sync" ''
|
|
set -euo pipefail
|
|
REPO_DIR="/etc/naxos/repo"
|
|
|
|
if [ ! -d "$REPO_DIR/.git" ]; then
|
|
echo "Git repository not initialized in $REPO_DIR."
|
|
exit 0
|
|
fi
|
|
|
|
cd "$REPO_DIR"
|
|
|
|
if [ -n "''${NAXOS_REMOTE_URL:-}" ]; then
|
|
echo "Synchronizing with remote GitOps repository..."
|
|
git fetch origin main || true
|
|
git push origin main || true
|
|
fi
|
|
'';
|
|
|
|
in {
|
|
options.services.naxos.gitops = {
|
|
enable = mkEnableOption "NaxOS GitOps Configuration Synchronization Engine";
|
|
|
|
remoteUrl = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
example = "ssh://git@git.lholz.de:2222/naxos/naxos-config.git";
|
|
description = "Remote Git repository URL for automated backup, auditing, and disaster recovery.";
|
|
};
|
|
|
|
branch = mkOption {
|
|
type = types.str;
|
|
default = "main";
|
|
description = "GitOps target branch.";
|
|
};
|
|
|
|
tokenFile = mkOption {
|
|
type = types.nullOr types.str;
|
|
default = null;
|
|
description = "Path to Gitea/Git access token or SSH private key.";
|
|
};
|
|
|
|
autoPushOnCommit = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
description = "Automatically push to remote repository whenever web dashboard commits a change.";
|
|
};
|
|
};
|
|
|
|
config = mkIf cfg.enable {
|
|
environment.systemPackages = with pkgs; [
|
|
git
|
|
naxosRebuildWrapper
|
|
naxosGitSync
|
|
];
|
|
|
|
# Create config repo directory structure
|
|
systemd.tmpfiles.rules = [
|
|
"d /etc/naxos 0755 root root -"
|
|
"d /etc/naxos/repo 0750 root root -"
|
|
"d /var/log 0755 root root -"
|
|
];
|
|
};
|
|
}
|