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 | <packing> |
7 | <property name="expand">False</property> |
8 | <property name="fill">True</property> |
9 | - <property name="position">0</property> |
10 | + </packing> |
11 | + </child> |
12 | + <child> |
13 | + <object class="GtkLabel"> |
14 | + <property name="visible">True</property> |
15 | + <property name="can_focus">False</property> |
16 | + <property name="label" translatable="yes">Snap package updates are checked routinely and installed automatically.</property> |
17 | + <property name="xalign">0</property> |
18 | + </object> |
19 | + <packing> |
20 | + <property name="expand">False</property> |
21 | + <property name="fill">False</property> |
22 | </packing> |
23 | </child> |
24 | <child> |
25 | @@ -562,6 +573,98 @@ |
26 | <property name="can_focus">False</property> |
27 | <property name="spacing">6</property> |
28 | <child> |
29 | + <object class="GtkHBox"> |
30 | + <property name="visible">True</property> |
31 | + <property name="can_focus">False</property> |
32 | + <property name="spacing">6</property> |
33 | + <child> |
34 | + <object class="GtkLabel" id="label_esm_heading"> |
35 | + <property name="visible">True</property> |
36 | + <property name="can_focus">False</property> |
37 | + <property name="xalign">1</property> |
38 | + <property name="label" translatable="yes">For other packages, this system has:</property> |
39 | + </object> |
40 | + <packing> |
41 | + <property name="expand">False</property> |
42 | + <property name="fill">False</property> |
43 | + <property name="position">0</property> |
44 | + </packing> |
45 | + </child> |
46 | + <child> |
47 | + <object class="GtkHBox"> |
48 | + <property name="visible">True</property> |
49 | + <property name="can_focus">False</property> |
50 | + <property name="spacing">6</property> |
51 | + <child> |
52 | + <object class="GtkLabel" id="label_esm_status"> |
53 | + <property name="visible">True</property> |
54 | + <property name="can_focus">False</property> |
55 | + <property name="xalign">0</property> |
56 | + </object> |
57 | + <packing> |
58 | + <property name="expand">False</property> |
59 | + <property name="fill">True</property> |
60 | + </packing> |
61 | + </child> |
62 | + <child> |
63 | + <object class="GtkLabel" id="label_esm_subscribe"> |
64 | + <property name="visible">True</property> |
65 | + <property name="can_focus">False</property> |
66 | + <property name="xalign">1</property> |
67 | + </object> |
68 | + <packing> |
69 | + <property name="expand">True</property> |
70 | + <property name="fill">True</property> |
71 | + </packing> |
72 | + </child> |
73 | + </object> |
74 | + <packing> |
75 | + <property name="expand">True</property> |
76 | + <property name="fill">True</property> |
77 | + <property name="position">1</property> |
78 | + </packing> |
79 | + </child> |
80 | + </object> |
81 | + <packing> |
82 | + <property name="expand">False</property> |
83 | + <property name="fill">False</property> |
84 | + </packing> |
85 | + </child> |
86 | + <child> |
87 | + <object class="GtkHBox"> |
88 | + <property name="visible">True</property> |
89 | + <property name="can_focus">False</property> |
90 | + <property name="spacing">6</property> |
91 | + <child> |
92 | + <object class="GtkLabel" id="label_eol_heading"> |
93 | + <property name="visible">True</property> |
94 | + <property name="can_focus">False</property> |
95 | + </object> |
96 | + <packing> |
97 | + <property name="expand">False</property> |
98 | + <property name="fill">False</property> |
99 | + <property name="position">0</property> |
100 | + </packing> |
101 | + </child> |
102 | + <child> |
103 | + <object class="GtkLabel" id="label_eol"> |
104 | + <property name="visible">True</property> |
105 | + <property name="can_focus">False</property> |
106 | + <property name="xalign">0</property> |
107 | + </object> |
108 | + <packing> |
109 | + <property name="expand">True</property> |
110 | + <property name="fill">True</property> |
111 | + <property name="position">1</property> |
112 | + </packing> |
113 | + </child> |
114 | + </object> |
115 | + <packing> |
116 | + <property name="expand">False</property> |
117 | + <property name="fill">False</property> |
118 | + </packing> |
119 | + </child> |
120 | + <child> |
121 | <object class="GtkHBox" id="hbox_check_for_updates"> |
122 | <property name="visible">True</property> |
123 | <property name="can_focus">False</property> |
124 | @@ -601,7 +704,6 @@ |
125 | <packing> |
126 | <property name="expand">False</property> |
127 | <property name="fill">False</property> |
128 | - <property name="position">0</property> |
129 | </packing> |
130 | </child> |
131 | <child> |
132 | @@ -644,7 +746,6 @@ |
133 | <packing> |
134 | <property name="expand">False</property> |
135 | <property name="fill">False</property> |
136 | - <property name="position">1</property> |
137 | </packing> |
138 | </child> |
139 | <child> |
140 | @@ -687,7 +788,6 @@ |
141 | <packing> |
142 | <property name="expand">False</property> |
143 | <property name="fill">False</property> |
144 | - <property name="position">2</property> |
145 | </packing> |
146 | </child> |
147 | </object> |
148 | @@ -696,7 +796,6 @@ |
149 | <packing> |
150 | <property name="expand">True</property> |
151 | <property name="fill">True</property> |
152 | - <property name="position">1</property> |
153 | </packing> |
154 | </child> |
155 | <child> |
156 | @@ -746,7 +845,6 @@ |
157 | <packing> |
158 | <property name="expand">False</property> |
159 | <property name="fill">False</property> |
160 | - <property name="position">2</property> |
161 | </packing> |
162 | </child> |
163 | </object> |
164 | @@ -1180,6 +1278,8 @@ |
165 | </object> |
166 | <object class="GtkSizeGroup" id="sizegroup1"> |
167 | <widgets> |
168 | + <widget name="label_esm_heading"/> |
169 | + <widget name="label_eol_heading"/> |
170 | <widget name="label3"/> |
171 | <widget name="label4"/> |
172 | <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 | +software-properties (0.96.20.11) UNRELEASED; urgency=medium |
179 | + |
180 | + * Show ESM support status (LP: #1920836) |
181 | + |
182 | + -- Robert Ancell <robert.ancell@canonical.com> Tue, 23 Mar 2021 11:51:12 +1300 |
183 | + |
184 | software-properties (0.96.20.10) xenial-security; urgency=medium |
185 | |
186 | * 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 | ubuntu-drivers-common (>= 1:0.2.75), |
193 | python3-gi, |
194 | libgtk2-perl, |
195 | + distro-info-data, |
196 | Description: manage the repositories that you install software from (gtk) |
197 | This software provides an abstraction of the used apt repositories. |
198 | 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 | |
205 | import apt |
206 | import apt_pkg |
207 | +import datetime |
208 | import dbus |
209 | from gettext import gettext as _ |
210 | import gettext |
211 | @@ -51,6 +52,12 @@ import softwareproperties.distro |
212 | from softwareproperties.SoftwareProperties import SoftwareProperties |
213 | import softwareproperties.SoftwareProperties |
214 | |
215 | +from softwareproperties.gtk.utils import ( |
216 | + get_esm_apps_status, |
217 | + current_distro_eol, |
218 | + current_distro_eol_esm |
219 | +) |
220 | + |
221 | from UbuntuDrivers import detect |
222 | |
223 | if GLib.pyglib_version < (3, 9, 1): |
224 | @@ -349,6 +356,22 @@ class SoftwarePropertiesGtk(SoftwareProperties, SimpleGtkbuilderApp): |
225 | self.vbox_updates.add(checkbox) |
226 | checkbox.show() |
227 | |
228 | + (esm_available, esm_enabled) = get_esm_apps_status() |
229 | + if esm_enabled: |
230 | + eol_text = _("Extended Security Maintenance") |
231 | + eol_date = current_distro_eol_esm() |
232 | + else: |
233 | + eol_text = _("Basic Security Maintenance") |
234 | + eol_date = current_distro_eol() |
235 | + self.label_esm_status.set_markup(eol_text) |
236 | + self.label_esm_subscribe.set_markup("<a href=\"https://ubuntu.com/security/esm\">%s</a>" % _("Extend…")) |
237 | + self.label_esm_subscribe.set_visible(esm_available and not esm_enabled) |
238 | + if datetime.datetime.now().date() > eol_date: |
239 | + eol_expiry_text = _("Ended %s") % eol_date.strftime("%x") |
240 | + else: |
241 | + eol_expiry_text = _("Active until %s") % eol_date.strftime("%x") |
242 | + self.label_eol.set_label(eol_expiry_text); |
243 | + |
244 | # setup the server chooser |
245 | cell = Gtk.CellRendererText() |
246 | 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 | from __future__ import print_function |
253 | |
254 | from gi.repository import Gtk |
255 | +import aptsources.distro |
256 | +import csv |
257 | +import datetime |
258 | +import json |
259 | +import subprocess |
260 | import logging |
261 | LOG=logging.getLogger(__name__) |
262 | |
263 | @@ -34,3 +39,73 @@ def setup_ui(self, path, domain): |
264 | setattr(self, name, o) |
265 | else: |
266 | logging.debug("can not get name for object '%s'" % o) |
267 | + |
268 | +class DistroInfo: |
269 | + def __init__ (self, version, codename, series, created, release, eol, eol_server, eol_esm): |
270 | + self.version = version |
271 | + self.codename = codename |
272 | + self.series = series |
273 | + self.created = created |
274 | + self.release = release |
275 | + self.eol = eol |
276 | + self.eol_server = eol_server |
277 | + self.eol_esm = eol_esm |
278 | + |
279 | +def _parse_date(date_string): |
280 | + if date_string is None: |
281 | + return None |
282 | + try: |
283 | + return datetime.datetime.strptime(date_string, '%Y-%m-%d').date() |
284 | + except ValueError: |
285 | + return None |
286 | + |
287 | +def _current_distro(): |
288 | + distro = aptsources.distro.get_distro() |
289 | + try: |
290 | + reader = csv.reader(open('/usr/share/distro-info/ubuntu.csv')) |
291 | + except Exception as e: |
292 | + print("Failed to read distro info:\n%s" % e) |
293 | + reader = [] |
294 | + |
295 | + for line in reader: |
296 | + (version, codename, series, created, release, eol, eol_server, eol_esm) = line[:8] + [None] * max(0, 8 - len(line)) |
297 | + if series == distro.codename: |
298 | + return DistroInfo(version, codename, series, _parse_date(created), _parse_date(release), _parse_date(eol), _parse_date(eol_server), _parse_date(eol_esm)) |
299 | + |
300 | + return DistroInfo('', '', '', datetime.date.today(), datetime.date.today(), datetime.date.today(), datetime.date.today(), datetime.date.today()) |
301 | + |
302 | +def current_distro_eol(): |
303 | + return _current_distro().eol |
304 | + |
305 | +def current_distro_eol_esm(): |
306 | + return _current_distro().eol_esm |
307 | + |
308 | +def get_esm_apps_status(): |
309 | + try: |
310 | + result = subprocess.run(['ua', 'status', '--format=json'], stdout=subprocess.PIPE) |
311 | + except Exception as e: |
312 | + print("Failed to call ubuntu advantage client:\n%s" % e) |
313 | + return (False, False) |
314 | + |
315 | + if result.returncode != 0: |
316 | + print("Ubuntu advantage client returned code %d" % result.returncode) |
317 | + return (False, False) |
318 | + |
319 | + try: |
320 | + status = json.loads(result.stdout.decode("utf-8")) |
321 | + except Exception as e: |
322 | + print("Failed to parse ubuntu advantage client JSON:\n%s" % e) |
323 | + return (False, False) |
324 | + |
325 | + services = status.get("services") |
326 | + if services == None: |
327 | + services = [] |
328 | + |
329 | + for service in services: |
330 | + if service.get("name") == "esm-apps": |
331 | + available = service.get("available") == "yes" |
332 | + entitled = service.get("entitled") == "yes" |
333 | + service_status = service.get("status") |
334 | + return (available or entitled, service_status == "enabled") |
335 | + |
336 | + return (False, False) |
See https:/ /code.launchpad .net/~robert- ancell/ software- properties/ +git/software- properties/ +merge/ 400153 for the related change to master.