Commit bac94c4f245e
Changed files (8)
secrets
systems
secrets/aomi/gemini-api-key.age
@@ -1,9 +0,0 @@
-age-encryption.org/v1
--> piv-p256 ItIHHA AmC/PmZfjSfS0o9+w3Mf/H+3Sv4rs6RcleR4PZkKK9SA
-H814D8zvgjja42MX6gwNEDZmUlx4mI0v0A5Chs+XT5E
--> piv-p256 cUinNw AyKkpqaKAvmjDQtjC4fmLz6NXXK/1I92zCiX5vqzTZV/
-aX3LdHEAshLvRGkN5KwvG/7e+C1RGo+LmxgHreun5KI
--> ssh-ed25519 irMfZA HuBjC2aevr+qXhdiaeqVdffZKMxHTsQj8Lb/pR4XR0o
-O0RQ2G+xIxu+J1WIDztU1SHLx+yg77mfixKqYHClasw
---- PVohZg1s5zBqcLnCdIaimcZgwNXZRsvGPfF6M8bNg9E
-ʋ������hi�2A���w>��>-��?�/�{�DʏU.��x����$�E���z�|���2#Y�8AS(]+
\ No newline at end of file
secrets/aomi/searxng-secret-key.age
Binary file
secrets/aomi/xmpp-research-bot-password.age
@@ -1,9 +0,0 @@
-age-encryption.org/v1
--> piv-p256 ItIHHA Ax5u3xLpCoDuYz1eY/e4zhWGfBTcwrlBFJDEsvvnElzW
-xz9T6QYjm1I1gh8l89R2uOrAd292gMqfsEXK60c/LP4
--> piv-p256 cUinNw AucD5hYQfqoeGr/Att7csZovuLJIFnY/Si9K3XiRtJzk
-Ib/aFpGphcEGAPtNZmIvofTysbwyQA+LW7M8n9P476k
--> ssh-ed25519 irMfZA V+bd3169fs/LekuqTfQu7Zy/Iugk/N8fNLvzOaYF0nk
-UTE3ChjxWcOtFw0c39XZ0KEXPdjoRAClYyZn1ba0tZE
---- hh+cyyTFWuKBGXrnTyTgZGrCP0heUsWoA2Bt2qlSpHI
-�'��a���st�k��Sr9��wn��S�ܳ�OD4=����mLYwr
\ No newline at end of file
secrets/harmonia/aomi-signing-key.age
@@ -1,11 +0,0 @@
-age-encryption.org/v1
--> piv-p256 ItIHHA AtlOIJQtjfzIWrUi7bzRXpTCGXjtWlb709xTIrBGoG7G
-AwFcRU4BM4zx+eJe+gKmwLxlPOwMjdd5hnpa6AZFapY
--> piv-p256 cUinNw A10EqJVYzhwNM5e7SDJMyfbxRQ5loUf3JsAOwbxSW0KZ
-Cp4ZE4i5QJEOJD4HESFmm898dzJJMuw36dvliM2p8r0
--> ssh-ed25519 irMfZA cfc/vZ2S4akXVV9MQ9KMZrIEElupGEQnxAsd4id9Swg
-L2Fj1wyW9qKjyG0Xk5qtNcE7Z/mnHx/IieZSDUNiHm8
---- KJvrtecFVq2QflN6INGS1znUvU6tNCYc8m3JMHKy2jg
-�����#��պ�kGU
-D&lrg��iޮ$��Vv�_��^-VZ;b�
-.��j��a_Q������w �T�R���A3�\ ����2���#�f)����� ��Ϸ��*�#ckr�P.��T��������`��?���,
\ No newline at end of file
systems/aomi/extra.nix
@@ -1,5 +1,4 @@
{
- config,
globals,
libx,
pkgs,
@@ -20,278 +19,21 @@
../common/services/docker.nix
../common/services/libvirt.nix
../common/services/binfmt.nix
- # ../common/services/oci-image-mirroring.nixi
- # ../common/services/ollama.nix # TODO handle nvidia vs not ?
../common/services/prometheus-exporters-node.nix
- # ../common/services/gitea-runner
../common/services/oomd.nix
../redhat
-
- # OpenShift port forwarding
- ./openshift-port-forward.nix
-
- # Remote build system
- ../../modules/job-notify
- ../../modules/microshift
-
- # Binary cache
- ../../modules/harmonia
-
- # Automated flake updates
- ../../modules/nix-flake-updater
];
- # Firewall is enabled in openshift-port-forward.nix
- # networking.firewall.enable = false;
-
# Suppress malformed DHCP option 24 (MTU plateau) warnings from router
networking.dhcpcd.extraConfig = ''
nooption mtu_plateau
denyinterfaces wg0
'';
- # OpenShift SNO endpoints
- networking.extraHosts = ''
- 192.168.100.7 api.ocp4.lab.home
- 192.168.100.7 api-int.ocp4.lab.home
- 192.168.100.7 console-openshift-console.apps.ocp4.lab.home
- 192.168.100.7 oauth-openshift.apps.ocp4.lab.home
- '';
-
- # Age secrets
- age.secrets."searxng-secret-key" = {
- file = ../../secrets/aomi/searxng-secret-key.age;
- mode = "400";
- owner = "searx";
- group = "searx";
- };
- age.secrets."ntfy-token" = {
- file = ../../secrets/sakhalin/ntfy-token.age;
- mode = "440";
- owner = "root";
- group = "users";
- };
- age.secrets."harmonia-aomi-signing-key" = {
- file = ../../secrets/harmonia/aomi-signing-key.age;
- mode = "440";
- owner = "root";
- group = "root";
- };
- age.secrets."gemini-api-key" = {
- file = ../../secrets/aomi/gemini-api-key.age;
- mode = "400";
- owner = "vincent";
- group = "users";
- };
-
# TODO make it an option ? (otherwise I'll add it for all)
users.users.vincent.linger = true;
- # Binary cache server (x86_64-linux)
- services.harmonia-cache = {
- enable = true;
- signKeyPath = config.age.secrets."harmonia-aomi-signing-key".path;
- port = 5000;
- workers = 4;
- priority = 30;
-
- # Nightly cache pre-population
- builder = {
- enable = true;
- systems = [
- "aomi" # Self
- "kyushu" # Work laptop
- "sakhalin" # Server
- ];
- schedule = "02:00"; # 2 AM daily
- notification = {
- enable = true;
- tokenFile = config.age.secrets."ntfy-token".path;
- };
- };
- };
-
- # Remote build system
- services.job-notify = {
- enable = true;
- ntfyServer = "https://ntfy.sbr.pm";
- ntfyTokenFile = config.age.secrets."ntfy-token".path;
- defaultTopic = "builds";
- };
-
- # XMPP Research Bot moved to okinawa (daneel)
-
- # Automated flake.lock updates with build verification
- services.nix-flake-updater = {
- # Weekly updates for all inputs
- weekly = {
- enable = true;
- repoPath = "/home/vincent/src/home";
-
- # Build systems across both architectures for verification
- buildSystems = [
- # x86_64-linux systems
- "aomi" # Self (laptop/build server)
- "kyushu" # Work laptop
- "sakhalin" # Server
- "kerkouane" # VPS server
-
- # aarch64-linux systems
- "rhea" # Main media server
- "aion" # XMPP/podcast server
- "athena" # Raspberry Pi 4
- "demeter" # Raspberry Pi 4
- "aix" # Raspberry Pi 4
- ];
-
- # Run weekly on Sunday at 2 AM
- schedule = "Sun *-*-* 02:00:00";
-
- # Notifications via ntfy
- ntfyServer = "https://ntfy.sbr.pm";
- ntfyTopic = "nix-updates";
- ntfyTokenFile = config.age.secrets."ntfy-token".path;
-
- # Git settings
- gitRemote = "origin";
- branchPrefix = "flake-update-";
-
- # Run as vincent (has git push access)
- user = "vincent";
-
- # Add randomized delay to avoid conflicts
- randomizedDelaySec = 1800; # 0-30 min delay
- };
-
- # Daily automated updates for chick-group and chapeau-rouge with auto-merge
- daily = {
- enable = true;
- repoPath = "/home/vincent/src/home";
-
- # Update only personal repos
- flakeInputs = [
- "chick-group"
- "chapeau-rouge"
- ];
-
- # Auto-merge to main on successful build
- autoMerge = true;
-
- # Build fewer systems for faster daily updates
- buildSystems = [
- "aomi" # Self (x86_64-linux)
- "kyushu" # Work laptop (x86_64-linux)
- ];
-
- # Run daily at 4 AM
- schedule = "*-*-* 04:00:00";
-
- # Notifications via ntfy (same topic as weekly)
- ntfyServer = "https://ntfy.sbr.pm";
- ntfyTopic = "nix-updates";
- ntfyTokenFile = config.age.secrets."ntfy-token".path;
-
- # Git settings
- gitRemote = "origin";
- mainBranch = "main";
- branchPrefix = "auto-update-daily-";
-
- # Org inbox for failure TODOs
- inboxOrg = "/home/vincent/desktop/org/inbox.org";
-
- # Run as vincent (has git push access)
- user = "vincent";
-
- # Smaller delay for daily updates
- randomizedDelaySec = 600; # 0-10 min delay
- };
- };
-
- # SearXNG metasearch engine (private, API-focused for Pi agent)
- services.searx = {
- enable = true;
- environmentFile = config.age.secrets."searxng-secret-key".path;
- settings = {
- use_default_settings = {
- engines.remove = [
- "ahmia"
- "torch"
- ];
- };
- server = {
- port = 8888;
- bind_address = "0.0.0.0";
- secret_key = "$SEARXNG_SECRET_KEY";
- limiter = false; # Private instance, no rate limiting needed
- image_proxy = false;
- };
- search = {
- safe_search = 0;
- autocomplete = "";
- default_lang = "en";
- formats = [
- "html"
- "json"
- ];
- };
- # Curated engines for quality results
- engines = [
- {
- name = "duckduckgo";
- engine = "duckduckgo";
- shortcut = "ddg";
- disabled = false;
- }
- {
- name = "google";
- engine = "google";
- shortcut = "g";
- disabled = false;
- }
- {
- name = "brave";
- engine = "brave";
- shortcut = "br";
- disabled = false;
- }
- {
- name = "wikipedia";
- engine = "wikipedia";
- shortcut = "wp";
- disabled = false;
- }
- {
- name = "github";
- engine = "github";
- shortcut = "gh";
- disabled = false;
- }
- {
- name = "stackoverflow";
- engine = "stackexchange";
- shortcut = "so";
- disabled = false;
- categories = "it";
- }
- {
- name = "arch wiki";
- engine = "archlinux";
- shortcut = "aw";
- disabled = false;
- }
- {
- name = "nixos wiki";
- engine = "mediawiki";
- shortcut = "nw";
- disabled = false;
- base_url = "https://wiki.nixos.org/";
- search_type = "text";
- }
- ];
- };
- };
-
services = {
logind.settings.Login = {
HandleLidSwitch = "ignore";
@@ -351,144 +93,8 @@
jayrah
];
- systemd.tmpfiles.rules = [
- "d /var/lib/git-builds 0755 builder users -"
+ # Firewall
+ networking.firewall.allowedTCPPorts = [
+ 9000 # Prometheus node exporter
];
-
- # NOTE: NixOS firewall is disabled (see openshift-port-forward.nix).
- # Firewall rules must be added to the nftables config there instead.
- # networking.firewall.allowedTCPPorts = [ 8000 8888 ];
-
- # Builder user for remote builds
- users.users.builder = {
- isSystemUser = true;
- group = "users";
- home = "/var/lib/git-builds";
- createHome = true;
- openssh.authorizedKeys.keys = [
- # This will be populated with kerkouane's SSH key for build triggering
- ];
- };
-
- # Build execution script
- environment.etc."git-builds/execute-build.sh" = {
- text = ''
- #!${pkgs.bash}/bin/bash
- set -euo pipefail
-
- REPO_NAME="$1"
- BUILD_TYPE="''${2:-auto}"
- REPO_URL="vincent@kerkouane.sbr.pm:git/public/$REPO_NAME.git"
-
- # Cache directory and worktree
- CACHE_DIR="/var/lib/git-builds/$REPO_NAME.git"
- BUILD_DIR="/var/lib/git-builds/$REPO_NAME-build-$(${pkgs.coreutils}/bin/date +%s)"
-
- echo "Building $REPO_NAME (type: $BUILD_TYPE)"
- echo "Cache: $CACHE_DIR"
- echo "Build directory: $BUILD_DIR"
-
- # Fetch or clone
- if [ -d "$CACHE_DIR" ]; then
- echo "Fetching updates for $REPO_NAME..."
- cd "$CACHE_DIR" && ${pkgs.git}/bin/git fetch origin
- else
- echo "Cloning $REPO_NAME..."
- ${pkgs.git}/bin/git clone --bare "$REPO_URL" "$CACHE_DIR"
- fi
-
- # Create worktree for isolated build
- echo "Creating worktree at $BUILD_DIR..."
- cd "$CACHE_DIR"
- ${pkgs.git}/bin/git worktree add "$BUILD_DIR" main
-
- cd "$BUILD_DIR"
- echo "Working directory: $(pwd)"
-
- # Execute build based on type
- case "$BUILD_TYPE" in
- nixos)
- echo "Running NixOS build..."
- ${pkgs.nixos-rebuild}/bin/nixos-rebuild build --flake .#aomi
- ;;
- make)
- echo "Running make build..."
- ${pkgs.gnumake}/bin/make build
- ;;
- docker)
- echo "Running Docker build..."
- ${pkgs.docker}/bin/docker build -t "$REPO_NAME:latest" .
- ;;
- go)
- echo "Running Go build..."
- ${pkgs.go}/bin/go build ./...
- ;;
- custom)
- if [ -x .git-build.sh ]; then
- echo "Running custom build script..."
- ./.git-build.sh
- else
- echo "ERROR: .git-build.sh not found or not executable"
- exit 1
- fi
- ;;
- auto)
- echo "Auto-detecting build type..."
- if [ -f flake.nix ]; then
- echo "Detected NixOS flake"
- ${pkgs.nixos-rebuild}/bin/nixos-rebuild build --flake .#aomi
- elif [ -f Makefile ]; then
- echo "Detected Makefile"
- ${pkgs.gnumake}/bin/make build
- elif [ -f Dockerfile ]; then
- echo "Detected Dockerfile"
- ${pkgs.docker}/bin/docker build -t "$REPO_NAME:latest" .
- elif [ -f go.mod ]; then
- echo "Detected Go module"
- ${pkgs.go}/bin/go build ./...
- else
- echo "ERROR: Could not auto-detect build type"
- exit 1
- fi
- ;;
- *)
- echo "ERROR: Unknown build type: $BUILD_TYPE"
- exit 1
- ;;
- esac
-
- echo "Build completed successfully!"
-
- # Cleanup worktree (keep cache)
- echo "Cleaning up worktree..."
- cd /
- ${pkgs.git}/bin/git -C "$CACHE_DIR" worktree remove "$BUILD_DIR"
- echo "Done!"
- '';
- mode = "0755";
- };
-
- # Allow builder to run systemd-run without password
- security.sudo.extraRules = [
- {
- users = [ "builder" ];
- commands = [
- {
- command = "${pkgs.systemd}/bin/systemd-run";
- options = [ "NOPASSWD" ];
- }
- ];
- }
- ];
-
- # MicroShift via CRC (disabled for now)
- services.microshift = {
- enable = false;
- cpus = 4;
- memory = 8192; # 8GB
- diskSize = 40;
- user = "vincent";
- # pullSecret will be configured via agenix later
- };
-
}
systems/aomi/openshift-port-forward.nix
@@ -1,124 +0,0 @@
-{ lib, ... }:
-
-{
- # Enable IP forwarding for libvirt network
- boot.kernel.sysctl = {
- "net.ipv4.ip_forward" = lib.mkForce 1;
- "net.ipv6.conf.all.forwarding" = lib.mkForce 1;
- };
-
- # Use nftables for better performance and cleaner syntax
- networking = {
- nftables = {
- enable = true;
-
- # IMPORTANT: Using tables instead of ruleset to allow libvirt to manage its own table
- # If we use ruleset, it completely replaces everything and libvirt can't create its table
- tables = {
- "nat" = {
- family = "ip";
- content = ''
- chain prerouting {
- type nat hook prerouting priority dstnat; policy accept;
-
- # Forward HTTP, HTTPS, and API traffic to OpenShift VM
- # Only from interfaces that are NOT virbr1 (to avoid loops)
- iifname != "virbr1" tcp dport 80 dnat to 192.168.100.7:80
- iifname != "virbr1" tcp dport 443 dnat to 192.168.100.7:443
- iifname != "virbr1" tcp dport 6443 dnat to 192.168.100.7:6443
- }
-
- chain postrouting {
- type nat hook postrouting priority srcnat; policy accept;
-
- # Masquerade traffic from libvirt network to external destinations
- ip saddr 192.168.100.0/24 ip daddr != 192.168.100.0/24 masquerade
- }
-
- chain output {
- type nat hook output priority dstnat; policy accept;
-
- # Forward localhost traffic destined for LAN IP to OpenShift VM
- ip daddr 192.168.1.23 tcp dport 80 dnat to 192.168.100.7:80
- ip daddr 192.168.1.23 tcp dport 443 dnat to 192.168.100.7:443
- ip daddr 192.168.1.23 tcp dport 6443 dnat to 192.168.100.7:6443
- }
- '';
- };
- "filter" = {
- family = "inet";
- content = ''
- chain input {
- type filter hook input priority filter; policy drop;
-
- # Allow established/related connections
- ct state { established, related } accept
-
- # Allow loopback
- iifname "lo" accept
-
- # Allow trusted interfaces
- iifname { "wg0", "docker0" } accept
-
- # Allow ICMP (ping)
- ip protocol icmp accept
- ip6 nexthdr ipv6-icmp accept
-
- # Allow SSH
- tcp dport 22 accept
-
- # Allow OpenShift ports
- tcp dport { 80, 443, 6443 } accept
-
- # Allow Prometheus node exporter
- tcp dport 9000 accept
-
- # Allow Docker Prometheus metrics
- tcp dport 9323 accept
-
- # Allow Ollama API
- tcp dport 11434 accept
-
- # Allow Ollama Prometheus exporter
- tcp dport 8000 accept
-
- # Allow SearXNG metasearch engine
- tcp dport 8888 accept
-
- # Allow Harmonia binary cache
- tcp dport 5000 accept
-
- # Allow libvirt
- tcp dport 16509 accept
-
- # Allow mDNS
- udp dport 5353 accept
- }
-
- chain forward {
- type filter hook forward priority filter; policy accept;
-
- # Allow established/related connections
- ct state { established, related } accept
-
- # Allow forwarding to/from the libvirt OpenShift network
- ip daddr 192.168.100.0/24 accept
- ip saddr 192.168.100.0/24 accept
- }
-
- chain output {
- type filter hook output priority filter; policy accept;
- }
- '';
- };
- };
-
- # Old ruleset approach - completely removed
- # Using ruleset would prevent libvirt from managing its own table
- # See tables configuration above instead
- };
-
- # Disable the default NixOS firewall since we're using custom nftables ruleset
- firewall.enable = false;
- };
-}
systems/default.nix
@@ -93,9 +93,8 @@
"https://chapeau-rouge.cachix.org"
"https://nixos-raspberrypi.cachix.org"
# Local Harmonia binary caches
- "http://aomi.sbr.pm:5000" # x86_64-linux
+ "http://okinawa.sbr.pm:5000" # x86_64-linux
"http://aion.sbr.pm:5000" # aarch64-linux
- "http://okinawa.sbr.pm:5000" # x86_64-linux (migration target)
];
trusted-public-keys = [
"r-ryantm.cachix.org-1:gkUbLkouDAyvBdpBX0JOdIiD2/DP1ldF3Z3Y6Gqcc4c="
@@ -104,9 +103,8 @@
"vdemeester.cachix.org-1:eZWNOrLR9A9szeMahn9ENaoT9DB3WgOos8va+d2CU44="
"nixos-raspberrypi.cachix.org-1:4iMO9LXa8BqhU+Rpg6LQKiGa2lsNh/j2oiYLNOQ5sPI="
# Local Harmonia cache public keys
- "cache.aomi.home-1:QjLpxXo2XgJoZRGd/u6tSoJoKmrndesKcwd5gR6sBuY="
- "cache.aion.home-1:VIbchtAJWf8+T46viAsLaQYDhG9KUGVo+vWxH1Tlz94="
"cache.okinawa.home:gp+IG0OaO4L/J0drL8OwmDtMPmdUq4kfLwg3mR8BkCs="
+ "cache.aion.home-1:VIbchtAJWf8+T46viAsLaQYDhG9KUGVo+vWxH1Tlz94="
];
};
secrets.nix
@@ -151,7 +151,6 @@ in
"secrets/sakhalin/ntfy-token.age".publicKeys = users ++ [
sakhalin
aion
- aomi
okinawa
rhea
kerkouane
@@ -159,10 +158,6 @@ in
"secrets/sakhalin/homeassistant-prometheus-token.age".publicKeys = users ++ [ sakhalin ];
"secrets/demeter/mosquitto-homeassistant-password.age".publicKeys = users ++ [ demeter ];
"secrets/aion/restic-aix-password.age".publicKeys = users ++ [ aion ];
- "secrets/aomi/xmpp-research-bot-password.age".publicKeys = users ++ [ aomi ];
- "secrets/aomi/gemini-api-key.age".publicKeys = users ++ [ aomi ];
- "secrets/aomi/searxng-secret-key.age".publicKeys = users ++ [ aomi ];
-
# OpenCode web on okinawa
"secrets/okinawa/opencode-password.age".publicKeys = users ++ [ okinawa ];
"secrets/okinawa/groq-api-key.age".publicKeys = users ++ [ okinawa ];
@@ -173,7 +168,6 @@ in
"secrets/rhea/restic-aix-password.age".publicKeys = users ++ [ rhea ];
# Harmonia binary cache signing keys
- "secrets/harmonia/aomi-signing-key.age".publicKeys = users ++ [ aomi ];
"secrets/harmonia/aion-signing-key.age".publicKeys = users ++ [ aion ];
"secrets/harmonia/okinawa-signing-key.age".publicKeys = users ++ [ okinawa ];