1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 cfg = config.services.shairport-sync;
8
9in
10
11{
12
13 ###### interface
14
15 options = {
16
17 services.shairport-sync = {
18
19 enable = mkOption {
20 type = types.bool;
21 default = false;
22 description = lib.mdDoc ''
23 Enable the shairport-sync daemon.
24
25 Running with a local system-wide or remote pulseaudio server
26 is recommended.
27 '';
28 };
29
30 arguments = mkOption {
31 type = types.str;
32 default = "-v -o pa";
33 description = lib.mdDoc ''
34 Arguments to pass to the daemon. Defaults to a local pulseaudio
35 server.
36 '';
37 };
38
39 openFirewall = mkOption {
40 type = types.bool;
41 default = false;
42 description = lib.mdDoc ''
43 Whether to automatically open ports in the firewall.
44 '';
45 };
46
47 user = mkOption {
48 type = types.str;
49 default = "shairport";
50 description = lib.mdDoc ''
51 User account name under which to run shairport-sync. The account
52 will be created.
53 '';
54 };
55
56 group = mkOption {
57 type = types.str;
58 default = "shairport";
59 description = lib.mdDoc ''
60 Group account name under which to run shairport-sync. The account
61 will be created.
62 '';
63 };
64
65 };
66
67 };
68
69
70 ###### implementation
71
72 config = mkIf config.services.shairport-sync.enable {
73
74 services.avahi.enable = true;
75 services.avahi.publish.enable = true;
76 services.avahi.publish.userServices = true;
77
78 users = {
79 users.${cfg.user} = {
80 description = "Shairport user";
81 isSystemUser = true;
82 createHome = true;
83 home = "/var/lib/shairport-sync";
84 group = cfg.group;
85 extraGroups = [ "audio" ] ++ optional config.hardware.pulseaudio.enable "pulse";
86 };
87 groups.${cfg.group} = {};
88 };
89
90 networking.firewall = mkIf cfg.openFirewall {
91 allowedTCPPorts = [ 5000 ];
92 allowedUDPPortRanges = [ { from = 6001; to = 6011; } ];
93 };
94
95 systemd.services.shairport-sync =
96 {
97 description = "shairport-sync";
98 after = [ "network.target" "avahi-daemon.service" ];
99 wantedBy = [ "multi-user.target" ];
100 serviceConfig = {
101 User = cfg.user;
102 Group = cfg.group;
103 ExecStart = "${pkgs.shairport-sync}/bin/shairport-sync ${cfg.arguments}";
104 RuntimeDirectory = "shairport-sync";
105 };
106 };
107
108 environment.systemPackages = [ pkgs.shairport-sync ];
109
110 };
111
112}