1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8 cfg = config.services.ympd;
9in
10{
11
12 ###### interface
13
14 options = {
15
16 services.ympd = {
17
18 enable = lib.mkEnableOption "ympd, the MPD Web GUI";
19
20 webPort = lib.mkOption {
21 type = lib.types.either lib.types.str lib.types.port; # string for backwards compat
22 default = "8080";
23 description = "The port where ympd's web interface will be available.";
24 example = "ssl://8080:/path/to/ssl-private-key.pem";
25 };
26
27 mpd = {
28 host = lib.mkOption {
29 type = lib.types.str;
30 default = "localhost";
31 description = "The host where MPD is listening.";
32 };
33
34 port = lib.mkOption {
35 type = lib.types.port;
36 default = config.services.mpd.network.port;
37 defaultText = lib.literalExpression "config.services.mpd.network.port";
38 description = "The port where MPD is listening.";
39 example = 6600;
40 };
41 };
42
43 };
44
45 };
46
47 ###### implementation
48
49 config = lib.mkIf cfg.enable {
50
51 systemd.services.ympd = {
52 description = "Standalone MPD Web GUI written in C";
53
54 wantedBy = [ "multi-user.target" ];
55 wants = [ "network-online.target" ];
56 after = [ "network-online.target" ];
57
58 serviceConfig = {
59 ExecStart = ''
60 ${pkgs.ympd}/bin/ympd \
61 --host ${cfg.mpd.host} \
62 --port ${toString cfg.mpd.port} \
63 --webport ${toString cfg.webPort}
64 '';
65
66 DynamicUser = true;
67 NoNewPrivileges = true;
68
69 ProtectProc = "invisible";
70 ProtectSystem = "strict";
71 ProtectHome = "tmpfs";
72
73 PrivateTmp = true;
74 PrivateDevices = true;
75 PrivateIPC = true;
76
77 ProtectHostname = true;
78 ProtectClock = true;
79 ProtectKernelTunables = true;
80 ProtectKernelModules = true;
81 ProtectKernelLogs = true;
82 ProtectControlGroups = true;
83
84 RestrictAddressFamilies = [
85 "AF_INET"
86 "AF_INET6"
87 ];
88 RestrictRealtime = true;
89 RestrictSUIDSGID = true;
90
91 SystemCallFilter = [
92 "@system-service"
93 "~@process"
94 "~@setuid"
95 ];
96 };
97 };
98
99 };
100
101}