I have a little module that enables my remote builder, which I’ve used on a few NixOS machines to allow building on my relatively beefy server.
Today I decided to set up my M1 Mac to allow remote builds on this machine so I could hopefully have an easier time running x86_64-linux
-based tests on various PRs. (I’m setting up to use nixpkgs#darwin.builder
as well.) programs.ssh
doesn’t exist on nix-darwin, so I need to adapt my module to only include this part of the configuration on Linux hosts.
Unfortunately I’m again running into the dreaded "infinite recursion with config
" issues, of which there are many threads and SO posts.
I thought I was getting pretty good at this problem, but none of my usual tricks are working:
- I initially tried
inherit (pkgs.stdenv) isLinux
, and when it didn’t work read several threads aboutpkgs
depending onconfig
, so obviously I can’t change usepkgs
while definingconfig
. - A common suggestion (at least for the
pkgs.stdenv.isLinux
issues in home-manager) is makingisLinux ? false
a passed in argument from the parent config, but I still get infinite recursion (orattribute missing
if I changeoptionalAttrs
tomkIf
) - As a test, I tried removing the
${config.age.secrets...
line, but still get infinite recursion - I really thought it would work if I just made it a configuration option, which is the version I’m including below, but I still get infinite recursion.
- Also tried swapping out
optionalAttrs
formkIf
, which then gets me back toerror: The option 'programs.ssh.extraConfig' does not exist.
(even if I configure as false and set the default tofalse
)
I’m sure there’s some fundamental concept I’m missing here. Why am I unable to configure this module based on the host OS?
{
pkgs,
config,
lib,
...
}: let
service_name = "use_builder";
cfg = config.services.${service_name};
in
with lib; {
options.services.${service_name} = {
enable = mkEnableOption service_name;
isLinux = mkOption {
type = types.bool;
description = "Is this a Linux machine?";
default = true;
};
};
config = mkIf cfg.enable (mkMerge [
{
age.secrets.builder_id_ed25519.file = ../secrets/builder_id_ed25519.age;
nix = {
buildMachines = [
{
hostName = "builder";
systems = ["aarch64-linux" "x86_64-linux"];
maxJobs = 12;
speedFactor = 2;
}
];
distributedBuilds = true;
};
}
(optionalAttrs cfg.isLinux {
programs.ssh.extraConfig = ''
Host builder
hostName myBuilderMachine.home.arpa
User builder
Port 2222
IdentityFile = ${config.age.secrets.builder_id_ed25519.path}
'';
})
]);
Happy to include the full trace if helpful, this is the abbreviated version:
at /nix/store/k90rk91pfcfl5cajsgi5pnvxkwfi77p1-source/lib/modules.nix:483:28:
482| builtins.addErrorContext (context name)
483| (args.${name} or config._module.args.${name})
| ^
484| ) (lib.functionArgs f);