Merge ~robert-ancell/software-properties:esm-xenial into software-properties:ubuntu/xenial
- Git
- lp:~robert-ancell/software-properties
- esm-xenial
- Merge into ubuntu/xenial
Proposed by
Robert Ancell
Status: | Needs review |
---|---|
Proposed branch: | ~robert-ancell/software-properties:esm-xenial |
Merge into: | software-properties:ubuntu/xenial |
Diff against target: |
336 lines (+211/-6) 5 files modified
data/gtkbuilder/main.ui (+106/-6) debian/changelog (+6/-0) debian/control (+1/-0) softwareproperties/gtk/SoftwarePropertiesGtk.py (+23/-0) softwareproperties/gtk/utils.py (+75/-0) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Core Development Team | Pending | ||
Review via email: mp+400302@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Unmerged commits
- 7b8920c... by Robert Ancell
-
Show extended security maintenance status
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/data/gtkbuilder/main.ui b/data/gtkbuilder/main.ui | |||
2 | index ed4abc1..d1704e9 100644 | |||
3 | --- a/data/gtkbuilder/main.ui | |||
4 | +++ b/data/gtkbuilder/main.ui | |||
5 | @@ -547,7 +547,18 @@ | |||
6 | 547 | <packing> | 547 | <packing> |
7 | 548 | <property name="expand">False</property> | 548 | <property name="expand">False</property> |
8 | 549 | <property name="fill">True</property> | 549 | <property name="fill">True</property> |
10 | 550 | <property name="position">0</property> | 550 | </packing> |
11 | 551 | </child> | ||
12 | 552 | <child> | ||
13 | 553 | <object class="GtkLabel"> | ||
14 | 554 | <property name="visible">True</property> | ||
15 | 555 | <property name="can_focus">False</property> | ||
16 | 556 | <property name="label" translatable="yes">Snap package updates are checked routinely and installed automatically.</property> | ||
17 | 557 | <property name="xalign">0</property> | ||
18 | 558 | </object> | ||
19 | 559 | <packing> | ||
20 | 560 | <property name="expand">False</property> | ||
21 | 561 | <property name="fill">False</property> | ||
22 | 551 | </packing> | 562 | </packing> |
23 | 552 | </child> | 563 | </child> |
24 | 553 | <child> | 564 | <child> |
25 | @@ -562,6 +573,98 @@ | |||
26 | 562 | <property name="can_focus">False</property> | 573 | <property name="can_focus">False</property> |
27 | 563 | <property name="spacing">6</property> | 574 | <property name="spacing">6</property> |
28 | 564 | <child> | 575 | <child> |
29 | 576 | <object class="GtkHBox"> | ||
30 | 577 | <property name="visible">True</property> | ||
31 | 578 | <property name="can_focus">False</property> | ||
32 | 579 | <property name="spacing">6</property> | ||
33 | 580 | <child> | ||
34 | 581 | <object class="GtkLabel" id="label_esm_heading"> | ||
35 | 582 | <property name="visible">True</property> | ||
36 | 583 | <property name="can_focus">False</property> | ||
37 | 584 | <property name="xalign">1</property> | ||
38 | 585 | <property name="label" translatable="yes">For other packages, this system has:</property> | ||
39 | 586 | </object> | ||
40 | 587 | <packing> | ||
41 | 588 | <property name="expand">False</property> | ||
42 | 589 | <property name="fill">False</property> | ||
43 | 590 | <property name="position">0</property> | ||
44 | 591 | </packing> | ||
45 | 592 | </child> | ||
46 | 593 | <child> | ||
47 | 594 | <object class="GtkHBox"> | ||
48 | 595 | <property name="visible">True</property> | ||
49 | 596 | <property name="can_focus">False</property> | ||
50 | 597 | <property name="spacing">6</property> | ||
51 | 598 | <child> | ||
52 | 599 | <object class="GtkLabel" id="label_esm_status"> | ||
53 | 600 | <property name="visible">True</property> | ||
54 | 601 | <property name="can_focus">False</property> | ||
55 | 602 | <property name="xalign">0</property> | ||
56 | 603 | </object> | ||
57 | 604 | <packing> | ||
58 | 605 | <property name="expand">False</property> | ||
59 | 606 | <property name="fill">True</property> | ||
60 | 607 | </packing> | ||
61 | 608 | </child> | ||
62 | 609 | <child> | ||
63 | 610 | <object class="GtkLabel" id="label_esm_subscribe"> | ||
64 | 611 | <property name="visible">True</property> | ||
65 | 612 | <property name="can_focus">False</property> | ||
66 | 613 | <property name="xalign">1</property> | ||
67 | 614 | </object> | ||
68 | 615 | <packing> | ||
69 | 616 | <property name="expand">True</property> | ||
70 | 617 | <property name="fill">True</property> | ||
71 | 618 | </packing> | ||
72 | 619 | </child> | ||
73 | 620 | </object> | ||
74 | 621 | <packing> | ||
75 | 622 | <property name="expand">True</property> | ||
76 | 623 | <property name="fill">True</property> | ||
77 | 624 | <property name="position">1</property> | ||
78 | 625 | </packing> | ||
79 | 626 | </child> | ||
80 | 627 | </object> | ||
81 | 628 | <packing> | ||
82 | 629 | <property name="expand">False</property> | ||
83 | 630 | <property name="fill">False</property> | ||
84 | 631 | </packing> | ||
85 | 632 | </child> | ||
86 | 633 | <child> | ||
87 | 634 | <object class="GtkHBox"> | ||
88 | 635 | <property name="visible">True</property> | ||
89 | 636 | <property name="can_focus">False</property> | ||
90 | 637 | <property name="spacing">6</property> | ||
91 | 638 | <child> | ||
92 | 639 | <object class="GtkLabel" id="label_eol_heading"> | ||
93 | 640 | <property name="visible">True</property> | ||
94 | 641 | <property name="can_focus">False</property> | ||
95 | 642 | </object> | ||
96 | 643 | <packing> | ||
97 | 644 | <property name="expand">False</property> | ||
98 | 645 | <property name="fill">False</property> | ||
99 | 646 | <property name="position">0</property> | ||
100 | 647 | </packing> | ||
101 | 648 | </child> | ||
102 | 649 | <child> | ||
103 | 650 | <object class="GtkLabel" id="label_eol"> | ||
104 | 651 | <property name="visible">True</property> | ||
105 | 652 | <property name="can_focus">False</property> | ||
106 | 653 | <property name="xalign">0</property> | ||
107 | 654 | </object> | ||
108 | 655 | <packing> | ||
109 | 656 | <property name="expand">True</property> | ||
110 | 657 | <property name="fill">True</property> | ||
111 | 658 | <property name="position">1</property> | ||
112 | 659 | </packing> | ||
113 | 660 | </child> | ||
114 | 661 | </object> | ||
115 | 662 | <packing> | ||
116 | 663 | <property name="expand">False</property> | ||
117 | 664 | <property name="fill">False</property> | ||
118 | 665 | </packing> | ||
119 | 666 | </child> | ||
120 | 667 | <child> | ||
121 | 565 | <object class="GtkHBox" id="hbox_check_for_updates"> | 668 | <object class="GtkHBox" id="hbox_check_for_updates"> |
122 | 566 | <property name="visible">True</property> | 669 | <property name="visible">True</property> |
123 | 567 | <property name="can_focus">False</property> | 670 | <property name="can_focus">False</property> |
124 | @@ -601,7 +704,6 @@ | |||
125 | 601 | <packing> | 704 | <packing> |
126 | 602 | <property name="expand">False</property> | 705 | <property name="expand">False</property> |
127 | 603 | <property name="fill">False</property> | 706 | <property name="fill">False</property> |
128 | 604 | <property name="position">0</property> | ||
129 | 605 | </packing> | 707 | </packing> |
130 | 606 | </child> | 708 | </child> |
131 | 607 | <child> | 709 | <child> |
132 | @@ -644,7 +746,6 @@ | |||
133 | 644 | <packing> | 746 | <packing> |
134 | 645 | <property name="expand">False</property> | 747 | <property name="expand">False</property> |
135 | 646 | <property name="fill">False</property> | 748 | <property name="fill">False</property> |
136 | 647 | <property name="position">1</property> | ||
137 | 648 | </packing> | 749 | </packing> |
138 | 649 | </child> | 750 | </child> |
139 | 650 | <child> | 751 | <child> |
140 | @@ -687,7 +788,6 @@ | |||
141 | 687 | <packing> | 788 | <packing> |
142 | 688 | <property name="expand">False</property> | 789 | <property name="expand">False</property> |
143 | 689 | <property name="fill">False</property> | 790 | <property name="fill">False</property> |
144 | 690 | <property name="position">2</property> | ||
145 | 691 | </packing> | 791 | </packing> |
146 | 692 | </child> | 792 | </child> |
147 | 693 | </object> | 793 | </object> |
148 | @@ -696,7 +796,6 @@ | |||
149 | 696 | <packing> | 796 | <packing> |
150 | 697 | <property name="expand">True</property> | 797 | <property name="expand">True</property> |
151 | 698 | <property name="fill">True</property> | 798 | <property name="fill">True</property> |
152 | 699 | <property name="position">1</property> | ||
153 | 700 | </packing> | 799 | </packing> |
154 | 701 | </child> | 800 | </child> |
155 | 702 | <child> | 801 | <child> |
156 | @@ -746,7 +845,6 @@ | |||
157 | 746 | <packing> | 845 | <packing> |
158 | 747 | <property name="expand">False</property> | 846 | <property name="expand">False</property> |
159 | 748 | <property name="fill">False</property> | 847 | <property name="fill">False</property> |
160 | 749 | <property name="position">2</property> | ||
161 | 750 | </packing> | 848 | </packing> |
162 | 751 | </child> | 849 | </child> |
163 | 752 | </object> | 850 | </object> |
164 | @@ -1180,6 +1278,8 @@ | |||
165 | 1180 | </object> | 1278 | </object> |
166 | 1181 | <object class="GtkSizeGroup" id="sizegroup1"> | 1279 | <object class="GtkSizeGroup" id="sizegroup1"> |
167 | 1182 | <widgets> | 1280 | <widgets> |
168 | 1281 | <widget name="label_esm_heading"/> | ||
169 | 1282 | <widget name="label_eol_heading"/> | ||
170 | 1183 | <widget name="label3"/> | 1283 | <widget name="label3"/> |
171 | 1184 | <widget name="label4"/> | 1284 | <widget name="label4"/> |
172 | 1185 | <widget name="label5"/> | 1285 | <widget name="label5"/> |
173 | diff --git a/debian/changelog b/debian/changelog | |||
174 | index ce037cf..1d17ec0 100644 | |||
175 | --- a/debian/changelog | |||
176 | +++ b/debian/changelog | |||
177 | @@ -1,3 +1,9 @@ | |||
178 | 1 | software-properties (0.96.20.11) UNRELEASED; urgency=medium | ||
179 | 2 | |||
180 | 3 | * Show ESM support status (LP: #1920836) | ||
181 | 4 | |||
182 | 5 | -- Robert Ancell <robert.ancell@canonical.com> Tue, 23 Mar 2021 11:51:12 +1300 | ||
183 | 6 | |||
184 | 1 | software-properties (0.96.20.10) xenial-security; urgency=medium | 7 | software-properties (0.96.20.10) xenial-security; urgency=medium |
185 | 2 | 8 | ||
186 | 3 | * SECURITY UPDATE: malicious repo could send ANSI sequences to terminal | 9 | * SECURITY UPDATE: malicious repo could send ANSI sequences to terminal |
187 | diff --git a/debian/control b/debian/control | |||
188 | index 20d0e4b..a1dd141 100644 | |||
189 | --- a/debian/control | |||
190 | +++ b/debian/control | |||
191 | @@ -64,6 +64,7 @@ Depends: ${python3:Depends}, ${misc:Depends}, python3, | |||
192 | 64 | ubuntu-drivers-common (>= 1:0.2.75), | 64 | ubuntu-drivers-common (>= 1:0.2.75), |
193 | 65 | python3-gi, | 65 | python3-gi, |
194 | 66 | libgtk2-perl, | 66 | libgtk2-perl, |
195 | 67 | distro-info-data, | ||
196 | 67 | Description: manage the repositories that you install software from (gtk) | 68 | Description: manage the repositories that you install software from (gtk) |
197 | 68 | This software provides an abstraction of the used apt repositories. | 69 | This software provides an abstraction of the used apt repositories. |
198 | 69 | It allows you to easily manage your distribution and independent software | 70 | It allows you to easily manage your distribution and independent software |
199 | diff --git a/softwareproperties/gtk/SoftwarePropertiesGtk.py b/softwareproperties/gtk/SoftwarePropertiesGtk.py | |||
200 | index 033c6b8..d9e462e 100644 | |||
201 | --- a/softwareproperties/gtk/SoftwarePropertiesGtk.py | |||
202 | +++ b/softwareproperties/gtk/SoftwarePropertiesGtk.py | |||
203 | @@ -26,6 +26,7 @@ from __future__ import absolute_import, print_function | |||
204 | 26 | 26 | ||
205 | 27 | import apt | 27 | import apt |
206 | 28 | import apt_pkg | 28 | import apt_pkg |
207 | 29 | import datetime | ||
208 | 29 | import dbus | 30 | import dbus |
209 | 30 | from gettext import gettext as _ | 31 | from gettext import gettext as _ |
210 | 31 | import gettext | 32 | import gettext |
211 | @@ -51,6 +52,12 @@ import softwareproperties.distro | |||
212 | 51 | from softwareproperties.SoftwareProperties import SoftwareProperties | 52 | from softwareproperties.SoftwareProperties import SoftwareProperties |
213 | 52 | import softwareproperties.SoftwareProperties | 53 | import softwareproperties.SoftwareProperties |
214 | 53 | 54 | ||
215 | 55 | from softwareproperties.gtk.utils import ( | ||
216 | 56 | get_esm_apps_status, | ||
217 | 57 | current_distro_eol, | ||
218 | 58 | current_distro_eol_esm | ||
219 | 59 | ) | ||
220 | 60 | |||
221 | 54 | from UbuntuDrivers import detect | 61 | from UbuntuDrivers import detect |
222 | 55 | 62 | ||
223 | 56 | if GLib.pyglib_version < (3, 9, 1): | 63 | if GLib.pyglib_version < (3, 9, 1): |
224 | @@ -349,6 +356,22 @@ class SoftwarePropertiesGtk(SoftwareProperties, SimpleGtkbuilderApp): | |||
225 | 349 | self.vbox_updates.add(checkbox) | 356 | self.vbox_updates.add(checkbox) |
226 | 350 | checkbox.show() | 357 | checkbox.show() |
227 | 351 | 358 | ||
228 | 359 | (esm_available, esm_enabled) = get_esm_apps_status() | ||
229 | 360 | if esm_enabled: | ||
230 | 361 | eol_text = _("Extended Security Maintenance") | ||
231 | 362 | eol_date = current_distro_eol_esm() | ||
232 | 363 | else: | ||
233 | 364 | eol_text = _("Basic Security Maintenance") | ||
234 | 365 | eol_date = current_distro_eol() | ||
235 | 366 | self.label_esm_status.set_markup(eol_text) | ||
236 | 367 | self.label_esm_subscribe.set_markup("<a href=\"https://ubuntu.com/security/esm\">%s</a>" % _("Extend…")) | ||
237 | 368 | self.label_esm_subscribe.set_visible(esm_available and not esm_enabled) | ||
238 | 369 | if datetime.datetime.now().date() > eol_date: | ||
239 | 370 | eol_expiry_text = _("Ended %s") % eol_date.strftime("%x") | ||
240 | 371 | else: | ||
241 | 372 | eol_expiry_text = _("Active until %s") % eol_date.strftime("%x") | ||
242 | 373 | self.label_eol.set_label(eol_expiry_text); | ||
243 | 374 | |||
244 | 352 | # setup the server chooser | 375 | # setup the server chooser |
245 | 353 | cell = Gtk.CellRendererText() | 376 | cell = Gtk.CellRendererText() |
246 | 354 | self.combobox_server.pack_start(cell, True) | 377 | self.combobox_server.pack_start(cell, True) |
247 | diff --git a/softwareproperties/gtk/utils.py b/softwareproperties/gtk/utils.py | |||
248 | index 9554fea..8fe682c 100644 | |||
249 | --- a/softwareproperties/gtk/utils.py | |||
250 | +++ b/softwareproperties/gtk/utils.py | |||
251 | @@ -19,6 +19,11 @@ | |||
252 | 19 | from __future__ import print_function | 19 | from __future__ import print_function |
253 | 20 | 20 | ||
254 | 21 | from gi.repository import Gtk | 21 | from gi.repository import Gtk |
255 | 22 | import aptsources.distro | ||
256 | 23 | import csv | ||
257 | 24 | import datetime | ||
258 | 25 | import json | ||
259 | 26 | import subprocess | ||
260 | 22 | import logging | 27 | import logging |
261 | 23 | LOG=logging.getLogger(__name__) | 28 | LOG=logging.getLogger(__name__) |
262 | 24 | 29 | ||
263 | @@ -34,3 +39,73 @@ def setup_ui(self, path, domain): | |||
264 | 34 | setattr(self, name, o) | 39 | setattr(self, name, o) |
265 | 35 | else: | 40 | else: |
266 | 36 | logging.debug("can not get name for object '%s'" % o) | 41 | logging.debug("can not get name for object '%s'" % o) |
267 | 42 | |||
268 | 43 | class DistroInfo: | ||
269 | 44 | def __init__ (self, version, codename, series, created, release, eol, eol_server, eol_esm): | ||
270 | 45 | self.version = version | ||
271 | 46 | self.codename = codename | ||
272 | 47 | self.series = series | ||
273 | 48 | self.created = created | ||
274 | 49 | self.release = release | ||
275 | 50 | self.eol = eol | ||
276 | 51 | self.eol_server = eol_server | ||
277 | 52 | self.eol_esm = eol_esm | ||
278 | 53 | |||
279 | 54 | def _parse_date(date_string): | ||
280 | 55 | if date_string is None: | ||
281 | 56 | return None | ||
282 | 57 | try: | ||
283 | 58 | return datetime.datetime.strptime(date_string, '%Y-%m-%d').date() | ||
284 | 59 | except ValueError: | ||
285 | 60 | return None | ||
286 | 61 | |||
287 | 62 | def _current_distro(): | ||
288 | 63 | distro = aptsources.distro.get_distro() | ||
289 | 64 | try: | ||
290 | 65 | reader = csv.reader(open('/usr/share/distro-info/ubuntu.csv')) | ||
291 | 66 | except Exception as e: | ||
292 | 67 | print("Failed to read distro info:\n%s" % e) | ||
293 | 68 | reader = [] | ||
294 | 69 | |||
295 | 70 | for line in reader: | ||
296 | 71 | (version, codename, series, created, release, eol, eol_server, eol_esm) = line[:8] + [None] * max(0, 8 - len(line)) | ||
297 | 72 | if series == distro.codename: | ||
298 | 73 | return DistroInfo(version, codename, series, _parse_date(created), _parse_date(release), _parse_date(eol), _parse_date(eol_server), _parse_date(eol_esm)) | ||
299 | 74 | |||
300 | 75 | return DistroInfo('', '', '', datetime.date.today(), datetime.date.today(), datetime.date.today(), datetime.date.today(), datetime.date.today()) | ||
301 | 76 | |||
302 | 77 | def current_distro_eol(): | ||
303 | 78 | return _current_distro().eol | ||
304 | 79 | |||
305 | 80 | def current_distro_eol_esm(): | ||
306 | 81 | return _current_distro().eol_esm | ||
307 | 82 | |||
308 | 83 | def get_esm_apps_status(): | ||
309 | 84 | try: | ||
310 | 85 | result = subprocess.run(['ua', 'status', '--format=json'], stdout=subprocess.PIPE) | ||
311 | 86 | except Exception as e: | ||
312 | 87 | print("Failed to call ubuntu advantage client:\n%s" % e) | ||
313 | 88 | return (False, False) | ||
314 | 89 | |||
315 | 90 | if result.returncode != 0: | ||
316 | 91 | print("Ubuntu advantage client returned code %d" % result.returncode) | ||
317 | 92 | return (False, False) | ||
318 | 93 | |||
319 | 94 | try: | ||
320 | 95 | status = json.loads(result.stdout.decode("utf-8")) | ||
321 | 96 | except Exception as e: | ||
322 | 97 | print("Failed to parse ubuntu advantage client JSON:\n%s" % e) | ||
323 | 98 | return (False, False) | ||
324 | 99 | |||
325 | 100 | services = status.get("services") | ||
326 | 101 | if services == None: | ||
327 | 102 | services = [] | ||
328 | 103 | |||
329 | 104 | for service in services: | ||
330 | 105 | if service.get("name") == "esm-apps": | ||
331 | 106 | available = service.get("available") == "yes" | ||
332 | 107 | entitled = service.get("entitled") == "yes" | ||
333 | 108 | service_status = service.get("status") | ||
334 | 109 | return (available or entitled, service_status == "enabled") | ||
335 | 110 | |||
336 | 111 | return (False, False) |
See https:/ /code.launchpad .net/~robert- ancell/ software- properties/ +git/software- properties/ +merge/ 400153 for the related change to master.