at 24.11-pre 5.4 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 inInitrd = config.boot.initrd.supportedFilesystems.nfs or false; 8 9 nfsStateDir = "/var/lib/nfs"; 10 11 rpcMountpoint = "${nfsStateDir}/rpc_pipefs"; 12 13 format = pkgs.formats.ini {}; 14 15 idmapdConfFile = format.generate "idmapd.conf" cfg.idmapd.settings; 16 17 # merge parameters from services.nfs.server 18 nfsConfSettings = 19 optionalAttrs (cfg.server.nproc != null) { 20 nfsd.threads = cfg.server.nproc; 21 } // optionalAttrs (cfg.server.hostName != null) { 22 nfsd.host= cfg.hostName; 23 } // optionalAttrs (cfg.server.mountdPort != null) { 24 mountd.port = cfg.server.mountdPort; 25 } // optionalAttrs (cfg.server.statdPort != null) { 26 statd.port = cfg.server.statdPort; 27 } // optionalAttrs (cfg.server.lockdPort != null) { 28 lockd.port = cfg.server.lockdPort; 29 lockd.udp-port = cfg.server.lockdPort; 30 }; 31 32 nfsConfDeprecated = cfg.extraConfig + '' 33 [nfsd] 34 threads=${toString cfg.server.nproc} 35 ${optionalString (cfg.server.hostName != null) "host=${cfg.server.hostName}"} 36 ${cfg.server.extraNfsdConfig} 37 38 [mountd] 39 ${optionalString (cfg.server.mountdPort != null) "port=${toString cfg.server.mountdPort}"} 40 41 [statd] 42 ${optionalString (cfg.server.statdPort != null) "port=${toString cfg.server.statdPort}"} 43 44 [lockd] 45 ${optionalString (cfg.server.lockdPort != null) '' 46 port=${toString cfg.server.lockdPort} 47 udp-port=${toString cfg.server.lockdPort} 48 ''} 49 ''; 50 51 nfsConfFile = 52 if cfg.settings != {} 53 then format.generate "nfs.conf" (recursiveUpdate nfsConfSettings cfg.settings) 54 else pkgs.writeText "nfs.conf" nfsConfDeprecated; 55 56 requestKeyConfFile = pkgs.writeText "request-key.conf" '' 57 create id_resolver * * ${pkgs.nfs-utils}/bin/nfsidmap -t 600 %k %d 58 ''; 59 60 cfg = config.services.nfs; 61 62in 63 64{ 65 ###### interface 66 67 options = { 68 services.nfs = { 69 idmapd.settings = mkOption { 70 type = format.type; 71 default = {}; 72 description = '' 73 libnfsidmap configuration. Refer to 74 <https://linux.die.net/man/5/idmapd.conf> 75 for details. 76 ''; 77 example = literalExpression '' 78 { 79 Translation = { 80 GSS-Methods = "static,nsswitch"; 81 }; 82 Static = { 83 "root/hostname.domain.com@REALM.COM" = "root"; 84 }; 85 } 86 ''; 87 }; 88 settings = mkOption { 89 type = format.type; 90 default = {}; 91 description = '' 92 General configuration for NFS daemons and tools. 93 See nfs.conf(5) and related man pages for details. 94 ''; 95 example = literalExpression '' 96 { 97 mountd.manage-gids = true; 98 } 99 ''; 100 }; 101 extraConfig = mkOption { 102 type = types.lines; 103 default = ""; 104 description = '' 105 Extra nfs-utils configuration. 106 ''; 107 }; 108 }; 109 }; 110 111 ###### implementation 112 113 config = mkIf (config.boot.supportedFilesystems.nfs or config.boot.supportedFilesystems.nfs4 or false) { 114 115 warnings = 116 (optional (cfg.extraConfig != "") '' 117 `services.nfs.extraConfig` is deprecated. Use `services.nfs.settings` instead. 118 '') ++ (optional (cfg.server.extraNfsdConfig != "") '' 119 `services.nfs.server.extraNfsdConfig` is deprecated. Use `services.nfs.settings` instead. 120 ''); 121 assertions = [{ 122 assertion = cfg.settings != {} -> cfg.extraConfig == "" && cfg.server.extraNfsdConfig == ""; 123 message = "`services.nfs.settings` cannot be used together with `services.nfs.extraConfig` and `services.nfs.server.extraNfsdConfig`."; 124 }]; 125 126 services.rpcbind.enable = true; 127 128 services.nfs.idmapd.settings = { 129 General = mkMerge [ 130 { Pipefs-Directory = rpcMountpoint; } 131 (mkIf (config.networking.domain != null) { Domain = config.networking.domain; }) 132 ]; 133 Mapping = { 134 Nobody-User = "nobody"; 135 Nobody-Group = "nogroup"; 136 }; 137 Translation = { 138 Method = "nsswitch"; 139 }; 140 }; 141 142 system.fsPackages = [ pkgs.nfs-utils ]; 143 144 boot.initrd.kernelModules = mkIf inInitrd [ "nfs" ]; 145 146 systemd.packages = [ pkgs.nfs-utils ]; 147 148 environment.systemPackages = [ pkgs.keyutils ]; 149 150 environment.etc = { 151 "idmapd.conf".source = idmapdConfFile; 152 "nfs.conf".source = nfsConfFile; 153 "request-key.conf".source = requestKeyConfFile; 154 }; 155 156 systemd.services.nfs-blkmap = 157 { restartTriggers = [ nfsConfFile ]; 158 }; 159 160 systemd.targets.nfs-client = 161 { wantedBy = [ "multi-user.target" "remote-fs.target" ]; 162 }; 163 164 systemd.services.nfs-idmapd = 165 { restartTriggers = [ idmapdConfFile ]; 166 }; 167 168 systemd.services.nfs-mountd = 169 { restartTriggers = [ nfsConfFile ]; 170 enable = mkDefault false; 171 }; 172 173 systemd.services.nfs-server = 174 { restartTriggers = [ nfsConfFile ]; 175 enable = mkDefault false; 176 }; 177 178 systemd.services.auth-rpcgss-module = 179 { 180 unitConfig.ConditionPathExists = [ "" "/etc/krb5.keytab" ]; 181 }; 182 183 systemd.services.rpc-gssd = 184 { restartTriggers = [ nfsConfFile ]; 185 unitConfig.ConditionPathExists = [ "" "/etc/krb5.keytab" ]; 186 }; 187 188 systemd.services.rpc-statd = 189 { restartTriggers = [ nfsConfFile ]; 190 191 preStart = 192 '' 193 mkdir -p /var/lib/nfs/{sm,sm.bak} 194 ''; 195 }; 196 197 }; 198}