nixos/preload: init
[NixPkgs.git] / nixos / modules / services / network-filesystems / glusterfs.nix
blobee03bada492dc9ce204426c51ea342943ce72db7
1 { config, lib, pkgs, ... }:
3 with lib;
5 let
6   inherit (pkgs) glusterfs rsync;
8   tlsCmd = if (cfg.tlsSettings != null) then
9   ''
10     mkdir -p /var/lib/glusterd
11     touch /var/lib/glusterd/secure-access
12   ''
13   else
14   ''
15     rm -f /var/lib/glusterd/secure-access
16   '';
18   restartTriggers = optionals (cfg.tlsSettings != null) [
19     config.environment.etc."ssl/glusterfs.pem".source
20     config.environment.etc."ssl/glusterfs.key".source
21     config.environment.etc."ssl/glusterfs.ca".source
22   ];
24   cfg = config.services.glusterfs;
30   ###### interface
32   options = {
34     services.glusterfs = {
36       enable = mkEnableOption (lib.mdDoc "GlusterFS Daemon");
38       logLevel = mkOption {
39         type = types.enum ["DEBUG" "INFO" "WARNING" "ERROR" "CRITICAL" "TRACE" "NONE"];
40         description = lib.mdDoc "Log level used by the GlusterFS daemon";
41         default = "INFO";
42       };
44       useRpcbind = mkOption {
45         type = types.bool;
46         description = lib.mdDoc ''
47           Enable use of rpcbind. This is required for Gluster's NFS functionality.
49           You may want to turn it off to reduce the attack surface for DDoS reflection attacks.
51           See https://davelozier.com/glusterfs-and-rpcbind-portmap-ddos-reflection-attacks/
52           and https://bugzilla.redhat.com/show_bug.cgi?id=1426842 for details.
53         '';
54         default = true;
55       };
57       enableGlustereventsd = mkOption {
58         type = types.bool;
59         description = lib.mdDoc "Whether to enable the GlusterFS Events Daemon";
60         default = true;
61       };
63       killMode = mkOption {
64         type = types.enum ["control-group" "process" "mixed" "none"];
65         description = lib.mdDoc ''
66           The systemd KillMode to use for glusterd.
68           glusterd spawns other daemons like gsyncd.
69           If you want these to stop when glusterd is stopped (e.g. to ensure
70           that NixOS config changes are reflected even for these sub-daemons),
71           set this to 'control-group'.
72           If however you want running volume processes (glusterfsd) and thus
73           gluster mounts not be interrupted when glusterd is restarted
74           (for example, when you want to restart them manually at a later time),
75           set this to 'process'.
76         '';
77         default = "control-group";
78       };
80       stopKillTimeout = mkOption {
81         type = types.str;
82         description = lib.mdDoc ''
83           The systemd TimeoutStopSec to use.
85           After this time after having been asked to shut down, glusterd
86           (and depending on the killMode setting also its child processes)
87           are killed by systemd.
89           The default is set low because GlusterFS (as of 3.10) is known to
90           not tell its children (like gsyncd) to terminate at all.
91         '';
92         default = "5s";
93       };
95       extraFlags = mkOption {
96         type = types.listOf types.str;
97         description = lib.mdDoc "Extra flags passed to the GlusterFS daemon";
98         default = [];
99       };
101       tlsSettings = mkOption {
102         description = lib.mdDoc ''
103           Make the server communicate via TLS.
104           This means it will only connect to other gluster
105           servers having certificates signed by the same CA.
107           Enabling this will create a file {file}`/var/lib/glusterd/secure-access`.
108           Disabling will delete this file again.
110           See also: https://gluster.readthedocs.io/en/latest/Administrator%20Guide/SSL/
111         '';
112         default = null;
113         type = types.nullOr (types.submodule {
114           options = {
115             tlsKeyPath = mkOption {
116               type = types.str;
117               description = lib.mdDoc "Path to the private key used for TLS.";
118             };
120             tlsPem = mkOption {
121               type = types.path;
122               description = lib.mdDoc "Path to the certificate used for TLS.";
123             };
125             caCert = mkOption {
126               type = types.path;
127               description = lib.mdDoc "Path certificate authority used to sign the cluster certificates.";
128             };
129           };
130         });
131       };
132     };
133   };
135   ###### implementation
137   config = mkIf cfg.enable {
138     environment.systemPackages = [ pkgs.glusterfs ];
140     services.rpcbind.enable = cfg.useRpcbind;
142     environment.etc = mkIf (cfg.tlsSettings != null) {
143       "ssl/glusterfs.pem".source = cfg.tlsSettings.tlsPem;
144       "ssl/glusterfs.key".source = cfg.tlsSettings.tlsKeyPath;
145       "ssl/glusterfs.ca".source = cfg.tlsSettings.caCert;
146     };
148     systemd.services.glusterd = {
149       inherit restartTriggers;
151       description = "GlusterFS, a clustered file-system server";
153       wantedBy = [ "multi-user.target" ];
155       requires = lib.optional cfg.useRpcbind "rpcbind.service";
156       after = [ "network.target" ] ++ lib.optional cfg.useRpcbind "rpcbind.service";
158       preStart = ''
159         install -m 0755 -d /var/log/glusterfs
160       ''
161       # The copying of hooks is due to upstream bug https://bugzilla.redhat.com/show_bug.cgi?id=1452761
162       # Excludes one hook due to missing SELinux binaries.
163       + ''
164         mkdir -p /var/lib/glusterd/hooks/
165         ${rsync}/bin/rsync -a --exclude="S10selinux-label-brick.sh" ${glusterfs}/var/lib/glusterd/hooks/ /var/lib/glusterd/hooks/
167         ${tlsCmd}
168       ''
169       # `glusterfind` needs dirs that upstream installs at `make install` phase
170       # https://github.com/gluster/glusterfs/blob/v3.10.2/tools/glusterfind/Makefile.am#L16-L17
171       + ''
172         mkdir -p /var/lib/glusterd/glusterfind/.keys
173         mkdir -p /var/lib/glusterd/hooks/1/delete/post/
174       '';
176       serviceConfig = {
177         LimitNOFILE=65536;
178         ExecStart="${glusterfs}/sbin/glusterd --no-daemon --log-level=${cfg.logLevel} ${toString cfg.extraFlags}";
179         KillMode=cfg.killMode;
180         TimeoutStopSec=cfg.stopKillTimeout;
181       };
182     };
184     systemd.services.glustereventsd = mkIf cfg.enableGlustereventsd {
185       inherit restartTriggers;
187       description = "Gluster Events Notifier";
189       wantedBy = [ "multi-user.target" ];
191       after = [ "network.target" ];
193       preStart = ''
194         install -m 0755 -d /var/log/glusterfs
195       '';
197       # glustereventsd uses the `gluster` executable
198       path = [ glusterfs ];
200       serviceConfig = {
201         Type="simple";
202         PIDFile="/run/glustereventsd.pid";
203         ExecStart="${glusterfs}/sbin/glustereventsd --pid-file /run/glustereventsd.pid";
204         ExecReload="/bin/kill -SIGUSR2 $MAINPID";
205         KillMode="control-group";
206       };
207     };
208   };