1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.subsonic;
7 homeDir = "/var/subsonic";
8
9in
10{
11 options = {
12 services.subsonic = {
13 enable = mkEnableOption "Subsonic daemon";
14
15 home = mkOption {
16 type = types.path;
17 default = "${homeDir}";
18 description = ''
19 The directory where Subsonic will create files.
20 Make sure it is writable.
21 '';
22 };
23
24 host = mkOption {
25 type = types.string;
26 default = "0.0.0.0";
27 description = ''
28 The host name or IP address on which to bind Subsonic.
29 Only relevant if you have multiple network interfaces and want
30 to make Subsonic available on only one of them. The default value
31 will bind Subsonic to all available network interfaces.
32 '';
33 };
34
35 port = mkOption {
36 type = types.int;
37 default = 4040;
38 description = ''
39 The port on which Subsonic will listen for
40 incoming HTTP traffic. Set to 0 to disable.
41 '';
42 };
43
44 httpsPort = mkOption {
45 type = types.int;
46 default = 0;
47 description = ''
48 The port on which Subsonic will listen for
49 incoming HTTPS traffic. Set to 0 to disable.
50 '';
51 };
52
53 contextPath = mkOption {
54 type = types.path;
55 default = "/";
56 description = ''
57 The context path, i.e., the last part of the Subsonic
58 URL. Typically '/' or '/subsonic'. Default '/'
59 '';
60 };
61
62 maxMemory = mkOption {
63 type = types.int;
64 default = 100;
65 description = ''
66 The memory limit (max Java heap size) in megabytes.
67 Default: 100
68 '';
69 };
70
71 defaultMusicFolder = mkOption {
72 type = types.path;
73 default = "/var/music";
74 description = ''
75 Configure Subsonic to use this folder for music. This option
76 only has effect the first time Subsonic is started.
77 '';
78 };
79
80 defaultPodcastFolder = mkOption {
81 type = types.path;
82 default = "/var/music/Podcast";
83 description = ''
84 Configure Subsonic to use this folder for Podcasts. This option
85 only has effect the first time Subsonic is started.
86 '';
87 };
88
89 defaultPlaylistFolder = mkOption {
90 type = types.path;
91 default = "/var/playlists";
92 description = ''
93 Configure Subsonic to use this folder for playlists. This option
94 only has effect the first time Subsonic is started.
95 '';
96 };
97
98 transcoders = mkOption {
99 type = types.listOf types.path;
100 description = ''
101 List of paths to transcoder executables that should be accessible
102 from Subsonic. Symlinks will be created to each executable inside
103 ${cfg.home}/transcoders.
104 '';
105 };
106 };
107 };
108
109 config = mkIf cfg.enable {
110 systemd.services.subsonic = {
111 description = "Personal media streamer";
112 after = [ "local-fs.target" "network.target" ];
113 wantedBy = [ "multi-user.target" ];
114 serviceConfig = {
115 ExecStart = ''
116 ${pkgs.jre}/bin/java -Xmx${toString cfg.maxMemory}m \
117 -Dsubsonic.home=${cfg.home} \
118 -Dsubsonic.host=${cfg.host} \
119 -Dsubsonic.port=${toString cfg.port} \
120 -Dsubsonic.httpsPort=${toString cfg.httpsPort} \
121 -Dsubsonic.contextPath=${cfg.contextPath} \
122 -Dsubsonic.defaultMusicFolder=${cfg.defaultMusicFolder} \
123 -Dsubsonic.defaultPodcastFolder=${cfg.defaultPodcastFolder} \
124 -Dsubsonic.defaultPlaylistFolder=${cfg.defaultPlaylistFolder} \
125 -Djava.awt.headless=true \
126 -verbose:gc \
127 -jar ${pkgs.subsonic}/subsonic-booter-jar-with-dependencies.jar
128 '';
129 # Install transcoders.
130 ExecStartPre = ''
131 ${pkgs.coreutils}/bin/rm -rf ${cfg.home}/transcode ; \
132 ${pkgs.coreutils}/bin/mkdir -p ${cfg.home}/transcode ; \
133 ${pkgs.bash}/bin/bash -c ' \
134 for exe in "$@"; do \
135 ${pkgs.coreutils}/bin/ln -sf "$exe" ${cfg.home}/transcode; \
136 done' IGNORED_FIRST_ARG ${toString cfg.transcoders}
137 '';
138 # Needed for Subsonic to find subsonic.war.
139 WorkingDirectory = "${pkgs.subsonic}";
140 Restart = "always";
141 User = "subsonic";
142 UMask = "0022";
143 };
144 };
145
146 users.extraUsers.subsonic = {
147 description = "Subsonic daemon user";
148 home = homeDir;
149 createHome = true;
150 group = "subsonic";
151 uid = config.ids.uids.subsonic;
152 };
153
154 users.extraGroups.subsonic.gid = config.ids.gids.subsonic;
155
156 services.subsonic.transcoders = mkDefault [ "${pkgs.ffmpeg}/bin/ffmpeg" ];
157
158 };
159}