Merge lp:~robert-ancell/update-manager/ua-bionic-merge into lp:~ubuntu-core-dev/update-manager/bionic
- ua-bionic-merge
- Merge into bionic
Proposed by
Robert Ancell
Status: | Merged |
---|---|
Merged at revision: | 2841 |
Proposed branch: | lp:~robert-ancell/update-manager/ua-bionic-merge |
Merge into: | lp:~ubuntu-core-dev/update-manager/bionic |
Diff against target: |
353 lines (+112/-22) 5 files modified
UpdateManager/Core/UpdateList.py (+53/-13) UpdateManager/Dialogs.py (+4/-4) UpdateManager/UpdateManager.py (+28/-1) UpdateManager/UpdatesAvailable.py (+21/-4) debian/changelog (+6/-0) |
To merge this branch: | bzr merge lp:~robert-ancell/update-manager/ua-bionic-merge |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Core Development Team | Pending | ||
Review via email: mp+435932@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Robert Ancell (robert-ancell) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'UpdateManager/Core/UpdateList.py' |
2 | --- UpdateManager/Core/UpdateList.py 2018-10-03 17:45:08 +0000 |
3 | +++ UpdateManager/Core/UpdateList.py 2023-01-18 03:42:01 +0000 |
4 | @@ -43,11 +43,12 @@ |
5 | |
6 | |
7 | class UpdateItem(): |
8 | - def __init__(self, pkg, name, icon, to_remove): |
9 | + def __init__(self, pkg, name, icon, to_remove, sensitive=True): |
10 | self.icon = icon |
11 | self.name = name |
12 | self.pkg = pkg |
13 | self.to_remove = to_remove |
14 | + self.sensitive = sensitive |
15 | |
16 | def is_selected(self): |
17 | if not self.to_remove: |
18 | @@ -59,13 +60,13 @@ |
19 | class UpdateGroup(UpdateItem): |
20 | _depcache = {} |
21 | |
22 | - def __init__(self, pkg, name, icon, to_remove): |
23 | - UpdateItem.__init__(self, pkg, name, icon, to_remove) |
24 | + def __init__(self, pkg, name, icon, to_remove, sensitive=True): |
25 | + UpdateItem.__init__(self, pkg, name, icon, to_remove, sensitive) |
26 | self._items = set() |
27 | self._deps = set() |
28 | self.core_item = None |
29 | if pkg is not None: |
30 | - self.core_item = UpdateItem(pkg, name, icon, to_remove) |
31 | + self.core_item = UpdateItem(pkg, name, icon, to_remove, sensitive) |
32 | self._items.add(self.core_item) |
33 | |
34 | @property |
35 | @@ -74,10 +75,11 @@ |
36 | all_items.extend(self._items) |
37 | return sorted(all_items, key=lambda a: a.name.lower()) |
38 | |
39 | - def add(self, pkg, cache=None, eventloop_callback=None, to_remove=False): |
40 | + def add(self, pkg, cache=None, eventloop_callback=None, to_remove=False, |
41 | + sensitive=True): |
42 | name = utils.get_package_label(pkg) |
43 | icon = Gio.ThemedIcon.new("package") |
44 | - self._items.add(UpdateItem(pkg, name, icon, to_remove)) |
45 | + self._items.add(UpdateItem(pkg, name, icon, to_remove, sensitive)) |
46 | # If the pkg is in self._deps, stop here. We have already calculated |
47 | # the recursive dependencies for this package, no need to do it again. |
48 | if cache and pkg.name in cache and pkg.name not in self._deps: |
49 | @@ -153,27 +155,29 @@ |
50 | |
51 | |
52 | class UpdateApplicationGroup(UpdateGroup): |
53 | - def __init__(self, pkg, application, to_remove): |
54 | + def __init__(self, pkg, application, to_remove, sensitive=True): |
55 | name = application.get_display_name() |
56 | icon = application.get_icon() |
57 | super(UpdateApplicationGroup, self).__init__(pkg, name, icon, |
58 | - to_remove) |
59 | + to_remove, sensitive) |
60 | |
61 | |
62 | class UpdatePackageGroup(UpdateGroup): |
63 | - def __init__(self, pkg, to_remove): |
64 | + def __init__(self, pkg, to_remove, sensitive=True): |
65 | name = utils.get_package_label(pkg) |
66 | icon = Gio.ThemedIcon.new("package") |
67 | - super(UpdatePackageGroup, self).__init__(pkg, name, icon, to_remove) |
68 | + super(UpdatePackageGroup, self).__init__(pkg, name, icon, to_remove, |
69 | + sensitive) |
70 | |
71 | |
72 | class UpdateSystemGroup(UpdateGroup): |
73 | - def __init__(self, cache, to_remove): |
74 | + def __init__(self, cache, to_remove, sensitive=True): |
75 | # Translators: the %s is a distro name, like 'Ubuntu' and 'base' as in |
76 | # the core components and packages. |
77 | name = _("%s base") % utils.get_ubuntu_flavor_name(cache=cache) |
78 | icon = Gio.ThemedIcon.new("distributor-logo") |
79 | - super(UpdateSystemGroup, self).__init__(None, name, icon, to_remove) |
80 | + super(UpdateSystemGroup, self).__init__(None, name, icon, to_remove, |
81 | + sensitive) |
82 | |
83 | |
84 | class UpdateOrigin(): |
85 | @@ -213,6 +217,7 @@ |
86 | self.update_groups = [] |
87 | self.security_groups = [] |
88 | self.kernel_autoremove_groups = [] |
89 | + self.ubuntu_pro_groups = [] |
90 | self.num_updates = 0 |
91 | self.random = random.Random() |
92 | self.ignored_phased_updates = [] |
93 | @@ -472,7 +477,7 @@ |
94 | |
95 | return app_groups + pkg_groups |
96 | |
97 | - def update(self, cache, eventloop_callback=None): |
98 | + def update(self, cache, eventloop_callback=None, ua_security_packages=[]): |
99 | self.held_back = [] |
100 | |
101 | # do the upgrade |
102 | @@ -482,6 +487,34 @@ |
103 | upgrade_pkgs = [] |
104 | kernel_autoremove_pkgs = [] |
105 | |
106 | + class FakeUbuntuProPackageCandidate: |
107 | + def __init__(self, source_name, version, size): |
108 | + self.source_name = source_name |
109 | + self.summary = source_name |
110 | + self.description = source_name |
111 | + self.version = version |
112 | + self.size = size |
113 | + self.downloadable = False |
114 | + self.record = {} |
115 | + |
116 | + class FakeUbuntuProPackage: |
117 | + def __init__(self, package_name, version, size): |
118 | + self.name = package_name |
119 | + self.candidate = FakeUbuntuProPackageCandidate(package_name, |
120 | + version, size) |
121 | + self.marked_install = False |
122 | + self.marked_upgrade = False |
123 | + |
124 | + def mark_install(self): |
125 | + pass |
126 | + |
127 | + def mark_delete(self): |
128 | + pass |
129 | + fake_ua_packages = [] |
130 | + for (package_name, version, size) in ua_security_packages: |
131 | + fake_ua_packages.append(FakeUbuntuProPackage(package_name, |
132 | + version, size)) |
133 | + |
134 | # Find all upgradable packages |
135 | for pkg in cache: |
136 | if pkg.is_upgradable or pkg.marked_install: |
137 | @@ -535,3 +568,10 @@ |
138 | eventloop_callback) |
139 | self.kernel_autoremove_groups = self._make_groups( |
140 | cache, kernel_autoremove_pkgs, eventloop_callback, True) |
141 | + if len(fake_ua_packages) > 0: |
142 | + ubuntu_pro_group = UpdateGroup(None, |
143 | + "Ubuntu Pro (enable in Settings…)", |
144 | + None, False, False) |
145 | + for package in fake_ua_packages: |
146 | + ubuntu_pro_group.add(package) |
147 | + self.ubuntu_pro_groups = [ubuntu_pro_group] |
148 | |
149 | === modified file 'UpdateManager/Dialogs.py' |
150 | --- UpdateManager/Dialogs.py 2022-09-13 23:50:38 +0000 |
151 | +++ UpdateManager/Dialogs.py 2023-01-18 03:42:01 +0000 |
152 | @@ -161,10 +161,10 @@ |
153 | if self._is_livepatch_supported() and \ |
154 | self.settings_button and \ |
155 | self.settings.get_int('launch-count') >= 4: |
156 | - self.set_desc(_("<b>Tip:</b> You can use Livepatch to " |
157 | - "keep your computer more secure between " |
158 | - "restarts.")) |
159 | - self.settings_button.set_label(_("Settings & Livepatch…")) |
160 | + self.set_desc(_("<b>Tip:</b> You can use Livepatch with " |
161 | + "Ubuntu Pro to keep your computer more " |
162 | + "secure between restarts.")) |
163 | + self.settings_button.set_label(_("Settings & Pro…")) |
164 | return |
165 | |
166 | needs_reschedule = False |
167 | |
168 | === modified file 'UpdateManager/UpdateManager.py' |
169 | --- UpdateManager/UpdateManager.py 2022-09-13 23:50:56 +0000 |
170 | +++ UpdateManager/UpdateManager.py 2023-01-18 03:42:01 +0000 |
171 | @@ -36,6 +36,7 @@ |
172 | |
173 | import apt_pkg |
174 | import distro_info |
175 | +import json |
176 | import os |
177 | import subprocess |
178 | import sys |
179 | @@ -85,6 +86,7 @@ |
180 | self.unity = UnitySupport() |
181 | self.controller = None |
182 | self.cache = None |
183 | + self.ua_security_packages = [] |
184 | self.update_list = None |
185 | self.meta_release = None |
186 | self.hwe_replacement_packages = None |
187 | @@ -247,6 +249,27 @@ |
188 | cancelled_update, error_occurred) |
189 | self._start_pane(pane) |
190 | |
191 | + def _get_ua_security_status(self): |
192 | + self.ua_security_packages = [] |
193 | + try: |
194 | + p = subprocess.Popen(['ua', 'security-status', '--format=json'], |
195 | + stdout=subprocess.PIPE) |
196 | + except OSError: |
197 | + pass |
198 | + else: |
199 | + while p.poll() is None: |
200 | + while Gtk.events_pending(): |
201 | + Gtk.main_iteration() |
202 | + time.sleep(0.05) |
203 | + s = json.load(p.stdout) |
204 | + for package in s.get('packages', []): |
205 | + status = package.get('status', '') |
206 | + if status == 'pending_attach': |
207 | + name = package.get('name', '') |
208 | + version = package.get('version', '') |
209 | + size = package.get('download_size', 0) |
210 | + self.ua_security_packages.append((name, version, size)) |
211 | + |
212 | def _make_available_pane(self, install_count, need_reboot=False, |
213 | cancelled_update=False, error_occurred=False): |
214 | self._check_hwe_support_status() |
215 | @@ -406,9 +429,13 @@ |
216 | Gtk.main_iteration() |
217 | iterate() |
218 | |
219 | + self._get_ua_security_status() |
220 | + |
221 | self.update_list = UpdateList(self) |
222 | try: |
223 | - self.update_list.update(self.cache, eventloop_callback=iterate) |
224 | + self.update_list.update(self.cache, eventloop_callback=iterate, |
225 | + ua_security_packages=self. |
226 | + ua_security_packages) |
227 | except SystemError as e: |
228 | header = _("Could not calculate the upgrade") |
229 | desc = _("An unresolvable problem occurred while " |
230 | |
231 | === modified file 'UpdateManager/UpdatesAvailable.py' |
232 | --- UpdateManager/UpdatesAvailable.py 2018-03-18 21:43:58 +0000 |
233 | +++ UpdateManager/UpdatesAvailable.py 2023-01-18 03:42:01 +0000 |
234 | @@ -74,7 +74,8 @@ |
235 | # - screen reader does not say "Downloaded" for downloaded updates |
236 | |
237 | # list constants |
238 | -(LIST_NAME, LIST_UPDATE_DATA, LIST_SIZE, LIST_TOGGLE_ACTIVE) = range(4) |
239 | +(LIST_NAME, LIST_UPDATE_DATA, LIST_SIZE, LIST_TOGGLE_ACTIVE, |
240 | + LIST_SENSITIVE) = range(5) |
241 | |
242 | # NetworkManager enums |
243 | from .Core.roam import NetworkManagerHelper |
244 | @@ -261,7 +262,7 @@ |
245 | changes_buffer.create_tag("versiontag", weight=Pango.Weight.BOLD) |
246 | |
247 | # the treeview (move into it's own code!) |
248 | - self.store = Gtk.TreeStore(str, GObject.TYPE_PYOBJECT, str, bool) |
249 | + self.store = Gtk.TreeStore(str, GObject.TYPE_PYOBJECT, str, bool, bool) |
250 | self.treeview_update.set_model(None) |
251 | |
252 | self.image_restart.set_from_gicon(self.get_restart_icon(), |
253 | @@ -293,6 +294,8 @@ |
254 | pkg_column.pack_start(pkg_toggle_renderer, False) |
255 | pkg_column.add_attribute(pkg_toggle_renderer, |
256 | 'active', LIST_TOGGLE_ACTIVE) |
257 | + pkg_column.add_attribute(pkg_toggle_renderer, |
258 | + 'sensitive', LIST_SENSITIVE) |
259 | pkg_column.set_cell_data_func(pkg_toggle_renderer, |
260 | self.pkg_toggle_renderer_data_func) |
261 | |
262 | @@ -319,6 +322,8 @@ |
263 | size_column = Gtk.TreeViewColumn(_("Download"), size_renderer, |
264 | text=LIST_SIZE) |
265 | size_column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) |
266 | + size_column.add_attribute(size_renderer, |
267 | + 'sensitive', LIST_SENSITIVE) |
268 | self.treeview_update.append_column(size_column) |
269 | |
270 | self.treeview_update.set_headers_visible(True) |
271 | @@ -404,8 +409,11 @@ |
272 | def restart_icon_renderer_data_func(self, cell_layout, renderer, model, |
273 | iter, user_data): |
274 | data = model.get_value(iter, LIST_UPDATE_DATA) |
275 | + sensitive = model.get_value(iter, LIST_SENSITIVE) |
276 | path = model.get_path(iter) |
277 | |
278 | + renderer.set_sensitive(sensitive) |
279 | + |
280 | requires_restart = False |
281 | if data.item and data.item.pkg: |
282 | requires_restart = self.pkg_requires_restart(data.item.pkg) |
283 | @@ -433,6 +441,7 @@ |
284 | if data.item: |
285 | activatable = data.item.pkg.name not in self.list.held_back |
286 | inconsistent = False |
287 | + renderer.set_sensitive(data.item.sensitive) |
288 | elif data.group: |
289 | activatable = True |
290 | inconsistent = data.group.selection_is_inconsistent() |
291 | @@ -485,8 +494,11 @@ |
292 | def pkg_label_renderer_data_func(self, cell_layout, renderer, model, |
293 | iter, user_data): |
294 | data = model.get_value(iter, LIST_UPDATE_DATA) |
295 | + sensitive = model.get_value(iter, LIST_SENSITIVE) |
296 | name = GLib.markup_escape_text(model.get_value(iter, LIST_NAME)) |
297 | |
298 | + renderer.set_sensitive(sensitive) |
299 | + |
300 | if data.group: |
301 | markup = name |
302 | elif data.item: |
303 | @@ -997,6 +1009,7 @@ |
304 | name, |
305 | UpdateData(groups, None, None), |
306 | humanize_size(total_size), |
307 | + True, |
308 | True |
309 | ] |
310 | return self.store.append(None, header_row) |
311 | @@ -1020,7 +1033,8 @@ |
312 | group.name, |
313 | UpdateData(None, group, group_is_item), |
314 | humanize_size(group.get_total_size()), |
315 | - True |
316 | + True, |
317 | + group.sensitive |
318 | ] |
319 | group_iter = self.store.append(None, group_row) |
320 | |
321 | @@ -1031,7 +1045,8 @@ |
322 | item.name, |
323 | UpdateData(None, None, item), |
324 | humanize_size(getattr(item.pkg.candidate, "size", 0)), |
325 | - True |
326 | + True, |
327 | + group.sensitive |
328 | ] |
329 | self.store.append(group_iter, item_row) |
330 | |
331 | @@ -1063,6 +1078,8 @@ |
332 | _("Unused kernel updates to be removed"), |
333 | self.list.kernel_autoremove_groups) |
334 | self._add_groups(self.list.kernel_autoremove_groups) |
335 | + if self.list.ubuntu_pro_groups: |
336 | + self._add_groups(self.list.ubuntu_pro_groups) |
337 | |
338 | self.treeview_update.set_model(self.store) |
339 | self.pkg_cell_area.indent_toplevel = ( |
340 | |
341 | === modified file 'debian/changelog' |
342 | --- debian/changelog 2022-09-13 23:51:20 +0000 |
343 | +++ debian/changelog 2023-01-18 03:42:01 +0000 |
344 | @@ -1,3 +1,9 @@ |
345 | +update-manager (1:18.04.11.15) bionic; urgency=medium |
346 | + |
347 | + * Show pending Ubuntu pro packages (LP: #1990450) |
348 | + |
349 | + -- Robert Ancell <robert.ancell@canonical.com> Wed, 18 Jan 2023 15:09:17 +1300 |
350 | + |
351 | update-manager (1:18.04.11.14) bionic; urgency=medium |
352 | |
353 | * tests/test_meta_release_core.py: switch a test from using lucid to bionic |
Merged because this has been uploaded as a SRU.