1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8 cfg = config.services.icecast;
9 configFile = pkgs.writeText "icecast.xml" ''
10 <icecast>
11 <hostname>${cfg.hostname}</hostname>
12
13 <authentication>
14 <admin-user>${cfg.admin.user}</admin-user>
15 <admin-password>${cfg.admin.password}</admin-password>
16 </authentication>
17
18 <paths>
19 <logdir>${cfg.logDir}</logdir>
20 <adminroot>${pkgs.icecast}/share/icecast/admin</adminroot>
21 <webroot>${pkgs.icecast}/share/icecast/web</webroot>
22 <alias source="/" dest="/status.xsl"/>
23 </paths>
24
25 <listen-socket>
26 <port>${toString cfg.listen.port}</port>
27 <bind-address>${cfg.listen.address}</bind-address>
28 </listen-socket>
29
30 <security>
31 <chroot>0</chroot>
32 <changeowner>
33 <user>${cfg.user}</user>
34 <group>${cfg.group}</group>
35 </changeowner>
36 </security>
37
38 ${cfg.extraConf}
39 </icecast>
40 '';
41in
42{
43
44 ###### interface
45
46 options = {
47
48 services.icecast = {
49
50 enable = lib.mkEnableOption "Icecast server";
51
52 hostname = lib.mkOption {
53 type = lib.types.nullOr lib.types.str;
54 description = "DNS name or IP address that will be used for the stream directory lookups or possibly the playlist generation if a Host header is not provided.";
55 default = config.networking.domain;
56 defaultText = lib.literalExpression "config.networking.domain";
57 };
58
59 admin = {
60 user = lib.mkOption {
61 type = lib.types.str;
62 description = "Username used for all administration functions.";
63 default = "admin";
64 };
65
66 password = lib.mkOption {
67 type = lib.types.str;
68 description = "Password used for all administration functions.";
69 };
70 };
71
72 logDir = lib.mkOption {
73 type = lib.types.path;
74 description = "Base directory used for logging.";
75 default = "/var/log/icecast";
76 };
77
78 listen = {
79 port = lib.mkOption {
80 type = lib.types.port;
81 description = "TCP port that will be used to accept client connections.";
82 default = 8000;
83 };
84
85 address = lib.mkOption {
86 type = lib.types.str;
87 description = "Address Icecast will listen on.";
88 default = "::";
89 };
90 };
91
92 user = lib.mkOption {
93 type = lib.types.str;
94 description = "User privileges for the server.";
95 default = "nobody";
96 };
97
98 group = lib.mkOption {
99 type = lib.types.str;
100 description = "Group privileges for the server.";
101 default = "nogroup";
102 };
103
104 extraConf = lib.mkOption {
105 type = lib.types.lines;
106 description = "icecast.xml content.";
107 default = "";
108 };
109
110 };
111
112 };
113
114 ###### implementation
115
116 config = lib.mkIf cfg.enable {
117
118 systemd.services.icecast = {
119 after = [ "network.target" ];
120 description = "Icecast Network Audio Streaming Server";
121 wantedBy = [ "multi-user.target" ];
122
123 preStart = "mkdir -p ${cfg.logDir} && chown ${cfg.user}:${cfg.group} ${cfg.logDir}";
124 serviceConfig = {
125 Type = "simple";
126 ExecStart = "${pkgs.icecast}/bin/icecast -c ${configFile}";
127 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
128 };
129 };
130
131 };
132
133}