at 25.11-pre 4.1 kB view raw
1{ 2 pkgs, 3 config, 4 lib, 5 ... 6}: 7 8let 9 cfg = config.services.mympd; 10in 11{ 12 options = { 13 14 services.mympd = { 15 16 enable = lib.mkEnableOption "MyMPD server"; 17 18 package = lib.mkPackageOption pkgs "mympd" { }; 19 20 openFirewall = lib.mkOption { 21 type = lib.types.bool; 22 default = false; 23 description = '' 24 Open ports needed for the functionality of the program. 25 ''; 26 }; 27 28 extraGroups = lib.mkOption { 29 type = lib.types.listOf lib.types.str; 30 default = [ ]; 31 example = [ "music" ]; 32 description = '' 33 Additional groups for the systemd service. 34 ''; 35 }; 36 37 settings = lib.mkOption { 38 type = lib.types.submodule { 39 freeformType = 40 with lib.types; 41 attrsOf ( 42 nullOr (oneOf [ 43 str 44 bool 45 int 46 ]) 47 ); 48 options = { 49 http_port = lib.mkOption { 50 type = lib.types.port; 51 description = '' 52 The HTTP port where mympd's web interface will be available. 53 54 The HTTPS/SSL port can be configured via {option}`config`. 55 ''; 56 example = "8080"; 57 }; 58 59 ssl = lib.mkOption { 60 type = lib.types.bool; 61 description = '' 62 Whether to enable listening on the SSL port. 63 64 Refer to <https://jcorporation.github.io/myMPD/configuration/configuration-files#ssl-options> 65 for more information. 66 ''; 67 default = false; 68 }; 69 }; 70 }; 71 description = '' 72 Manages the configuration files declaratively. For all the configuration 73 options, see <https://jcorporation.github.io/myMPD/configuration/configuration-files>. 74 75 Each key represents the "File" column from the upstream configuration table, and the 76 value is the content of that file. 77 ''; 78 }; 79 }; 80 81 }; 82 83 config = lib.mkIf cfg.enable { 84 systemd.services.mympd = { 85 # upstream service config: https://github.com/jcorporation/myMPD/blob/master/contrib/initscripts/mympd.service.in 86 after = [ "mpd.service" ]; 87 wantedBy = [ "multi-user.target" ]; 88 preStart = with lib; '' 89 config_dir="/var/lib/mympd/config" 90 mkdir -p "$config_dir" 91 92 ${pipe cfg.settings [ 93 (mapAttrsToList ( 94 name: value: '' 95 echo -n "${if isBool value then boolToString value else toString value}" > "$config_dir/${name}" 96 '' 97 )) 98 (concatStringsSep "\n") 99 ]} 100 ''; 101 unitConfig = { 102 Description = "myMPD server daemon"; 103 Documentation = "man:mympd(1)"; 104 }; 105 serviceConfig = { 106 AmbientCapabilities = "CAP_NET_BIND_SERVICE"; 107 CapabilityBoundingSet = "CAP_NET_BIND_SERVICE"; 108 DynamicUser = true; 109 ExecStart = lib.getExe cfg.package; 110 LockPersonality = true; 111 MemoryDenyWriteExecute = true; 112 PrivateDevices = true; 113 ProtectClock = true; 114 ProtectControlGroups = true; 115 ProtectHome = true; 116 ProtectHostname = true; 117 ProtectKernelLogs = true; 118 ProtectKernelModules = true; 119 ProtectKernelTunables = true; 120 ProtectProc = "invisible"; 121 RestrictRealtime = true; 122 StateDirectory = "mympd"; 123 CacheDirectory = "mympd"; 124 RestrictAddressFamilies = "AF_INET AF_INET6 AF_NETLINK AF_UNIX"; 125 RestrictNamespaces = true; 126 SystemCallArchitectures = "native"; 127 SystemCallFilter = "@system-service"; 128 SupplementaryGroups = cfg.extraGroups; 129 }; 130 }; 131 132 networking.firewall = lib.mkMerge [ 133 (lib.mkIf cfg.openFirewall { 134 allowedTCPPorts = [ cfg.settings.http_port ]; 135 }) 136 (lib.mkIf (cfg.openFirewall && cfg.settings.ssl && cfg.settings.ssl_port != null) { 137 allowedTCPPorts = [ cfg.settings.ssl_port ]; 138 }) 139 ]; 140 141 }; 142 143 meta.maintainers = [ lib.maintainers.eliandoran ]; 144 145}