grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / services / misc / subsonic.nix
blob2dda8970dd3063afb70774ef7d185114c49ab1b8
1 { config, lib, options, pkgs, ... }:
3 with lib;
5 let
6   cfg = config.services.subsonic;
7   opt = options.services.subsonic;
8 in {
9   options = {
10     services.subsonic = {
11       enable = mkEnableOption "Subsonic daemon";
13       home = mkOption {
14         type = types.path;
15         default = "/var/lib/subsonic";
16         description = ''
17           The directory where Subsonic will create files.
18           Make sure it is writable.
19         '';
20       };
22       listenAddress = mkOption {
23         type = types.str;
24         default = "0.0.0.0";
25         description = ''
26           The host name or IP address on which to bind Subsonic.
27           Only relevant if you have multiple network interfaces and want
28           to make Subsonic available on only one of them. The default value
29           will bind Subsonic to all available network interfaces.
30         '';
31       };
33       port = mkOption {
34         type = types.port;
35         default = 4040;
36         description = ''
37           The port on which Subsonic will listen for
38           incoming HTTP traffic. Set to 0 to disable.
39         '';
40       };
42       httpsPort = mkOption {
43         type = types.port;
44         default = 0;
45         description = ''
46           The port on which Subsonic will listen for
47           incoming HTTPS traffic. Set to 0 to disable.
48         '';
49       };
51       contextPath = mkOption {
52         type = types.path;
53         default = "/";
54         description = ''
55           The context path, i.e., the last part of the Subsonic
56           URL. Typically '/' or '/subsonic'. Default '/'
57         '';
58       };
60       maxMemory = mkOption {
61         type = types.int;
62         default = 100;
63         description = ''
64           The memory limit (max Java heap size) in megabytes.
65           Default: 100
66         '';
67       };
69       defaultMusicFolder = mkOption {
70         type = types.path;
71         default = "/var/music";
72         description = ''
73           Configure Subsonic to use this folder for music.  This option
74           only has effect the first time Subsonic is started.
75         '';
76       };
78       defaultPodcastFolder = mkOption {
79         type = types.path;
80         default = "/var/music/Podcast";
81         description = ''
82           Configure Subsonic to use this folder for Podcasts.  This option
83           only has effect the first time Subsonic is started.
84         '';
85       };
87       defaultPlaylistFolder = mkOption {
88         type = types.path;
89         default = "/var/playlists";
90         description = ''
91           Configure Subsonic to use this folder for playlists.  This option
92           only has effect the first time Subsonic is started.
93         '';
94       };
96       transcoders = mkOption {
97         type = types.listOf types.path;
98         default = [ "${pkgs.ffmpeg.bin}/bin/ffmpeg" ];
99         defaultText = literalExpression ''[ "''${pkgs.ffmpeg.bin}/bin/ffmpeg" ]'';
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           ''${config.${opt.home}}/transcoders.
104         '';
105       };
106     };
107   };
109   config = mkIf cfg.enable {
110     systemd.services.subsonic = {
111       description = "Personal media streamer";
112       after = [ "network.target" ];
113       wantedBy = [ "multi-user.target" ];
114       script = ''
115         ${pkgs.jre8}/bin/java -Xmx${toString cfg.maxMemory}m \
116           -Dsubsonic.home=${cfg.home} \
117           -Dsubsonic.host=${cfg.listenAddress} \
118           -Dsubsonic.port=${toString cfg.port} \
119           -Dsubsonic.httpsPort=${toString cfg.httpsPort} \
120           -Dsubsonic.contextPath=${cfg.contextPath} \
121           -Dsubsonic.defaultMusicFolder=${cfg.defaultMusicFolder} \
122           -Dsubsonic.defaultPodcastFolder=${cfg.defaultPodcastFolder} \
123           -Dsubsonic.defaultPlaylistFolder=${cfg.defaultPlaylistFolder} \
124           -Djava.awt.headless=true \
125           -verbose:gc \
126           -jar ${pkgs.subsonic}/subsonic-booter-jar-with-dependencies.jar
127       '';
129       preStart = ''
130         # Formerly this module set cfg.home to /var/subsonic. Try to move
131         # /var/subsonic to cfg.home.
132         oldHome="/var/subsonic"
133         if [ "${cfg.home}" != "$oldHome" ] &&
134                 ! [ -e "${cfg.home}" ] &&
135                 [ -d "$oldHome" ] &&
136                 [ $(${pkgs.coreutils}/bin/stat -c %u "$oldHome") -eq \
137                     ${toString config.users.users.subsonic.uid} ]; then
138             logger Moving "$oldHome" to "${cfg.home}"
139             ${pkgs.coreutils}/bin/mv -T "$oldHome" "${cfg.home}"
140         fi
142         # Install transcoders.
143         ${pkgs.coreutils}/bin/rm -rf ${cfg.home}/transcode ; \
144         ${pkgs.coreutils}/bin/mkdir -p ${cfg.home}/transcode ; \
145         ${pkgs.bash}/bin/bash -c ' \
146           for exe in "$@"; do \
147             ${pkgs.coreutils}/bin/ln -sf "$exe" ${cfg.home}/transcode; \
148           done' IGNORED_FIRST_ARG ${toString cfg.transcoders}
149       '';
150       serviceConfig = {
151         # Needed for Subsonic to find subsonic.war.
152         WorkingDirectory = "${pkgs.subsonic}";
153         Restart = "always";
154         User = "subsonic";
155         UMask = "0022";
156       };
157     };
159     users.users.subsonic = {
160       description = "Subsonic daemon user";
161       home = cfg.home;
162       createHome = true;
163       group = "subsonic";
164       uid = config.ids.uids.subsonic;
165     };
167     users.groups.subsonic.gid = config.ids.gids.subsonic;
168   };