1 { config, lib, pkgs, ... }:
6 inherit (pkgs) glusterfs rsync;
8 tlsCmd = if (cfg.tlsSettings != null) then
10 mkdir -p /var/lib/glusterd
11 touch /var/lib/glusterd/secure-access
15 rm -f /var/lib/glusterd/secure-access
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
24 cfg = config.services.glusterfs;
34 services.glusterfs = {
36 enable = mkEnableOption (lib.mdDoc "GlusterFS Daemon");
39 type = types.enum ["DEBUG" "INFO" "WARNING" "ERROR" "CRITICAL" "TRACE" "NONE"];
40 description = lib.mdDoc "Log level used by the GlusterFS daemon";
44 useRpcbind = mkOption {
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.
57 enableGlustereventsd = mkOption {
59 description = lib.mdDoc "Whether to enable the GlusterFS Events Daemon";
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'.
77 default = "control-group";
80 stopKillTimeout = mkOption {
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.
95 extraFlags = mkOption {
96 type = types.listOf types.str;
97 description = lib.mdDoc "Extra flags passed to the GlusterFS daemon";
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/
113 type = types.nullOr (types.submodule {
115 tlsKeyPath = mkOption {
117 description = lib.mdDoc "Path to the private key used for TLS.";
122 description = lib.mdDoc "Path to the certificate used for TLS.";
127 description = lib.mdDoc "Path certificate authority used to sign the cluster certificates.";
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;
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";
159 install -m 0755 -d /var/log/glusterfs
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.
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/
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
172 mkdir -p /var/lib/glusterd/glusterfind/.keys
173 mkdir -p /var/lib/glusterd/hooks/1/delete/post/
178 ExecStart="${glusterfs}/sbin/glusterd --no-daemon --log-level=${cfg.logLevel} ${toString cfg.extraFlags}";
179 KillMode=cfg.killMode;
180 TimeoutStopSec=cfg.stopKillTimeout;
184 systemd.services.glustereventsd = mkIf cfg.enableGlustereventsd {
185 inherit restartTriggers;
187 description = "Gluster Events Notifier";
189 wantedBy = [ "multi-user.target" ];
191 after = [ "network.target" ];
194 install -m 0755 -d /var/log/glusterfs
197 # glustereventsd uses the `gluster` executable
198 path = [ glusterfs ];
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";