Commit bac94c4f245e

Vincent Demeester <vincent@sbr.pm>
2026-02-18 10:15:58
feat(aomi): decommissioned migrated services
Removed services migrated to okinawa and sakhalin (Phase 5): - Harmonia binary cache, job-notify, nix-flake-updater - SearXNG metasearch engine - MicroShift, OpenShift port forwarding and nftables rules - Builder user and build execution script - All related age secrets and secret declarations - Removed aomi from substituters, kept okinawa as replacement aomi is now a lean laptop with core tools only.
1 parent 4754c31
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 ];