grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / services / video / unifi-video.nix
blob99c04bafd141031ee3f1ee13b0f38a10e157e8d6
1 { config, lib, options, pkgs, utils, ... }:
2 with lib;
3 let
4   cfg = config.services.unifi-video;
5   opt = options.services.unifi-video;
6   mainClass = "com.ubnt.airvision.Main";
7   cmd = ''
8     ${pkgs.jsvc}/bin/jsvc \
9     -cwd ${stateDir} \
10     -debug \
11     -verbose:class \
12     -nodetach \
13     -user unifi-video \
14     -home ${cfg.jrePackage}/lib/openjdk \
15     -cp ${pkgs.commonsDaemon}/share/java/commons-daemon-1.2.4.jar:${stateDir}/lib/airvision.jar \
16     -pidfile ${cfg.pidFile} \
17     -procname unifi-video \
18     -Djava.security.egd=file:/dev/./urandom \
19     -Xmx${toString cfg.maximumJavaHeapSize}M \
20     -Xss512K \
21     -XX:+UseG1GC \
22     -XX:+UseStringDeduplication \
23     -XX:MaxMetaspaceSize=768M \
24     -Djava.library.path=${stateDir}/lib \
25     -Djava.awt.headless=true \
26     -Djavax.net.ssl.trustStore=${stateDir}/etc/ufv-truststore \
27     -Dfile.encoding=UTF-8 \
28     -Dav.tempdir=/var/cache/unifi-video
29   '';
31   mongoConf = pkgs.writeTextFile {
32     name = "mongo.conf";
33     executable = false;
34     text = ''
35       # for documentation of all options, see https://www.mongodb.com/docs/manual/reference/configuration-options/
37       storage:
38          dbPath: ${cfg.dataDir}/db
39          journal:
40             enabled: true
41          syncPeriodSecs: 60
43       systemLog:
44          destination: file
45          logAppend: true
46          path: ${stateDir}/logs/mongod.log
48       net:
49          port: 7441
50          bindIp: 127.0.0.1
51          http:
52             enabled: false
54       operationProfiling:
55          slowOpThresholdMs: 500
56          mode: off
57     '';
58   };
61   mongoWtConf = pkgs.writeTextFile {
62     name = "mongowt.conf";
63     executable = false;
64     text = ''
65       # for documentation of all options, see:
66       #   https://www.mongodb.com/docs/manual/reference/configuration-options/
68       storage:
69          dbPath: ${cfg.dataDir}/db-wt
70          journal:
71             enabled: true
72          wiredTiger:
73             engineConfig:
74                cacheSizeGB: 1
76       systemLog:
77          destination: file
78          logAppend: true
79          path: logs/mongod.log
81       net:
82          port: 7441
83          bindIp: 127.0.0.1
85       operationProfiling:
86          slowOpThresholdMs: 500
87          mode: off
88     '';
89   };
91   stateDir = "/var/lib/unifi-video";
96   options.services.unifi-video = {
98     enable = mkOption {
99       type = types.bool;
100       default = false;
101       description = ''
102         Whether or not to enable the unifi-video service.
103       '';
104     };
106     jrePackage = mkPackageOption pkgs "jre8" { };
108     unifiVideoPackage = mkPackageOption pkgs "unifi-video" { };
110     mongodbPackage = mkPackageOption pkgs "mongodb" {
111       default = "mongodb-5_0";
112     };
114     logDir = mkOption {
115       type = types.str;
116       default = "${stateDir}/logs";
117       description = ''
118         Where to store the logs.
119       '';
120     };
122     dataDir = mkOption {
123       type = types.str;
124       default = "${stateDir}/data";
125       description = ''
126         Where to store the database and other data.
127       '';
128     };
130     openFirewall = mkOption {
131       type = types.bool;
132       default = false;
133       description = ''
134         Whether or not to open the required ports on the firewall.
135       '';
136     };
138     maximumJavaHeapSize = mkOption {
139       type = types.nullOr types.int;
140       default = 1024;
141       example = 4096;
142       description = ''
143         Set the maximum heap size for the JVM in MB.
144       '';
145     };
147     pidFile = mkOption {
148       type = types.path;
149       default = "${cfg.dataDir}/unifi-video.pid";
150       defaultText = literalExpression ''"''${config.${opt.dataDir}}/unifi-video.pid"'';
151       description = "Location of unifi-video pid file.";
152     };
154   };
156   config = mkIf cfg.enable {
158     warnings = optional
159       (options.services.unifi-video.openFirewall.highestPrio >= (mkOptionDefault null).priority)
160       "The current services.unifi-video.openFirewall = true default is deprecated and will change to false in 22.11. Set it explicitly to silence this warning.";
162     users.users.unifi-video = {
163       description = "UniFi Video controller daemon user";
164       home = stateDir;
165       group = "unifi-video";
166       isSystemUser = true;
167     };
168     users.groups.unifi-video = {};
170     networking.firewall = mkIf cfg.openFirewall {
171       # https://help.ui.com/hc/en-us/articles/217875218-UniFi-Video-Ports-Used
172       allowedTCPPorts = [
173         7080 # HTTP portal
174         7443 # HTTPS portal
175         7445 # Video over HTTP (mobile app)
176         7446 # Video over HTTPS (mobile app)
177         7447 # RTSP via the controller
178         7442 # Camera management from cameras to NVR over WAN
179       ];
180       allowedUDPPorts = [
181         6666 # Inbound camera streams sent over WAN
182       ];
183     };
185     systemd.tmpfiles.rules = [
186       "d '${stateDir}' 0700 unifi-video unifi-video - -"
187       "d '/var/cache/unifi-video' 0700 unifi-video unifi-video - -"
189       "d '${stateDir}/logs' 0700 unifi-video unifi-video - -"
190       "C '${stateDir}/etc' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/etc"
191       "C '${stateDir}/webapps' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/webapps"
192       "C '${stateDir}/email' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/email"
193       "C '${stateDir}/fw' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/fw"
194       "C '${stateDir}/lib' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/lib"
196       "d '${stateDir}/data' 0700 unifi-video unifi-video - -"
197       "d '${stateDir}/data/db' 0700 unifi-video unifi-video - -"
198       "C '${stateDir}/data/system.properties' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/etc/system.properties"
200       "d '${stateDir}/bin' 0700 unifi-video unifi-video - -"
201       "f '${stateDir}/bin/evostreamms' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/evostreamms"
202       "f '${stateDir}/bin/libavcodec.so.54' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/libavcodec.so.54"
203       "f '${stateDir}/bin/libavformat.so.54' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/libavformat.so.54"
204       "f '${stateDir}/bin/libavutil.so.52' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/libavutil.so.52"
205       "f '${stateDir}/bin/ubnt.avtool' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/ubnt.avtool"
206       "f '${stateDir}/bin/ubnt.updater' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/ubnt.updater"
207       "C '${stateDir}/bin/mongo' 0700 unifi-video unifi-video - ${cfg.mongodbPackage}/bin/mongo"
208       "C '${stateDir}/bin/mongod' 0700 unifi-video unifi-video - ${cfg.mongodbPackage}/bin/mongod"
209       "C '${stateDir}/bin/mongoperf' 0700 unifi-video unifi-video - ${cfg.mongodbPackage}/bin/mongoperf"
210       "C '${stateDir}/bin/mongos' 0700 unifi-video unifi-video - ${cfg.mongodbPackage}/bin/mongos"
212       "d '${stateDir}/conf' 0700 unifi-video unifi-video - -"
213       "C '${stateDir}/conf/evostream' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/evostream"
214       "Z '${stateDir}/conf/evostream' 0700 unifi-video unifi-video - -"
215       "L+ '${stateDir}/conf/mongodv3.0+.conf' 0700 unifi-video unifi-video - ${mongoConf}"
216       "L+ '${stateDir}/conf/mongodv3.6+.conf' 0700 unifi-video unifi-video - ${mongoConf}"
217       "L+ '${stateDir}/conf/mongod-wt.conf' 0700 unifi-video unifi-video - ${mongoWtConf}"
218       "L+ '${stateDir}/conf/catalina.policy' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/catalina.policy"
219       "L+ '${stateDir}/conf/catalina.properties' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/catalina.properties"
220       "L+ '${stateDir}/conf/context.xml' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/context.xml"
221       "L+ '${stateDir}/conf/logging.properties' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/logging.properties"
222       "L+ '${stateDir}/conf/server.xml' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/server.xml"
223       "L+ '${stateDir}/conf/tomcat-users.xml' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/tomcat-users.xml"
224       "L+ '${stateDir}/conf/web.xml' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/web.xml"
225     ];
227     systemd.services.unifi-video = {
228       description = "UniFi Video NVR daemon";
229       wantedBy = [ "multi-user.target" ];
230       after = [ "network.target" ] ;
231       unitConfig.RequiresMountsFor = stateDir;
232       # Make sure package upgrades trigger a service restart
233       restartTriggers = [ cfg.unifiVideoPackage cfg.mongodbPackage ];
234       path = with pkgs; [ gawk coreutils busybox which jre8 lsb-release libcap util-linux ];
235       serviceConfig = {
236         Type = "simple";
237         ExecStart = "${(removeSuffix "\n" cmd)} ${mainClass} start";
238         ExecStop = "${(removeSuffix "\n" cmd)} stop ${mainClass} stop";
239         Restart = "on-failure";
240         UMask = "0077";
241         User = "unifi-video";
242         WorkingDirectory = "${stateDir}";
243       };
244     };
245   };
247   imports = [
248     (mkRenamedOptionModule [ "services" "unifi-video" "openPorts" ] [ "services" "unifi-video" "openFirewall" ])
249   ];
251   meta.maintainers = with lib.maintainers; [ rsynnest ];