diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index 825b1c5bd407..0ff436c3f50b 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -20,6 +20,8 @@ - [mautrix-whatsapp](https://docs.mau.fi/bridges/go/whatsapp/index.html) A Matrix-WhatsApp puppeting bridge +- [hddfancontrol](https://github.com/desbma/hddfancontrol), a service to regulate fan speeds based on hard drive temperature. Available as [services.hddfancontrol](#opt-services.hddfancontrol.enable). + - [GoToSocial](https://gotosocial.org/), an ActivityPub social network server, written in Golang. Available as [services.gotosocial](#opt-services.gotosocial.enable). - [Typesense](https://github.com/typesense/typesense), a fast, typo-tolerant search engine for building delightful search experiences. Available as [services.typesense](#opt-services.typesense.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 97b8f61e1e70..01614762313c 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -505,6 +505,7 @@ ./services/hardware/fancontrol.nix ./services/hardware/freefall.nix ./services/hardware/fwupd.nix + ./services/hardware/hddfancontrol.nix ./services/hardware/illum.nix ./services/hardware/interception-tools.nix ./services/hardware/irqbalance.nix diff --git a/nixos/modules/services/hardware/hddfancontrol.nix b/nixos/modules/services/hardware/hddfancontrol.nix new file mode 100644 index 000000000000..463f63cc4940 --- /dev/null +++ b/nixos/modules/services/hardware/hddfancontrol.nix @@ -0,0 +1,67 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.hddfancontrol; + types = lib.types; +in + +{ + options = { + + services.hddfancontrol.enable = lib.mkEnableOption "hddfancontrol daemon"; + + services.hddfancontrol.disks = lib.mkOption { + type = with types; listOf path; + default = []; + description = lib.mdDoc '' + Drive(s) to get temperature from + ''; + example = ["/dev/sda"]; + }; + + services.hddfancontrol.pwmPaths = lib.mkOption { + type = with types; listOf path; + default = []; + description = lib.mdDoc '' + PWM filepath(s) to control fan speed (under /sys) + ''; + example = ["/sys/class/hwmon/hwmon2/pwm1"]; + }; + + services.hddfancontrol.smartctl = lib.mkOption { + type = types.bool; + default = false; + description = lib.mdDoc '' + Probe temperature using smartctl instead of hddtemp or hdparm + ''; + }; + + services.hddfancontrol.extraArgs = lib.mkOption { + type = with types; listOf str; + default = []; + description = lib.mdDoc '' + Extra commandline arguments for hddfancontrol + ''; + example = ["--pwm-start-value=32" + "--pwm-stop-value=0" + "--spin-down-time=900"]; + }; + }; + + config = lib.mkIf cfg.enable ( + let args = lib.concatLists [ + ["-d"] cfg.disks + ["-p"] cfg.pwmPaths + (lib.optional cfg.smartctl "--smartctl") + cfg.extraArgs + ]; in { + systemd.packages = [pkgs.hddfancontrol]; + + systemd.services.hddfancontrol = { + enable = true; + wantedBy = [ "multi-user.target" ]; + environment.HDDFANCONTROL_ARGS = lib.escapeShellArgs args; + }; + } + ); +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 23a4e41bb3f4..e07dc54b7981 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -341,6 +341,7 @@ in { hbase2 = handleTest ./hbase.nix { package=pkgs.hbase2; }; hbase_2_4 = handleTest ./hbase.nix { package=pkgs.hbase_2_4; }; hbase3 = handleTest ./hbase.nix { package=pkgs.hbase3; }; + hddfancontrol = handleTest ./hddfancontrol.nix {}; hedgedoc = handleTest ./hedgedoc.nix {}; herbstluftwm = handleTest ./herbstluftwm.nix {}; homepage-dashboard = handleTest ./homepage-dashboard.nix {}; diff --git a/nixos/tests/hddfancontrol.nix b/nixos/tests/hddfancontrol.nix new file mode 100644 index 000000000000..b5fa7ccb2c19 --- /dev/null +++ b/nixos/tests/hddfancontrol.nix @@ -0,0 +1,44 @@ +import ./make-test-python.nix ({ pkgs, ... }: { + name = "hddfancontrol"; + meta = with pkgs.lib.maintainers; { + maintainers = [ benley ]; + }; + + nodes.machine = { ... }: { + imports = [ ../modules/profiles/minimal.nix ]; + + services.hddfancontrol.enable = true; + services.hddfancontrol.disks = ["/dev/vda"]; + services.hddfancontrol.pwmPaths = ["/test/hwmon1/pwm1"]; + services.hddfancontrol.extraArgs = ["--pwm-start-value=32" + "--pwm-stop-value=0"]; + + systemd.services.hddfancontrol_fixtures = { + description = "Install test fixtures for hddfancontrol"; + serviceConfig = { + Type = "oneshot"; + }; + script = '' + mkdir -p /test/hwmon1 + echo 255 > /test/hwmon1/pwm1 + echo 2 > /test/hwmon1/pwm1_enable + ''; + wantedBy = ["hddfancontrol.service"]; + before = ["hddfancontrol.service"]; + }; + + systemd.services.hddfancontrol.serviceConfig.ReadWritePaths = "/test"; + }; + + # hddfancontrol.service will fail to start because qemu /dev/vda doesn't have + # any thermal interfaces, but it should ensure that fans appear to be running + # before it aborts. + testScript = '' + start_all() + machine.wait_for_unit("multi-user.target") + machine.succeed("journalctl -eu hddfancontrol.service|grep 'Setting fan speed'") + machine.shutdown() + + ''; + +})