nixos/polaris: init

authored by Peder Bergebakken Sundt and committed by Yt 50dd61a9 50ba995a

+184
+1
nixos/modules/module-list.nix
··· 615 615 ./services/misc/plex.nix 616 616 ./services/misc/plikd.nix 617 617 ./services/misc/podgrab.nix 618 + ./services/misc/polaris.nix 618 619 ./services/misc/prowlarr.nix 619 620 ./services/misc/tautulli.nix 620 621 ./services/misc/pinnwand.nix
+151
nixos/modules/services/misc/polaris.nix
··· 1 + { config 2 + , pkgs 3 + , lib 4 + , ...}: 5 + 6 + with lib; 7 + let 8 + cfg = config.services.polaris; 9 + settingsFormat = pkgs.formats.toml {}; 10 + in 11 + { 12 + options = { 13 + services.polaris = { 14 + enable = mkEnableOption "Polaris Music Server"; 15 + 16 + package = mkPackageOption pkgs "polaris" { }; 17 + 18 + user = mkOption { 19 + type = types.str; 20 + default = "polaris"; 21 + description = "User account under which Polaris runs."; 22 + }; 23 + 24 + group = mkOption { 25 + type = types.str; 26 + default = "polaris"; 27 + description = "Group under which Polaris is run."; 28 + }; 29 + 30 + extraGroups = mkOption { 31 + type = types.listOf types.str; 32 + default = []; 33 + description = "Polaris' auxiliary groups."; 34 + example = literalExpression ''["media" "music"]''; 35 + }; 36 + 37 + port = mkOption { 38 + type = types.port; 39 + default = 5050; 40 + description = '' 41 + The port which the Polaris REST api and web UI should listen to. 42 + Note: polaris is hardcoded to listen to the hostname "0.0.0.0". 43 + ''; 44 + }; 45 + 46 + settings = mkOption { 47 + type = settingsFormat.type; 48 + default = {}; 49 + description = '' 50 + Contents for the TOML Polaris config, applied each start. 51 + Although poorly documented, an example may be found here: 52 + <link xlink:href="https://github.com/agersant/polaris/blob/374d0ca56fc0a466d797a4b252e2078607476797/test-data/config.toml">test-config.toml</link> 53 + ''; 54 + example = literalExpression '' 55 + { 56 + settings.reindex_every_n_seconds = 7*24*60*60; # weekly, default is 1800 57 + settings.album_art_pattern = 58 + "(cover|front|folder)\.(jpeg|jpg|png|bmp|gif)"; 59 + mount_dirs = [ 60 + { 61 + name = "NAS"; 62 + source = "/mnt/nas/music"; 63 + } 64 + { 65 + name = "Local"; 66 + source = "/home/my_user/Music"; 67 + } 68 + ]; 69 + } 70 + ''; 71 + }; 72 + 73 + openFirewall = mkOption { 74 + type = types.bool; 75 + default = false; 76 + description = '' 77 + Open the configured port in the firewall. 78 + ''; 79 + }; 80 + }; 81 + }; 82 + 83 + config = mkIf cfg.enable { 84 + systemd.services.polaris = { 85 + description = "Polaris Music Server"; 86 + after = [ "network.target" ]; 87 + wantedBy = [ "multi-user.target" ]; 88 + 89 + serviceConfig = rec { 90 + User = cfg.user; 91 + Group = cfg.group; 92 + DynamicUser = true; 93 + SupplementaryGroups = cfg.extraGroups; 94 + StateDirectory = "polaris"; 95 + CacheDirectory = "polaris"; 96 + ExecStart = escapeShellArgs ([ 97 + "${cfg.package}/bin/polaris" 98 + "--foreground" 99 + "--port" cfg.port 100 + "--database" "/var/lib/${StateDirectory}/db.sqlite" 101 + "--cache" "/var/cache/${CacheDirectory}" 102 + ] ++ optionals (cfg.settings != {}) [ 103 + "--config" (settingsFormat.generate "polaris-config.toml" cfg.settings) 104 + ]); 105 + Restart = "on-failure"; 106 + 107 + # Security options: 108 + 109 + #NoNewPrivileges = true; # implied by DynamicUser 110 + #RemoveIPC = true; # implied by DynamicUser 111 + 112 + AmbientCapabilities = ""; 113 + CapabilityBoundingSet = ""; 114 + 115 + DeviceAllow = ""; 116 + 117 + LockPersonality = true; 118 + 119 + #PrivateTmp = true; # implied by DynamicUser 120 + PrivateDevices = true; 121 + PrivateUsers = true; 122 + 123 + ProtectClock = true; 124 + ProtectControlGroups = true; 125 + ProtectHostname = true; 126 + ProtectKernelLogs = true; 127 + ProtectKernelModules = true; 128 + ProtectKernelTunables = true; 129 + 130 + RestrictNamespaces = true; 131 + RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ]; 132 + RestrictRealtime = true; 133 + #RestrictSUIDSGID = true; # implied by DynamicUser 134 + 135 + SystemCallArchitectures = "native"; 136 + SystemCallErrorNumber = "EPERM"; 137 + SystemCallFilter = [ 138 + "@system-service" 139 + "~@cpu-emulation" "~@debug" "~@keyring" "~@memlock" "~@obsolete" "~@privileged" "~@setuid" 140 + ]; 141 + }; 142 + }; 143 + 144 + networking.firewall = mkIf cfg.openFirewall { 145 + allowedTCPPorts = [ cfg.port ]; 146 + }; 147 + 148 + }; 149 + 150 + meta.maintainers = with maintainers; [ pbsds ]; 151 + }
+1
nixos/tests/all-tests.nix
··· 439 439 podman = handleTestOn ["x86_64-linux"] ./podman/default.nix {}; 440 440 podman-dnsname = handleTestOn ["x86_64-linux"] ./podman/dnsname.nix {}; 441 441 podman-tls-ghostunnel = handleTestOn ["x86_64-linux"] ./podman/tls-ghostunnel.nix {}; 442 + polaris = handleTest ./polaris.nix {}; 442 443 pomerium = handleTestOn ["x86_64-linux"] ./pomerium.nix {}; 443 444 postfix = handleTest ./postfix.nix {}; 444 445 postfix-raise-smtpd-tls-security-level = handleTest ./postfix-raise-smtpd-tls-security-level.nix {};
+31
nixos/tests/polaris.nix
··· 1 + import ./make-test-python.nix ({ lib, ... }: 2 + 3 + with lib; 4 + 5 + { 6 + name = "polaris"; 7 + meta.maintainers = with maintainers; [ pbsds ]; 8 + 9 + nodes.machine = 10 + { pkgs, ... }: { 11 + environment.systemPackages = [ pkgs.jq ]; 12 + services.polaris = { 13 + enable = true; 14 + port = 5050; 15 + settings.users = [ 16 + { 17 + name = "test_user"; 18 + password = "very_secret_password"; 19 + admin = true; 20 + } 21 + ]; 22 + }; 23 + }; 24 + 25 + testScript = '' 26 + machine.wait_for_unit("polaris.service") 27 + machine.wait_for_open_port("5050") 28 + machine.succeed("curl http://localhost:5050/api/version") 29 + machine.succeed("curl -X GET http://localhost:5050/api/initial_setup -H 'accept: application/json' | jq -e '.has_any_users == true'") 30 + ''; 31 + })