From a6c7a5b4b5f7df210bbe079fa649dc96e0f8518f Mon Sep 17 00:00:00 2001 From: Alois Wohlschlager Date: Mon, 8 Dec 2025 17:25:16 +0100 Subject: [PATCH] nixos/lix: init Over time, it is expected that the setups for Lix and Nix will diverge in some ways. To prevent cluttering the modules too much, we will introduce a separate Lix module. It begins its existence as a fork of the nix-daemon module, right now without major changes, although this will change soon. It is also slightly weird due to not having any option definitions on its own and instead dispatching on the pname of `nix.package`, which is done for backwards compatibility (particularly on 25.11), and will also change soon by the gradual introduction of a separate `programs.lix` option subtree. --- nixos/modules/module-list.nix | 1 + nixos/modules/programs/lix.nix | 115 +++++++++++++++++++ nixos/modules/services/system/nix-daemon.nix | 2 +- 3 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 nixos/modules/programs/lix.nix diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 2df1045248b5..7dd29a7dafff 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -256,6 +256,7 @@ ./programs/less.nix ./programs/liboping.nix ./programs/light.nix + ./programs/lix.nix ./programs/localsend.nix ./programs/mdevctl.nix ./programs/mepo.nix diff --git a/nixos/modules/programs/lix.nix b/nixos/modules/programs/lix.nix new file mode 100644 index 000000000000..7499121b862a --- /dev/null +++ b/nixos/modules/programs/lix.nix @@ -0,0 +1,115 @@ +{ + config, + lib, + pkgs, + ... +}: +let + + cfg = config.nix; + + nixPackage = cfg.package.out; + + makeNixBuildUser = nr: { + name = "nixbld${toString nr}"; + value = { + description = "Lix build user ${toString nr}"; + uid = builtins.add config.ids.uids.nixbld nr; + isSystemUser = true; + group = "nixbld"; + extraGroups = [ "nixbld" ]; + }; + }; + + nixbldUsers = lib.listToAttrs (map makeNixBuildUser (lib.range 1 cfg.nrBuildUsers)); + +in + +{ + config = lib.mkIf (cfg.enable && nixPackage.pname == "lix") { + environment.systemPackages = [ + nixPackage + pkgs.nix-info + ] + ++ lib.optional (config.programs.bash.completion.enable) pkgs.nix-bash-completions; + + systemd.packages = [ nixPackage ]; + + systemd.tmpfiles.packages = [ nixPackage ]; + + systemd.sockets.nix-daemon.wantedBy = [ "sockets.target" ]; + + systemd.services.nix-daemon = { + path = [ + nixPackage + config.programs.ssh.package + ]; + + environment = + cfg.envVars + // { + CURL_CA_BUNDLE = config.security.pki.caBundle; + } + // config.networking.proxy.envVars; + + serviceConfig = { + CPUSchedulingPolicy = cfg.daemonCPUSchedPolicy; + IOSchedulingClass = cfg.daemonIOSchedClass; + IOSchedulingPriority = cfg.daemonIOSchedPriority; + }; + + restartTriggers = [ config.environment.etc."nix/nix.conf".source ]; + + # `stopIfChanged = false` changes to switch behavior + # from stop -> update units -> start + # to update units -> restart + # + # The `stopIfChanged` setting therefore controls a trade-off between a + # more predictable lifecycle, which runs the correct "version" of + # the `ExecStop` line, and on the other hand the availability of + # sockets during the switch, as the effectiveness of the stop operation + # depends on the socket being stopped as well. + # + # As `nix-daemon.service` does not make use of `ExecStop`, we prefer + # to keep the socket up and available. This is important for machines + # that run Nix-based services, such as automated build, test, and deploy + # services, that expect the daemon socket to be available at all times. + # + # Notably, the Nix client does not retry on failure to connect to the + # daemon socket, and the in-process RemoteStore instance will disable + # itself. This makes retries infeasible even for services that are + # aware of the issue. Failure to connect can affect not only new client + # processes, but also new RemoteStore instances in existing processes, + # as well as existing RemoteStore instances that have not saturated + # their connection pool. + # + # Also note that `stopIfChanged = true` does not kill existing + # connection handling daemons, as one might wish to happen before a + # breaking Nix upgrade (which is rare). The daemon forks that handle + # the individual connections split off into their own sessions, causing + # them not to be stopped by systemd. + # If a Nix upgrade does require all existing daemon processes to stop, + # nix-daemon must do so on its own accord, and only when the new version + # starts and detects that Nix's persistent state needs an upgrade. + stopIfChanged = false; + + }; + + # Set up the environment variables for running Nix. + environment.sessionVariables = cfg.envVars; + + nix.nrBuildUsers = lib.mkDefault ( + if cfg.settings.auto-allocate-uids or false then + 0 + else + lib.max 32 (if cfg.settings.max-jobs == "auto" then 0 else cfg.settings.max-jobs) + ); + + users.users = nixbldUsers; + + services.displayManager.hiddenUsers = lib.attrNames nixbldUsers; + + # Legacy configuration conversion. + nix.settings.sandbox-fallback = false; + }; +} diff --git a/nixos/modules/services/system/nix-daemon.nix b/nixos/modules/services/system/nix-daemon.nix index 9c3fba3f6dba..ef740b9ba8d9 100644 --- a/nixos/modules/services/system/nix-daemon.nix +++ b/nixos/modules/services/system/nix-daemon.nix @@ -183,7 +183,7 @@ in ###### implementation - config = lib.mkIf cfg.enable { + config = lib.mkIf (cfg.enable && nixPackage.pname != "lix") { environment.systemPackages = [ nixPackage pkgs.nix-info