Merge ~ahasenack/ubuntu/+source/zoneminder:focal-zoneminder-mysql8 into ~ahasenack/ubuntu/+source/zoneminder:master
- Git
- lp:~ahasenack/ubuntu/+source/zoneminder
- focal-zoneminder-mysql8
- Merge into master
Status: | Merged | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Approved by: | Andreas Hasenack | ||||||||||||
Approved revision: | 6dfc7d363f874e9417bd563ed95c96031ae9568b | ||||||||||||
Merged at revision: | ebdcb0ab8587f01cf4c6b448bf0d5773e2be7dcf | ||||||||||||
Proposed branch: | ~ahasenack/ubuntu/+source/zoneminder:focal-zoneminder-mysql8 | ||||||||||||
Merge into: | ~ahasenack/ubuntu/+source/zoneminder:master | ||||||||||||
Diff against target: |
569 lines (+484/-4) 9 files modified
debian/README.Debian (+9/-2) debian/changelog (+14/-0) debian/control (+2/-1) debian/patches/mysql8-password-deprecated.patch (+26/-0) debian/patches/mysql8-replace-password-call.patch (+58/-0) debian/patches/mysql8-reserved-keywords.patch (+326/-0) debian/patches/mysql8_my_bool.patch (+43/-0) debian/patches/series (+4/-0) debian/rules (+2/-1) |
||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Christian Ehrhardt (community) | Approve | ||
Canonical Server | Pending | ||
Review via email: mp+379771@code.launchpad.net |
Commit message
Description of the change
PPA: https:/
zoneminder isn't in git-ubuntu, and currently fails to import (see bug #1864255).
This fixes several things:
- ftbfs due to mysql8
- another unrelated ftbfs
- runtime issue with mysql8
Newer upstream version claims to work with mysql8, but debian hasn't grabbed it yet. One of the upstream fixes isn't really a good candidate for a patch here, as it's a kind of a refactoring (getting rid of mysql's password()).
I decided to update d/README.Debian a bit because the instructions there didn't work out of the box, and I wanted to try out the package to avoid another bug like #1859295). At least now it comes up and one can see its web interface at http://<ip>/zm. I also updated the php links, expecting 7.4 for focal.
The auth issue workaround I gathered from https:/
I could add a simple dep8 test without too much extra effort, and that would be one that simply loaded the sql dump into mysql: cat /usr/share/
It would have caught one issue (using password() in that sql file), but not the rest. Let me know if you think it's worth it. I didn't do it now because it's late :)
All those other steps from the README.Debian file are also doable as a dep8 test, up to the license displayed at first in http://<ip>/zm. We can still do it after feature freeze.
Andreas Hasenack (ahasenack) wrote : | # |
Thanks, I filed https:/
I'll take a look at the tmpfile bit
Andreas Hasenack (ahasenack) wrote : | # |
Hmm, RUNDIR is set all over the place at /var/run, even in d/rules, just changing it in the systemd tmpfile would be incomplete, and I'm not ready to test such a larger change at this moment. I'll drop that bit for now, and file a bug to do it properly.
Andreas Hasenack (ahasenack) wrote : | # |
Andreas Hasenack (ahasenack) wrote : | # |
Uploading (no tagging, since this isn't in g-u) ebdcb0ab8587f01
$ dput ubuntu ../zoneminder_
Checking signature on .changes
gpg: ../zoneminder_
Checking signature on .dsc
gpg: ../zoneminder_
Uploading to ubuntu (via ftp to upload.ubuntu.com):
Uploading zoneminder_
Uploading zoneminder_
Uploading zoneminder_
Uploading zoneminder_
Successfully uploaded packages.
Joseph Yasi (joe-yasi) : | # |
Andreas Hasenack (ahasenack) : | # |
Preview Diff
1 | diff --git a/debian/README.Debian b/debian/README.Debian |
2 | index 712526a..1ee8bb5 100644 |
3 | --- a/debian/README.Debian |
4 | +++ b/debian/README.Debian |
5 | @@ -11,6 +11,13 @@ OR |
6 | echo 'grant lock tables,alter,create,select,insert,update,delete,index on zm.* to 'zmuser'@localhost identified by "zmpass";'\ |
7 | | sudo mysql --defaults-file=/etc/mysql/debian.cnf mysql |
8 | |
9 | +With MySQL8: |
10 | + |
11 | + echo "CREATE USER 'zmuser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'zmpass';"\ |
12 | + | sudo mysql --defaults-file=/etc/mysql/debian.cnf mysql |
13 | + echo 'grant lock tables,alter,create,select,insert,update,delete,index on zm.* to 'zmuser'@localhost;'\ |
14 | + | sudo mysql --defaults-file=/etc/mysql/debian.cnf mysql |
15 | + |
16 | Hint: generate secure password with `pwgen` and update "/etc/zm/zm.conf" |
17 | accordingly. |
18 | |
19 | @@ -128,8 +135,8 @@ System time zone can be set by the following command: |
20 | PHP time zone can be configured by changing value of "date.timezone" in one |
21 | of the following files: |
22 | |
23 | - /etc/php/7.2/fpm/php.ini |
24 | - /etc/php/7.2/apache2/php.ini |
25 | + /etc/php/7.4/fpm/php.ini |
26 | + /etc/php/7.4/apache2/php.ini |
27 | |
28 | Please note that MariaDB/MySQL time zone should be identical to system and |
29 | PHP time zones. By default MariaDB uses system time zone but it might be |
30 | diff --git a/debian/changelog b/debian/changelog |
31 | index 68b6007..3d575f6 100644 |
32 | --- a/debian/changelog |
33 | +++ b/debian/changelog |
34 | @@ -1,3 +1,17 @@ |
35 | +zoneminder (1.32.3-2ubuntu1) focal; urgency=medium |
36 | + |
37 | + * d/p/mysql8_my_bool.patch: Reintroduce my_bool to fix build with MySQL 8. |
38 | + (LP: #1863026) |
39 | + * d/rules: override build-dep to fix FTBFS (thanks to |
40 | + robie.basak@canonical.com) (LP: #1863793, Closes: #951600) |
41 | + * MySQL8 runtime fixes (LP: #1859295): |
42 | + - d/p/mysql8-password-deprecated.patch: password() is deprecated |
43 | + - d/p/mysql8-reserved-keywords.patch: quote MySQL8 reserved keywords |
44 | + - d/p/mysql8-replace-password-call.patch: replace password() |
45 | + * d/README.Debian: quick update for MySQL8 and Focal |
46 | + |
47 | + -- Andreas Hasenack <andreas@canonical.com> Tue, 25 Feb 2020 10:22:20 -0300 |
48 | + |
49 | zoneminder (1.32.3-2build1) eoan; urgency=medium |
50 | |
51 | * No change rebuild for libmysqlclient21. |
52 | diff --git a/debian/control b/debian/control |
53 | index d435117..c561ce0 100644 |
54 | --- a/debian/control |
55 | +++ b/debian/control |
56 | @@ -2,7 +2,8 @@ Source: zoneminder |
57 | Section: net |
58 | Priority: optional |
59 | Standards-Version: 4.3.0 |
60 | -Maintainer: Dmitry Smirnov <onlyjob@debian.org> |
61 | +Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com> |
62 | +XSBC-Original-Maintainer: Dmitry Smirnov <onlyjob@debian.org> |
63 | Uploaders: Chris Lamb <lamby@debian.org> |
64 | Build-Depends: debhelper (>= 11~) ,dh-linktree |
65 | ,apache2-dev |
66 | diff --git a/debian/patches/mysql8-password-deprecated.patch b/debian/patches/mysql8-password-deprecated.patch |
67 | new file mode 100644 |
68 | index 0000000..f16dc63 |
69 | --- /dev/null |
70 | +++ b/debian/patches/mysql8-password-deprecated.patch |
71 | @@ -0,0 +1,26 @@ |
72 | +From 5b896b5e5ca57fe9780e852d570a31c7a5b2ecfb Mon Sep 17 00:00:00 2001 |
73 | +From: Isaac Connor <isaac@zoneminder.com> |
74 | +Date: Mon, 8 Jul 2019 14:16:57 -0400 |
75 | +Subject: [PATCH] Replace password('admin') with the resulting string because |
76 | + use of password is deprecated |
77 | + |
78 | +--- |
79 | + db/zm_create.sql.in | 2 +- |
80 | + 1 file changed, 1 insertion(+), 1 deletion(-) |
81 | + |
82 | +Origin: https://github.com/ZoneMinder/zoneminder/commit/5b896b5e5ca57fe9780e852d570a31c7a5b2ecfb |
83 | +Bug: https://github.com/ZoneMinder/zoneminder/issues/2658 |
84 | +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/zoneminder/+bug/1859295 |
85 | +Last-Updated: 2020-02-21 |
86 | + |
87 | +--- a/db/zm_create.sql.in |
88 | ++++ b/db/zm_create.sql.in |
89 | +@@ -738,7 +738,7 @@ |
90 | + -- |
91 | + -- Create a default admin user. |
92 | + -- |
93 | +-insert into Users VALUES (NULL,'admin',password('admin'),'',1,'View','Edit','Edit','Edit','Edit','Edit','Edit','',''); |
94 | ++insert into Users VALUES (NULL,'admin','$2b$12$NHZsm6AM2f2LQVROriz79ul3D6DnmFiZC.ZK5eqbF.ZWfwH9bqUJ6','',1,'View','Edit','Edit','Edit','Edit','Edit','Edit','',''); |
95 | + |
96 | + -- |
97 | + -- Add a sample filter to purge the oldest 100 events when the disk is 95% full |
98 | diff --git a/debian/patches/mysql8-replace-password-call.patch b/debian/patches/mysql8-replace-password-call.patch |
99 | new file mode 100644 |
100 | index 0000000..574bf24 |
101 | --- /dev/null |
102 | +++ b/debian/patches/mysql8-replace-password-call.patch |
103 | @@ -0,0 +1,58 @@ |
104 | +Description: replace password() |
105 | + password() is deprecated in MySQL8, replace it with an equivalent implementation: |
106 | + . |
107 | + mysql> select password('secret'),CONCAT('*',UPPER(SHA1(UNHEX(SHA1('secret'))))); |
108 | + +-------------------------------------------+------------------------------------------------+ |
109 | + | password('secret') | CONCAT('*',UPPER(SHA1(UNHEX(SHA1('secret'))))) | |
110 | + +-------------------------------------------+------------------------------------------------+ |
111 | + | *14E65567ABDB5135D0CFD9A70B3032C179A49EE7 | *14E65567ABDB5135D0CFD9A70B3032C179A49EE7 | |
112 | + +-------------------------------------------+------------------------------------------------+ |
113 | +Author: Joseph Yasi <joe.yasi@gmail.com> |
114 | +Origin: other, https://bugs.launchpad.net/ubuntu/+source/zoneminder/+bug/1859295/comments/1 |
115 | +Bug: https://github.com/ZoneMinder/zoneminder/issues/2659 |
116 | +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/zoneminder/+bug/1859295 |
117 | +Last-Update: 2020-02-24 |
118 | +--- |
119 | +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ |
120 | +--- a/src/zm_user.cpp |
121 | ++++ b/src/zm_user.cpp |
122 | +@@ -99,7 +99,7 @@ |
123 | + int password_length = strlen(password); |
124 | + char *safer_password = new char[(password_length * 2) + 1]; |
125 | + mysql_real_escape_string(&dbconn, safer_password, password, password_length); |
126 | +- snprintf( sql, sizeof(sql), "select Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, `System`+0, MonitorIds from Users where Username = '%s' and Password = password('%s') and Enabled = 1", safer_username, safer_password ); |
127 | ++ snprintf( sql, sizeof(sql), "select Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, `System`+0, MonitorIds from Users where Username = '%s' and Password = CONCAT('*',UPPER(SHA1(UNHEX(SHA1('%s'))))) and Enabled = 1", safer_username, safer_password ); |
128 | + delete safer_password; |
129 | + } else { |
130 | + snprintf( sql, sizeof(sql), "select Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, `System`+0, MonitorIds from Users where Username = '%s' and Enabled = 1", safer_username ); |
131 | +--- a/web/includes/actions.php |
132 | ++++ b/web/includes/actions.php |
133 | +@@ -960,7 +960,7 @@ |
134 | + $changes = getFormChanges($dbUser, $_REQUEST['newUser'], $types); |
135 | + |
136 | + if ( $_REQUEST['newUser']['Password'] ) |
137 | +- $changes['Password'] = 'Password = password('.dbEscape($_REQUEST['newUser']['Password']).')'; |
138 | ++ $changes['Password'] = 'Password = CONCAT(\'*\',UPPER(SHA1(UNHEX(SHA1('.dbEscape($_REQUEST['newUser']['Password']).')))))'; |
139 | + else |
140 | + unset($changes['Password']); |
141 | + |
142 | +@@ -1015,7 +1015,7 @@ |
143 | + $changes = getFormChanges($dbUser, $_REQUEST['newUser'], $types); |
144 | + |
145 | + if ( !empty($_REQUEST['newUser']['Password']) ) |
146 | +- $changes['Password'] = 'Password = password('.dbEscape($_REQUEST['newUser']['Password']).')'; |
147 | ++ $changes['Password'] = 'Password = CONCAT(\'*\',UPPER(SHA1(UNHEX(SHA1('.dbEscape($_REQUEST['newUser']['Password']).')))))'; |
148 | + else |
149 | + unset($changes['Password']); |
150 | + if ( count($changes) ) { |
151 | +--- a/web/includes/auth.php |
152 | ++++ b/web/includes/auth.php |
153 | +@@ -27,7 +27,7 @@ |
154 | + if ( $passwordHashed ) { |
155 | + $sql .= ' AND Username=? AND Password=?'; |
156 | + } else { |
157 | +- $sql .= ' AND Username=? AND Password=password(?)'; |
158 | ++ $sql .= ' AND Username=? AND Password=CONCAT(\'*\',UPPER(SHA1(UNHEX(SHA1(?)))))'; |
159 | + } |
160 | + $sql_values = array($username, $password); |
161 | + } else { |
162 | diff --git a/debian/patches/mysql8-reserved-keywords.patch b/debian/patches/mysql8-reserved-keywords.patch |
163 | new file mode 100644 |
164 | index 0000000..bc067d1 |
165 | --- /dev/null |
166 | +++ b/debian/patches/mysql8-reserved-keywords.patch |
167 | @@ -0,0 +1,326 @@ |
168 | +Description: Quote MySQL8 reserved keywords |
169 | +Author: Joseph Yasi <joe.yasi@gmail.com> |
170 | +Origin: other, https://bugs.launchpad.net/ubuntu/+source/zoneminder/+bug/1859295/comments/1 |
171 | +Bug: https://github.com/ZoneMinder/zoneminder/issues/2659 |
172 | +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/zoneminder/+bug/1859295 |
173 | +Last-Update: 2020-02-21 |
174 | +--- |
175 | +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ |
176 | +--- a/scripts/zmtelemetry.pl.in |
177 | ++++ b/scripts/zmtelemetry.pl.in |
178 | +@@ -243,7 +243,7 @@ |
179 | + sub getMonitorRef { |
180 | + my $dbh = shift; |
181 | + |
182 | +- my $sql = 'SELECT Id,Name,Type,Function,Width,Height,Colours,MaxFPS,AlarmMaxFPS FROM Monitors'; |
183 | ++ my $sql = 'SELECT Id,Name,Type,`Function`,Width,Height,Colours,MaxFPS,AlarmMaxFPS FROM Monitors'; |
184 | + my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); |
185 | + my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() ); |
186 | + my $arrayref = $sth->fetchall_arrayref({}); |
187 | +--- a/scripts/zmtrigger.pl.in |
188 | ++++ b/scripts/zmtrigger.pl.in |
189 | +@@ -333,7 +333,7 @@ |
190 | + my %new_monitors = (); |
191 | + |
192 | + my $sql = "SELECT * FROM Monitors |
193 | +- WHERE find_in_set( Function, 'Modect,Mocord,Nodect' )". |
194 | ++ WHERE find_in_set( `Function`, 'Modect,Mocord,Nodect' )". |
195 | + ( $Config{ZM_SERVER_ID} ? 'AND ServerId=?' : '' ) |
196 | + ; |
197 | + my $sth = $dbh->prepare_cached( $sql ) |
198 | +--- a/scripts/zmx10.pl.in |
199 | ++++ b/scripts/zmx10.pl.in |
200 | +@@ -464,7 +464,7 @@ |
201 | + |
202 | + my $sql = "SELECT M.*,T.* from Monitors as M |
203 | + INNER JOIN TriggersX10 as T on (M.Id = T.MonitorId) |
204 | +- WHERE find_in_set( M.Function, 'Modect,Record,Mocord,Nodect' ) |
205 | ++ WHERE find_in_set( M.`Function`, 'Modect,Record,Mocord,Nodect' ) |
206 | + AND M.Enabled = 1 |
207 | + AND find_IN_set( 'X10', M.Triggers )" |
208 | + ; |
209 | +--- a/scripts/ZoneMinder/lib/ZoneMinder/Database.pm |
210 | ++++ b/scripts/ZoneMinder/lib/ZoneMinder/Database.pm |
211 | +@@ -145,15 +145,15 @@ |
212 | + |
213 | + if ( $function ) { |
214 | + if ( $function == DB_MON_CAPT ) { |
215 | +- $sql .= " where Function >= 'Monitor'"; |
216 | ++ $sql .= " where `Function` >= 'Monitor'"; |
217 | + } elsif ( $function == DB_MON_ACTIVE ) { |
218 | +- $sql .= " where Function > 'Monitor'"; |
219 | ++ $sql .= " where `Function` > 'Monitor'"; |
220 | + } elsif ( $function == DB_MON_MOTION ) { |
221 | +- $sql .= " where Function = 'Modect' or Function = 'Mocord'"; |
222 | ++ $sql .= " where `Function` = 'Modect' or `Function` = 'Mocord'"; |
223 | + } elsif ( $function == DB_MON_RECORD ) { |
224 | +- $sql .= " where Function = 'Record' or Function = 'Mocord'"; |
225 | ++ $sql .= " where `Function` = 'Record' or `Function` = 'Mocord'"; |
226 | + } elsif ( $function == DB_MON_PASSIVE ) { |
227 | +- $sql .= " where Function = 'Nodect'"; |
228 | ++ $sql .= " where `Function` = 'Nodect'"; |
229 | + } |
230 | + } |
231 | + my $sth = $dbh->prepare_cached( $sql ); |
232 | +--- a/src/zm_monitor.cpp |
233 | ++++ b/src/zm_monitor.cpp |
234 | +@@ -67,7 +67,7 @@ |
235 | + // This is the official SQL (and ordering of the fields) to load a Monitor. |
236 | + // It will be used whereever a Monitor dbrow is needed. WHERE conditions can be appended |
237 | + std::string load_monitor_sql = |
238 | +-"SELECT Id, Name, ServerId, StorageId, Type, Function+0, Enabled, LinkedMonitors, " |
239 | ++"SELECT Id, Name, ServerId, StorageId, Type, `Function`+0, Enabled, LinkedMonitors, " |
240 | + "AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS," |
241 | + "Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, " // V4L Settings |
242 | + "Protocol, Method, Options, User, Pass, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, " |
243 | +@@ -1770,7 +1770,7 @@ |
244 | + |
245 | + static char sql[ZM_SQL_MED_BUFSIZ]; |
246 | + // This seems to have fallen out of date. |
247 | +- snprintf( sql, sizeof(sql), "select Function+0, Enabled, LinkedMonitors, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, WarmupCount, PreEventCount, PostEventCount, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Id = '%d'", id ); |
248 | ++ snprintf( sql, sizeof(sql), "select `Function`+0, Enabled, LinkedMonitors, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, WarmupCount, PreEventCount, PostEventCount, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Id = '%d'", id ); |
249 | + |
250 | + zmDbRow *row = zmDbFetchOne(sql); |
251 | + if ( !row ) { |
252 | +@@ -1904,7 +1904,7 @@ |
253 | + |
254 | + db_mutex.lock(); |
255 | + static char sql[ZM_SQL_SML_BUFSIZ]; |
256 | +- snprintf(sql, sizeof(sql), "select Id, Name from Monitors where Id = %d and Function != 'None' and Function != 'Monitor' and Enabled = 1", link_ids[i] ); |
257 | ++ snprintf(sql, sizeof(sql), "select Id, Name from Monitors where Id = %d and `Function` != 'None' and `Function` != 'Monitor' and Enabled = 1", link_ids[i] ); |
258 | + if ( mysql_query(&dbconn, sql) ) { |
259 | + Error("Can't run query: %s", mysql_error(&dbconn)); |
260 | + db_mutex.unlock(); |
261 | +@@ -1961,7 +1961,7 @@ |
262 | + #if ZM_HAS_V4L |
263 | + int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose purpose ) { |
264 | + |
265 | +- std::string sql = load_monitor_sql + " WHERE Function != 'None' AND Type = 'Local'"; |
266 | ++ std::string sql = load_monitor_sql + " WHERE `Function` != 'None' AND Type = 'Local'"; |
267 | + |
268 | + if ( device[0] ) |
269 | + sql += " AND Device='" + std::string(device) + "'"; |
270 | +@@ -1972,7 +1972,7 @@ |
271 | + #endif // ZM_HAS_V4L |
272 | + |
273 | + int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const char *port, const char *path, Monitor **&monitors, Purpose purpose ) { |
274 | +- std::string sql = load_monitor_sql + " WHERE Function != 'None' AND Type = 'Remote'"; |
275 | ++ std::string sql = load_monitor_sql + " WHERE `Function` != 'None' AND Type = 'Remote'"; |
276 | + if ( staticConfig.SERVER_ID ) |
277 | + sql += stringtf( " AND ServerId=%d", staticConfig.SERVER_ID ); |
278 | + |
279 | +@@ -1982,7 +1982,7 @@ |
280 | + } |
281 | + |
282 | + int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose purpose ) { |
283 | +- std::string sql = load_monitor_sql + " WHERE Function != 'None' AND Type = 'File'"; |
284 | ++ std::string sql = load_monitor_sql + " WHERE `Function` != 'None' AND Type = 'File'"; |
285 | + if ( file[0] ) |
286 | + sql += " AND Path='" + std::string(file) + "'"; |
287 | + if ( staticConfig.SERVER_ID ) { |
288 | +@@ -1993,7 +1993,7 @@ |
289 | + |
290 | + #if HAVE_LIBAVFORMAT |
291 | + int Monitor::LoadFfmpegMonitors(const char *file, Monitor **&monitors, Purpose purpose) { |
292 | +- std::string sql = load_monitor_sql + " WHERE Function != 'None' AND Type = 'Ffmpeg'"; |
293 | ++ std::string sql = load_monitor_sql + " WHERE `Function` != 'None' AND Type = 'Ffmpeg'"; |
294 | + if ( file[0] ) |
295 | + sql += " AND Path = '" + std::string(file) + "'"; |
296 | + |
297 | +@@ -2006,7 +2006,7 @@ |
298 | + |
299 | + /* |
300 | + std::string load_monitor_sql = |
301 | +- "SELECT Id, Name, ServerId, StorageId, Type, Function+0, Enabled, LinkedMonitors, " |
302 | ++ "SELECT Id, Name, ServerId, StorageId, Type, `Function`+0, Enabled, LinkedMonitors, " |
303 | + "AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS," |
304 | + "Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, " // V4L Settings |
305 | + "Protocol, Method, Options, User, Pass, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, " |
306 | +@@ -2811,7 +2811,7 @@ |
307 | + // At the moment, only load groups once. |
308 | + if ( ! groups.size() ) { |
309 | + std::string sql = stringtf( |
310 | +- "SELECT Id,ParentId,Name FROM Groups WHERE Groups.Id IN " |
311 | ++ "SELECT Id,ParentId,Name FROM `Groups` WHERE `Groups`.Id IN " |
312 | + "(SELECT GroupId FROM Groups_Monitors WHERE MonitorId=%d)",id); |
313 | + MYSQL_RES *result = zmDbFetch(sql.c_str()); |
314 | + if ( !result ) { |
315 | +--- a/src/zm_rtsp.cpp |
316 | ++++ b/src/zm_rtsp.cpp |
317 | +@@ -93,7 +93,7 @@ |
318 | + int RtspThread::requestPorts() { |
319 | + if ( !smMinDataPort ) { |
320 | + char sql[ZM_SQL_SML_BUFSIZ]; |
321 | +- strncpy( sql, "select Id from Monitors where Function != 'None' and Type = 'Remote' and Protocol = 'rtsp' and Method = 'rtpUni' order by Id asc", sizeof(sql) ); |
322 | ++ strncpy( sql, "select Id from Monitors where `Function` != 'None' and Type = 'Remote' and Protocol = 'rtsp' and Method = 'rtpUni' order by Id asc", sizeof(sql) ); |
323 | + if ( mysql_query( &dbconn, sql ) ) { |
324 | + Error( "Can't run query: %s", mysql_error( &dbconn ) ); |
325 | + exit( mysql_errno( &dbconn ) ); |
326 | +--- a/src/zmu.cpp |
327 | ++++ b/src/zmu.cpp |
328 | +@@ -691,9 +691,9 @@ |
329 | + } |
330 | + |
331 | + if ( function & ZMU_LIST ) { |
332 | +- std::string sql = "select Id, Function+0 from Monitors"; |
333 | ++ std::string sql = "select Id, `Function`+0 from Monitors"; |
334 | + if ( !verbose ) { |
335 | +- sql += "where Function != 'None'"; |
336 | ++ sql += "where `Function` != 'None'"; |
337 | + } |
338 | + sql += " order by Id asc"; |
339 | + |
340 | +--- a/src/zm_user.cpp |
341 | ++++ b/src/zm_user.cpp |
342 | +@@ -99,10 +99,10 @@ |
343 | + int password_length = strlen(password); |
344 | + char *safer_password = new char[(password_length * 2) + 1]; |
345 | + mysql_real_escape_string(&dbconn, safer_password, password, password_length); |
346 | +- snprintf( sql, sizeof(sql), "select Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds from Users where Username = '%s' and Password = password('%s') and Enabled = 1", safer_username, safer_password ); |
347 | ++ snprintf( sql, sizeof(sql), "select Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, `System`+0, MonitorIds from Users where Username = '%s' and Password = password('%s') and Enabled = 1", safer_username, safer_password ); |
348 | + delete safer_password; |
349 | + } else { |
350 | +- snprintf( sql, sizeof(sql), "select Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds from Users where Username = '%s' and Enabled = 1", safer_username ); |
351 | ++ snprintf( sql, sizeof(sql), "select Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, `System`+0, MonitorIds from Users where Username = '%s' and Enabled = 1", safer_username ); |
352 | + } |
353 | + |
354 | + if ( mysql_query( &dbconn, sql ) ) { |
355 | +@@ -157,7 +157,7 @@ |
356 | + |
357 | + Debug( 1, "Attempting to authenticate user from auth string '%s'", auth ); |
358 | + char sql[ZM_SQL_SML_BUFSIZ] = ""; |
359 | +- snprintf( sql, sizeof(sql), "SELECT Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds FROM Users WHERE Enabled = 1" ); |
360 | ++ snprintf( sql, sizeof(sql), "SELECT Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, `System`+0, MonitorIds FROM Users WHERE Enabled = 1" ); |
361 | + |
362 | + if ( mysql_query( &dbconn, sql ) ) { |
363 | + Error( "Can't run query: %s", mysql_error( &dbconn ) ); |
364 | +--- a/utils/zm-alarm.pl |
365 | ++++ b/utils/zm-alarm.pl |
366 | +@@ -16,7 +16,7 @@ |
367 | + my $dbh = zmDbConnect(); |
368 | + |
369 | + my $sql = "SELECT * FROM Monitors |
370 | +- WHERE find_in_set( Function, 'Modect,Mocord,Nodect' )". |
371 | ++ WHERE find_in_set( `Function`, 'Modect,Mocord,Nodect' )". |
372 | + ( $Config{ZM_SERVER_ID} ? 'AND ServerId=?' : '' ) |
373 | + ; |
374 | + |
375 | +--- a/web/ajax/status.php |
376 | ++++ b/web/ajax/status.php |
377 | +@@ -16,7 +16,7 @@ |
378 | + 'limit' => 1, |
379 | + 'elements' => array( |
380 | + 'MonitorCount' => array( 'sql' => 'count(*)' ), |
381 | +- 'ActiveMonitorCount' => array( 'sql' => "count(if(Function != 'None',1,NULL))" ), |
382 | ++ 'ActiveMonitorCount' => array( 'sql' => "count(if(`Function` != 'None',1,NULL))" ), |
383 | + 'State' => array( 'func' => 'daemonCheck()?'.translate('Running').':'.translate('Stopped') ), |
384 | + 'Load' => array( 'func' => 'getLoad()' ), |
385 | + 'Disk' => array( 'func' => 'getDiskPercent()' ), |
386 | +--- a/web/includes/database.php |
387 | ++++ b/web/includes/database.php |
388 | +@@ -227,7 +227,7 @@ |
389 | + } |
390 | + |
391 | + function getEnumValues( $table, $column ) { |
392 | +- $row = dbFetchOne( "describe $table $column" ); |
393 | ++ $row = dbFetchOne( "describe `$table` `$column`" ); |
394 | + preg_match_all( "/'([^']+)'/", $row['Type'], $matches ); |
395 | + return( $matches[1] ); |
396 | + } |
397 | +@@ -238,7 +238,7 @@ |
398 | + |
399 | + function getUniqueValues( $table, $column, $asString=1 ) { |
400 | + $values = array(); |
401 | +- $sql = "select distinct $column from $table where (not isnull($column) and $column != '') order by $column"; |
402 | ++ $sql = "select distinct `$column` from `$table` where (not isnull(`$column`) and `$column` != '') order by `$column`"; |
403 | + foreach( dbFetchAll( $sql ) as $row ) { |
404 | + if ( $asString ) |
405 | + $values[$row[$column]] = $row[$column]; |
406 | +@@ -250,7 +250,7 @@ |
407 | + |
408 | + function getTableColumns( $table, $asString=1 ) { |
409 | + $columns = array(); |
410 | +- $sql = "describe $table"; |
411 | ++ $sql = "describe `$table`"; |
412 | + foreach( dbFetchAll( $sql ) as $row ) { |
413 | + if ( $asString ) |
414 | + $columns[$row['Field']] = $row['Type']; |
415 | +@@ -267,7 +267,7 @@ |
416 | + |
417 | + function getTableDescription( $table, $asString=1 ) { |
418 | + $columns = array(); |
419 | +- foreach( dbFetchAll( "describe $table" ) as $row ) { |
420 | ++ foreach( dbFetchAll( "describe `$table`" ) as $row ) { |
421 | + $desc = array( |
422 | + 'name' => $row['Field'], |
423 | + 'required' => ($row['Null']=='NO')?true:false, |
424 | +@@ -377,7 +377,7 @@ |
425 | + } |
426 | + |
427 | + function dbFetchGroup( $gid ) { |
428 | +- return( dbFetchOne( 'select * from Groups where Id = ?', NULL, array($gid) ) ); |
429 | ++ return( dbFetchOne( 'select * from `Groups` where Id = ?', NULL, array($gid) ) ); |
430 | + } |
431 | + |
432 | + ?> |
433 | +--- a/web/includes/Group.php |
434 | ++++ b/web/includes/Group.php |
435 | +@@ -16,7 +16,7 @@ |
436 | + $row = NULL; |
437 | + if ( $IdOrRow ) { |
438 | + if ( is_integer($IdOrRow) or is_numeric($IdOrRow) ) { |
439 | +- $row = dbFetchOne('SELECT * FROM Groups WHERE Id=?', NULL, array($IdOrRow)); |
440 | ++ $row = dbFetchOne('SELECT * FROM `Groups` WHERE Id=?', NULL, array($IdOrRow)); |
441 | + if ( ! $row ) { |
442 | + Error('Unable to load Group record for Id=' . $IdOrRow); |
443 | + } |
444 | +@@ -59,7 +59,7 @@ |
445 | + } |
446 | + |
447 | + public static function find( $parameters = null, $options = null ) { |
448 | +- $sql = 'SELECT * FROM Groups '; |
449 | ++ $sql = 'SELECT * FROM `Groups` '; |
450 | + $values = array(); |
451 | + |
452 | + if ( $parameters ) { |
453 | +@@ -125,7 +125,7 @@ |
454 | + public function delete() { |
455 | + if ( array_key_exists('Id', $this) ) { |
456 | + dbQuery( 'DELETE FROM Groups_Monitors WHERE GroupId=?', array($this->{'Id'}) ); |
457 | +- dbQuery( 'DELETE FROM Groups WHERE Id=?', array($this->{'Id'}) ); |
458 | ++ dbQuery( 'DELETE FROM `Groups` WHERE Id=?', array($this->{'Id'}) ); |
459 | + if ( isset($_COOKIE['zmGroup']) ) { |
460 | + if ( $this->{'Id'} == $_COOKIE['zmGroup'] ) { |
461 | + unset($_COOKIE['zmGroup']); |
462 | +@@ -239,11 +239,11 @@ |
463 | + |
464 | + $MonitorIds = dbFetchAll('SELECT MonitorId FROM Groups_Monitors WHERE GroupId'.$group_id_sql_part, 'MonitorId', $group_id); |
465 | + |
466 | +- $MonitorIds = array_merge($MonitorIds, dbFetchAll('SELECT MonitorId FROM Groups_Monitors WHERE GroupId IN (SELECT Id FROM Groups WHERE ParentId'.$group_id_sql_part.')', 'MonitorId', $group_id)); |
467 | ++ $MonitorIds = array_merge($MonitorIds, dbFetchAll('SELECT MonitorId FROM Groups_Monitors WHERE GroupId IN (SELECT Id FROM `Groups` WHERE ParentId'.$group_id_sql_part.')', 'MonitorId', $group_id)); |
468 | + } else { |
469 | + $MonitorIds = dbFetchAll('SELECT MonitorId FROM Groups_Monitors WHERE GroupId=?', 'MonitorId', array($group_id)); |
470 | + |
471 | +- $MonitorIds = array_merge($MonitorIds, dbFetchAll('SELECT MonitorId FROM Groups_Monitors WHERE GroupId IN (SELECT Id FROM Groups WHERE ParentId = ?)', 'MonitorId', array($group_id))); |
472 | ++ $MonitorIds = array_merge($MonitorIds, dbFetchAll('SELECT MonitorId FROM Groups_Monitors WHERE GroupId IN (SELECT Id FROM `Groups` WHERE ParentId = ?)', 'MonitorId', array($group_id))); |
473 | + } |
474 | + $groupSql = " find_in_set( M.Id, '".implode(',', $MonitorIds)."' )"; |
475 | + } |
476 | +--- a/web/skins/classic/views/control.php |
477 | ++++ b/web/skins/classic/views/control.php |
478 | +@@ -25,13 +25,13 @@ |
479 | + |
480 | + $groupSql = ''; |
481 | + if ( !empty($_REQUEST['group']) ) { |
482 | +- $row = dbFetchOne( 'SELECT * FROM Groups WHERE Id = ?', NULL, array($_REQUEST['group']) ); |
483 | ++ $row = dbFetchOne( 'SELECT * FROM `Groups` WHERE Id = ?', NULL, array($_REQUEST['group']) ); |
484 | + $groupSql = " and find_in_set( Id, '".$row['MonitorIds']."' )"; |
485 | + } |
486 | + |
487 | + $mid = !empty($_REQUEST['mid']) ? validInt($_REQUEST['mid']) : 0; |
488 | + |
489 | +-$sql = "SELECT * FROM Monitors WHERE Function != 'None' AND Controllable = 1$groupSql ORDER BY Sequence"; |
490 | ++$sql = "SELECT * FROM Monitors WHERE `Function` != 'None' AND Controllable = 1$groupSql ORDER BY Sequence"; |
491 | + $mids = array(); |
492 | + foreach( dbFetchAll( $sql ) as $row ) { |
493 | + if ( !visibleMonitor( $row['Id'] ) ) { |
494 | diff --git a/debian/patches/mysql8_my_bool.patch b/debian/patches/mysql8_my_bool.patch |
495 | new file mode 100644 |
496 | index 0000000..cee2469 |
497 | --- /dev/null |
498 | +++ b/debian/patches/mysql8_my_bool.patch |
499 | @@ -0,0 +1,43 @@ |
500 | +Description: Reintroduce my_bool to fix build with MySQL 8 |
501 | +Author: Andreas Hasenack <andreas@canonical.com> |
502 | +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1863026 |
503 | +Forwarded: no |
504 | +Last-Update: 2020-02-12 |
505 | +--- |
506 | +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ |
507 | +diff --git a/src/zm_db.h b/src/zm_db.h |
508 | +index c707ad2..9f3381f 100644 |
509 | +--- a/src/zm_db.h |
510 | ++++ b/src/zm_db.h |
511 | +@@ -21,6 +21,7 @@ |
512 | + #define ZM_DB_H |
513 | + |
514 | + #include <mysql/mysql.h> |
515 | ++typedef bool my_bool; |
516 | + #include "zm_thread.h" |
517 | + |
518 | + class zmDbRow { |
519 | +diff --git a/src/zm_event.h b/src/zm_event.h |
520 | +index 1e55ae5..c3225c0 100644 |
521 | +--- a/src/zm_event.h |
522 | ++++ b/src/zm_event.h |
523 | +@@ -30,6 +30,7 @@ |
524 | + #include <sys/stat.h> |
525 | + #include <sys/types.h> |
526 | + #include <mysql/mysql.h> |
527 | ++typedef bool my_bool; |
528 | + |
529 | + #include <set> |
530 | + #include <map> |
531 | +diff --git a/src/zm_logger.h b/src/zm_logger.h |
532 | +index 8e2ab6c..c842a28 100644 |
533 | +--- a/src/zm_logger.h |
534 | ++++ b/src/zm_logger.h |
535 | +@@ -29,6 +29,7 @@ |
536 | + #include <sys/syscall.h> |
537 | + #endif // HAVE_SYS_SYSCALL_H |
538 | + #include <mysql/mysql.h> |
539 | ++typedef bool my_bool; |
540 | + |
541 | + class Logger { |
542 | + public: |
543 | diff --git a/debian/patches/series b/debian/patches/series |
544 | index f16125a..c295979 100644 |
545 | --- a/debian/patches/series |
546 | +++ b/debian/patches/series |
547 | @@ -25,3 +25,7 @@ |
548 | 0009-Allow-generation-of-random-seeds-on-install-time-not.patch |
549 | 0010-Use-mootools-shipped-by-debian-rather-than-the-zonem.patch |
550 | include_path.patch |
551 | +mysql8_my_bool.patch |
552 | +mysql8-password-deprecated.patch |
553 | +mysql8-reserved-keywords.patch |
554 | +mysql8-replace-password-call.patch |
555 | diff --git a/debian/rules b/debian/rules |
556 | index 98131b0..90031c5 100755 |
557 | --- a/debian/rules |
558 | +++ b/debian/rules |
559 | @@ -34,8 +34,9 @@ override_dh_clean: |
560 | dh_clean $(MANPAGES1) |
561 | $(RM) -r docs/_build docs/installationguide web/api/app/Plugin/Crud |
562 | |
563 | -build-indep: |
564 | +override_dh_auto_build-indep: |
565 | $(MAKE) -C docs html |
566 | + dh_auto_build |
567 | |
568 | MANPAGES1 = \ |
569 | dbuild/scripts/zmupdate.pl.1 \ |
I don't think we need to add the test for it, would it be nice: yes; is it really necessary: no.
At least not needed right now.
The mysql8 patches are a bit messy, but I agree that it does the job in as-minimal- as-possible fashion. And when moving to the next version it can be dropped.
Changelog:
- [√] changelog entry correct version and targeted codename
- [√] changelog entries correct
- [√] update-maintainer has been run
Actual changes:
- [√] no further upstream version that we want right now
New Delta: patches/ series
- [√] new patches are good and while not matching the final way they are from upstream and do the job for now.
- [√] new patches correctly included in debian/
- [√] new patches have correct DEP3 metadata linking to discussions and such
Build/Test:
- [√] build is ok
- [√] sanity checks test fine
I tested it with mythzoneminder and the basics there worked - if we could long term add an autopkgtest that would be good (as discussed above).
I ran this with a mix of php 7.4 and zoneminder to represent how focal will soon look like: core-8. 0 ocl-icd-libopencl1 php-apcu php-apcu-bc php-gd php-mysql php7.3-cli php7.3-common php7.3-json php7.3-opcache
... mysql-server-8.0 mysql-server-
php7.3-phpdbg php7.3-readline php7.4-gd php7.4-mysql zoneminder zoneminder-doc ...
All the perl installs also looked a lot.
But so far things worked.
One thing you might want to look at before an upload is this (up to you): 2ubuntu1~ ppa2) ... zoneminder/ www/api/ app/Config/ core.php. default ...
Setting up zoneminder (1.32.3-
I: Generating /etc/zm/core.php from /usr/share/
zoneminder.conf:1: Line references path below legacy directory /var/run/, updating /var/run/zm → /run/zm; please update the tmpfiles.d/ drop-in file accordingly.
It feels a bit less stable than usual, but ok still: +1 for this