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