1 { config, lib, pkgs, ... }:
4 inInitrd = config.boot.initrd.supportedFilesystems.nfs or false;
6 nfsStateDir = "/var/lib/nfs";
8 rpcMountpoint = "${nfsStateDir}/rpc_pipefs";
10 format = pkgs.formats.ini {};
12 idmapdConfFile = format.generate "idmapd.conf" cfg.idmapd.settings;
14 # merge parameters from services.nfs.server
16 lib.optionalAttrs (cfg.server.nproc != null) {
17 nfsd.threads = cfg.server.nproc;
18 } // lib.optionalAttrs (cfg.server.hostName != null) {
19 nfsd.host = cfg.server.hostName;
20 } // lib.optionalAttrs (cfg.server.mountdPort != null) {
21 mountd.port = cfg.server.mountdPort;
22 } // lib.optionalAttrs (cfg.server.statdPort != null) {
23 statd.port = cfg.server.statdPort;
24 } // lib.optionalAttrs (cfg.server.lockdPort != null) {
25 lockd.port = cfg.server.lockdPort;
26 lockd.udp-port = cfg.server.lockdPort;
29 nfsConfDeprecated = cfg.extraConfig + ''
31 threads=${toString cfg.server.nproc}
32 ${lib.optionalString (cfg.server.hostName != null) "host=${cfg.server.hostName}"}
33 ${cfg.server.extraNfsdConfig}
36 ${lib.optionalString (cfg.server.mountdPort != null) "port=${toString cfg.server.mountdPort}"}
39 ${lib.optionalString (cfg.server.statdPort != null) "port=${toString cfg.server.statdPort}"}
42 ${lib.optionalString (cfg.server.lockdPort != null) ''
43 port=${toString cfg.server.lockdPort}
44 udp-port=${toString cfg.server.lockdPort}
50 then format.generate "nfs.conf" (lib.recursiveUpdate nfsConfSettings cfg.settings)
51 else pkgs.writeText "nfs.conf" nfsConfDeprecated;
53 requestKeyConfFile = pkgs.writeText "request-key.conf" ''
54 create id_resolver * * ${pkgs.nfs-utils}/bin/nfsidmap -t 600 %k %d
57 cfg = config.services.nfs;
66 idmapd.settings = lib.mkOption {
70 libnfsidmap configuration. Refer to
71 <https://linux.die.net/man/5/idmapd.conf>
74 example = lib.literalExpression ''
77 GSS-Methods = "static,nsswitch";
80 "root/hostname.domain.com@REALM.COM" = "root";
85 settings = lib.mkOption {
89 General configuration for NFS daemons and tools.
90 See nfs.conf(5) and related man pages for details.
92 example = lib.literalExpression ''
94 mountd.manage-gids = true;
98 extraConfig = lib.mkOption {
99 type = lib.types.lines;
102 Extra nfs-utils configuration.
108 ###### implementation
110 config = lib.mkIf (config.boot.supportedFilesystems.nfs or config.boot.supportedFilesystems.nfs4 or false) {
113 (lib.optional (cfg.extraConfig != "") ''
114 `services.nfs.extraConfig` is deprecated. Use `services.nfs.settings` instead.
115 '') ++ (lib.optional (cfg.server.extraNfsdConfig != "") ''
116 `services.nfs.server.extraNfsdConfig` is deprecated. Use `services.nfs.settings` instead.
119 assertion = cfg.settings != {} -> cfg.extraConfig == "" && cfg.server.extraNfsdConfig == "";
120 message = "`services.nfs.settings` cannot be used together with `services.nfs.extraConfig` and `services.nfs.server.extraNfsdConfig`.";
123 services.rpcbind.enable = true;
125 services.nfs.idmapd.settings = {
126 General = lib.mkMerge [
127 { Pipefs-Directory = rpcMountpoint; }
128 (lib.mkIf (config.networking.domain != null) { Domain = config.networking.domain; })
131 Nobody-User = "nobody";
132 Nobody-Group = "nogroup";
139 system.fsPackages = [ pkgs.nfs-utils ];
141 boot.initrd.kernelModules = lib.mkIf inInitrd [ "nfs" ];
143 systemd.packages = [ pkgs.nfs-utils ];
145 environment.systemPackages = [ pkgs.keyutils ];
148 "idmapd.conf".source = idmapdConfFile;
149 "nfs.conf".source = nfsConfFile;
150 "request-key.conf".source = requestKeyConfFile;
153 systemd.services.nfs-blkmap =
154 { restartTriggers = [ nfsConfFile ];
157 systemd.targets.nfs-client =
158 { wantedBy = [ "multi-user.target" "remote-fs.target" ];
161 systemd.services.nfs-idmapd =
162 { restartTriggers = [ idmapdConfFile ];
165 systemd.services.nfs-mountd =
166 { restartTriggers = [ nfsConfFile ];
167 enable = lib.mkDefault false;
170 systemd.services.nfs-server =
171 { restartTriggers = [ nfsConfFile ];
172 enable = lib.mkDefault false;
175 systemd.services.auth-rpcgss-module =
177 unitConfig.ConditionPathExists = [ "" "/etc/krb5.keytab" ];
180 systemd.services.rpc-gssd =
181 { restartTriggers = [ nfsConfFile ];
182 unitConfig.ConditionPathExists = [ "" "/etc/krb5.keytab" ];
185 systemd.services.rpc-statd =
186 { restartTriggers = [ nfsConfFile ];
190 mkdir -p /var/lib/nfs/{sm,sm.bak}