refactor: separate out conditional and unconditional modules for nfs and samba

This commit is contained in:
Ceferino Patino 2026-06-29 22:39:17 -05:00
commit 224176d2d2
Signed by: c4patino
SSH key fingerprint: SHA256:Wu+cU1t+7zVT9wzew/4meNmeulo66NzMqc22MdDBgXI
4 changed files with 139 additions and 105 deletions

View file

@ -3,13 +3,17 @@
lib,
namespace,
...
}: let
inherit (lib) types mkIf mkEnableOption mkOption mapAttrs' concatStringsSep;
} @ args: let
inherit (lib) types mkIf mkEnableOption mkMerge concatStringsSep;
inherit (lib.${namespace}) getAttrByNamespace mkOptionsWithNamespace resolveHostIP mkOpt mkRequiredOpt mkNullableOpt mkListOpt mkOptAttrset;
base = "${namespace}.services.storage.nfs";
cfg = getAttrByNamespace config base;
networkCfg = getAttrByNamespace config "${namespace}.services.networking";
in {
imports = [
(import ./mount.nix args)
];
options = with types;
mkOptionsWithNamespace base {
enable = mkEnableOption "nfs";
@ -29,30 +33,8 @@ in {
}) {} "Set of NFS mounts with custom configuration.";
};
config = {
fileSystems = let
mapFolderToMount = name: mntCfg: let
hostIP = resolveHostIP networkCfg.devices mntCfg.host;
localPath =
if mntCfg.mountPath != null
then mntCfg.mountPath
else "/mnt/nfs/${name}";
in {
name = localPath;
value = {
device = "${hostIP}:${mntCfg.folder}";
fsType = "nfs";
options = [
"_netdev"
"nofail"
"x-systemd.automount"
];
};
};
in
cfg.mounts |> mapAttrs' mapFolderToMount;
services.nfs.server = mkIf cfg.enable {
config = mkIf cfg.enable {
services.nfs.server = {
enable = true;
exports = let
mapMountToPermissions = mount: let
@ -68,10 +50,11 @@ in {
|> concatStringsSep "\n";
};
${namespace}.services.storage.impermanence.folders = mkIf (cfg.enable && cfg.shares != []) (
["/var/lib/nfs"] ++ (cfg.shares |> map (s: "/mnt/nfs/${s.name}"))
);
${namespace}.services.storage.impermanence.folders = mkMerge [
["/var/lib/nfs"]
(mkIf (cfg.shares != []) (cfg.shares |> map (s: "/mnt/nfs/${s.name}")))
];
networking.firewall.allowedTCPPorts = mkIf cfg.enable [2049];
networking.firewall.allowedTCPPorts = [2049];
};
}

View file

@ -0,0 +1,35 @@
{
config,
lib,
namespace,
...
}: let
inherit (lib) mapAttrs';
inherit (lib.${namespace}) getAttrByNamespace resolveHostIP;
cfg = getAttrByNamespace config "${namespace}.services.storage.nfs";
networkCfg = getAttrByNamespace config "${namespace}.services.networking";
in {
config = {
fileSystems = let
mapFolderToMount = name: mntCfg: let
hostIP = resolveHostIP networkCfg.devices mntCfg.host;
localPath =
if mntCfg.mountPath != null
then mntCfg.mountPath
else "/mnt/nfs/${name}";
in {
name = localPath;
value = {
device = "${hostIP}:${mntCfg.folder}";
fsType = "nfs";
options = [
"_netdev"
"nofail"
"x-systemd.automount"
];
};
};
in
cfg.mounts |> mapAttrs' mapFolderToMount;
};
}

View file

@ -1,17 +1,20 @@
{
config,
inputs,
lib,
namespace,
...
}: let
inherit (lib) types mkIf mkEnableOption mkOption mapAttrs' mkMerge map;
inherit (lib.${namespace}) getAttrByNamespace mkOptionsWithNamespace resolveHostIP readJsonOrEmpty getIn mkOpt mkRequiredOpt mkNullableOpt mkListOpt mkOptAttrset;
} @ args: let
inherit (lib) types mkIf mkEnableOption mkMerge;
inherit (lib.${namespace}) getAttrByNamespace mkOptionsWithNamespace mkRequiredOpt mkNullableOpt mkListOpt mkOptAttrset;
inherit (config.users) users;
base = "${namespace}.services.storage.samba";
cfg = getAttrByNamespace config base;
networkCfg = getAttrByNamespace config "${namespace}.services.networking";
in {
imports = [
(import ./mount.nix args)
];
options = with types;
mkOptionsWithNamespace base {
enable = mkEnableOption "Samba";
@ -25,80 +28,55 @@ in {
}) {} "Set of Samba mounts with custom configuration.";
};
config = {
fileSystems = let
processMount = name: mountCfg: let
hostIP = resolveHostIP networkCfg.devices mountCfg.host;
localPath =
if mountCfg.mountPath != null
then mountCfg.mountPath
else "/mnt/samba/${name}";
automount_opts = "x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s";
in {
name = localPath;
value = {
device = "//${hostIP}/${mountCfg.folder}";
fsType = "cifs";
options = [
"${automount_opts},credentials=/etc/samba/.credentials,uid=1000,gid=100"
config = mkIf cfg.enable {
services = {
samba = {
enable = true;
openFirewall = true;
settings = let
mkShare = folderPath: {
"path" = "/mnt/samba/${folderPath}";
"browsable" = "yes";
"read only" = "no";
"guest ok" = "no";
"create mask" = "0644";
"directory mask" = "0755";
"force user" = users.c4patino.name;
"force group" = users.c4patino.group;
};
mapFolderToShare = folderPath: {
name = folderPath;
value = mkShare folderPath;
};
shareConfigs =
cfg.shares
|> map mapFolderToShare
|> builtins.listToAttrs;
in
mkMerge [
{
global = {
"workgroup" = "WORKGROUP";
"server string" = "smbnix";
"netbios name" = "smbnix";
"security" = "user";
};
}
shareConfigs
];
};
};
in
cfg.mounts |> mapAttrs' processMount;
environment.etc."samba/.credentials".text = let
secrets = readJsonOrEmpty "${inputs.self}/secrets/crypt/secrets.json";
in ''
username=${getIn "samba.username" secrets}
password=${getIn "samba.password" secrets}
'';
services.samba = mkIf cfg.enable {
enable = true;
openFirewall = true;
settings = let
mkShare = folderPath: {
"path" = "/mnt/samba/${folderPath}";
"browsable" = "yes";
"read only" = "no";
"guest ok" = "no";
"create mask" = "0644";
"directory mask" = "0755";
"force user" = users.c4patino.name;
"force group" = users.c4patino.group;
};
mapFolderToShare = folderPath: {
name = folderPath;
value = mkShare folderPath;
};
shareConfigs =
cfg.shares
|> map mapFolderToShare
|> builtins.listToAttrs;
in
mkMerge [
{
global = {
"workgroup" = "WORKGROUP";
"server string" = "smbnix";
"netbios name" = "smbnix";
"security" = "user";
};
}
shareConfigs
];
samba-wsdd = {
enable = true;
openFirewall = true;
};
};
services.samba-wsdd = mkIf cfg.enable {
enable = true;
openFirewall = true;
};
${namespace}.services.storage.impermanence.folders = mkIf (cfg.enable && cfg.shares != []) (
["/var/lib/samba"] ++ (cfg.shares |> map (s: "/mnt/samba/${s}"))
);
${namespace}.services.storage.impermanence.folders = mkMerge [
["/var/lib/samba"]
(mkIf (cfg.shares != []) (cfg.shares |> map (s: "/mnt/samba/${s}")))
];
};
}

View file

@ -0,0 +1,38 @@
{
config,
inputs,
lib,
namespace,
...
}: let
inherit (lib) mapAttrs';
inherit (lib.${namespace}) getAttrByNamespace resolveHostIP readJsonOrEmpty getIn;
cfg = getAttrByNamespace config "${namespace}.services.storage.samba";
networkCfg = getAttrByNamespace config "${namespace}.services.networking";
in {
config = {
fileSystems = let
processMount = name: mountCfg: let
hostIP = resolveHostIP networkCfg.devices mountCfg.host;
localPath =
if mountCfg.mountPath != null
then mountCfg.mountPath
else "/mnt/samba/${name}";
automount_opts = "x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s";
in {
name = localPath;
value = {
device = "//${hostIP}/${mountCfg.folder}";
fsType = "cifs";
options = [
"${automount_opts},credentials=/etc/samba/.credentials,uid=1000,gid=100"
];
};
};
in
cfg.mounts |> mapAttrs' processMount;
sops.secrets."samba" = {};
};
}