This repository has no description
Something went wrong. Try again.
5.1 kB · 160 lines
Nix
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161{ config, pkgs, lib, otherHosts, ...}:let cfg = config.sidonia; forEachOtherHost = f: map f otherHosts;in{ options.sidonia.services.distributedBuilds = with lib; { host = { enable = mkEnableOption "Enable becoming a distributed build host"; user = mkOption { type = types.str; default = "builder"; }; signing = { pubKey = mkOption { description = "Public key for store binary cache signing"; type = types.str; }; privKeyPath = mkOption { description = "Path to private cache signing key"; type = types.path; }; }; ssh.pubKey = mkOption { description = "known_hosts public key"; type = types.str; }; hostNames = mkOption { description = "Hostnames or ip addresses of the build host"; type = types.listOf types.str; }; maxJobs = mkOption { description = "Maximum amount of jobs to accept from a single client"; type = types.either types.int (types.enum [ "auto" ]); default = config.nix.settings.max-jobs; }; }; client = { enable = mkEnableOption "Enable taking advantage of distributed builds"; ssh = { pubKey = mkOption { type = types.str; default = cfg.ssh.pubKey; }; privKeyPath = mkOption { type = types.path; default = cfg.ssh.privKeyPath; }; }; }; };
config = let host = cfg.services.distributedBuilds.host; client = cfg.services.distributedBuilds.client; in lib.mkMerge [ (lib.mkIf client.enable ( lib.mkMerge ( (forEachOtherHost ( remote: let remoteHost = remote.config.sidonia.services.distributedBuilds.host; builderName = "${remoteHost.user}_at_${remote.config.networking.hostName}"; substituterName = "substituter_at_${remote.config.networking.hostName}"; hostName = builtins.head remoteHost.hostNames; in lib.mkIf remoteHost.enable { programs.ssh = { knownHosts = { ${builderName} = { extraHostNames = remoteHost.hostNames; publicKey = remoteHost.ssh.pubKey; }; }; extraConfig = '' Host ${substituterName} User nix-ssh Hostname ${hostName} IdentitiesOnly yes IdentityFile ${client.ssh.privKeyPath} ConnectTimeout 3 ''; }; nix = { settings = { trusted-public-keys = [ remoteHost.signing.pubKey ]; substituters = [ "${remote.config.nix.sshServe.protocol}://${substituterName}" ]; }; buildMachines = [ ( { inherit hostName; sshUser = remoteHost.user; sshKey = client.ssh.privKeyPath; #publicHostKey = remoteHost.ssh.pubKey; # don't use this value as it wants base64, fall back to known_hosts instead systems = [ "x86_64-linux" "i686-linux" ]; protocol = "ssh-ng"; speedFactor = 2; supportedFeatures = remote.config.nix.settings.system-features; } // (if remoteHost.maxJobs != "auto" then { inherit (remoteHost) maxJobs; } else { }) ) ]; }; } )) ++ [ { nix.distributedBuilds = true; nix.settings.builders-use-substitutes = true; } ] ) )) (lib.mkIf host.enable ( lib.mkMerge ( (forEachOtherHost ( remote: let remoteCfg = remote.config.sidonia.services.distributedBuilds; in lib.mkIf remoteCfg.client.enable { users.users.${host.user}.openssh.authorizedKeys.keys = [ remoteCfg.client.ssh.pubKey ]; nix.sshServe.keys = [ remoteCfg.client.ssh.pubKey ]; } )) ++ [ { users.users.${host.user}.isNormalUser = true; services.openssh.settings.AllowUsers = [ host.user "nix-ssh" ]; nix.settings.secret-key-files = host.signing.privKeyPath; nix.settings.trusted-users = [ host.user ]; nix.sshServe = { enable = true; write = true; trusted = true; protocol = "ssh-ng"; }; } ] ) )) ];}