main
 1# Generic NFS mounts module
 2# This module provides configurable NFS mounts for shared directories from any server
 3{
 4  config,
 5  lib,
 6  ...
 7}:
 8let
 9  cfg = config.services.nfs-mounts;
10
11  # Helper to create mount configuration for a specific host
12  mkHostMounts =
13    hostName: hostCfg:
14    lib.listToAttrs (
15      map (folder: {
16        name = "/net/${hostName}/${folder}";
17        value = {
18          device = "${hostCfg.server}:${hostCfg.rootPath}/${folder}"; # NFSv4: path relative to export root
19          fsType = "nfs";
20          options = [
21            "nfsvers=4.2" # Use NFSv4.2 for best performance
22            "x-systemd.automount" # Lazy-mount on first access
23            "noauto" # Don't mount at boot
24            "x-systemd.idle-timeout=600" # Auto-unmount after 10 min idle
25            "soft" # Don't hang if server unavailable
26            "timeo=14" # Timeout after 1.4s (14 * 0.1s)
27            "retrans=2" # Retry twice before timing out
28            "_netdev" # Wait for network before mounting
29          ];
30        };
31      }) hostCfg.folders
32    );
33in
34{
35  options.services.nfs-mounts = {
36    hosts = lib.mkOption {
37      type = lib.types.attrsOf (
38        lib.types.submodule {
39          options = {
40            server = lib.mkOption {
41              type = lib.types.str;
42              example = "rhea.sbr.pm";
43              description = "NFS server hostname or IP";
44            };
45            rootPath = lib.mkOption {
46              type = lib.types.str;
47              default = "";
48              example = "/zion";
49              description = "Root path prefix on the NFS server (for servers with multiple export roots)";
50            };
51            folders = lib.mkOption {
52              type = lib.types.listOf lib.types.str;
53              default = [ ];
54              example = [
55                "audiobooks"
56                "music"
57                "pictures"
58              ];
59              description = "List of folders to mount from the server's exported directory";
60            };
61          };
62        }
63      );
64      default = { };
65      example = {
66        rhea = {
67          server = "rhea.sbr.pm";
68          folders = [
69            "music"
70            "audiobooks"
71          ];
72        };
73        aion = {
74          server = "aion.sbr.pm";
75          folders = [
76            "music"
77            "audiobooks"
78          ];
79        };
80      };
81      description = ''
82        NFS servers and their folders to mount.
83        Each host's folders will be mounted at /net/{hostname}/{folder}.
84      '';
85    };
86  };
87
88  config = lib.mkIf (cfg.hosts != { }) {
89    # Enable NFS support
90    boot.supportedFilesystems = [ "nfs" ];
91
92    # Create NFS mounts for all configured hosts
93    fileSystems = lib.mkMerge (lib.mapAttrsToList mkHostMounts cfg.hosts);
94  };
95}