python3Packages.orjson: Disable failing tests on 32 bit
[NixPkgs.git] / nixos / modules / services / misc / bees.nix
blob37f90c682221acf6f61e9dc0546a5a3153da7cf0
1 { config, lib, pkgs, ... }:
3 with lib;
5 let
7   cfg = config.services.beesd;
9   logLevels = { emerg = 0; alert = 1; crit = 2; err = 3; warning = 4; notice = 5; info = 6; debug = 7; };
11   fsOptions = with types; {
12     options.spec = mkOption {
13       type = str;
14       description = lib.mdDoc ''
15         Description of how to identify the filesystem to be duplicated by this
16         instance of bees. Note that deduplication crosses subvolumes; one must
17         not configure multiple instances for subvolumes of the same filesystem
18         (or block devices which are part of the same filesystem), but only for
19         completely independent btrfs filesystems.
21         This must be in a format usable by findmnt; that could be a key=value
22         pair, or a bare path to a mount point.
23         Using bare paths will allow systemd to start the beesd service only
24         after mounting the associated path.
25       '';
26       example = "LABEL=MyBulkDataDrive";
27     };
28     options.hashTableSizeMB = mkOption {
29       type = types.addCheck types.int (n: mod n 16 == 0);
30       default = 1024; # 1GB; default from upstream beesd script
31       description = lib.mdDoc ''
32         Hash table size in MB; must be a multiple of 16.
34         A larger ratio of index size to storage size means smaller blocks of
35         duplicate content are recognized.
37         If you have 1TB of data, a 4GB hash table (which is to say, a value of
38         4096) will permit 4KB extents (the smallest possible size) to be
39         recognized, whereas a value of 1024 -- creating a 1GB hash table --
40         will recognize only aligned duplicate blocks of 16KB.
41       '';
42     };
43     options.verbosity = mkOption {
44       type = types.enum (attrNames logLevels ++ attrValues logLevels);
45       apply = v: if isString v then logLevels.${v} else v;
46       default = "info";
47       description = lib.mdDoc "Log verbosity (syslog keyword/level).";
48     };
49     options.workDir = mkOption {
50       type = str;
51       default = ".beeshome";
52       description = lib.mdDoc ''
53         Name (relative to the root of the filesystem) of the subvolume where
54         the hash table will be stored.
55       '';
56     };
57     options.extraOptions = mkOption {
58       type = listOf str;
59       default = [ ];
60       description = lib.mdDoc ''
61         Extra command-line options passed to the daemon. See upstream bees documentation.
62       '';
63       example = literalExpression ''
64         [ "--thread-count" "4" ]
65       '';
66     };
67   };
72   options.services.beesd = {
73     filesystems = mkOption {
74       type = with types; attrsOf (submodule fsOptions);
75       description = lib.mdDoc "BTRFS filesystems to run block-level deduplication on.";
76       default = { };
77       example = literalExpression ''
78         {
79           root = {
80             spec = "LABEL=root";
81             hashTableSizeMB = 2048;
82             verbosity = "crit";
83             extraOptions = [ "--loadavg-target" "5.0" ];
84           };
85         }
86       '';
87     };
88   };
89   config = {
90     systemd.services = mapAttrs'
91       (name: fs: nameValuePair "beesd@${name}" {
92         description = "Block-level BTRFS deduplication for %i";
93         after = [ "sysinit.target" ];
95         serviceConfig =
96           let
97             configOpts = [
98               fs.spec
99               "verbosity=${toString fs.verbosity}"
100               "idxSizeMB=${toString fs.hashTableSizeMB}"
101               "workDir=${fs.workDir}"
102             ];
103             configOptsStr = escapeShellArgs configOpts;
104           in
105           {
106             # Values from https://github.com/Zygo/bees/blob/v0.6.5/scripts/beesd@.service.in
107             ExecStart = "${pkgs.bees}/bin/bees-service-wrapper run ${configOptsStr} -- --no-timestamps ${escapeShellArgs fs.extraOptions}";
108             ExecStopPost = "${pkgs.bees}/bin/bees-service-wrapper cleanup ${configOptsStr}";
109             CPUAccounting = true;
110             CPUSchedulingPolicy = "batch";
111             CPUWeight = 12;
112             IOSchedulingClass = "idle";
113             IOSchedulingPriority = 7;
114             IOWeight = 10;
115             KillMode = "control-group";
116             KillSignal = "SIGTERM";
117             MemoryAccounting = true;
118             Nice = 19;
119             Restart = "on-abnormal";
120             StartupCPUWeight = 25;
121             StartupIOWeight = 25;
122             SyslogIdentifier = "beesd"; # would otherwise be "bees-service-wrapper"
123           };
124         unitConfig.RequiresMountsFor = lib.mkIf (lib.hasPrefix "/" fs.spec) fs.spec;
125         wantedBy = [ "multi-user.target" ];
126       })
127       cfg.filesystems;
128   };