144 lines
5.0 KiB
Nix
144 lines
5.0 KiB
Nix
# Comprehensive test for Nixarr file permissions, user/group creation, and directory structure
|
|
{
|
|
pkgs,
|
|
nixosModules,
|
|
lib ? pkgs.lib,
|
|
}:
|
|
pkgs.nixosTest {
|
|
name = "nixarr-permissions-test";
|
|
|
|
nodes.machine = {
|
|
config,
|
|
pkgs,
|
|
...
|
|
}: {
|
|
imports = [nixosModules.default];
|
|
|
|
networking.firewall.enable = false;
|
|
|
|
nixarr = {
|
|
enable = true;
|
|
stateDir = "/data/.state/nixarr";
|
|
mediaDir = "/data/media";
|
|
mediaUsers = ["testuser"];
|
|
|
|
# Enable key services to trigger tmpfiles directory creation
|
|
jellyfin.enable = true;
|
|
|
|
transmission = {
|
|
enable = true;
|
|
vpn.enable = false;
|
|
privateTrackers.cross-seed.enable = true;
|
|
};
|
|
|
|
sonarr = {
|
|
enable = true;
|
|
vpn.enable = false;
|
|
};
|
|
|
|
radarr = {
|
|
enable = true;
|
|
vpn.enable = false;
|
|
};
|
|
|
|
lidarr = {
|
|
enable = true;
|
|
vpn.enable = false;
|
|
};
|
|
|
|
prowlarr = {
|
|
enable = true;
|
|
vpn.enable = false;
|
|
};
|
|
};
|
|
|
|
# Create a test user to verify mediaUsers functionality
|
|
users.users.testuser = {
|
|
isNormalUser = true;
|
|
home = "/home/testuser";
|
|
};
|
|
};
|
|
|
|
testScript = ''
|
|
machine.wait_for_unit("multi-user.target")
|
|
print("Starting Nixarr permissions test...")
|
|
|
|
# Test 1: Verify key users and groups exist
|
|
print("\n=== Testing User/Group Creation ===")
|
|
|
|
# Check essential users exist
|
|
key_users = ["jellyfin", "transmission", "sonarr", "radarr", "testuser"]
|
|
for user in key_users:
|
|
machine.succeed(f"id {user}")
|
|
print(f"✓ User {user} exists")
|
|
|
|
# Check media group exists and has correct members
|
|
media_members = machine.succeed("getent group media | cut -d: -f4").strip()
|
|
expected_members = ["jellyfin", "transmission", "sonarr", "radarr", "lidarr", "testuser"]
|
|
for member in expected_members:
|
|
if member in media_members:
|
|
print(f"✓ {member} is in media group")
|
|
else:
|
|
machine.fail(f"{member} not in media group")
|
|
|
|
# Test 2: Verify directory structure and ownership
|
|
print("\n=== Testing Directory Permissions ===")
|
|
|
|
def check_dir(path, expected_user, expected_group, description):
|
|
stat_output = machine.succeed(f"stat -c '%U:%G' '{path}'").strip()
|
|
user, group = stat_output.split(":")
|
|
if user == expected_user and group == expected_group:
|
|
print(f"✓ {description}: {user}:{group}")
|
|
else:
|
|
machine.fail(f"{description} has wrong ownership: {user}:{group}, expected {expected_user}:{expected_group}")
|
|
|
|
# Check key directories exist with correct ownership
|
|
check_dir("/data/media", "root", "media", "Media root directory")
|
|
check_dir("/data/media/library/movies", "root", "media", "Movies directory")
|
|
check_dir("/data/media/library/shows", "root", "media", "Shows directory")
|
|
check_dir("/data/media/library/music", "root", "media", "Music directory")
|
|
check_dir("/data/media/torrents", "transmission", "media", "Torrents directory")
|
|
|
|
# Test 3: Verify service file access
|
|
print("\n=== Testing Service File Access ===")
|
|
|
|
# Test Jellyfin can write to media directories
|
|
test_dirs = ["/data/media/library/movies", "/data/media/library/shows"]
|
|
for test_dir in test_dirs:
|
|
if machine.succeed(f"test -d '{test_dir}' && echo 'exists' || echo 'missing'").strip() == "exists":
|
|
test_file = f"{test_dir}/jellyfin-test.txt"
|
|
machine.succeed(f"sudo -u jellyfin touch '{test_file}'")
|
|
machine.succeed(f"sudo -u jellyfin sh -c 'echo test > {test_file}'")
|
|
content = machine.succeed(f"cat '{test_file}'").strip()
|
|
if content != "test":
|
|
machine.fail(f"Expected 'test' but got '{content}'")
|
|
machine.succeed(f"sudo -u jellyfin rm '{test_file}'")
|
|
print(f"✓ Jellyfin can write/read/delete in {test_dir}")
|
|
|
|
# Test 4: Verify fix-permissions command
|
|
print("\n=== Testing fix-permissions Command ===")
|
|
|
|
# Create file with wrong permissions
|
|
test_file = "/data/media/library/movies/test-wrong-perms.txt"
|
|
if machine.succeed("test -d '/data/media/library/movies' && echo 'exists' || echo 'missing'").strip() == "exists":
|
|
machine.succeed(f"umask 077 && touch '{test_file}'")
|
|
|
|
# Verify initial permissions are wrong
|
|
initial_perms = machine.succeed(f"stat -c '%a' '{test_file}'").strip()
|
|
if initial_perms != "600":
|
|
machine.fail(f"Expected 600 permissions, got {initial_perms}")
|
|
|
|
machine.succeed("nixarr fix-permissions")
|
|
|
|
# Verify permissions were fixed
|
|
fixed_perms = machine.succeed(f"stat -c '%a' '{test_file}'").strip()
|
|
if fixed_perms not in ["644", "664"]:
|
|
machine.fail(f"fix-permissions failed: permissions are {fixed_perms}, expected 644 or 664")
|
|
|
|
machine.succeed(f"rm '{test_file}'")
|
|
print(f"✓ fix-permissions corrected file permissions from 600 to {fixed_perms}")
|
|
|
|
print("\n=== All Permission Tests Completed ===")
|
|
'';
|
|
}
|