1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8 inherit (lib) mkIf mkOption types;
9
10 cfg = config.hardware.sensor.hddtemp;
11
12 wrapper = pkgs.writeShellScript "hddtemp-wrapper" ''
13 set -eEuo pipefail
14
15 file=/var/lib/hddtemp/hddtemp.db
16
17 drives=(${toString (map (e: ''$(realpath ${lib.escapeShellArg e}) '') cfg.drives)})
18
19 cp ${pkgs.hddtemp}/share/hddtemp/hddtemp.db $file
20 ${lib.concatMapStringsSep "\n" (e: "echo ${lib.escapeShellArg e} >> $file") cfg.dbEntries}
21
22 exec ${pkgs.hddtemp}/bin/hddtemp ${lib.escapeShellArgs cfg.extraArgs} \
23 --daemon \
24 --unit=${cfg.unit} \
25 --file=$file \
26 ''${drives[@]}
27 '';
28
29in
30{
31 meta.maintainers = with lib.maintainers; [ peterhoeg ];
32
33 ###### interface
34
35 options = {
36 hardware.sensor.hddtemp = {
37 enable = mkOption {
38 description = ''
39 Enable this option to support HDD/SSD temperature sensors.
40 '';
41 type = types.bool;
42 default = false;
43 };
44
45 drives = mkOption {
46 description = "List of drives to monitor. If you pass /dev/disk/by-path/* entries the symlinks will be resolved as hddtemp doesn't like names with colons.";
47 type = types.listOf types.str;
48 };
49
50 unit = mkOption {
51 description = "Celsius or Fahrenheit";
52 type = types.enum [
53 "C"
54 "F"
55 ];
56 default = "C";
57 };
58
59 dbEntries = mkOption {
60 description = "Additional DB entries";
61 type = types.listOf types.str;
62 default = [ ];
63 };
64
65 extraArgs = mkOption {
66 description = "Additional arguments passed to the daemon.";
67 type = types.listOf types.str;
68 default = [ ];
69 };
70 };
71 };
72
73 ###### implementation
74
75 config = mkIf cfg.enable {
76 systemd.services.hddtemp = {
77 description = "HDD/SSD temperature";
78 documentation = [ "man:hddtemp(8)" ];
79 wantedBy = [ "multi-user.target" ];
80 serviceConfig = {
81 Type = "forking";
82 ExecStart = wrapper;
83 StateDirectory = "hddtemp";
84 PrivateTmp = true;
85 ProtectHome = "tmpfs";
86 ProtectSystem = "strict";
87 };
88 };
89 };
90}