Rebase to flake parts #10

This commit is contained in:
2026-05-15 00:24:13 -03:00
parent f02606902c
commit fba5a7a2aa
24 changed files with 565 additions and 83 deletions
@@ -1,9 +1,15 @@
# Export large Jellyfin media trees to nix-server. Local path must already exist
# (e.g. /mnt/test/jellyfin/{movies,tv}). On nix-server this is mounted at /mnt/nixdesk-jellyfin.
# NFS exports from nixdesk (14900k) to nix-server (192.168.2.238):
# - /mnt/test/jellyfin → nix-server /mnt/nixdesk-jellyfin (Jellyfin bulk libraries)
# - /mnt/media → nix-server /mnt/media (Btrfs MediaLibrary disk; see media-disk.nix)
#
# After deploy: ensure Jellyfin can read files over NFS — typical fix:
# chmod -R a+rX /mnt/test/jellyfin
{ ... }:
# NTFS on nixdesk uses uid=olivier + gid=nfsmedia (990); dirs here are olivier:nfsmedia 2775 so
# local writes and NFS all_squash (anonuid=olivier, anongid=990) get rwx via owner or group.
#
# Legacy trees may still need a one-time `chgrp -R nfsmedia` / `chmod -R g+rwX` on deep folders.
{ config, pkgs, ... }:
let
olivierUid = config.users.users.olivier.uid or 1000;
in
{
# Avoid UID/GID mismatches across machines: map all NFS writes from nix-server to a single
# local system user/group on this server.
@@ -14,10 +20,32 @@
group = "nfsmedia";
};
systemd.tmpfiles.settings."14900k-jellyfin-media-dirs" = {
"/mnt/test/jellyfin"."d" = { mode = "2775"; user = "nfsmedia"; group = "nfsmedia"; };
"/mnt/test/jellyfin/movies"."d" = { mode = "2775"; user = "nfsmedia"; group = "nfsmedia"; };
"/mnt/test/jellyfin/tv"."d" = { mode = "2775"; user = "nfsmedia"; group = "nfsmedia"; };
# olivier: owner for local use; nfsmedia: group matches NTFS gid=990 and NFS all_squash (990).
systemd.tmpfiles.settings."14900k-nfs-export-paths" = {
"/mnt/test"."d" = { mode = "2775"; user = "olivier"; group = "nfsmedia"; };
"/mnt/test/jellyfin"."d" = { mode = "2775"; user = "olivier"; group = "nfsmedia"; };
"/mnt/test/jellyfin/movies"."d" = { mode = "2775"; user = "olivier"; group = "nfsmedia"; };
"/mnt/test/jellyfin/tv"."d" = { mode = "2775"; user = "olivier"; group = "nfsmedia"; };
"/mnt/media"."d" = { mode = "2775"; user = "olivier"; group = "nfsmedia"; };
"/mnt/media/Movies"."d" = { mode = "2775"; user = "olivier"; group = "nfsmedia"; };
"/mnt/media/TV"."d" = { mode = "2775"; user = "olivier"; group = "nfsmedia"; };
"/mnt/media/Videos"."d" = { mode = "2775"; user = "olivier"; group = "nfsmedia"; };
};
# After exports are up, ensure group nfsmedia can write throughout library roots (idempotent;
# scoped to library folders only — not whole disks). Runs on each `nixos-rebuild switch`.
system.activationScripts.nfs-export-group-write = {
deps = [ "specialfs" ];
text = ''
for d in \
/mnt/media/TV /mnt/media/Movies /mnt/media/Videos \
/mnt/test/jellyfin/tv /mnt/test/jellyfin/movies
do
[ -d "$d" ] || continue
${pkgs.acl}/bin/setfacl -R -m g:nfsmedia:rwx "$d" 2>/dev/null || true
${pkgs.acl}/bin/setfacl -R -d -m g:nfsmedia:rwx "$d" 2>/dev/null || true
done
'';
};
# Fixed ports so the firewall can allow NFS v3 helpers (see networking.firewall below).
@@ -26,9 +54,12 @@
mountdPort = 4000;
lockdPort = 4001;
statdPort = 4002;
# fsid= stabilizes file handles across server reboots/remounts of this tree (avoids client ESTALE).
# fsid= unique per export tree (avoids client ESTALE when multiple paths are exported).
# Squash nix-server clients to olivier:nfsmedia so Jellyfin can write .nfo/posters into
# existing olivier-owned library folders (990-only squash was "other" r-x on typical 755 trees).
exports = ''
/mnt/test/jellyfin 192.168.2.238(rw,sync,no_subtree_check,crossmnt,root_squash,all_squash,anonuid=990,anongid=990,fsid=1)
/mnt/test/jellyfin 192.168.2.238(rw,sync,no_subtree_check,crossmnt,root_squash,all_squash,anonuid=${toString olivierUid},anongid=990,fsid=1)
/mnt/media 192.168.2.238(rw,sync,no_subtree_check,crossmnt,root_squash,all_squash,anonuid=${toString olivierUid},anongid=990,fsid=2)
'';
};
@@ -0,0 +1,34 @@
# Extra local disks. Declared here, not in hardware.nix (hardware.nix is generated).
{ config, lib, ... }:
let
# Stable UID so NTFS `uid=` matches `users.users.olivier` (override if your account is not 1000).
olivierUid = config.users.users.olivier.uid or 1000;
in
{
users.users.olivier.uid = lib.mkDefault 1000;
fileSystems."/mnt/media" = {
device = "/dev/disk/by-uuid/17d8a981-db3b-415e-a0f7-7dbc519e04ab";
fsType = "btrfs";
options = [
"subvol=@"
"compress=zstd"
"noatime"
];
};
# LABEL="Deep Storage Unit". Owner olivier, group nfsmedia (990) so:
# - local logins write as user 1000 (owner rwx);
# - NFS (all_squash → uid/gid 990) matches group 990 → rwx (see jellyfin-nfs-export).
fileSystems."/mnt/test" = {
device = "/dev/disk/by-uuid/BC12E55E12E51DE0";
fsType = "ntfs-3g";
options = [
"rw"
"force"
"uid=${toString olivierUid}"
"gid=990"
"umask=0002"
];
};
}
+8
View File
@@ -17,6 +17,7 @@
./_private/peripherals.nix
# ./_private/printing-epson.nix
./_private/displays.nix
./_private/media-disk.nix
./_private/jellyfin-nfs-export.nix
];
@@ -108,8 +109,13 @@ services.cloudflare-warp.enable = true;
# Native install (avoid flatpak sandbox issues for QSV/VAAPI).
handbrake
qbittorrent
# Diagnostics
libva-utils # vainfo
vlc
element-desktop
thunderbird
];
@@ -136,6 +142,7 @@ services.cloudflare-warp.enable = true;
self.homeManagerModules.wisdomAppsDiscord
self.homeManagerModules.wisdomAppsSpotify
self.homeManagerModules.wisdomAppsLocalsend
self.homeManagerModules.wisdomAppsSpacedrive
self.homeManagerModules.wisdomAppsPokeclicker
self.homeManagerModules.wisdomDesktopScreenshot
self.homeManagerModules.wisdomDesktopGtkQtTheming
@@ -171,6 +178,7 @@ services.cloudflare-warp.enable = true;
spotify.enable = true;
spotify.openDiscoveryFirewall = true;
localsend.enable = true;
spacedrive.enable = true;
pokeclicker.enable = true;
};