nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 stdenv,
3 lib,
4 fetchFromGitHub,
5 fetchurl,
6 cmake,
7 makeWrapper,
8 pkg-config,
9 curl,
10 ffmpeg,
11 glib,
12 libjpeg,
13 libselinux,
14 libsepol,
15 mp4v2,
16 libmysqlclient,
17 mariadb,
18 pcre,
19 perl,
20 perlPackages,
21 polkit,
22 util-linuxMinimal,
23 x264,
24 zlib,
25 coreutils,
26 procps,
27 psmisc,
28 nixosTests,
29}:
30
31# NOTES:
32#
33# 1. ZM_CONFIG_DIR is set to $out/etc/zoneminder as the .conf file distributed
34# by upstream contains defaults and is not supposed to be edited so it is fine
35# to keep it read-only.
36#
37# 2. ZM_CONFIG_SUBDIR is where we place our configuration from the NixOS module
38# but as the installer will try to put files there, we patch Config.pm after the
39# install.
40#
41# 3. ZoneMinder is run with -T passed to the perl interpreter which makes perl
42# ignore PERL5LIB. We therefore have to do the substitution into -I parameters
43# ourselves which results in ugly wrappers.
44#
45# 4. The makefile for the perl modules needs patching to put things into the
46# right place. That also means we have to not run "make install" for them.
47#
48# 5. In principal the various ZM_xx variables should be overridable from the
49# config file but some of them are baked into the perl scripts, so we *have* to
50# set them here instead of in the configuration in the NixOS module.
51#
52# 6. I am no PolicyKit expert but the .policy file looks fishy:
53# a. The user needs to be known at build-time so we should probably throw
54# upstream's policy file away and generate it from the NixOS module
55# b. I *think* we may have to substitute the store paths with
56# /run/current-system/sw/bin paths for it to work.
57#
58# 7. we manually fix up the perl paths in the scripts as fixupPhase will only
59# handle pkexec and not perl if both are present.
60#
61# 8. There are several perl modules needed at runtime which are not checked when
62# building so if a new version stops working, check if there is a missing
63# dependency by running the failing component manually.
64#
65# 9. Parts of the web UI has a hardcoded /zm path so we create a symlink to work
66# around it.
67
68let
69 addons = [
70 {
71 path = "scripts/ZoneMinder/lib/ZoneMinder/Control/Xiaomi.pm";
72 src = fetchurl {
73 url = "https://gist.githubusercontent.com/joshstrange/73a2f24dfaf5cd5b470024096ce2680f/raw/e964270c5cdbf95e5b7f214f7f0fc6113791530e/Xiaomi.pm";
74 sha256 = "04n1ap8fx66xfl9q9rypj48pzbgzikq0gisfsfm8wdsmflarz43v";
75 };
76 }
77 ];
78
79 user = "zoneminder";
80 dirName = "zoneminder";
81 perlBin = "${perl}/bin/perl";
82
83in
84stdenv.mkDerivation rec {
85 pname = "zoneminder";
86 version = "1.36.35";
87
88 src = fetchFromGitHub {
89 owner = "ZoneMinder";
90 repo = "zoneminder";
91 rev = version;
92 hash = "sha256-0mpT3qjF8zlcsd6OlNIvrabDsz+oJPPy9Vn2TQSuHAI=";
93 fetchSubmodules = true;
94 };
95
96 patches = [
97 ./default-to-http-1dot1.patch
98 ./0001-Don-t-use-file-timestamp-in-cache-filename.patch
99 ];
100
101 postPatch = ''
102 rm -rf web/api/lib/Cake/Test
103
104 ${lib.concatStringsSep "\n" (
105 map (e: ''
106 cp ${e.src} ${e.path}
107 '') addons
108 )}
109
110 for d in scripts/ZoneMinder onvif/{modules,proxy} ; do
111 substituteInPlace $d/CMakeLists.txt \
112 --replace 'DESTDIR="''${CMAKE_CURRENT_BINARY_DIR}/output"' "PREFIX=$out INSTALLDIRS=site"
113 sed -i '/^install/d' $d/CMakeLists.txt
114 done
115
116 substituteInPlace misc/CMakeLists.txt \
117 --replace '"''${PC_POLKIT_PREFIX}/''${CMAKE_INSTALL_DATAROOTDIR}' "\"$out/share"
118
119 for f in misc/*.policy.in \
120 scripts/*.pl* \
121 scripts/ZoneMinder/lib/ZoneMinder/Memory.pm.in ; do
122 substituteInPlace $f \
123 --replace '/usr/bin/perl' '${perlBin}' \
124 --replace '/bin:/usr/bin' "$out/bin:${
125 lib.makeBinPath [
126 coreutils
127 procps
128 psmisc
129 ]
130 }"
131 done
132
133 substituteInPlace scripts/zmdbbackup.in \
134 --replace /usr/bin/mysqldump ${mariadb.client}/bin/mysqldump
135
136 substituteInPlace scripts/zmupdate.pl.in \
137 --replace "'mysql'" "'${mariadb.client}/bin/mysql'" \
138 --replace "'mysqldump'" "'${mariadb.client}/bin/mysqldump'"
139
140 for f in scripts/ZoneMinder/lib/ZoneMinder/Config.pm.in \
141 scripts/zmupdate.pl.in \
142 src/zm_config_data.h.in \
143 web/api/app/Config/bootstrap.php.in \
144 web/includes/config.php.in ; do
145 substituteInPlace $f --replace @ZM_CONFIG_SUBDIR@ /etc/zoneminder
146 done
147
148 for f in includes/Event.php views/image.php ; do
149 substituteInPlace web/$f \
150 --replace "'ffmpeg " "'${ffmpeg}/bin/ffmpeg "
151 done
152
153 for f in scripts/ZoneMinder/lib/ZoneMinder/Event.pm \
154 scripts/ZoneMinder/lib/ZoneMinder/Storage.pm ; do
155 substituteInPlace $f \
156 --replace '/bin/rm' "${coreutils}/bin/rm"
157 done
158
159 substituteInPlace web/includes/functions.php \
160 --replace "'date " "'${coreutils}/bin/date " \
161 --subst-var-by srcHash "`basename $out`"
162 '';
163
164 buildInputs = [
165 curl
166 ffmpeg
167 glib
168 libjpeg
169 libselinux
170 libsepol
171 mp4v2
172 libmysqlclient
173 mariadb
174 pcre
175 perl
176 polkit
177 x264
178 zlib
179 util-linuxMinimal # for libmount
180 ]
181 ++ (with perlPackages; [
182 # build-time dependencies
183 DateManip
184 DBI
185 DBDmysql
186 LWP
187 SysMmap
188 # run-time dependencies not checked at build-time
189 ClassStdFast
190 DataDump
191 DeviceSerialPort
192 JSONMaybeXS
193 LWPProtocolHttps
194 NumberBytesHuman
195 SysCPU
196 SysMemInfo
197 TimeDate
198 CryptEksblowfish
199 DataEntropy # zmupdate.pl
200 ]);
201
202 nativeBuildInputs = [
203 cmake
204 makeWrapper
205 pkg-config
206 ];
207
208 cmakeFlags = [
209 "-DWITH_SYSTEMD=ON"
210 "-DZM_LOGDIR=/var/log/${dirName}"
211 "-DZM_RUNDIR=/run/${dirName}"
212 "-DZM_SOCKDIR=/run/${dirName}"
213 "-DZM_TMPDIR=/tmp/${dirName}"
214 "-DZM_CONFIG_DIR=${placeholder "out"}/etc/zoneminder"
215 "-DZM_WEB_USER=${user}"
216 "-DZM_WEB_GROUP=${user}"
217 ];
218
219 passthru = {
220 inherit dirName;
221 tests = nixosTests.zoneminder;
222 };
223
224 postInstall = ''
225 PERL5LIB="$PERL5LIB''${PERL5LIB:+:}$out/${perl.libPrefix}"
226
227 perlFlags="-wT"
228 for i in $(IFS=$'\n'; echo $PERL5LIB | tr ':' "\n" | sort -u); do
229 perlFlags="$perlFlags -I$i"
230 done
231
232 mkdir -p $out/libexec
233 for f in $out/bin/*.pl ; do
234 mv $f $out/libexec/
235 makeWrapper ${perlBin} $f \
236 --prefix PATH : $out/bin \
237 --add-flags "$perlFlags $out/libexec/$(basename $f)"
238 done
239
240 ln -s $out/share/zoneminder/www $out/share/zoneminder/www/zm
241 '';
242
243 meta = with lib; {
244 description = "Video surveillance software system";
245 homepage = "https://zoneminder.com";
246 license = licenses.gpl3;
247 maintainers = [ ];
248 platforms = platforms.linux;
249 };
250}