Merge pull request #120297 from rsynnest/master

nixos/unifi-video module and supporting packages

authored by Rok Garbas and committed by GitHub ae7c092d b4c4784f

+404
+6
maintainers/maintainer-list.nix
··· 9158 9158 githubId = 1387224; 9159 9159 name = "Richard Szibele"; 9160 9160 }; 9161 + rsynnest = { 9162 + email = "contact@rsynnest.com"; 9163 + github = "rsynnest"; 9164 + githubId = 4392850; 9165 + name = "Roland Synnestvedt"; 9166 + }; 9161 9167 rtburns-jpl = { 9162 9168 email = "rtburns@jpl.nasa.gov"; 9163 9169 github = "rtburns-jpl";
+1
nixos/modules/module-list.nix
··· 848 848 ./services/networking/ucarp.nix 849 849 ./services/networking/unbound.nix 850 850 ./services/networking/unifi.nix 851 + ./services/video/unifi-video.nix 851 852 ./services/networking/v2ray.nix 852 853 ./services/networking/vsftpd.nix 853 854 ./services/networking/wakeonlan.nix
+265
nixos/modules/services/video/unifi-video.nix
··· 1 + { config, lib, pkgs, utils, ... }: 2 + with lib; 3 + let 4 + cfg = config.services.unifi-video; 5 + mainClass = "com.ubnt.airvision.Main"; 6 + cmd = '' 7 + ${pkgs.jsvc}/bin/jsvc \ 8 + -cwd ${stateDir} \ 9 + -debug \ 10 + -verbose:class \ 11 + -nodetach \ 12 + -user unifi-video \ 13 + -home ${cfg.jrePackage}/lib/openjdk \ 14 + -cp ${pkgs.commonsDaemon}/share/java/commons-daemon-1.2.4.jar:${stateDir}/lib/airvision.jar \ 15 + -pidfile ${cfg.pidFile} \ 16 + -procname unifi-video \ 17 + -Djava.security.egd=file:/dev/./urandom \ 18 + -Xmx${cfg.maximumJavaHeapSize}M \ 19 + -Xss512K \ 20 + -XX:+UseG1GC \ 21 + -XX:+UseStringDeduplication \ 22 + -XX:MaxMetaspaceSize=768M \ 23 + -Djava.library.path=${stateDir}/lib \ 24 + -Djava.awt.headless=true \ 25 + -Djavax.net.ssl.trustStore=${stateDir}/etc/ufv-truststore \ 26 + -Dfile.encoding=UTF-8 \ 27 + -Dav.tempdir=/var/cache/unifi-video 28 + ''; 29 + 30 + mongoConf = pkgs.writeTextFile { 31 + name = "mongo.conf"; 32 + executable = false; 33 + text = '' 34 + # for documentation of all options, see http://docs.mongodb.org/manual/reference/configuration-options/ 35 + 36 + storage: 37 + dbPath: ${cfg.dataDir}/db 38 + journal: 39 + enabled: true 40 + syncPeriodSecs: 60 41 + 42 + systemLog: 43 + destination: file 44 + logAppend: true 45 + path: ${stateDir}/logs/mongod.log 46 + 47 + net: 48 + port: 7441 49 + bindIp: 127.0.0.1 50 + http: 51 + enabled: false 52 + 53 + operationProfiling: 54 + slowOpThresholdMs: 500 55 + mode: off 56 + ''; 57 + }; 58 + 59 + 60 + mongoWtConf = pkgs.writeTextFile { 61 + name = "mongowt.conf"; 62 + executable = false; 63 + text = '' 64 + # for documentation of all options, see: 65 + # http://docs.mongodb.org/manual/reference/configuration-options/ 66 + 67 + storage: 68 + dbPath: ${cfg.dataDir}/db-wt 69 + journal: 70 + enabled: true 71 + wiredTiger: 72 + engineConfig: 73 + cacheSizeGB: 1 74 + 75 + systemLog: 76 + destination: file 77 + logAppend: true 78 + path: logs/mongod.log 79 + 80 + net: 81 + port: 7441 82 + bindIp: 127.0.0.1 83 + 84 + operationProfiling: 85 + slowOpThresholdMs: 500 86 + mode: off 87 + ''; 88 + }; 89 + 90 + stateDir = "/var/lib/unifi-video"; 91 + 92 + in 93 + { 94 + 95 + options.services.unifi-video = { 96 + enable = mkOption { 97 + type = types.bool; 98 + default = false; 99 + description = '' 100 + Whether or not to enable the unifi-video service. 101 + ''; 102 + }; 103 + 104 + jrePackage = mkOption { 105 + type = types.package; 106 + default = pkgs.jre8; 107 + defaultText = "pkgs.jre8"; 108 + description = '' 109 + The JRE package to use. Check the release notes to ensure it is supported. 110 + ''; 111 + }; 112 + 113 + unifiVideoPackage = mkOption { 114 + type = types.package; 115 + default = pkgs.unifi-video; 116 + defaultText = "pkgs.unifi-video"; 117 + description = '' 118 + The unifi-video package to use. 119 + ''; 120 + }; 121 + 122 + mongodbPackage = mkOption { 123 + type = types.package; 124 + default = pkgs.mongodb-4_0; 125 + defaultText = "pkgs.mongodb"; 126 + description = '' 127 + The mongodb package to use. 128 + ''; 129 + }; 130 + 131 + logDir = mkOption { 132 + type = types.str; 133 + default = "${stateDir}/logs"; 134 + description = '' 135 + Where to store the logs. 136 + ''; 137 + }; 138 + 139 + dataDir = mkOption { 140 + type = types.str; 141 + default = "${stateDir}/data"; 142 + description = '' 143 + Where to store the database and other data. 144 + ''; 145 + }; 146 + 147 + openPorts = mkOption { 148 + type = types.bool; 149 + default = true; 150 + description = '' 151 + Whether or not to open the required ports on the firewall. 152 + ''; 153 + }; 154 + 155 + maximumJavaHeapSize = mkOption { 156 + type = types.nullOr types.int; 157 + default = 1024; 158 + example = 4096; 159 + description = '' 160 + Set the maximimum heap size for the JVM in MB. 161 + ''; 162 + }; 163 + 164 + pidFile = mkOption { 165 + type = types.path; 166 + default = "${cfg.dataDir}/unifi-video.pid"; 167 + description = "Location of unifi-video pid file."; 168 + }; 169 + 170 + }; 171 + 172 + config = mkIf cfg.enable { 173 + users = { 174 + users.unifi-video = { 175 + description = "UniFi Video controller daemon user"; 176 + home = stateDir; 177 + group = "unifi-video"; 178 + isSystemUser = true; 179 + }; 180 + groups.unifi-video = {}; 181 + }; 182 + 183 + networking.firewall = mkIf cfg.openPorts { 184 + # https://help.ui.com/hc/en-us/articles/217875218-UniFi-Video-Ports-Used 185 + allowedTCPPorts = [ 186 + 7080 # HTTP portal 187 + 7443 # HTTPS portal 188 + 7445 # Video over HTTP (mobile app) 189 + 7446 # Video over HTTPS (mobile app) 190 + 7447 # RTSP via the controller 191 + 7442 # Camera management from cameras to NVR over WAN 192 + ]; 193 + allowedUDPPorts = [ 194 + 6666 # Inbound camera streams sent over WAN 195 + ]; 196 + }; 197 + 198 + systemd.tmpfiles.rules = [ 199 + "d '${stateDir}' 0700 unifi-video unifi-video - -" 200 + "d '/var/cache/unifi-video' 0700 unifi-video unifi-video - -" 201 + 202 + "d '${stateDir}/logs' 0700 unifi-video unifi-video - -" 203 + "C '${stateDir}/etc' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/etc" 204 + "C '${stateDir}/webapps' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/webapps" 205 + "C '${stateDir}/email' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/email" 206 + "C '${stateDir}/fw' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/fw" 207 + "C '${stateDir}/lib' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/lib" 208 + 209 + "d '${stateDir}/data' 0700 unifi-video unifi-video - -" 210 + "d '${stateDir}/data/db' 0700 unifi-video unifi-video - -" 211 + "C '${stateDir}/data/system.properties' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/etc/system.properties" 212 + 213 + "d '${stateDir}/bin' 0700 unifi-video unifi-video - -" 214 + "f '${stateDir}/bin/evostreamms' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/evostreamms" 215 + "f '${stateDir}/bin/libavcodec.so.54' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/libavcodec.so.54" 216 + "f '${stateDir}/bin/libavformat.so.54' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/libavformat.so.54" 217 + "f '${stateDir}/bin/libavutil.so.52' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/libavutil.so.52" 218 + "f '${stateDir}/bin/ubnt.avtool' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/ubnt.avtool" 219 + "f '${stateDir}/bin/ubnt.updater' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/ubnt.updater" 220 + "C '${stateDir}/bin/mongo' 0700 unifi-video unifi-video - ${cfg.mongodbPackage}/bin/mongo" 221 + "C '${stateDir}/bin/mongod' 0700 unifi-video unifi-video - ${cfg.mongodbPackage}/bin/mongod" 222 + "C '${stateDir}/bin/mongoperf' 0700 unifi-video unifi-video - ${cfg.mongodbPackage}/bin/mongoperf" 223 + "C '${stateDir}/bin/mongos' 0700 unifi-video unifi-video - ${cfg.mongodbPackage}/bin/mongos" 224 + 225 + "d '${stateDir}/conf' 0700 unifi-video unifi-video - -" 226 + "C '${stateDir}/conf/evostream' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/evostream" 227 + "Z '${stateDir}/conf/evostream' 0700 unifi-video unifi-video - -" 228 + "L+ '${stateDir}/conf/mongodv3.0+.conf' 0700 unifi-video unifi-video - ${mongoConf}" 229 + "L+ '${stateDir}/conf/mongodv3.6+.conf' 0700 unifi-video unifi-video - ${mongoConf}" 230 + "L+ '${stateDir}/conf/mongod-wt.conf' 0700 unifi-video unifi-video - ${mongoWtConf}" 231 + "L+ '${stateDir}/conf/catalina.policy' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/catalina.policy" 232 + "L+ '${stateDir}/conf/catalina.properties' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/catalina.properties" 233 + "L+ '${stateDir}/conf/context.xml' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/context.xml" 234 + "L+ '${stateDir}/conf/logging.properties' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/logging.properties" 235 + "L+ '${stateDir}/conf/server.xml' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/server.xml" 236 + "L+ '${stateDir}/conf/tomcat-users.xml' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/tomcat-users.xml" 237 + "L+ '${stateDir}/conf/web.xml' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/web.xml" 238 + 239 + ]; 240 + 241 + systemd.services.unifi-video = { 242 + description = "UniFi Video NVR daemon"; 243 + wantedBy = [ "multi-user.target" ]; 244 + after = [ "network.target" ] ; 245 + unitConfig.RequiresMountsFor = stateDir; 246 + # Make sure package upgrades trigger a service restart 247 + restartTriggers = [ cfg.unifiVideoPackage cfg.mongodbPackage ]; 248 + path = with pkgs; [ gawk coreutils busybox which jre8 lsb-release libcap util-linux ]; 249 + serviceConfig = { 250 + Type = "simple"; 251 + ExecStart = "${(removeSuffix "\n" cmd)} ${mainClass} start"; 252 + ExecStop = "${(removeSuffix "\n" cmd)} stop ${mainClass} stop"; 253 + Restart = "on-failure"; 254 + UMask = "0077"; 255 + User = "unifi-video"; 256 + WorkingDirectory = "${stateDir}"; 257 + }; 258 + }; 259 + 260 + }; 261 + 262 + meta = { 263 + maintainers = with lib.maintainers; [ rsynnest ]; 264 + }; 265 + }
+25
pkgs/development/libraries/java/commons/daemon/default.nix
··· 1 + { lib, stdenv, fetchurl }: 2 + 3 + stdenv.mkDerivation rec { 4 + version = "1.2.4"; 5 + pname = "commons-daemon"; 6 + 7 + src = fetchurl { 8 + url = "mirror://apache/commons/daemon/binaries/commons-daemon-${version}-bin.tar.gz"; 9 + sha256 = "0bsy4xn3gncgrxj3vkpplvyhx06c1470kycj0j5gwq46ylgady9s"; 10 + }; 11 + 12 + installPhase = '' 13 + tar xf ${src} 14 + mkdir -p $out/share/java 15 + cp *.jar $out/share/java/ 16 + ''; 17 + 18 + meta = { 19 + homepage = "https://commons.apache.org/proper/commons-daemon"; 20 + description = "Apache Commons Daemon software is a set of utilities and Java support classes for running Java applications as server processes."; 21 + maintainers = with lib.maintainers; [ rsynnest ]; 22 + license = lib.licenses.asl20; 23 + platforms = with lib.platforms; unix; 24 + }; 25 + }
+61
pkgs/servers/unifi-video/default.nix
··· 1 + { dpkg 2 + , stdenv 3 + , lib 4 + , fetchurl 5 + , jre8 6 + , jsvc 7 + , lsb-release 8 + , libcap 9 + , util-linux 10 + , makeWrapper 11 + , autoPatchelfHook 12 + , glibc 13 + , gcc-unwrapped 14 + }: 15 + 16 + stdenv.mkDerivation rec { 17 + pname = "unifi-video"; 18 + version = "3.10.13"; 19 + src = fetchurl { 20 + urls = [ "https://dl.ui.com/firmwares/ufv/v${version}/unifi-video.Debian9_amd64.v${version}.deb" "https://archive.org/download/unifi-video.Debian9_amd64.v${version}/unifi-video.Debian9_amd64.v${version}.deb" ]; 21 + sha256 = "06mxjdizs4mhm1by8kj4pg5hhdi8ns6x75ggwyp1k6zb26jvvdny"; 22 + }; 23 + 24 + buildInputs = [ jre8 jsvc lsb-release libcap util-linux ]; 25 + nativeBuildInputs = [ dpkg makeWrapper autoPatchelfHook glibc gcc-unwrapped ]; 26 + 27 + unpackCmd = '' 28 + runHook preUnpack 29 + 30 + dpkg-deb -x $src . 31 + rm -r etc 32 + 33 + runHook postUnpack 34 + ''; 35 + 36 + installPhase = '' 37 + runHook preInstall 38 + 39 + mkdir -p $out 40 + cp -ar sbin $out/bin 41 + cp -ar lib share $out 42 + chmod +x $out/bin/* 43 + wrapProgram $out/bin/unifi-video --set JAVA_HOME "${jre8}" --prefix PATH : ${lib.makeBinPath [ jre8 lsb-release libcap util-linux]} 44 + 45 + runHook postInstall 46 + ''; 47 + 48 + meta = with lib; { 49 + description = "Unifi Video NVR (aka Airvision) is a software package for controlling Unifi cameras"; 50 + longDescription = '' 51 + Unifi Video is the NVR server software which can monitor and 52 + record footage from supported Unifi video cameras 53 + ''; 54 + homepage = "https://www.ui.com"; 55 + downloadPage = "https://www.ui.com/download/unifi-video/"; 56 + license = licenses.unfree; 57 + maintainers = [ maintainers.rsynnest ]; 58 + platforms = [ "x86_64-linux" ]; 59 + knownVulnerabilities = [ "Upstream support for Unifi Video ended January 1st, 2021." ]; 60 + }; 61 + }
+40
pkgs/tools/system/jsvc/default.nix
··· 1 + { lib, stdenv, fetchurl, commonsDaemon, jdk, makeWrapper, jre }: 2 + 3 + stdenv.mkDerivation rec { 4 + pname = "jsvc"; 5 + version = "1.2.4"; 6 + 7 + src = fetchurl { 8 + url = "https://downloads.apache.org//commons/daemon/source/commons-daemon-${version}-src.tar.gz"; 9 + sha256 = "1nrr6ggy6h20r9zyv14vx6vc9p1w6l8fl9fn6i8dx2hrq6kk2bjw"; 10 + }; 11 + 12 + buildInputs = [ commonsDaemon ]; 13 + nativeBuildInputs = [ jdk makeWrapper ]; 14 + 15 + preConfigure = '' 16 + cd ./src/native/unix/ 17 + sh ./support/buildconf.sh 18 + ''; 19 + 20 + preBuild = '' 21 + export JAVA_HOME=${jre} 22 + ''; 23 + 24 + installPhase = '' 25 + runHook preInstall 26 + mkdir -p $out/bin 27 + cp jsvc $out/bin/jsvc 28 + chmod +x $out/bin/jsvc 29 + wrapProgram $out/bin/jsvc --set JAVA_HOME "${jre}" 30 + runHook postInstall 31 + ''; 32 + 33 + meta = { 34 + homepage = "https://commons.apache.org/proper/commons-daemon"; 35 + description = "JSVC is part of the Apache Commons Daemon software, a set of utilities and Java support classes for running Java applications as server processes."; 36 + maintainers = with lib.maintainers; [ rsynnest ]; 37 + license = lib.licenses.asl20; 38 + platforms = with lib.platforms; unix; 39 + }; 40 + }
+6
pkgs/top-level/all-packages.nix
··· 6105 6105 6106 6106 jnettop = callPackage ../tools/networking/jnettop { }; 6107 6107 6108 + jsvc = callPackage ../tools/system/jsvc { }; 6109 + 6108 6110 jumpnbump = callPackage ../games/jumpnbump { }; 6109 6111 6110 6112 junkie = callPackage ../tools/networking/junkie { }; ··· 19031 19033 19032 19034 commonsCompress = callPackage ../development/libraries/java/commons/compress { }; 19033 19035 19036 + commonsDaemon = callPackage ../development/libraries/java/commons/daemon { }; 19037 + 19034 19038 commonsFileUpload = callPackage ../development/libraries/java/commons/fileupload { }; 19035 19039 19036 19040 commonsLang = callPackage ../development/libraries/java/commons/lang { }; ··· 20273 20277 unifi5 20274 20278 unifi6; 20275 20279 unifi = unifi6; 20280 + 20281 + unifi-video = callPackage ../servers/unifi-video { }; 20276 20282 20277 20283 unpackerr = callPackage ../servers/unpackerr { 20278 20284 inherit (darwin.apple_sdk.frameworks) Cocoa WebKit;