{ config, lib, ... }: { options = { host.network_storage.nfs = { enable = lib.mkEnableOption "is this server going to export network storage as nfs shares"; port = lib.mkOption { type = lib.types.int; default = 2049; description = "port that nfs will run on"; }; directories = lib.mkOption { type = lib.types.listOf ( lib.types.enum ( builtins.map ( directory: directory.folder ) config.host.network_storage.directories ) ); description = "list of exported directories to be exported via nfs"; }; }; }; config = lib.mkMerge [ { assertions = [ { assertion = !(config.host.network_storage.nfs.enable && !config.host.network_storage.enable); message = "nfs cant be enabled with network storage disabled"; } ]; } ( lib.mkIf (config.host.network_storage.nfs.enable && config.host.network_storage.enable) { services.nfs = { settings = { nfsd = { threads = 32; port = config.host.network_storage.nfs.port; }; }; server = { enable = true; lockdPort = 4001; mountdPort = 4002; statdPort = 4000; exports = lib.strings.concatLines ( [ "${config.host.network_storage.export_directory} 100.64.0.0/10(rw,fsid=0,no_subtree_check)" ] ++ ( lib.lists.imap0 ( i: directory: let createOptions = fsid: "(rw,fsid=${toString fsid},nohide,insecure,no_subtree_check)"; addresses = [ # loopback "127.0.0.1" "::1" # local network # "192.168.0.0/24" # tailscale "100.64.0.0/10" "fd7a:115c:a1e0::/48" ]; options = lib.strings.concatStrings ( lib.strings.intersperse " " ( lib.lists.imap0 (index: address: "${address}${createOptions (1 + (i * (builtins.length addresses)) + index)}") addresses ) ); in "${directory._directory} ${options}" ) ( builtins.filter ( directory: lib.lists.any (target: target == directory.folder) config.host.network_storage.nfs.directories ) config.host.network_storage.directories ) ) ); }; }; networking.firewall.interfaces.${config.services.tailscale.interfaceName} = let ports = [ 111 config.host.network_storage.nfs.port config.services.nfs.server.lockdPort config.services.nfs.server.mountdPort config.services.nfs.server.statdPort 20048 ]; in { allowedTCPPorts = ports; allowedUDPPorts = ports; }; } ) ]; }