From aecfea098e17eaf5cd4a80fab440e0e29b12420c Mon Sep 17 00:00:00 2001 From: Matthew Harm Bekkema Date: Sat, 23 Nov 2019 19:07:06 +1100 Subject: [PATCH 1/2] nixos/upower: Allow customization of UPower.conf Documentation of options and default values taken from the upstream UPower.conf. The documentation was modified slightly to make more sense when displayed on https://nixos.org/nixos/options.html. A copy of upstream UPower.conf can be found here: https://cgit.freedesktop.org/upower/tree/etc/UPower.conf?id=28bd86c181e2510ef6a1dc7cfa26f97803698a79 --- nixos/doc/manual/release-notes/rl-2003.xml | 6 + nixos/modules/services/hardware/upower.nix | 184 +++++++++++++++++++++ 2 files changed, 190 insertions(+) diff --git a/nixos/doc/manual/release-notes/rl-2003.xml b/nixos/doc/manual/release-notes/rl-2003.xml index 6916fd225dac..645f7416ab11 100644 --- a/nixos/doc/manual/release-notes/rl-2003.xml +++ b/nixos/doc/manual/release-notes/rl-2003.xml @@ -77,6 +77,12 @@ be set if the hostname of the node should be non default. + + + UPower's configuration is now managed by NixOS and can be customized + via . + + diff --git a/nixos/modules/services/hardware/upower.nix b/nixos/modules/services/hardware/upower.nix index 5e7ac7a6e659..5713bfb15fd3 100644 --- a/nixos/modules/services/hardware/upower.nix +++ b/nixos/modules/services/hardware/upower.nix @@ -37,6 +37,172 @@ in ''; }; + enableWattsUpPro = mkOption { + type = types.bool; + default = false; + description = '' + Enable the Watts Up Pro device. + + The Watts Up Pro contains a generic FTDI USB device without a specific + vendor and product ID. When we probe for WUP devices, we can cause + the user to get a perplexing "Device or resource busy" error when + attempting to use their non-WUP device. + + The generic FTDI device is known to also be used on: + + + Sparkfun FT232 breakout board + Parallax Propeller + + ''; + }; + + noPollBatteries = mkOption { + type = types.bool; + default = false; + description = '' + Don't poll the kernel for battery level changes. + + Some hardware will send us battery level changes through + events, rather than us having to poll for it. This option + allows disabling polling for hardware that sends out events. + ''; + }; + + ignoreLid = mkOption { + type = types.bool; + default = false; + description = '' + Do we ignore the lid state + + Some laptops are broken. The lid state is either inverted, or stuck + on or off. We can't do much to fix these problems, but this is a way + for users to make the laptop panel vanish, a state that might be used + by a couple of user-space daemons. On Linux systems, see also + logind.conf(5). + ''; + }; + + usePercentageForPolicy = mkOption { + type = types.bool; + default = true; + description = '' + Policy for warnings and action based on battery levels + + Whether battery percentage based policy should be used. The default + is to use the percentage, which + should work around broken firmwares. It is also more reliable than + the time left (frantically saving all your files is going to use more + battery than letting it rest for example). + ''; + }; + + percentageLow = mkOption { + type = types.ints.unsigned; + default = 10; + description = '' + When usePercentageForPolicy is + true, the levels at which UPower will consider the + battery low. + + This will also be used for batteries which don't have time information + such as that of peripherals. + + If any value (of percentageLow, + percentageCritical and + percentageAction) is invalid, or not in descending + order, the defaults will be used. + ''; + }; + + percentageCritical = mkOption { + type = types.ints.unsigned; + default = 3; + description = '' + When usePercentageForPolicy is + true, the levels at which UPower will consider the + battery critical. + + This will also be used for batteries which don't have time information + such as that of peripherals. + + If any value (of percentageLow, + percentageCritical and + percentageAction) is invalid, or not in descending + order, the defaults will be used. + ''; + }; + + percentageAction = mkOption { + type = types.ints.unsigned; + default = 2; + description = '' + When usePercentageForPolicy is + true, the levels at which UPower will take action + for the critical battery level. + + This will also be used for batteries which don't have time information + such as that of peripherals. + + If any value (of percentageLow, + percentageCritical and + percentageAction) is invalid, or not in descending + order, the defaults will be used. + ''; + }; + + timeLow = mkOption { + type = types.ints.unsigned; + default = 1200; + description = '' + When usePercentageForPolicy is + false, the time remaining at which UPower will + consider the battery low. + + If any value (of timeLow, + timeCritical and timeAction) is + invalid, or not in descending order, the defaults will be used. + ''; + }; + + timeCritical = mkOption { + type = types.ints.unsigned; + default = 300; + description = '' + When usePercentageForPolicy is + false, the time remaining at which UPower will + consider the battery critical. + + If any value (of timeLow, + timeCritical and timeAction) is + invalid, or not in descending order, the defaults will be used. + ''; + }; + + timeAction = mkOption { + type = types.ints.unsigned; + default = 120; + description = '' + When usePercentageForPolicy is + false, the time remaining at which UPower will + take action for the critical battery level. + + If any value (of timeLow, + timeCritical and timeAction) is + invalid, or not in descending order, the defaults will be used. + ''; + }; + + criticalPowerAction = mkOption { + type = types.enum [ "PowerOff" "Hibernate" "HybridSleep" ]; + default = "HybridSleep"; + description = '' + The action to take when timeAction or + percentageAction has been reached for the batteries + (UPS or laptop batteries) supplying the computer + ''; + }; + }; }; @@ -54,6 +220,24 @@ in systemd.packages = [ cfg.package ]; + systemd.services.upower.environment.UPOWER_CONF_FILE_NAME = pkgs.writeTextFile { + name = "UPower.conf"; + text = generators.toINI {} { + UPower = { + EnableWattsUpPro = cfg.enableWattsUpPro; + NoPollBatteries = cfg.noPollBatteries; + IgnoreLid = cfg.ignoreLid; + UsePercentageForPolicy = cfg.usePercentageForPolicy; + PercentageLow = cfg.percentageLow; + PercentageCritical = cfg.percentageCritical; + PercentageAction = cfg.percentageAction; + TimeLow = cfg.timeLow; + TimeCritical = cfg.timeCritical; + TimeAction = cfg.timeAction; + CriticalPowerAction = cfg.criticalPowerAction; + }; + }; + }; }; } From f83a83f964a9894a837788d0253888187cfa4778 Mon Sep 17 00:00:00 2001 From: Matthew Harm Bekkema Date: Tue, 3 Dec 2019 20:50:42 +1100 Subject: [PATCH 2/2] upower: load config from /etc In the process of making UPower.conf customizable (#73968), it came up that UPower doesn't load its config from /etc by default. The UPower derivation is modified to make it load its config from /etc at runtime, but still install the default config to its nix store path as before. The UPower module is modified to put the config in /etc. --- nixos/modules/services/hardware/upower.nix | 29 ++++++++++------------ pkgs/os-specific/linux/upower/default.nix | 2 ++ 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/nixos/modules/services/hardware/upower.nix b/nixos/modules/services/hardware/upower.nix index 5713bfb15fd3..449810b53150 100644 --- a/nixos/modules/services/hardware/upower.nix +++ b/nixos/modules/services/hardware/upower.nix @@ -220,22 +220,19 @@ in systemd.packages = [ cfg.package ]; - systemd.services.upower.environment.UPOWER_CONF_FILE_NAME = pkgs.writeTextFile { - name = "UPower.conf"; - text = generators.toINI {} { - UPower = { - EnableWattsUpPro = cfg.enableWattsUpPro; - NoPollBatteries = cfg.noPollBatteries; - IgnoreLid = cfg.ignoreLid; - UsePercentageForPolicy = cfg.usePercentageForPolicy; - PercentageLow = cfg.percentageLow; - PercentageCritical = cfg.percentageCritical; - PercentageAction = cfg.percentageAction; - TimeLow = cfg.timeLow; - TimeCritical = cfg.timeCritical; - TimeAction = cfg.timeAction; - CriticalPowerAction = cfg.criticalPowerAction; - }; + environment.etc."UPower/UPower.conf".text = generators.toINI {} { + UPower = { + EnableWattsUpPro = cfg.enableWattsUpPro; + NoPollBatteries = cfg.noPollBatteries; + IgnoreLid = cfg.ignoreLid; + UsePercentageForPolicy = cfg.usePercentageForPolicy; + PercentageLow = cfg.percentageLow; + PercentageCritical = cfg.percentageCritical; + PercentageAction = cfg.percentageAction; + TimeLow = cfg.timeLow; + TimeCritical = cfg.timeCritical; + TimeAction = cfg.timeAction; + CriticalPowerAction = cfg.criticalPowerAction; }; }; }; diff --git a/pkgs/os-specific/linux/upower/default.nix b/pkgs/os-specific/linux/upower/default.nix index d787acae61b4..ab7f65925ee3 100644 --- a/pkgs/os-specific/linux/upower/default.nix +++ b/pkgs/os-specific/linux/upower/default.nix @@ -52,12 +52,14 @@ stdenv.mkDerivation { "--with-systemdsystemunitdir=${placeholder "out"}/etc/systemd/system" "--with-systemdutildir=${placeholder "out"}/lib/systemd" "--with-udevrulesdir=${placeholder "out"}/lib/udev/rules.d" + "--sysconfdir=/etc" ]; doCheck = false; # fails with "env: './linux/integration-test': No such file or directory" installFlags = [ "historydir=$(TMPDIR)/foo" + "sysconfdir=${placeholder "out"}/etc" ]; meta = with stdenv.lib; {