{ config, lib, pkgs, ... }: with lib; let vars = import ../vars.nix; cfg = config.services.nix_builder; runnerUsername = "gitea-runner"; runnerUserid = 601; runnerLabels = [ "self-hosted:host" "nixos:host" ]; containerConfig = { config, pkgs, lib, ... }: let runnerConfigFile = (pkgs.formats.yaml { }).generate "gitea-runner.yaml" { }; registerRunner = pkgs.writeShellApplication { name = "register-gitea-runner"; runtimeInputs = [ pkgs.coreutils pkgs.hostname config.services.gitea-actions-runner.package ]; text = builtins.readFile ./register_gitea_runner.sh; }; in { networking = { hostName = "nix-builder"; useDHCP = lib.mkDefault true; interfaces.eth0.useDHCP = true; # Ensure containers don't inherit the host's stub resolver (127.0.0.53) which was causing issues useHostResolvConf = false; }; nix.settings = { system-features = lib.mkAfter [ "gccarch-x86-64-v2" "gccarch-x86-64-v3" ]; trusted-substituters = [ "https://cache.nixos.org" "https://cache.tmmworkshop.com" "https://nix-community.cachix.org" ]; substituters = [ "https://cache.nixos.org/?priority=2&want-mass-query=true" "https://cache.tmmworkshop.com/?priority=2&want-mass-query=true" "https://nix-community.cachix.org/?priority=10&want-mass-query=true" ]; trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" "cache.tmmworkshop.com:jHffkpgbmEdstQPoihJPYW9TQe6jnQbWR2LqkNGV3iA=" "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" ]; experimental-features = [ "flakes" "nix-command" ]; sandbox = true; allowed-users = [ runnerUsername ]; trusted-users = [ "root" runnerUsername ]; }; users = { users.${runnerUsername} = { isSystemUser = true; group = runnerUsername; uid = runnerUserid; }; groups.${runnerUsername}.gid = runnerUserid; }; services.gitea-actions-runner.instances.builder = { enable = true; name = "jeeves-nix-builder"; url = "http://192.168.99.14:6443/"; labels = runnerLabels; tokenFile = "/run/secrets/gitea-runners/registration-token"; hostPackages = with pkgs; [ bash coreutils curl gawk gitMinimal gnused my_python nix nixfmt nixos-rebuild nodejs treefmt wget ]; }; systemd.services."gitea-runner-builder" = { serviceConfig = { DynamicUser = mkForce false; User = mkForce runnerUsername; Group = mkForce runnerUsername; ExecStartPre = mkForce [ "${getExe registerRunner} builder http://192.168.99.14:6443/ ${runnerConfigFile} ${escapeShellArgs runnerLabels}" ]; }; }; system.stateVersion = "24.05"; }; sharedContainerPath = (import "${pkgs.path}/nixos/lib/eval-config.nix" { modules = [ { boot.isNspawnContainer = true; nixpkgs.pkgs = pkgs; } containerConfig ]; system = null; }).config.system.build.toplevel; in { options.services.nix_builder = { bridgeName = mkOption { type = types.str; default = "br-nix-builder"; description = "Bridge name for the builder containers."; }; containers = mkOption { type = types.attrsOf ( types.submodule ( { name, ... }: { options.enable = mkEnableOption "Gitea runner container"; } ) ); default = { }; description = "Gitea runner container configurations"; }; }; config = { users = { users.${runnerUsername} = { isSystemUser = true; group = runnerUsername; uid = runnerUserid; }; groups.${runnerUsername}.gid = runnerUserid; }; containers = mapAttrs ( name: containerCfg: mkIf containerCfg.enable { path = sharedContainerPath; autoStart = true; privateNetwork = true; hostBridge = cfg.bridgeName; extraFlags = [ "--hostname=${name}" ]; bindMounts = { host-nix = { mountPoint = "/host-nix/var/nix/daemon-socket"; hostPath = "/nix/var/nix/daemon-socket"; isReadOnly = false; }; token = { hostPath = "${vars.secrets}/services/gitea-runners"; mountPoint = "/run/secrets/gitea-runners"; isReadOnly = true; }; uv-cache = { hostPath = vars.uv_cache; mountPoint = "/var/cache/uv"; isReadOnly = false; }; }; } ) cfg.containers; systemd = { services = builtins.listToAttrs ( map (name: { name = "container@${name}"; value = { requires = [ "gitea.service" ]; after = [ "gitea.service" ]; }; }) (builtins.attrNames (filterAttrs (_: c: c.enable) cfg.containers)) ); tmpfiles.rules = [ "d ${vars.uv_cache} 0755 ${runnerUsername} ${runnerUsername} - -" ]; }; }; }