Code change:
type = with types; attrsOf (submodule upsOptions); }; <ins> users = mkOption { default = {}; description = lib.mdDoc '' Users that can access upsd. See `man upsd.users`. ''; type = with types; attrsOf (submodule userOptions); }; </ins> }; }; config = mkIf cfg.enable { <ins> assertions = [ (let totalPowerValue = foldl' add 0 (map (monitor: monitor.powerValue) (attrValues cfg.upsmon.monitor)); minSupplies = cfg.upsmon.settings.MINSUPPLIES; in mkIf cfg.upsmon.enable { assertion = totalPowerValue >= minSupplies; message = '' `power.ups.upsmon`: Total configured power value (${toString totalPowerValue}) must be at least MINSUPPLIES (${toString minSupplies}). ''; }) ]; </ins> environment.systemPackages = [ pkgs.nut ]; <del> systemd.services.upsmon = { </del> <ins> networking.firewall = mkIf cfg.openFirewall { allowedTCPPorts = if cfg.upsd.listen == [] then [ defaultPort ] else unique (forEach cfg.upsd.listen (listen: listen.port)); }; systemd.services.upsmon = let secrets = mapAttrsToList (name: monitor: "upsmon_password_${name}") cfg.upsmon.monitor; createUpsmonConf = installSecrets upsmonConf "/run/nut/upsmon.conf" secrets; in { enable = cfg.upsmon.enable; </ins> description = "Uninterruptible Power Supplies (Monitor)"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; <del> serviceConfig.Type = "forking"; script = "${pkgs.nut}/sbin/upsmon"; environment.NUT_CONFPATH = "/etc/nut/"; environment.NUT_STATEPATH = "/var/lib/nut/"; </del> <ins> serviceConfig = { Type = "forking"; ExecStartPre = "${createUpsmonConf}"; ExecStart = "${pkgs.nut}/sbin/upsmon"; ExecReload = "${pkgs.nut}/sbin/upsmon -c reload"; LoadCredential = mapAttrsToList (name: monitor: "upsmon_password_${name}:${monitor.passwordFile}") cfg.upsmon.monitor; }; environment.NUT_CONFPATH = "/etc/nut"; environment.NUT_STATEPATH = "/var/lib/nut"; </ins> }; <del> systemd.services.upsd = { </del> <ins> systemd.services.upsd = let secrets = mapAttrsToList (name: user: "upsdusers_password_${name}") cfg.users; createUpsdUsers = installSecrets upsdUsers "/run/nut/upsd.users" secrets; in { enable = cfg.upsd.enable; </ins> description = "Uninterruptible Power Supplies (Daemon)"; after = [ "network.target" "upsmon.service" ]; wantedBy = [ "multi-user.target" ]; <del> serviceConfig.Type = "forking"; # TODO: replace 'root' by another username. script = "${pkgs.nut}/sbin/upsd -u root"; environment.NUT_CONFPATH = "/etc/nut/"; environment.NUT_STATEPATH = "/var/lib/nut/"; </del> <ins> serviceConfig = { Type = "forking"; ExecStartPre = "${createUpsdUsers}"; # TODO: replace 'root' by another username. ExecStart = "${pkgs.nut}/sbin/upsd -u root"; ExecReload = "${pkgs.nut}/sbin/upsd -c reload"; LoadCredential = mapAttrsToList (name: user: "upsdusers_password_${name}:${user.passwordFile}") cfg.users; }; environment.NUT_CONFPATH = "/etc/nut"; environment.NUT_STATEPATH = "/var/lib/nut"; restartTriggers = [ config.environment.etc."nut/upsd.conf".source ]; </ins> }; systemd.services.upsdrv = { <ins> enable = cfg.upsd.enable; </ins> description = "Uninterruptible Power Supplies (Register all UPS)"; after = [ "upsd.service" ]; wantedBy = [ "multi-user.target" ]; <del> # TODO: replace 'root' by another username. script = "${pkgs.nut}/bin/upsdrvctl -u root start"; </del> serviceConfig = { Type = "oneshot"; RemainAfterExit = true; <ins> # TODO: replace 'root' by another username. ExecStart = "${pkgs.nut}/bin/upsdrvctl -u root start"; </ins> }; <del> environment.NUT_CONFPATH = "/etc/nut/"; environment.NUT_STATEPATH = "/var/lib/nut/"; </del> <ins> environment.NUT_CONFPATH = "/etc/nut"; environment.NUT_STATEPATH = "/var/lib/nut"; </ins> }; environment.etc = {

Related discussion:
text: Describe the bug I'm trying to use NixOS in a UPS client (not server). When , the and services shouldn't be running. There is a note that says that is not used currently. To Reproduce Steps to reproduce the behavior: Error: and fail. Expected behavior only upsmon should be running Notify maintainers <!-- Please @ people who are in the list of the offending package or module. If in doubt, check for whoever last touched something. --Metadata Maintainer information: See also
Looks like there's a pretty simple workaround:
I marked this as stale due to inactivity. &rarr;