Merge lp:~juliank/update-notifier/esm into lp:update-notifier/ubuntu
- esm
- Merge into ubuntu
Proposed by
Julian Andres Klode
Status: | Merged |
---|---|
Merged at revision: | 958 |
Proposed branch: | lp:~juliank/update-notifier/esm |
Merge into: | lp:update-notifier/ubuntu |
Diff against target: |
339 lines (+243/-7) 4 files modified
data/apt_check.py (+97/-7) debian/changelog (+7/-0) debian/rules (+2/-0) tests/test_motd.py (+137/-0) |
To merge this branch: | bzr merge lp:~juliank/update-notifier/esm |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Core Development Team | Pending | ||
Review via email: mp+365288@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Brian Murray (brian-murray) wrote : | # |
Revision history for this message
Joshua Powers (powersj) wrote : | # |
one in-line
Revision history for this message
Patricia Gaughen (gaughen) : | # |
lp:~juliank/update-notifier/esm
updated
- 960. By Julian Andres Klode
-
apt-check: Count enabled ESM upgrades
Revision history for this message
Brian Murray (brian-murray) wrote : | # |
A few more comments, thanks for addressing the other ones.
Revision history for this message
Julian Andres Klode (juliank) : | # |
lp:~juliank/update-notifier/esm
updated
- 961. By Julian Andres Klode
-
apt-check: Tell people to enable ESM if ESM updates are available
- 962. By Julian Andres Klode
-
Add changelog entry and test case
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'data/apt_check.py' |
2 | --- data/apt_check.py 2018-11-13 20:53:28 +0000 |
3 | +++ data/apt_check.py 2019-04-02 13:17:38 +0000 |
4 | @@ -45,6 +45,7 @@ |
5 | def isSecurityUpgrade(ver): |
6 | " check if the given version is a security update (or masks one) " |
7 | security_pockets = [("Ubuntu", "%s-security" % DISTRO), |
8 | + ("UbuntuESM", "%s-security" % DISTRO), |
9 | ("gNewSense", "%s-security" % DISTRO), |
10 | ("Debian", "%s-updates" % DISTRO)] |
11 | for (file, index) in ver.file_list: |
12 | @@ -54,6 +55,14 @@ |
13 | return False |
14 | |
15 | |
16 | +def isESMUpgrade(ver): |
17 | + " check if the given version is a security update (or masks one) " |
18 | + for (file, index) in ver.file_list: |
19 | + if file.origin == "UbuntuESM" and file.archive.startswith(DISTRO): |
20 | + return True |
21 | + return False |
22 | + |
23 | + |
24 | def write_package_names(outstream, cache, depcache): |
25 | " write out package names that change to outstream " |
26 | pkgs = [pkg for pkg in cache.packages if depcache.marked_install(pkg) |
27 | @@ -61,19 +70,77 @@ |
28 | outstream.write("\n".join([p.name for p in pkgs])) |
29 | |
30 | |
31 | -def write_human_readable_summary(outstream, upgrades, security_updates): |
32 | +def write_human_readable_summary(outstream, upgrades, security_updates, |
33 | + esm_updates, have_esm, disabled_esm_updates): |
34 | " write out human summary summary to outstream " |
35 | + if have_esm is not None: |
36 | + if have_esm: |
37 | + outstream.write(gettext.dgettext("update-notifier", |
38 | + "Extended Security Maintenance " |
39 | + "(ESM) is enabled.")) |
40 | + else: |
41 | + outstream.write(gettext.dgettext("update-notifier", |
42 | + "Extended Security Maintenance " |
43 | + "(ESM) is not enabled.")) |
44 | + outstream.write("\n\n") |
45 | + |
46 | outstream.write(gettext.dngettext("update-notifier", |
47 | - "%i package can be updated.", |
48 | - "%i packages can be updated.", |
49 | + "%i update can be installed " |
50 | + "immediately.", |
51 | + "%i updates can be installed " |
52 | + "immediately.", |
53 | upgrades) % upgrades) |
54 | outstream.write("\n") |
55 | + if esm_updates > 0: |
56 | + outstream.write(gettext.dngettext("update-notifier", |
57 | + "%i of these updates is " |
58 | + "provided through ESM.", |
59 | + "%i of these updates are " |
60 | + "provided through ESM.", |
61 | + esm_updates) % |
62 | + esm_updates) |
63 | + outstream.write("\n") |
64 | outstream.write(gettext.dngettext("update-notifier", |
65 | - "%i update is a security update.", |
66 | - "%i updates are security updates.", |
67 | - security_updates) % security_updates) |
68 | + "%i of these updates is a " |
69 | + "security update.", |
70 | + "%i of these updates are " |
71 | + "security updates.", |
72 | + security_updates) % |
73 | + security_updates) |
74 | outstream.write("\n") |
75 | |
76 | + if disabled_esm_updates > 0: |
77 | + outstream.write("\n") |
78 | + outstream.write(gettext.dngettext("update-notifier", |
79 | + "Enable ESM to receive %i additional " |
80 | + "security update.", |
81 | + "Enable ESM to receive %i additional " |
82 | + "security updates.", |
83 | + disabled_esm_updates) % |
84 | + disabled_esm_updates) |
85 | + outstream.write("\n") |
86 | + outstream.write(gettext.dgettext("update-notifier", |
87 | + "See 'ua enable esm' or " |
88 | + "https://ubuntu.com/esm")) |
89 | + outstream.write("\n") |
90 | + |
91 | + |
92 | +def has_disabled_esm_security_update(depcache, pkg): |
93 | + " check if we have a disabled ESM security update " |
94 | + inst_ver = pkg.current_ver |
95 | + if not inst_ver: |
96 | + return False |
97 | + |
98 | + for ver in pkg.version_list: |
99 | + if ver == inst_ver: |
100 | + break |
101 | + |
102 | + for (file, index) in ver.file_list: |
103 | + if (file.origin == "UbuntuESM" and file.archive.startswith(DISTRO) |
104 | + and depcache.policy.get_priority(file) == -32768): |
105 | + return True |
106 | + return False |
107 | + |
108 | |
109 | def init(): |
110 | " init the system, be nice " |
111 | @@ -115,13 +182,30 @@ |
112 | sys.stderr.write("E: " + _("Error: Marking the upgrade (%s)") % e) |
113 | sys.exit(-1) |
114 | |
115 | + # Check if we have ESM enabled or disabled; and if it exists in the |
116 | + # first place. |
117 | + have_esm = None # None == does not exist |
118 | + for file in cache.file_list: |
119 | + if file.origin == "UbuntuESM" and file.archive.startswith(DISTRO): |
120 | + # In case of multiple ESM repos, one enabled is sufficient. |
121 | + if have_esm is None and depcache.policy.get_priority(file) == -32768: |
122 | + have_esm = False |
123 | + else: |
124 | + have_esm = True |
125 | + break |
126 | + |
127 | # analyze the ugprade |
128 | upgrades = 0 |
129 | security_updates = 0 |
130 | + esm_updates = 0 |
131 | + disabled_esm_updates = 0 |
132 | |
133 | # we need another cache that has more pkg details |
134 | with apt.Cache() as aptcache: |
135 | for pkg in cache.packages: |
136 | + if has_disabled_esm_security_update(depcache, pkg): |
137 | + disabled_esm_updates += 1 |
138 | + |
139 | # skip packages that are not marked upgraded/installed |
140 | if not (depcache.marked_install(pkg) |
141 | or depcache.marked_upgrade(pkg)): |
142 | @@ -134,6 +218,8 @@ |
143 | continue |
144 | # check for security upgrades |
145 | if isSecurityUpgrade(cand_ver): |
146 | + if isESMUpgrade(cand_ver): |
147 | + esm_updates += 1 |
148 | upgrades += 1 |
149 | security_updates += 1 |
150 | continue |
151 | @@ -159,6 +245,8 @@ |
152 | and apt_pkg.version_compare(ver.ver_str, |
153 | inst_ver.ver_str) <= 0): |
154 | continue |
155 | + if isESMUpgrade(ver): |
156 | + esm_updates += 1 |
157 | if isSecurityUpgrade(ver): |
158 | security_updates += 1 |
159 | break |
160 | @@ -167,7 +255,9 @@ |
161 | if options and options.show_package_names: |
162 | write_package_names(sys.stderr, cache, depcache) |
163 | elif options and options.readable_output: |
164 | - write_human_readable_summary(sys.stdout, upgrades, security_updates) |
165 | + write_human_readable_summary(sys.stdout, upgrades, security_updates, |
166 | + esm_updates, have_esm, |
167 | + disabled_esm_updates) |
168 | else: |
169 | # print the number of regular upgrades and the number of |
170 | # security upgrades |
171 | |
172 | === modified file 'debian/changelog' |
173 | --- debian/changelog 2019-03-19 10:27:07 +0000 |
174 | +++ debian/changelog 2019-04-02 13:17:38 +0000 |
175 | @@ -1,3 +1,10 @@ |
176 | +update-notifier (3.192.16) UNRELEASED; urgency=medium |
177 | + |
178 | + * Rewrite and extend motd messaging (LP: #1822340) |
179 | + * Count ESM security updates as security updates |
180 | + |
181 | + -- Julian Andres Klode <juliank@ubuntu.com> Fri, 29 Mar 2019 16:26:45 +0100 |
182 | + |
183 | update-notifier (3.192.15) disco; urgency=medium |
184 | |
185 | * debian/control: |
186 | |
187 | === modified file 'debian/rules' |
188 | --- debian/rules 2018-05-09 10:59:08 +0000 |
189 | +++ debian/rules 2019-04-02 13:17:38 +0000 |
190 | @@ -13,3 +13,5 @@ |
191 | |
192 | override_dh_auto_test: |
193 | cd tests && python3 test_package-data-downloader.py |
194 | + cd tests && python3 test_motd.py |
195 | + |
196 | |
197 | === added symlink 'tests/apt_check.py' |
198 | === target is u'../data/apt_check.py' |
199 | === added file 'tests/test_motd.py' |
200 | --- tests/test_motd.py 1970-01-01 00:00:00 +0000 |
201 | +++ tests/test_motd.py 2019-04-02 13:17:38 +0000 |
202 | @@ -0,0 +1,137 @@ |
203 | +#!/usr/bin/python3 |
204 | +# -*- Mode: Python; indent-tabs-mode: nil; tab-width: 4; coding: utf-8 -*- |
205 | + |
206 | +import apt_check |
207 | +import io |
208 | +import os |
209 | +import subprocess |
210 | +import unittest |
211 | +import textwrap |
212 | + |
213 | + |
214 | +def get_message(*args, **kwds): |
215 | + with io.StringIO() as stream: |
216 | + apt_check.write_human_readable_summary(stream, *args, **kwds) |
217 | + return stream.getvalue() |
218 | + |
219 | + |
220 | +class TestMotd(unittest.TestCase): |
221 | + """ ensure that the tree is pep8 clean """ |
222 | + |
223 | + def test_esm_disabled_upto_date_esm_avail(self): |
224 | + self.assertEqual( |
225 | + get_message(upgrades=0, security_updates=0, |
226 | + esm_updates=0, have_esm=False, |
227 | + disabled_esm_updates=23), |
228 | + textwrap.dedent( |
229 | + """ |
230 | + Extended Security Maintenance (ESM) is not enabled. |
231 | + |
232 | + 0 updates can be installed immediately. |
233 | + 0 of these updates are security updates. |
234 | + |
235 | + Enable ESM to receive 23 additional security updates. |
236 | + See 'ua enable esm' or https://ubuntu.com/esm |
237 | + """).lstrip()) |
238 | + |
239 | + def test_esm_disabled_security_esm_avail(self): |
240 | + self.assertEqual( |
241 | + get_message(upgrades=15, security_updates=7, |
242 | + esm_updates=0, have_esm=False, |
243 | + disabled_esm_updates=23), |
244 | + textwrap.dedent( |
245 | + """ |
246 | + Extended Security Maintenance (ESM) is not enabled. |
247 | + |
248 | + 15 updates can be installed immediately. |
249 | + 7 of these updates are security updates. |
250 | + |
251 | + Enable ESM to receive 23 additional security updates. |
252 | + See 'ua enable esm' or https://ubuntu.com/esm |
253 | + """).lstrip()) |
254 | + |
255 | + def test_esm_disabled_security_no_esm_avail(self): |
256 | + self.assertEqual( |
257 | + get_message(upgrades=15, security_updates=7, |
258 | + esm_updates=0, have_esm=False, |
259 | + disabled_esm_updates=0), |
260 | + textwrap.dedent( |
261 | + """ |
262 | + Extended Security Maintenance (ESM) is not enabled. |
263 | + |
264 | + 15 updates can be installed immediately. |
265 | + 7 of these updates are security updates. |
266 | + """).lstrip()) |
267 | + |
268 | + def test_esm_disabled_nosecurity(self): |
269 | + self.assertEqual( |
270 | + get_message(upgrades=15, security_updates=0, |
271 | + esm_updates=0, have_esm=False, |
272 | + disabled_esm_updates=0), |
273 | + textwrap.dedent( |
274 | + """ |
275 | + Extended Security Maintenance (ESM) is not enabled. |
276 | + |
277 | + 15 updates can be installed immediately. |
278 | + 0 of these updates are security updates. |
279 | + """).lstrip()) |
280 | + |
281 | + def test_esm_disabled_noupdates(self): |
282 | + self.assertEqual( |
283 | + get_message(upgrades=0, security_updates=0, |
284 | + esm_updates=0, have_esm=False, |
285 | + disabled_esm_updates=0), |
286 | + textwrap.dedent( |
287 | + """ |
288 | + Extended Security Maintenance (ESM) is not enabled. |
289 | + |
290 | + 0 updates can be installed immediately. |
291 | + 0 of these updates are security updates. |
292 | + """).lstrip()) |
293 | + |
294 | + def test_esm_enabled_nosecurity(self): |
295 | + self.assertEqual( |
296 | + get_message(upgrades=35, security_updates=0, |
297 | + esm_updates=13, have_esm=True, |
298 | + disabled_esm_updates=0), |
299 | + textwrap.dedent( |
300 | + """ |
301 | + Extended Security Maintenance (ESM) is enabled. |
302 | + |
303 | + 35 updates can be installed immediately. |
304 | + 13 of these updates are provided through ESM. |
305 | + 0 of these updates are security updates. |
306 | + """).lstrip()) |
307 | + |
308 | + def test_esm_enabled_somesecurity(self): |
309 | + self.assertEqual( |
310 | + get_message(upgrades=47, security_updates=7, |
311 | + esm_updates=13, have_esm=True, |
312 | + disabled_esm_updates=0), |
313 | + textwrap.dedent( |
314 | + """ |
315 | + Extended Security Maintenance (ESM) is enabled. |
316 | + |
317 | + 47 updates can be installed immediately. |
318 | + 13 of these updates are provided through ESM. |
319 | + 7 of these updates are security updates. |
320 | + """).lstrip()) |
321 | + |
322 | + def test_esm_enabled_noupdates(self): |
323 | + self.assertEqual( |
324 | + get_message(upgrades=0, security_updates=0, |
325 | + esm_updates=0, have_esm=True, |
326 | + disabled_esm_updates=0), |
327 | + textwrap.dedent( |
328 | + """ |
329 | + Extended Security Maintenance (ESM) is enabled. |
330 | + |
331 | + 0 updates can be installed immediately. |
332 | + 0 of these updates are security updates. |
333 | + """).lstrip()) |
334 | + |
335 | + |
336 | +if __name__ == "__main__": |
337 | + import logging |
338 | + logging.basicConfig(level=logging.DEBUG) |
339 | + unittest.main() |
Nothing critical but a few comments appear in-line.