{ config, pkgs, lib, ... }: with lib; let cfg = config.services.naxos.shares.nfs; in { options.services.naxos.shares.nfs = { enable = mkEnableOption "NaxOS Declarative NFS Service"; lockdPort = mkOption { type = types.int; default = 4001; description = "Port for lockd."; }; mountdPort = mkOption { type = types.int; default = 4002; description = "Port for mountd."; }; exports = mkOption { type = types.listOf (types.submodule { options = { path = mkOption { type = types.str; description = "Path to exported directory or dataset."; }; clients = mkOption { type = types.listOf (types.submodule { options = { subnet = mkOption { type = types.str; example = "10.0.0.0/23"; description = "Allowed client subnet or IP."; }; options = mkOption { type = types.str; default = "rw,sync,no_subtree_check,no_root_squash"; description = "NFS export options."; }; }; }); default = []; description = "Clients allowed to mount this export."; }; }; }); default = []; description = "List of NFS exported directories."; }; }; config = mkIf cfg.enable { services.nfs.server = { enable = true; lockdPort = cfg.lockdPort; mountdPort = cfg.mountdPort; exports = concatMapStringsSep "\n" (exp: let clientList = concatMapStringsSep " " (c: "${c.subnet}(${c.options})") exp.clients; in "${exp.path} ${clientList}" ) cfg.exports; }; networking.firewall = { allowedTCPPorts = [ 111 2049 cfg.lockdPort cfg.mountdPort ]; allowedUDPPorts = [ 111 2049 cfg.lockdPort cfg.mountdPort ]; }; }; }