zfs: fix qbittorrent
This commit is contained in:
parent
ae5189b6c6
commit
223910744a
99
lib.nix
99
lib.nix
@ -69,67 +69,68 @@ inputs.nixpkgs.lib.extend (
|
|||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
RemainAfterExit = true;
|
RemainAfterExit = true;
|
||||||
ExecStart = lib.getExe (
|
ExecStart = [
|
||||||
pkgs.writeShellApplication {
|
(lib.getExe (
|
||||||
name = "ensure-zfs-mounts-with-pool-${serviceName}";
|
pkgs.writeShellApplication {
|
||||||
runtimeInputs = with pkgs; [
|
name = "ensure-zfs-mounts-with-pool-${serviceName}-${zpool}";
|
||||||
gawk
|
runtimeInputs = with pkgs; [
|
||||||
coreutils
|
gawk
|
||||||
config.boot.zfs.package
|
coreutils
|
||||||
];
|
config.boot.zfs.package
|
||||||
|
];
|
||||||
|
|
||||||
text = ''
|
text = ''
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
echo "Ensuring ZFS mounts for service: ${serviceName}"
|
echo "Ensuring ZFS mounts for service: ${serviceName} (pool: ${zpool})"
|
||||||
echo "Directories: ${lib.strings.concatStringsSep ", " dirs}"
|
echo "Directories: ${lib.strings.concatStringsSep ", " dirs}"
|
||||||
|
|
||||||
# Validate mounts exist (ensureZfsMounts already has proper PATH)
|
# Validate mounts exist (ensureZfsMounts already has proper PATH)
|
||||||
${lib.getExe pkgs.ensureZfsMounts} ${lib.strings.concatStringsSep " " dirs}
|
${lib.getExe pkgs.ensureZfsMounts} ${lib.strings.concatStringsSep " " dirs}
|
||||||
|
|
||||||
# Additional runtime check: verify paths are on correct zpool
|
# Additional runtime check: verify paths are on correct zpool
|
||||||
${lib.optionalString (zpool != "") ''
|
${lib.optionalString (zpool != "") ''
|
||||||
echo "Verifying ZFS mountpoints are on pool '${zpool}'..."
|
echo "Verifying ZFS mountpoints are on pool '${zpool}'..."
|
||||||
|
|
||||||
if ! zfs_list_output=$(zfs list -H -o name,mountpoint 2>&1); then
|
if ! zfs_list_output=$(zfs list -H -o name,mountpoint 2>&1); then
|
||||||
echo "ERROR: Failed to query ZFS datasets: $zfs_list_output" >&2
|
echo "ERROR: Failed to query ZFS datasets: $zfs_list_output" >&2
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# This loop handles variable number of directories, shellcheck false positive
|
|
||||||
# shellcheck disable=SC2043
|
|
||||||
for target in ${lib.strings.concatStringsSep " " dirs}; do
|
|
||||||
echo "Checking: $target"
|
|
||||||
|
|
||||||
# Find dataset that has this mountpoint
|
|
||||||
dataset=$(echo "$zfs_list_output" | awk -v target="$target" '$2 == target {print $1; exit}')
|
|
||||||
|
|
||||||
if [ -z "$dataset" ]; then
|
|
||||||
echo "ERROR: No ZFS dataset found for mountpoint: $target" >&2
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Extract pool name from dataset (first part before /)
|
# shellcheck disable=SC2043
|
||||||
actual_pool=$(echo "$dataset" | cut -d'/' -f1)
|
for target in ${lib.strings.concatStringsSep " " dirs}; do
|
||||||
|
echo "Checking: $target"
|
||||||
|
|
||||||
if [ "$actual_pool" != "${zpool}" ]; then
|
# Find dataset that has this mountpoint
|
||||||
echo "ERROR: ZFS pool mismatch for $target" >&2
|
dataset=$(echo "$zfs_list_output" | awk -v target="$target" '$2 == target {print $1; exit}')
|
||||||
echo " Expected pool: ${zpool}" >&2
|
|
||||||
echo " Actual pool: $actual_pool" >&2
|
|
||||||
echo " Dataset: $dataset" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "$target is on $dataset (pool: $actual_pool)"
|
if [ -z "$dataset" ]; then
|
||||||
done
|
echo "ERROR: No ZFS dataset found for mountpoint: $target" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
echo "All paths verified successfully on pool '${zpool}'"
|
# Extract pool name from dataset (first part before /)
|
||||||
''}
|
actual_pool=$(echo "$dataset" | cut -d'/' -f1)
|
||||||
|
|
||||||
echo "Mount validation completed for ${serviceName}"
|
if [ "$actual_pool" != "${zpool}" ]; then
|
||||||
'';
|
echo "ERROR: ZFS pool mismatch for $target" >&2
|
||||||
}
|
echo " Expected pool: ${zpool}" >&2
|
||||||
);
|
echo " Actual pool: $actual_pool" >&2
|
||||||
|
echo " Dataset: $dataset" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$target is on $dataset (pool: $actual_pool)"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "All paths verified successfully on pool '${zpool}'"
|
||||||
|
''}
|
||||||
|
|
||||||
|
echo "Mount validation completed for ${serviceName} (pool: ${zpool})"
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
))
|
||||||
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,9 @@
|
|||||||
(lib.serviceMountWithZpool "qbittorrent" service_configs.zpool_hdds [
|
(lib.serviceMountWithZpool "qbittorrent" service_configs.zpool_hdds [
|
||||||
service_configs.torrents_path
|
service_configs.torrents_path
|
||||||
config.services.qbittorrent.serverConfig.Preferences.Downloads.TempPath
|
config.services.qbittorrent.serverConfig.Preferences.Downloads.TempPath
|
||||||
|
|
||||||
|
])
|
||||||
|
(lib.serviceMountWithZpool "qbittorrent" service_configs.zpool_ssds [
|
||||||
"${config.services.qbittorrent.profileDir}/qBittorrent"
|
"${config.services.qbittorrent.profileDir}/qBittorrent"
|
||||||
])
|
])
|
||||||
(lib.vpnNamespaceOpenPort config.services.qbittorrent.webuiPort "qbittorrent")
|
(lib.vpnNamespaceOpenPort config.services.qbittorrent.webuiPort "qbittorrent")
|
||||||
|
|||||||
@ -21,6 +21,10 @@ testPkgs.testers.runNixOSTest {
|
|||||||
|
|
||||||
# Test service with paths outside zpool (should fail assertion)
|
# Test service with paths outside zpool (should fail assertion)
|
||||||
(lib.serviceMountWithZpool "invalid-service" "rpool2" [ "/mnt/rpool_data" ])
|
(lib.serviceMountWithZpool "invalid-service" "rpool2" [ "/mnt/rpool_data" ])
|
||||||
|
|
||||||
|
# Test multi-command logic: service with multiple serviceMountWithZpool calls
|
||||||
|
(lib.serviceMountWithZpool "multi-service" "rpool" [ "/mnt/rpool_data" ])
|
||||||
|
(lib.serviceMountWithZpool "multi-service" "rpool2" [ "/mnt/rpool2_data" ])
|
||||||
];
|
];
|
||||||
|
|
||||||
virtualisation = {
|
virtualisation = {
|
||||||
@ -56,6 +60,14 @@ testPkgs.testers.runNixOSTest {
|
|||||||
ExecStart = lib.getExe pkgs.bash;
|
ExecStart = lib.getExe pkgs.bash;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
systemd.services."multi-service" = {
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
ExecStart = lib.getExe pkgs.bash;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
@ -105,6 +117,7 @@ testPkgs.testers.runNixOSTest {
|
|||||||
assert "Expected pool: rpool2" in journal_output
|
assert "Expected pool: rpool2" in journal_output
|
||||||
assert "Actual pool: rpool" in journal_output
|
assert "Actual pool: rpool" in journal_output
|
||||||
|
|
||||||
print("SUCCESS: Runtime validation correctly detected zpool mismatch!")
|
machine.succeed("systemctl start multi-service")
|
||||||
|
machine.succeed("systemctl is-active multi-service-mounts.service")
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user