2024-04-16 06:10:04 +02:00
|
|
|
{ config, lib, ... }:
|
|
|
|
|
|
|
|
# TODO: make a remote-build user on nixos boxes, instead of giving access to pbsds
|
|
|
|
# TODO: https://exozy.me/quickstart
|
|
|
|
# TODO: https://github.com/winterqt/darwin-build-box
|
|
|
|
|
|
|
|
let
|
2024-07-31 21:35:42 +02:00
|
|
|
inherit (builtins) map fromTOML readFile elem attrNames attrValues;
|
2024-04-16 06:10:04 +02:00
|
|
|
inherit (lib) mkIf;
|
|
|
|
|
2024-10-07 11:22:08 +02:00
|
|
|
known-hosts' = lib.importTOML ../hosts/known-hosts.toml; # TODO: eww
|
2024-10-04 08:30:58 +02:00
|
|
|
known-hosts = lib.pipe known-hosts' [
|
2024-10-07 11:22:08 +02:00
|
|
|
(lib.flip lib.removeAttrs ["__default__"])
|
2024-04-16 06:10:04 +02:00
|
|
|
(lib.mapAttrs (name: host:
|
2024-10-04 08:30:58 +02:00
|
|
|
lib.recursiveUpdate (known-hosts'."__default__" or {}) host
|
2024-04-16 06:10:04 +02:00
|
|
|
))
|
|
|
|
];
|
2024-10-04 08:30:58 +02:00
|
|
|
hostNames = attrNames known-hosts;
|
|
|
|
thisHost = known-hosts.${config.networking.fqdn};
|
2024-10-07 11:22:08 +02:00
|
|
|
thisHostIsBuilder = thisHost.buildMachine.maxJobs > 0;
|
2024-10-04 08:30:58 +02:00
|
|
|
thisHostIsHopHost = builtins.elem config.networking.fqdn (lib.forEach (attrValues known-hosts) (host: host.ssh.proxyJump or null));
|
2024-07-10 01:12:00 +02:00
|
|
|
thisHostIsConsumer = thisHost.ssh ? userPublicKey;
|
2024-04-16 06:10:04 +02:00
|
|
|
|
|
|
|
mkRemoteConfig = fqdn: let
|
2024-10-04 08:30:58 +02:00
|
|
|
thatHost = known-hosts.${fqdn};
|
|
|
|
thatJump = known-hosts.${thatHost.ssh.proxyJump};
|
|
|
|
buildMachine = thatHost.buildMachine // {
|
2024-04-16 06:10:04 +02:00
|
|
|
hostName = fqdn;
|
2024-10-04 08:30:58 +02:00
|
|
|
sshUser = thatHost.ssh.listenUser;
|
2024-04-16 06:10:04 +02:00
|
|
|
};
|
2024-10-04 08:30:58 +02:00
|
|
|
thatHostIsBuilder = thatHost.buildMachine.maxJobs > 0;
|
|
|
|
thatHostIsConsumer = thatHost.ssh ? userPublicKey && thisHostIsBuilder;
|
|
|
|
thatHostIsThis = fqdn == config.networking.fqdn;
|
|
|
|
in mkIf (!thatHostIsThis) ( lib.mkMerge [
|
2024-04-16 06:10:04 +02:00
|
|
|
# out
|
2024-10-04 08:30:58 +02:00
|
|
|
(lib.mkIf (thisHostIsConsumer && thatHostIsBuilder) {
|
2024-07-10 00:34:38 +02:00
|
|
|
|
|
|
|
nix.buildMachines = [ buildMachine ];
|
2024-04-16 06:10:04 +02:00
|
|
|
|
2024-07-10 00:34:38 +02:00
|
|
|
})
|
|
|
|
# out or jump
|
2024-10-04 08:30:58 +02:00
|
|
|
(lib.mkIf (thisHostIsConsumer && thatHost.ssh ? listenPublicKey) {
|
|
|
|
programs.ssh.knownHosts.${fqdn}.publicKey = thatHost.ssh.listenPublicKey;
|
2024-07-31 01:57:47 +02:00
|
|
|
# TODO: use nix.buildMachines.*.publicHostKey ?
|
2024-04-16 06:10:04 +02:00
|
|
|
|
2024-08-18 03:16:17 +02:00
|
|
|
# timeouts are great when remote is unresponsive. nix doesn't care, lix is way and tests each remote only once
|
2024-07-10 00:34:38 +02:00
|
|
|
programs.ssh.extraConfig = ''
|
|
|
|
Host ${fqdn}
|
|
|
|
ConnectTimeout 3
|
2024-10-04 08:30:58 +02:00
|
|
|
Port ${builtins.toString thatHost.ssh.listenPort}
|
|
|
|
${lib.optionalString (thatHost.ssh ? proxyJump) ''
|
|
|
|
ProxyJump ${thatJump.ssh.listenUser}@${thatHost.ssh.proxyJump}:${builtins.toString thatJump.ssh.listenPort}
|
2024-07-10 00:34:38 +02:00
|
|
|
''}
|
2024-10-04 08:30:58 +02:00
|
|
|
${lib.optionalString (thatHost.ssh ? userPrivateKey) ''
|
|
|
|
IdentityFile ${thatHost.ssh.userPrivateKey}
|
2024-08-18 03:16:17 +02:00
|
|
|
''}
|
2024-07-10 00:34:38 +02:00
|
|
|
'';
|
2024-10-04 08:30:58 +02:00
|
|
|
|
|
|
|
sops.secrets = lib.mkIf (lib.hasPrefix "/run/secrets/" (thatHost.ssh.userPrivateKey or "")) {
|
2024-10-08 15:17:08 +02:00
|
|
|
"${lib.removePrefix "/run/secrets/" thatHost.ssh.userPrivateKey}" = {
|
|
|
|
mode = "0440";
|
|
|
|
group = "nix-community-builder";
|
|
|
|
};
|
2024-10-04 08:30:58 +02:00
|
|
|
};
|
2024-10-08 15:17:08 +02:00
|
|
|
users.groups.nix-community-builder = {};
|
|
|
|
|
2024-07-10 00:34:38 +02:00
|
|
|
})
|
2024-04-16 06:10:04 +02:00
|
|
|
# in
|
2024-10-04 08:30:58 +02:00
|
|
|
(mkIf ((thisHostIsBuilder || thisHostIsHopHost) && thatHostIsConsumer) {
|
2024-07-10 00:34:38 +02:00
|
|
|
users.users.${thisHost.ssh.listenUser} = {
|
2024-04-27 23:31:32 +02:00
|
|
|
isSystemUser = lib.mkDefault (!config.users.users.${thisHost.ssh.listenUser}.isNormalUser);
|
2024-10-04 08:30:58 +02:00
|
|
|
openssh.authorizedKeys.keys = [ thatHost.ssh.userPublicKey ];
|
2024-07-10 00:34:38 +02:00
|
|
|
group = lib.mkOptionDefault "nogroup";
|
2024-04-16 06:10:04 +02:00
|
|
|
};
|
2024-07-31 21:35:42 +02:00
|
|
|
})
|
2024-10-04 08:30:58 +02:00
|
|
|
(mkIf (thisHostIsBuilder && thatHostIsConsumer) {
|
2024-07-31 21:35:42 +02:00
|
|
|
nix.settings.allowed-users = [ thisHost.ssh.listenUser ];
|
|
|
|
nix.settings.trusted-users = [ thisHost.ssh.listenUser ];
|
2024-07-10 00:34:38 +02:00
|
|
|
})
|
|
|
|
]);
|
2024-04-16 06:10:04 +02:00
|
|
|
|
|
|
|
in {
|
|
|
|
|
|
|
|
nix.distributedBuilds = true;
|
|
|
|
|
|
|
|
# TODO: Allow setting speedFactor for local builds, as local is currently fixed to 0
|
|
|
|
# https://github.com/NixOS/nix/issues/2457
|
|
|
|
|
|
|
|
# useful when the builder has a faster internet connection than i do
|
|
|
|
nix.settings.builders-use-substitutes = true;
|
|
|
|
|
|
|
|
imports = lib.forEach hostNames mkRemoteConfig;
|
|
|
|
|
|
|
|
}
|