Commit 99206f7334ff

Vincent Demeester <vincent@sbr.pm>
2025-12-22 10:09:36
feat: add generic multi-host NFS mounts module
- Replace rhea-specific module with reusable infrastructure - Enable simultaneous mounting from multiple NFS servers - Grant homelab hosts access to both rhea and aion audio shares Signed-off-by: Vincent Demeester <vincent@sbr.pm>
1 parent 6b2fdb6
systems/aion/extra.nix
@@ -248,4 +248,3 @@ in
   ];
 
 }
-  a
systems/aix/hardware.nix
@@ -1,6 +1,6 @@
 _: {
   imports = [
-    ../common/services/nfs-rhea-mounts.nix
+    ../common/services/nfs-mounts.nix
   ];
 
   fileSystems = {
@@ -16,16 +16,25 @@ _: {
     };
   };
 
-  # NFS mounts from rhea
-  services.nfs-rhea-mounts = {
-    enable = true;
-    folders = [
-      "audiobooks"
-      "downloads"
-      "ebooks"
-      "music"
-      "pictures"
-      "videos"
-    ];
+  # NFS mounts from rhea and aion
+  services.nfs-mounts.hosts = {
+    rhea = {
+      server = "rhea.sbr.pm";
+      folders = [
+        "audiobooks"
+        "downloads"
+        "ebooks"
+        "music"
+        "pictures"
+        "videos"
+      ];
+    };
+    aion = {
+      server = "aion.sbr.pm";
+      folders = [
+        "audiobooks"
+        "music"
+      ];
+    };
   };
 }
systems/aomi/hardware.nix
@@ -11,7 +11,7 @@
 
     ../common/hardware/acpid.nix
     # ../common/hardware/bluetooth.nix
-    ../common/services/nfs-rhea-mounts.nix
+    ../common/services/nfs-mounts.nix
   ];
 
   hardware = {
@@ -46,16 +46,25 @@
 
   swapDevices = [ { device = "/dev/disk/by-uuid/24da6a46-cd28-4bff-9220-6f449e3bd8b5"; } ];
 
-  # NFS mounts from rhea
-  services.nfs-rhea-mounts = {
-    enable = true;
-    folders = [
-      "audiobooks"
-      "downloads"
-      "ebooks"
-      "music"
-      "pictures"
-      "videos"
-    ];
+  # NFS mounts from rhea and aion
+  services.nfs-mounts.hosts = {
+    rhea = {
+      server = "rhea.sbr.pm";
+      folders = [
+        "audiobooks"
+        "downloads"
+        "ebooks"
+        "music"
+        "pictures"
+        "videos"
+      ];
+    };
+    aion = {
+      server = "aion.sbr.pm";
+      folders = [
+        "audiobooks"
+        "music"
+      ];
+    };
   };
 }
systems/common/services/nfs-mounts.nix
@@ -0,0 +1,89 @@
+# Generic NFS mounts module
+# This module provides configurable NFS mounts for shared directories from any server
+{
+  config,
+  lib,
+  ...
+}:
+let
+  cfg = config.services.nfs-mounts;
+
+  # Helper to create mount configuration for a specific host
+  mkHostMounts =
+    hostName: hostCfg:
+    lib.listToAttrs (
+      map (folder: {
+        name = "/net/${hostName}/${folder}";
+        value = {
+          device = "${hostCfg.server}:/${folder}"; # NFSv4: path relative to fsid=0
+          fsType = "nfs";
+          options = [
+            "nfsvers=4.2" # Use NFSv4.2 for best performance
+            "x-systemd.automount" # Lazy-mount on first access
+            "noauto" # Don't mount at boot
+            "x-systemd.idle-timeout=600" # Auto-unmount after 10 min idle
+            "soft" # Don't hang if server unavailable
+            "timeo=14" # Timeout after 1.4s (14 * 0.1s)
+            "retrans=2" # Retry twice before timing out
+            "_netdev" # Wait for network before mounting
+          ];
+        };
+      }) hostCfg.folders
+    );
+in
+{
+  options.services.nfs-mounts = {
+    hosts = lib.mkOption {
+      type = lib.types.attrsOf (
+        lib.types.submodule {
+          options = {
+            server = lib.mkOption {
+              type = lib.types.str;
+              example = "rhea.sbr.pm";
+              description = "NFS server hostname or IP";
+            };
+            folders = lib.mkOption {
+              type = lib.types.listOf lib.types.str;
+              default = [ ];
+              example = [
+                "audiobooks"
+                "music"
+                "pictures"
+              ];
+              description = "List of folders to mount from the server's exported directory";
+            };
+          };
+        }
+      );
+      default = { };
+      example = {
+        rhea = {
+          server = "rhea.sbr.pm";
+          folders = [
+            "music"
+            "audiobooks"
+          ];
+        };
+        aion = {
+          server = "aion.sbr.pm";
+          folders = [
+            "music"
+            "audiobooks"
+          ];
+        };
+      };
+      description = ''
+        NFS servers and their folders to mount.
+        Each host's folders will be mounted at /net/{hostname}/{folder}.
+      '';
+    };
+  };
+
+  config = lib.mkIf (cfg.hosts != { }) {
+    # Enable NFS support
+    boot.supportedFilesystems = [ "nfs" ];
+
+    # Create NFS mounts for all configured hosts
+    fileSystems = lib.mkMerge (lib.mapAttrsToList mkHostMounts cfg.hosts);
+  };
+}
systems/common/services/nfs-rhea-mounts.nix
@@ -1,57 +0,0 @@
-# NFS mounts from rhea server
-# This module provides configurable NFS mounts for rhea's shared directories
-{
-  config,
-  lib,
-  ...
-}:
-let
-  cfg = config.services.nfs-rhea-mounts;
-in
-{
-  options.services.nfs-rhea-mounts = {
-    enable = lib.mkEnableOption "NFS mounts from rhea server";
-
-    folders = lib.mkOption {
-      type = lib.types.listOf lib.types.str;
-      default = [ ];
-      example = [
-        "audiobooks"
-        "music"
-        "pictures"
-        "videos"
-        "downloads"
-      ];
-      description = ''
-        List of folders to mount from rhea's /neo directory.
-        Each folder will be mounted at /net/rhea/{folder}.
-      '';
-    };
-  };
-
-  config = lib.mkIf cfg.enable {
-    # Enable NFS support
-    boot.supportedFilesystems = [ "nfs" ];
-
-    # Create NFS mounts for each folder
-    fileSystems = lib.listToAttrs (
-      map (folder: {
-        name = "/net/rhea/${folder}";
-        value = {
-          device = "rhea.sbr.pm:/${folder}"; # NFSv4: path relative to fsid=0 (/neo)
-          fsType = "nfs";
-          options = [
-            "nfsvers=4.2" # Use NFSv4.2 for best performance
-            "x-systemd.automount" # Lazy-mount on first access
-            "noauto" # Don't mount at boot
-            "x-systemd.idle-timeout=600" # Auto-unmount after 10 min idle
-            "soft" # Don't hang if server unavailable
-            "timeo=14" # Timeout after 1.4s (14 * 0.1s)
-            "retrans=2" # Retry twice before timing out
-            "_netdev" # Wait for network before mounting
-          ];
-        };
-      }) cfg.folders
-    );
-  };
-}
systems/kyushu/hardware.nix
@@ -8,24 +8,33 @@
 
     ../common/hardware/acpid.nix
     ../common/hardware/bluetooth.nix
-    ../common/services/nfs-rhea-mounts.nix
+    ../common/services/nfs-mounts.nix
   ];
 
   hardware = {
     # opengl.extraPackages = with pkgs; [ vaapiIntel libvdpau-va-gl vaapiVdpau intel-ocl intel-media-driver ];
   };
 
-  # NFS mounts from rhea
-  services.nfs-rhea-mounts = {
-    enable = true;
-    folders = [
-      "audiobooks"
-      "downloads"
-      "ebooks"
-      "music"
-      "pictures"
-      "videos"
-    ];
+  # NFS mounts from rhea and aion
+  services.nfs-mounts.hosts = {
+    rhea = {
+      server = "rhea.sbr.pm";
+      folders = [
+        "audiobooks"
+        "downloads"
+        "ebooks"
+        "music"
+        "pictures"
+        "videos"
+      ];
+    };
+    aion = {
+      server = "aion.sbr.pm";
+      folders = [
+        "audiobooks"
+        "music"
+      ];
+    };
   };
 
   # NFS mounts from synodine (NFSv3)
systems/sakhalin/hardware.nix
@@ -4,7 +4,7 @@
 {
   imports = [
     ../common/hardware/acpid.nix
-    ../common/services/nfs-rhea-mounts.nix
+    ../common/services/nfs-mounts.nix
   ];
   fileSystems."/" = {
     device = "/dev/disk/by-uuid/92ce650d-873e-41c1-a44e-71c2b9191b9d";
@@ -48,17 +48,26 @@
 
   swapDevices = [ { device = "/dev/disk/by-uuid/9eb067d1-b329-4fbb-ae27-38abfbe7c108"; } ];
 
-  # NFS mounts from rhea
-  services.nfs-rhea-mounts = {
-    enable = true;
-    folders = [
-      "audiobooks"
-      "downloads"
-      "ebooks"
-      "music"
-      "pictures"
-      "videos"
-    ];
+  # NFS mounts from rhea and aion
+  services.nfs-mounts.hosts = {
+    rhea = {
+      server = "rhea.sbr.pm";
+      folders = [
+        "audiobooks"
+        "downloads"
+        "ebooks"
+        "music"
+        "pictures"
+        "videos"
+      ];
+    };
+    aion = {
+      server = "aion.sbr.pm";
+      folders = [
+        "audiobooks"
+        "music"
+      ];
+    };
   };
 
   networking = {