feat: add nfs mesh

This commit is contained in:
2025-12-13 22:40:04 -08:00
parent ae0a4d5f21
commit 07e49b1591
5 changed files with 148 additions and 26 deletions

113
nix/modules/nfs-mesh.nix Normal file
View File

@@ -0,0 +1,113 @@
{
pkgs,
lib,
config,
...
}:
let
cfg = config.nfs-mesh;
remoteHosts = lib.filter (h: h != config.networking.hostName) cfg.hosts;
in
{
options.nfs-mesh = {
enable = lib.mkEnableOption "NFS mesh networking" // {
default = true;
};
hosts = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [
"usahara"
"kumatani"
"tux"
];
description = ''
List of hostnames participating in the NFS mesh.
Each host will export its configured path and mount all other hosts.
'';
example = [
"usahara"
"kumatani"
"tux"
];
};
exportPath = lib.mkOption {
type = lib.types.str;
default = "/home";
description = ''
Path to export to other hosts in the mesh.
This will be mounted at /mnt/{hostname} on remote hosts.
'';
example = "/home";
};
exportOptions = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [
"rw"
"sync"
"no_subtree_check"
"no_root_squash"
];
description = ''
NFS export options. Default allows read-write access with no root squashing
since all hosts are on a trusted Tailscale network.
'';
};
mountOptions = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [
"x-systemd.automount"
"noauto"
"x-systemd.idle-timeout=600"
"nfsvers=4.2"
"soft"
"timeo=10"
"retrans=3"
];
description = ''
NFS mount options. Uses automount for on-demand mounting with idle timeout.
Soft mount with short timeout to avoid hanging on unreachable hosts.
'';
};
};
config = lib.mkIf cfg.enable {
boot.supportedFilesystems = [ "nfs" ];
services.rpcbind.enable = true;
services.nfs.server = {
enable = true;
exports = ''
${cfg.exportPath} 100.64.0.0/10(${lib.concatStringsSep "," cfg.exportOptions})
'';
};
systemd.tmpfiles.rules = map (host: "d /mnt/${host} 0755 luca users -") remoteHosts;
fileSystems = lib.listToAttrs (
map (host: {
name = "/mnt/${host}";
value = {
device = "${host}:${cfg.exportPath}";
fsType = "nfs";
options = cfg.mountOptions;
};
}) remoteHosts
);
systemd.services.nfs-server = {
requires = [
"rpcbind.service"
"network-online.target"
];
after = [
"rpcbind.service"
"network-online.target"
];
};
};
}