infrastructure/nixos/kyuuto/nfs.nix
2024-11-24 13:55:12 -08:00

143 lines
3.9 KiB
Nix

{
config,
lib,
...
}: let
inherit (lib.modules) mkIf mkMerge;
inherit (lib.attrsets) mapAttrs' mapAttrsToList nameValuePair;
inherit (lib.lists) concatLists;
inherit (config) kyuuto;
inherit (config.services.nfs.export) flagSets;
nfsRoot = {
__toString = _: config.services.nfs.export.root.path;
transfer = "${nfsRoot}/kyuuto/transfer";
media = "${nfsRoot}/kyuuto/media";
data = "${nfsRoot}/kyuuto/data";
systems = "${nfsRoot}/kyuuto/systems";
};
mkSystemExport = { name, fsid, machine, flags ? ["async"], machineFlags ? flagSets.metal }: {
flags = flagSets.common ++ ["fsid=${toString fsid}"] ++ flags;
clients = {
${name} = {
inherit machine;
flags = machineFlags;
};
admin = {
machine = flagSets.adminClients;
flags = machineFlags;
};
};
};
mkSystemExports = name: { machine, fileSystems }: let
systemRoot = "${nfsRoot.systems}/${name}";
mapSystemExport = fsName: fs: nameValuePair "${systemRoot}/${fsName}" (mkSystemExport ({
inherit name machine;
} // fs));
in mapAttrs' mapSystemExport fileSystems;
exportedSystems = {
gengetsu = {
machine = flagSets.gengetsuClients;
fileSystems = {
root.fsid = 162;
boot.fsid = 163;
};
};
mugetsu = {
machine = flagSets.mugetsuClients;
fileSystems = {
root.fsid = 170;
boot.fsid = 171;
};
};
goliath = {
machine = flagSets.goliathClients;
fileSystems = {
root.fsid = 172;
boot.fsid = 173;
};
};
};
in {
services.nfs = {
export = let
exportPaths = {
${nfsRoot.media} = {
flags = flagSets.common ++ ["fsid=128"] ++ flagSets.secip ++ ["rw"] ++ flagSets.anon_ro;
clients = {
local = {
machine = flagSets.allClients;
flags = flagSets.seclocal ++ ["rw" "no_all_squash"];
};
};
};
${nfsRoot.data} = {
flags = flagSets.common ++ ["fsid=130"] ++ flagSets.secip ++ ["rw"] ++ flagSets.anon_ro;
clients = {
local = {
machine = flagSets.allClients;
flags = flagSets.seclocal ++ ["rw" "no_all_squash"];
};
};
};
${nfsRoot.transfer} = {
flags = flagSets.common ++ ["fsid=129"] ++ ["rw" "async"];
clients = {
local = {
machine = flagSets.allClients;
flags = flagSets.secanon;
};
};
};
};
systemPaths = mkMerge (mapAttrsToList mkSystemExports exportedSystems);
in {
paths = mkMerge [
exportPaths
systemPaths
];
};
};
systemd.mounts = let
type = "none";
options = "bind";
wantedBy = [
"nfs-server.service"
"nfs-mountd.service"
];
before = wantedBy;
mkMount = { what, where, ... }@args: {
inherit type options wantedBy before;
} // args;
mkSystemMount = { name, fsName }: let
systemRoot = "${nfsRoot.systems}/${name}";
in mkMount {
what = "${kyuuto.dataDir}/systems/${name}/fs/${fsName}";
where = "${systemRoot}/${fsName}";
};
mapSystemMounts = name: { fileSystems, ... }: let
mapFileSystem = fsName: fs: mkSystemMount { inherit name fsName; };
in mapAttrsToList mapFileSystem fileSystems;
systemMounts = let
systemMounts = mapAttrsToList mapSystemMounts exportedSystems;
in concatLists systemMounts;
exportMounts = map mkMount [
{
what = kyuuto.mountDir;
where = nfsRoot.media;
}
{
what = kyuuto.dataDir;
where = nfsRoot.data;
}
{
what = kyuuto.transferDir;
where = nfsRoot.transfer;
}
];
pathMounts = mkMerge [
exportMounts
systemMounts
];
in
mkIf config.services.nfs.server.enable pathMounts;
}