flake-update-20260201
 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}:/${folder}"; # NFSv4: path relative to fsid=0
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            folders = lib.mkOption {
46              type = lib.types.listOf lib.types.str;
47              default = [ ];
48              example = [
49                "audiobooks"
50                "music"
51                "pictures"
52              ];
53              description = "List of folders to mount from the server's exported directory";
54            };
55          };
56        }
57      );
58      default = { };
59      example = {
60        rhea = {
61          server = "rhea.sbr.pm";
62          folders = [
63            "music"
64            "audiobooks"
65          ];
66        };
67        aion = {
68          server = "aion.sbr.pm";
69          folders = [
70            "music"
71            "audiobooks"
72          ];
73        };
74      };
75      description = ''
76        NFS servers and their folders to mount.
77        Each host's folders will be mounted at /net/{hostname}/{folder}.
78      '';
79    };
80  };
81
82  config = lib.mkIf (cfg.hosts != { }) {
83    # Enable NFS support
84    boot.supportedFilesystems = [ "nfs" ];
85
86    # Create NFS mounts for all configured hosts
87    fileSystems = lib.mkMerge (lib.mapAttrsToList mkHostMounts cfg.hosts);
88  };
89}