Merge ~lamoura/update-notifier:update-esm-handling into update-notifier:master

Proposed by Lucas Albuquerque Medeiros de Moura
Status: Needs review
Proposed branch: ~lamoura/update-notifier:update-esm-handling
Merge into: update-notifier:master
Diff against target: 842 lines (+491/-121)
3 files modified
data/apt_check.py (+173/-73)
debian/control (+2/-0)
tests/test_motd.py (+316/-48)
Reviewer Review Type Date Requested Status
Brian Murray Approve
Chad Smith (community) Needs Fixing
Review via email: mp+401002@code.launchpad.net

Description of the change

Currently, the apt-check script is configured to only handle package count for ESM Infra. We are now updating the logic to also handle ESM Apps packages as well.

Furthermore, we are also updating the messaging that is created in apt-check. We are advertising ESM Apps if the service is disabled and only messaging about ESM Infra if the distro is already on ESM mode.

Finally, this PR also fixes LP #1883315, since we now check to see if the system has esm-infra or esm-apps before performing a package count for package with esm origins

To post a comment you must log in.
Revision history for this message
Chad Smith (chad.smith) wrote :

I think we might need a couple of changes here. Thanks Lucas for putting this together.

Revision history for this message
Chad Smith (chad.smith) :
review: Needs Fixing
Revision history for this message
Lucas Albuquerque Medeiros de Moura (lamoura) :
Revision history for this message
Richard Harding (rharding) :
Revision history for this message
Chad Smith (chad.smith) :
Revision history for this message
Grant Orndorff (orndorffgrant) wrote :

Overall looks great!

I left some small nitpicks and general comments about the messages that may be too late to change.

Also are we going to migrate this to use the shared messaging we're adding uaclient in the future?

Revision history for this message
Lucas Albuquerque Medeiros de Moura (lamoura) wrote :

Thanks for the review Grant,

I think the message suggestion is worth thinking about. But I agree that we don't have enough time to address it.

Regarding the integration, we are already relying on some parts of the shared messaging work. Specially for the ESM Apps header and the expired messages. But for other messages, I think that if in the future we do have a message that is not easy to compute in update-notifier and need to presented in the middle of the text produced by it, I think the right away is to rely on the uaclient shared messages infrastructure

Revision history for this message
Lucas Albuquerque Medeiros de Moura (lamoura) wrote :
Download full text (4.5 KiB)

This is the script that I am using to test this modifications on Xenial machine.
If needed, I can also extend it to address other releases:

--------------------
#!/bin/sh
set -x

series=xenial
name=$series-dev

function update-notifier-ua-not-installed () {
    # Expects this output
    # x packages can be updated.
    # x of these updates are security updates.
    echo "-----------------------------------------------------------"
    echo "xenial: ua not installed"
    lxc exec $name -- /usr/lib/update-notifier/apt-check --human-readable
    echo "-----------------------------------------------------------"
}

function update-notifier-ua-not-attached-esm () {
    # x updates can be installed immediately.
    # x of these updates are security updates.
    #
    # Enable UA Apps: ESM to receive x additional security updates.
    # See https://ubuntu.com/security/esm or run: sudo ua status
    echo "-----------------------------------------------------------"
    echo "xenial esm: ua not attached"
    lxc exec $name -- /usr/lib/update-notifier/apt-check --human-readable
    echo "-----------------------------------------------------------"
}

function update-notifier-ua-not-attached () {
    # Expects this output
    # UA Infra: Extended Security Maintenance (ESM) is not enabled.
    #
    # x updates can be installed immediately.
    # x of these updates are security updates.
    echo "-----------------------------------------------------------"
    echo "xenial non-esm: ua not attached"
    lxc exec $name -- /usr/lib/update-notifier/apt-check --human-readable
    echo "-----------------------------------------------------------"
}

function update-notifier-ua-attached-esm () {
    # Expects this output
    # x updates can be installed immediately.
    # x of these updates are fixed through UA Apps: ESM.
    # x of these updates are security updates.
    # To see these additional updates run: apt list --upgradable
    echo "-----------------------------------------------------------"
    echo "xenial esm: ua attached"
    lxc exec $name -- /usr/lib/update-notifier/apt-check --human-readable
    echo "-----------------------------------------------------------"
}

function update-notifier-ua-attached () {
    # Expects this output
    # x updates can be installed immediately.
    # x of these updates are fixed through UA Apps: ESM.
    # x of these updates are security updates.
    # To see these additional updates run: apt list --upgradable
    echo "-----------------------------------------------------------"
    echo "xenial non-esm: ua attached"
    lxc exec $name -- /usr/lib/update-notifier/apt-check --human-readable
    echo "-----------------------------------------------------------"
}

function turn-distro-into-esm-mode() {
    # guarantee that xenial distro is on ESM mode
    lxc exec $name -- sed -i 's/days_until_esm, _ = .*/days_until_esm = "-1"/' /usr/lib/update-notifier/apt-check
}

function turn-distro-into-non-esm-mode() {
    # guarantee that xenial distro is on ESM mode
    lxc exec $name -- sed -i 's/days_until_esm = .*/days_until_esm = "1"/' /usr/lib/update-notifier/apt-check
}

function setup-update-notifier() {
    ...

Read more...

Revision history for this message
Lucas Albuquerque Medeiros de Moura (lamoura) wrote :

Also, this is formatted output of my script:

-----------------------------------------------------------
xenial: ua not installed
0 updates can be installed immediately.
0 of these updates are security updates.
-----------------------------------------------------------
xenial esm: ua not attached
0 updates can be installed immediately.
0 of these updates are security updates.
-----------------------------------------------------------
xenial esm: ua attached
UA Infra: Extended Security Maintenance (ESM) is enabled.

5 updates can be installed immediately.
5 of these updates are UA Apps: ESM security updates.
5 of these updates are security updates.
To see these additional updates run: apt list --upgradable
-----------------------------------------------------------
xenial non-esm: ua not attached
0 updates can be installed immediately.
0 of these updates are security updates.

5 additional security updates can be applied with UA Apps: ESM
Learn more about enabling UA Apps: ESM service at https://ubuntu.com/esm
-----------------------------------------------------------
xenial non-esm: ua attached
5 updates can be installed immediately.
5 of these updates are UA Apps: ESM security updates.
5 of these updates are security updates.
To see these additional updates run: apt list --upgradable
-----------------------------------------------------------

Revision history for this message
Brian Murray (brian-murray) wrote :

I've one diff comment.

review: Needs Fixing
Revision history for this message
Brian Murray (brian-murray) wrote :

Also is there any reason the python module for distro-info wasn't used?

review: Needs Information
Revision history for this message
Lucas Albuquerque Medeiros de Moura (lamoura) wrote :

Hi Brian, thank you for the review on that. And the reason that I have not used python3-distro-info is just because I just recently discovered that it existed. But I have updated the code to use it. Thanks for pointing that out.

Also, this change also address the diff comment you made

Revision history for this message
Lucas Albuquerque Medeiros de Moura (lamoura) wrote :

Also Brian, I have updated the `is_esm_distro` logic here. I couldn't find any gaps on it, but if you want to double check if it sound, that would be great.

Revision history for this message
Lucas Albuquerque Medeiros de Moura (lamoura) wrote :

PTAL

Revision history for this message
Brian Murray (brian-murray) wrote :

I merged a previous version of this so I think that's why the status is still Needs Review.

review: Approve

Unmerged commits

946667b... by Lucas Albuquerque Medeiros de Moura

Update apt-check script for ESM Apps handling

Currently, the apt-check script is configured to only handle
package count for ESM Infra. We are now updating the logic
to also handle ESM Apps packages as well.

Furthermore, we are also updating the messaging that is created in
apt-check. We are advertising ESM Apps if the service is disabled
and only messaging about ESM Infra if the distro is already on ESM mode

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/data/apt_check.py b/data/apt_check.py
2index 2c18ef6..f984e45 100755
3--- a/data/apt_check.py
4+++ b/data/apt_check.py
5@@ -10,13 +10,16 @@ import sys
6 from optparse import OptionParser
7 import gettext
8 import subprocess
9+import distro_info
10
11 SYNAPTIC_PINFILE = "/var/lib/synaptic/preferences"
12 DISTRO = subprocess.check_output(
13 ["lsb_release", "-c", "-s"],
14 universal_newlines=True).strip()
15
16-ESM_ORIGINS = ("UbuntuESM", "UbuntuESMApps")
17+ESM_INFRA_ORIGIN = "UbuntuESM"
18+ESM_APPS_ORIGIN = "UbuntuESMApps"
19+ESM_ORIGINS = (ESM_INFRA_ORIGIN, ESM_APPS_ORIGIN)
20
21
22 def _(msg):
23@@ -47,8 +50,8 @@ def saveDistUpgrade(cache, depcache):
24 def isSecurityUpgrade(ver):
25 " check if the given version is a security update (or masks one) "
26 security_pockets = [("Ubuntu", "%s-security" % DISTRO),
27- ("UbuntuESM", "%s-infra-security" % DISTRO),
28- ("UbuntuESMApps", "%s-apps-security" % DISTRO),
29+ (ESM_INFRA_ORIGIN, "%s-infra-security" % DISTRO),
30+ (ESM_APPS_ORIGIN, "%s-apps-security" % DISTRO),
31 ("gNewSense", "%s-security" % DISTRO),
32 ("Debian", "%s-updates" % DISTRO)]
33 for (file, index) in ver.file_list:
34@@ -58,14 +61,22 @@ def isSecurityUpgrade(ver):
35 return False
36
37
38-def isESMUpgrade(ver):
39+def _isESMUpgrade(ver, esm_origin):
40 " check if the given version is a security update (or masks one) "
41 for (file, index) in ver.file_list:
42- if file.origin in ESM_ORIGINS and file.archive.startswith(DISTRO):
43+ if file.origin == esm_origin and file.archive.startswith(DISTRO):
44 return True
45 return False
46
47
48+def isESMAppsUpgrade(ver):
49+ return _isESMUpgrade(ver, esm_origin=ESM_APPS_ORIGIN)
50+
51+
52+def isESMInfraUpgrade(ver):
53+ return _isESMUpgrade(ver, esm_origin=ESM_INFRA_ORIGIN)
54+
55+
56 def write_package_names(outstream, cache, depcache):
57 " write out package names that change to outstream "
58 pkgs = [pkg for pkg in cache.packages if depcache.marked_install(pkg)
59@@ -73,11 +84,86 @@ def write_package_names(outstream, cache, depcache):
60 outstream.write("\n".join([p.name for p in pkgs]))
61
62
63+def is_esm_distro():
64+ ubuntu_distro = distro_info.UbuntuDistroInfo()
65+
66+ is_esm_supported = bool(
67+ DISTRO in ubuntu_distro.supported_esm()
68+ )
69+
70+ is_not_currently_supported = bool(
71+ DISTRO in ubuntu_distro.unsupported()
72+ )
73+
74+ return is_esm_supported and is_not_currently_supported
75+
76+
77+def is_lts_distro():
78+ return distro_info.UbuntuDistroInfo().is_lts(DISTRO)
79+
80+
81+def _output_esm_package_count(outstream, service_type, esm_pkg_count):
82+ if esm_pkg_count > 0:
83+ outstream.write("\n")
84+ outstream.write(gettext.dngettext("update-notifier",
85+ "%d of these updates "
86+ "are UA %s: ESM "
87+ "security updates.",
88+ "%d of these updates "
89+ "are UA %s: ESM "
90+ "security updates.",
91+ esm_pkg_count) %
92+ (esm_pkg_count, service_type))
93+
94+
95+def _output_esm_package_alert(
96+ outstream, service_type, disabled_pkg_count
97+):
98+ outstream.write("\n")
99+ if disabled_pkg_count > 0:
100+ outstream.write("\n")
101+ outstream.write(gettext.dngettext("update-notifier",
102+ "%i additional security "
103+ "updates can be applied "
104+ "with UA %s: ESM\nLearn "
105+ "more about enabling UA "
106+ "%s: ESM service at "
107+ "https://ubuntu.com/esm",
108+ "%i additional security "
109+ "updates can be applied "
110+ "with UA %s: ESM\nLearn "
111+ "more about enabling UA "
112+ "%s: ESM service at "
113+ "https://ubuntu.com/esm",
114+ disabled_pkg_count) %
115+ (disabled_pkg_count, service_type, service_type))
116+ else:
117+ outstream.write("\n")
118+ outstream.write(gettext.dgettext("update-notifier",
119+ "Enable UA %s: ESM to "
120+ "receive additional future "
121+ "security updates.") %
122+ service_type)
123+
124+ outstream.write("\n")
125+ outstream.write(
126+ gettext.dgettext("update-notifier",
127+ "See https://ubuntu.com/esm "
128+ "or run: sudo ua status")
129+ )
130+
131+
132 def write_human_readable_summary(outstream, upgrades, security_updates,
133- esm_updates, have_esm, disabled_esm_updates):
134+ esm_infra_updates, esm_apps_updates,
135+ have_esm_infra, have_esm_apps,
136+ disabled_esm_infra_updates,
137+ disabled_esm_apps_updates):
138+
139+ esm_distro = is_esm_distro()
140+ lts_distro = is_lts_distro()
141 " write out human summary summary to outstream "
142- if have_esm is not None:
143- if have_esm:
144+ if have_esm_infra is not None and esm_distro:
145+ if have_esm_infra:
146 outstream.write(gettext.dgettext("update-notifier",
147 "UA Infra: Extended "
148 "Security Maintenance (ESM) is "
149@@ -89,23 +175,19 @@ def write_human_readable_summary(outstream, upgrades, security_updates,
150 "not enabled."))
151 outstream.write("\n\n")
152
153- outstream.write(gettext.dngettext("update-notifier",
154- "%i update can be installed "
155- "immediately.",
156- "%i updates can be installed "
157- "immediately.",
158- upgrades) % upgrades)
159+ outstream.write(
160+ gettext.dngettext("update-notifier",
161+ "%i updates can be installed immediately.",
162+ "%i updates can be installed immediately.",
163+ upgrades) % upgrades
164+ )
165+
166+ _output_esm_package_count(
167+ outstream, service_type="Infra", esm_pkg_count=esm_infra_updates)
168+ _output_esm_package_count(
169+ outstream, service_type="Apps", esm_pkg_count=esm_apps_updates)
170+
171 outstream.write("\n")
172- if esm_updates > 0:
173- outstream.write(gettext.dngettext("update-notifier",
174- "%i of these updates is fixed "
175- "through UA Infra: ESM.",
176- "%i of these updates are "
177- "fixed through UA "
178- "Infra: ESM.",
179- esm_updates) %
180- esm_updates)
181- outstream.write("\n")
182 outstream.write(gettext.dngettext("update-notifier",
183 "%i of these updates is a "
184 "security update.",
185@@ -113,38 +195,27 @@ def write_human_readable_summary(outstream, upgrades, security_updates,
186 "security updates.",
187 security_updates) %
188 security_updates)
189- if upgrades > 0 or security_updates > 0 or esm_updates > 0:
190+
191+ if any([upgrades, security_updates, esm_infra_updates, esm_apps_updates]):
192 outstream.write("\n")
193 outstream.write(gettext.dgettext("update-notifier",
194 "To see these additional updates "
195 "run: apt list --upgradable"))
196- if have_esm is not None and not have_esm:
197- outstream.write("\n")
198- if disabled_esm_updates > 0:
199- outstream.write("\n")
200- outstream.write(gettext.dngettext("update-notifier",
201- "Enable UA Infra: ESM "
202- "to receive %i additional "
203- "security update.",
204- "Enable UA Infra: ESM "
205- "to receive %i additional "
206- "security updates.",
207- disabled_esm_updates) %
208- disabled_esm_updates)
209- else:
210- outstream.write("\n")
211- outstream.write(gettext.dgettext("update-notifier",
212- "Enable UA Infra: ESM to "
213- "receive additional future "
214- "security updates."))
215- outstream.write("\n")
216- outstream.write(gettext.dgettext("update-notifier",
217- "See https://ubuntu.com/security/esm "
218- "or run: sudo ua status"))
219+
220+ if have_esm_apps is not None and not have_esm_apps and lts_distro:
221+ _output_esm_package_alert(
222+ outstream, service_type="Apps",
223+ disabled_pkg_count=disabled_esm_apps_updates)
224+
225+ if have_esm_infra is not None and not have_esm_infra and esm_distro:
226+ _output_esm_package_alert(
227+ outstream, service_type="Infra",
228+ disabled_pkg_count=disabled_esm_infra_updates)
229+
230 outstream.write("\n")
231
232
233-def has_disabled_esm_security_update(depcache, pkg):
234+def has_disabled_esm_security_update(depcache, pkg, esm_origin):
235 " check if we have a disabled ESM security update "
236 inst_ver = pkg.current_ver
237 if not inst_ver:
238@@ -155,12 +226,39 @@ def has_disabled_esm_security_update(depcache, pkg):
239 break
240
241 for (file, index) in ver.file_list:
242- if (file.origin in ESM_ORIGINS and file.archive.startswith(DISTRO)
243+ if (file.origin == esm_origin and file.archive.startswith(DISTRO)
244 and depcache.policy.get_priority(file) == -32768):
245 return True
246 return False
247
248
249+def has_disabled_esm_apps_security_update(depcache, pkg):
250+ return has_disabled_esm_security_update(depcache, pkg, ESM_APPS_ORIGIN)
251+
252+
253+def has_disabled_esm_infra_security_update(depcache, pkg):
254+ return has_disabled_esm_security_update(depcache, pkg, ESM_INFRA_ORIGIN)
255+
256+
257+def has_esm_service(cache, depcache, esm_origin):
258+ have_esm = None
259+ for file in cache.file_list:
260+ origin = file.origin
261+ if origin == esm_origin and file.archive.startswith(DISTRO):
262+ # In case of multiple ESM repos, one enabled is sufficient.
263+ if depcache.policy.get_priority(file) == -32768:
264+ # We found a disabled ESM repository, but we'll only count
265+ # ESM as disabled here if we have not found any other ESM
266+ # repo, so one ESM repo being enabled means ESM is enabled.
267+ if have_esm is None:
268+ have_esm = False
269+ else:
270+ have_esm = True
271+ break
272+
273+ return have_esm
274+
275+
276 def init():
277 " init the system, be nice "
278 # FIXME: do a ionice here too?
279@@ -203,31 +301,26 @@ def run(options=None):
280
281 # Check if we have ESM enabled or disabled; and if it exists in the
282 # first place.
283- have_esm = None # None == does not exist
284- for file in cache.file_list:
285- if file.origin in ESM_ORIGINS and file.archive.startswith(DISTRO):
286- # In case of multiple ESM repos, one enabled is sufficient.
287- if depcache.policy.get_priority(file) == -32768:
288- # We found a disabled ESM repository, but we'll only count
289- # ESM as disabled here if we have not found any other ESM
290- # repo, so one ESM repo being enabled means ESM is enabled.
291- if have_esm is None:
292- have_esm = False
293- else:
294- have_esm = True
295- break
296+ have_esm_infra = has_esm_service(
297+ cache, depcache, esm_origin=ESM_INFRA_ORIGIN)
298+ have_esm_apps = has_esm_service(
299+ cache, depcache, esm_origin=ESM_APPS_ORIGIN)
300
301 # analyze the ugprade
302 upgrades = 0
303 security_updates = 0
304- esm_updates = 0
305- disabled_esm_updates = 0
306+ esm_apps_updates = 0
307+ esm_infra_updates = 0
308+ disabled_esm_apps_updates = 0
309+ disabled_esm_infra_updates = 0
310
311 # we need another cache that has more pkg details
312 with apt.Cache() as aptcache:
313 for pkg in cache.packages:
314- if has_disabled_esm_security_update(depcache, pkg):
315- disabled_esm_updates += 1
316+ if has_disabled_esm_apps_security_update(depcache, pkg):
317+ disabled_esm_apps_updates += 1
318+ if has_disabled_esm_infra_security_update(depcache, pkg):
319+ disabled_esm_infra_updates += 1
320
321 # skip packages that are not marked upgraded/installed
322 if not (depcache.marked_install(pkg)
323@@ -241,8 +334,10 @@ def run(options=None):
324 continue
325 # check for security upgrades
326 if isSecurityUpgrade(cand_ver):
327- if isESMUpgrade(cand_ver):
328- esm_updates += 1
329+ if have_esm_apps and isESMAppsUpgrade(cand_ver):
330+ esm_apps_updates += 1
331+ elif have_esm_infra and isESMInfraUpgrade(cand_ver):
332+ esm_infra_updates += 1
333 upgrades += 1
334 security_updates += 1
335 continue
336@@ -268,8 +363,11 @@ def run(options=None):
337 and apt_pkg.version_compare(ver.ver_str,
338 inst_ver.ver_str) <= 0):
339 continue
340- if isESMUpgrade(ver):
341- esm_updates += 1
342+ if have_esm_apps and isESMAppsUpgrade(cand_ver):
343+ esm_apps_updates += 1
344+ elif have_esm_infra and isESMInfraUpgrade(cand_ver):
345+ esm_infra_updates += 1
346+
347 if isSecurityUpgrade(ver):
348 security_updates += 1
349 break
350@@ -279,8 +377,10 @@ def run(options=None):
351 write_package_names(sys.stderr, cache, depcache)
352 elif options and options.readable_output:
353 write_human_readable_summary(sys.stdout, upgrades, security_updates,
354- esm_updates, have_esm,
355- disabled_esm_updates)
356+ esm_infra_updates, esm_apps_updates,
357+ have_esm_infra, have_esm_apps,
358+ disabled_esm_infra_updates,
359+ disabled_esm_apps_updates)
360 else:
361 # print the number of regular upgrades and the number of
362 # security upgrades
363diff --git a/debian/control b/debian/control
364index 79975d0..c6c9012 100644
365--- a/debian/control
366+++ b/debian/control
367@@ -18,6 +18,7 @@ Build-Depends: debhelper (>= 11~),
368 python3-apt,
369 python3-debconf,
370 python3-debian,
371+ python3-distro-info,
372 python3-mock
373 Standards-Version: 4.5.0
374 Vcs-Git: https://git.launchpad.net/update-notifier -b master
375@@ -51,6 +52,7 @@ Depends: ${shlibs:Depends},
376 python3:any,
377 python3-apt, python3-dbus, python3-debian,
378 python3-debconf | debconf (<< 1.5.64~),
379+ python3-distro-info,
380 patch, update-manager-core (>= 1:17.04.2)
381 Recommends: libpam-modules (>= 1.0.1-9ubuntu3)
382 Suggests: policykit-1
383diff --git a/tests/test_motd.py b/tests/test_motd.py
384index ec1a09f..f3b982c 100755
385--- a/tests/test_motd.py
386+++ b/tests/test_motd.py
387@@ -6,6 +6,8 @@ import io
388 import unittest
389 import textwrap
390
391+from unittest import mock
392+
393
394 def get_message(*args, **kwds):
395 with io.StringIO() as stream:
396@@ -16,132 +18,398 @@ def get_message(*args, **kwds):
397 class TestMotd(unittest.TestCase):
398 """ Validate /etc/motd text """
399
400- def test_esm_disabled_upto_date_esm_avail(self):
401+ @mock.patch("apt_check.is_lts_distro", return_value=True)
402+ @mock.patch("apt_check.is_esm_distro", return_value=True)
403+ def test_esm_infra_disabled_upto_date_esm_avail(
404+ self, _m_esm_distro, _m_is_lts
405+ ):
406 self.assertEqual(
407 get_message(upgrades=0, security_updates=0,
408- esm_updates=0, have_esm=False,
409- disabled_esm_updates=23),
410+ esm_infra_updates=0, esm_apps_updates=0,
411+ have_esm_infra=False, have_esm_apps=False,
412+ disabled_esm_infra_updates=23,
413+ disabled_esm_apps_updates=0),
414 textwrap.dedent(
415- """
416+ """\
417 UA Infra: Extended Security Maintenance (ESM) is not enabled.
418
419 0 updates can be installed immediately.
420 0 of these updates are security updates.
421
422- Enable UA Infra: ESM to receive 23 additional security updates.
423- See https://ubuntu.com/security/esm or run: sudo ua status
424- """).lstrip())
425+ Enable UA Apps: ESM to receive additional future security updates.
426+ See https://ubuntu.com/esm or run: sudo ua status
427
428- def test_esm_disabled_security_esm_avail(self):
429+ 23 additional security updates can be applied with UA Infra: ESM
430+ Learn more about enabling UA Infra: ESM service at https://ubuntu.com/esm
431+ """))
432+
433+ @mock.patch("apt_check.is_lts_distro", return_value=True)
434+ @mock.patch("apt_check.is_esm_distro", return_value=True)
435+ def test_esm_infra_disabled_security_esm_avail(
436+ self, _m_esm_distro, _m_is_lts
437+ ):
438 self.assertEqual(
439 get_message(upgrades=15, security_updates=7,
440- esm_updates=0, have_esm=False,
441- disabled_esm_updates=23),
442+ esm_infra_updates=0, esm_apps_updates=0,
443+ have_esm_infra=False, have_esm_apps=False,
444+ disabled_esm_infra_updates=23,
445+ disabled_esm_apps_updates=0),
446 textwrap.dedent(
447- """
448+ """\
449 UA Infra: Extended Security Maintenance (ESM) is not enabled.
450
451 15 updates can be installed immediately.
452 7 of these updates are security updates.
453 To see these additional updates run: apt list --upgradable
454
455- Enable UA Infra: ESM to receive 23 additional security updates.
456- See https://ubuntu.com/security/esm or run: sudo ua status
457- """).lstrip())
458+ Enable UA Apps: ESM to receive additional future security updates.
459+ See https://ubuntu.com/esm or run: sudo ua status
460
461- def test_esm_disabled_security_no_esm_avail(self):
462+ 23 additional security updates can be applied with UA Infra: ESM
463+ Learn more about enabling UA Infra: ESM service at https://ubuntu.com/esm
464+ """))
465+
466+ @mock.patch("apt_check.is_lts_distro", return_value=True)
467+ @mock.patch("apt_check.is_esm_distro", return_value=True)
468+ def test_esm_infra_disabled_security_no_esm_avail(
469+ self, _m_esm_distro, _m_is_lts
470+ ):
471 self.assertEqual(
472 get_message(upgrades=15, security_updates=7,
473- esm_updates=0, have_esm=False,
474- disabled_esm_updates=0),
475+ esm_infra_updates=0, esm_apps_updates=0,
476+ have_esm_infra=False, have_esm_apps=False,
477+ disabled_esm_infra_updates=0,
478+ disabled_esm_apps_updates=0),
479 textwrap.dedent(
480- """
481+ """\
482 UA Infra: Extended Security Maintenance (ESM) is not enabled.
483
484 15 updates can be installed immediately.
485 7 of these updates are security updates.
486 To see these additional updates run: apt list --upgradable
487
488+ Enable UA Apps: ESM to receive additional future security updates.
489+ See https://ubuntu.com/esm or run: sudo ua status
490+
491 Enable UA Infra: ESM to receive additional future security updates.
492- See https://ubuntu.com/security/esm or run: sudo ua status
493- """).lstrip())
494+ See https://ubuntu.com/esm or run: sudo ua status
495+ """))
496
497- def test_esm_disabled_nosecurity(self):
498+ @mock.patch("apt_check.is_lts_distro", return_value=True)
499+ @mock.patch("apt_check.is_esm_distro", return_value=True)
500+ def test_esm_infra_disabled_nosecurity(
501+ self, _m_esm_distro, _m_is_lts
502+ ):
503 self.assertEqual(
504 get_message(upgrades=15, security_updates=0,
505- esm_updates=0, have_esm=False,
506- disabled_esm_updates=0),
507+ esm_infra_updates=0, esm_apps_updates=0,
508+ have_esm_infra=False, have_esm_apps=False,
509+ disabled_esm_infra_updates=0,
510+ disabled_esm_apps_updates=0),
511 textwrap.dedent(
512- """
513+ """\
514 UA Infra: Extended Security Maintenance (ESM) is not enabled.
515
516 15 updates can be installed immediately.
517 0 of these updates are security updates.
518 To see these additional updates run: apt list --upgradable
519
520+ Enable UA Apps: ESM to receive additional future security updates.
521+ See https://ubuntu.com/esm or run: sudo ua status
522+
523 Enable UA Infra: ESM to receive additional future security updates.
524- See https://ubuntu.com/security/esm or run: sudo ua status
525- """).lstrip())
526+ See https://ubuntu.com/esm or run: sudo ua status
527+ """))
528
529- def test_esm_disabled_noupdates(self):
530+ @mock.patch("apt_check.is_lts_distro", return_value=True)
531+ @mock.patch("apt_check.is_esm_distro", return_value=True)
532+ def test_esm_infra_disabled_noupdates(
533+ self, _m_esm_distro, _m_is_lts
534+ ):
535 self.assertEqual(
536 get_message(upgrades=0, security_updates=0,
537- esm_updates=0, have_esm=False,
538- disabled_esm_updates=0),
539+ esm_infra_updates=0, esm_apps_updates=0,
540+ have_esm_infra=False, have_esm_apps=False,
541+ disabled_esm_infra_updates=0,
542+ disabled_esm_apps_updates=0),
543 textwrap.dedent(
544- """
545+ """\
546 UA Infra: Extended Security Maintenance (ESM) is not enabled.
547
548 0 updates can be installed immediately.
549 0 of these updates are security updates.
550
551+ Enable UA Apps: ESM to receive additional future security updates.
552+ See https://ubuntu.com/esm or run: sudo ua status
553+
554 Enable UA Infra: ESM to receive additional future security updates.
555- See https://ubuntu.com/security/esm or run: sudo ua status
556- """).lstrip())
557+ See https://ubuntu.com/esm or run: sudo ua status
558+ """))
559
560- def test_esm_enabled_nosecurity(self):
561+ @mock.patch("apt_check.is_lts_distro", return_value=True)
562+ @mock.patch("apt_check.is_esm_distro", return_value=True)
563+ def test_esm_infra_enabled_nosecurity(
564+ self, _m_esm_distro, _m_is_lts
565+ ):
566 self.assertEqual(
567 get_message(upgrades=35, security_updates=0,
568- esm_updates=13, have_esm=True,
569- disabled_esm_updates=0),
570+ esm_infra_updates=13, esm_apps_updates=0,
571+ have_esm_infra=True, have_esm_apps=False,
572+ disabled_esm_infra_updates=0,
573+ disabled_esm_apps_updates=0),
574 textwrap.dedent(
575- """
576+ """\
577 UA Infra: Extended Security Maintenance (ESM) is enabled.
578
579 35 updates can be installed immediately.
580- 13 of these updates are fixed through UA Infra: ESM.
581+ 13 of these updates are UA Infra: ESM security updates.
582 0 of these updates are security updates.
583 To see these additional updates run: apt list --upgradable
584- """).lstrip())
585
586- def test_esm_enabled_somesecurity(self):
587+ Enable UA Apps: ESM to receive additional future security updates.
588+ See https://ubuntu.com/esm or run: sudo ua status
589+ """))
590+
591+ @mock.patch("apt_check.is_lts_distro", return_value=True)
592+ @mock.patch("apt_check.is_esm_distro", return_value=True)
593+ def test_esm_infra_enabled_somesecurity(
594+ self, _m_esm_distro, _m_is_lts
595+ ):
596 self.assertEqual(
597 get_message(upgrades=47, security_updates=7,
598- esm_updates=13, have_esm=True,
599- disabled_esm_updates=0),
600+ esm_infra_updates=13, esm_apps_updates=0,
601+ have_esm_infra=True, have_esm_apps=False,
602+ disabled_esm_infra_updates=0,
603+ disabled_esm_apps_updates=0),
604 textwrap.dedent(
605- """
606+ """\
607 UA Infra: Extended Security Maintenance (ESM) is enabled.
608
609 47 updates can be installed immediately.
610- 13 of these updates are fixed through UA Infra: ESM.
611+ 13 of these updates are UA Infra: ESM security updates.
612 7 of these updates are security updates.
613 To see these additional updates run: apt list --upgradable
614- """).lstrip())
615
616- def test_esm_enabled_noupdates(self):
617+ Enable UA Apps: ESM to receive additional future security updates.
618+ See https://ubuntu.com/esm or run: sudo ua status
619+ """))
620+
621+ @mock.patch("apt_check.is_lts_distro", return_value=True)
622+ @mock.patch("apt_check.is_esm_distro", return_value=True)
623+ def test_esm_infra_enabled_noupdates(
624+ self, _m_esm_distro, _m_is_lts
625+ ):
626 self.assertEqual(
627 get_message(upgrades=0, security_updates=0,
628- esm_updates=0, have_esm=True,
629- disabled_esm_updates=0),
630+ esm_infra_updates=0, esm_apps_updates=0,
631+ have_esm_infra=True, have_esm_apps=False,
632+ disabled_esm_infra_updates=0,
633+ disabled_esm_apps_updates=10),
634 textwrap.dedent(
635- """
636+ """\
637 UA Infra: Extended Security Maintenance (ESM) is enabled.
638
639 0 updates can be installed immediately.
640 0 of these updates are security updates.
641+
642+ 10 additional security updates can be applied with UA Apps: ESM
643+ Learn more about enabling UA Apps: ESM service at https://ubuntu.com/esm
644+ """))
645+
646+ @mock.patch("apt_check.is_lts_distro", return_value=True)
647+ @mock.patch("apt_check.is_esm_distro", return_value=True)
648+ def test_esm_infra_and_esm_apps_enabled(
649+ self, _m_esm_distro, _m_is_lts
650+ ):
651+ self.assertEqual(
652+ get_message(upgrades=30, security_updates=18,
653+ esm_infra_updates=15, esm_apps_updates=15,
654+ have_esm_infra=True, have_esm_apps=True,
655+ disabled_esm_infra_updates=0,
656+ disabled_esm_apps_updates=0),
657+ textwrap.dedent(
658+ """
659+ UA Infra: Extended Security Maintenance (ESM) is enabled.
660+
661+ 30 updates can be installed immediately.
662+ 15 of these updates are UA Infra: ESM security updates.
663+ 15 of these updates are UA Apps: ESM security updates.
664+ 18 of these updates are security updates.
665+ To see these additional updates run: apt list --upgradable
666+ """).lstrip())
667+
668+ @mock.patch("apt_check.is_lts_distro", return_value=True)
669+ @mock.patch("apt_check.is_esm_distro", return_value=True)
670+ def test_esm_infra_disable_and_esm_apps_enabled(
671+ self, _m_esm_distro, _m_is_lts
672+ ):
673+ self.assertEqual(
674+ get_message(upgrades=30, security_updates=18,
675+ esm_infra_updates=0, esm_apps_updates=15,
676+ have_esm_infra=False, have_esm_apps=True,
677+ disabled_esm_infra_updates=0,
678+ disabled_esm_apps_updates=0),
679+ textwrap.dedent(
680+ """
681+ UA Infra: Extended Security Maintenance (ESM) is not enabled.
682+
683+ 30 updates can be installed immediately.
684+ 15 of these updates are UA Apps: ESM security updates.
685+ 18 of these updates are security updates.
686+ To see these additional updates run: apt list --upgradable
687+
688+ Enable UA Infra: ESM to receive additional future security updates.
689+ See https://ubuntu.com/esm or run: sudo ua status
690 """).lstrip())
691
692+ @mock.patch("apt_check.is_lts_distro", return_value=True)
693+ @mock.patch("apt_check.is_esm_distro", return_value=True)
694+ def test_esm_infra_disabled_wih_pkgs_and_esm_apps_enabled(
695+ self, _m_esm_distro, _m_is_lts
696+ ):
697+ self.assertEqual(
698+ get_message(upgrades=30, security_updates=18,
699+ esm_infra_updates=0, esm_apps_updates=15,
700+ have_esm_infra=False, have_esm_apps=True,
701+ disabled_esm_infra_updates=40,
702+ disabled_esm_apps_updates=0),
703+ textwrap.dedent(
704+ """
705+ UA Infra: Extended Security Maintenance (ESM) is not enabled.
706+
707+ 30 updates can be installed immediately.
708+ 15 of these updates are UA Apps: ESM security updates.
709+ 18 of these updates are security updates.
710+ To see these additional updates run: apt list --upgradable
711+
712+ 40 additional security updates can be applied with UA Infra: ESM
713+ Learn more about enabling UA Infra: ESM service at https://ubuntu.com/esm
714+ """).lstrip())
715+
716+ @mock.patch("apt_check.is_lts_distro", return_value=True)
717+ @mock.patch("apt_check.is_esm_distro", return_value=True)
718+ def test_esm_infra_disabled_and_esm_apps_disabled_with_pkgs(
719+ self, _m_esm_distro, _m_is_lts
720+ ):
721+ self.assertEqual(
722+ get_message(upgrades=30, security_updates=18,
723+ esm_infra_updates=0, esm_apps_updates=0,
724+ have_esm_infra=False, have_esm_apps=False,
725+ disabled_esm_infra_updates=0,
726+ disabled_esm_apps_updates=40),
727+ textwrap.dedent(
728+ """\
729+ UA Infra: Extended Security Maintenance (ESM) is not enabled.
730+
731+ 30 updates can be installed immediately.
732+ 18 of these updates are security updates.
733+ To see these additional updates run: apt list --upgradable
734+
735+ 40 additional security updates can be applied with UA Apps: ESM
736+ Learn more about enabling UA Apps: ESM service at https://ubuntu.com/esm
737+
738+ Enable UA Infra: ESM to receive additional future security updates.
739+ See https://ubuntu.com/esm or run: sudo ua status
740+ """))
741+
742+ @mock.patch("apt_check.is_lts_distro", return_value=True)
743+ @mock.patch("apt_check.is_esm_distro", return_value=True)
744+ def test_no_esm_infra_and_apps_index_in_esm_distro(
745+ self, _m_esm_distro, _m_is_lts
746+ ):
747+ self.assertEqual(
748+ get_message(upgrades=30, security_updates=18,
749+ esm_infra_updates=0, esm_apps_updates=0,
750+ have_esm_infra=None, have_esm_apps=None,
751+ disabled_esm_infra_updates=0,
752+ disabled_esm_apps_updates=0),
753+ textwrap.dedent(
754+ """\
755+ 30 updates can be installed immediately.
756+ 18 of these updates are security updates.
757+ To see these additional updates run: apt list --upgradable
758+ """))
759+
760+ @mock.patch("apt_check.is_lts_distro", return_value=False)
761+ @mock.patch("apt_check.is_esm_distro", return_value=False)
762+ def test_no_esm_infra_and_apps_index_in_non_lts_distro(
763+ self, _m_esm_distro, _m_is_lts
764+ ):
765+ self.assertEqual(
766+ get_message(upgrades=30, security_updates=18,
767+ esm_infra_updates=0, esm_apps_updates=0,
768+ have_esm_infra=None, have_esm_apps=None,
769+ disabled_esm_infra_updates=0,
770+ disabled_esm_apps_updates=0),
771+ textwrap.dedent(
772+ """\
773+ 30 updates can be installed immediately.
774+ 18 of these updates are security updates.
775+ To see these additional updates run: apt list --upgradable
776+ """))
777+
778+ @mock.patch("apt_check.is_lts_distro", return_value=False)
779+ @mock.patch("apt_check.is_esm_distro", return_value=False)
780+ def test_esm_infra_disabled_and_esm_apps_disabled_with_no_esm_distro(
781+ self, _m_esm_distro, _m_is_lts,
782+ ):
783+ self.assertEqual(
784+ get_message(upgrades=30, security_updates=18,
785+ esm_infra_updates=0, esm_apps_updates=0,
786+ have_esm_infra=False, have_esm_apps=False,
787+ disabled_esm_infra_updates=0,
788+ disabled_esm_apps_updates=40),
789+ textwrap.dedent(
790+ """\
791+ 30 updates can be installed immediately.
792+ 18 of these updates are security updates.
793+ To see these additional updates run: apt list --upgradable
794+ """))
795+
796+ @mock.patch("apt_check.is_lts_distro", return_value=False)
797+ @mock.patch("subprocess.Popen")
798+ def test_message_for_distro_that_will_not_go_into_esm_mode(
799+ self, m_popen, _m_is_lts
800+ ):
801+ comm_mock = mock.MagicMock()
802+ comm_mock.communicate.return_value = (
803+ "(unknown)".encode("utf-8"), "")
804+ m_popen.return_value = comm_mock
805+
806+ self.assertEqual(
807+ get_message(upgrades=30, security_updates=18,
808+ esm_infra_updates=0, esm_apps_updates=0,
809+ have_esm_infra=False, have_esm_apps=False,
810+ disabled_esm_infra_updates=0,
811+ disabled_esm_apps_updates=40),
812+ textwrap.dedent(
813+ """\
814+ 30 updates can be installed immediately.
815+ 18 of these updates are security updates.
816+ To see these additional updates run: apt list --upgradable
817+ """))
818+
819+ @mock.patch("apt_check.is_lts_distro", return_value=True)
820+ @mock.patch("apt_check.is_esm_distro", return_value=False)
821+ def test_message_for_lts_distro_not_in_esm_mode_yet(
822+ self, _m_is_esm, _m_is_lts
823+ ):
824+ self.assertEqual(
825+ get_message(upgrades=30, security_updates=18,
826+ esm_infra_updates=0, esm_apps_updates=0,
827+ have_esm_infra=False, have_esm_apps=False,
828+ disabled_esm_infra_updates=10,
829+ disabled_esm_apps_updates=40),
830+ textwrap.dedent(
831+ """\
832+ 30 updates can be installed immediately.
833+ 18 of these updates are security updates.
834+ To see these additional updates run: apt list --upgradable
835+
836+ 40 additional security updates can be applied with UA Apps: ESM
837+ Learn more about enabling UA Apps: ESM service at https://ubuntu.com/esm
838+ """))
839+
840
841 if __name__ == "__main__":
842 import logging

Subscribers

People subscribed via source and target branches