Merge ~nteodosio/update-manager:dont-nag-pro-focal into update-manager:main

Proposed by Nathan Teodosio
Status: Superseded
Proposed branch: ~nteodosio/update-manager:dont-nag-pro-focal
Merge into: update-manager:main
Diff against target: 1725 lines (+824/-0) (has conflicts)
15 files modified
UpdateManager/Core/MyCache.py (+7/-0)
UpdateManager/Core/UpdateList.py (+114/-0)
UpdateManager/Dialogs.py (+9/-0)
UpdateManager/UpdateManager.py (+94/-0)
UpdateManager/UpdatesAvailable.py (+81/-0)
UpdateManager/backend/InstallBackendAptdaemon.py (+175/-0)
UpdateManager/backend/__init__.py (+30/-0)
data/gtkbuilder/UpdateManager.ui (+4/-0)
debian/changelog (+155/-0)
debian/control (+30/-0)
debian/tests/control (+4/-0)
tests/test_cache.py (+5/-0)
tests/test_changelog.py (+12/-0)
tests/test_meta_release_core.py (+18/-0)
tests/test_update_list.py (+86/-0)
Conflict in UpdateManager/Core/MyCache.py
Conflict in UpdateManager/Core/UpdateList.py
Conflict in UpdateManager/Dialogs.py
Conflict in UpdateManager/UpdateManager.py
Conflict in UpdateManager/UpdatesAvailable.py
Conflict in UpdateManager/backend/InstallBackendAptdaemon.py
Conflict in UpdateManager/backend/__init__.py
Conflict in data/gtkbuilder/UpdateManager.ui
Conflict in debian/changelog
Conflict in debian/control
Conflict in debian/tests/control
Conflict in tests/test_cache.py
Conflict in tests/test_changelog.py
Conflict in tests/test_meta_release_core.py
Conflict in tests/test_update_list.py
Reviewer Review Type Date Requested Status
Sebastien Bacher Pending
Review via email: mp+459436@code.launchpad.net

This proposal has been superseded by a proposal from 2024-01-25.

Description of the change

Do not show the list of packages if the machine is not attached to Ubuntu Pro and only those coming from Ubuntu Pro are available.

To post a comment you must log in.

Unmerged commits

e954fc2... by Nathan Teodosio

Update change log for version 1:20.04.10.20.

2ffb4b0... by Nathan Teodosio

Do not offer Ubuntu Pro if they are the only updates available.

928b535... by Nathan Teodosio

Update changelog.

eac8e4b... by Nathan Teodosio

Removed widgets added back to *.ui file.

Even though unused, updating Update Manager in place would otherwise cause
a crash.

LP:2045918

dfd9a81... by Sebastien Bacher

releasing package update-manager version 1:20.04.10.18

9020957... by Nathan Teodosio

Fix incorrect available version for Ubuntu Pro updates in unattached case.

LP:2043425

cacc1f3... by Sebastien Bacher

releasing package update-manager version 1:20.04.10.17

3b7747b... by Sebastien Bacher

* Ubuntu Pro (LP: #1990450):
  - fix another linter error which was created while fixing a missing
    space in the previous upload...

5a1ded2... by Sebastien Bacher

releasing package update-manager version 1:20.04.10.16

5926e16... by Nathan Teodosio

Prepare changelog for 1:20.04.10.16.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/UpdateManager/Core/MyCache.py b/UpdateManager/Core/MyCache.py
2index 80557c6..4bd0486 100644
3--- a/UpdateManager/Core/MyCache.py
4+++ b/UpdateManager/Core/MyCache.py
5@@ -481,6 +481,7 @@ class MyCache(DistUpgrade.DistUpgradeCache.MyCache):
6 "get the changelog file from the changelog location"
7 origins = self[name].candidate.origins
8 version = self.pro_versions.get(name, self[name].candidate.version)
9+<<<<<<< UpdateManager/Core/MyCache.py
10 self.all_changes[name] = _(
11 "Changes for %s versions:\n"
12 "Installed version: %s\n"
13@@ -490,6 +491,12 @@ class MyCache(DistUpgrade.DistUpgradeCache.MyCache):
14 getattr(self[name].installed, "version", None),
15 version,
16 )
17+=======
18+ self.all_changes[name] = _("Changes for %s versions:\n"
19+ "Installed version: %s\n"
20+ "Available version: %s\n\n") % \
21+ (name, getattr(self[name].installed, "version", None), version)
22+>>>>>>> UpdateManager/Core/MyCache.py
23 if self.CHANGELOG_ORIGIN not in [o.origin for o in origins]:
24 self._fetch_changelog_for_third_party_package(name, origins)
25 return
26diff --git a/UpdateManager/Core/UpdateList.py b/UpdateManager/Core/UpdateList.py
27index 265ab90..4e904ed 100644
28--- a/UpdateManager/Core/UpdateList.py
29+++ b/UpdateManager/Core/UpdateList.py
30@@ -43,7 +43,11 @@ from gi.repository import Gio
31 from UpdateManager.Core import utils
32
33
34+<<<<<<< UpdateManager/Core/UpdateList.py
35 class UpdateItem:
36+=======
37+class UpdateItem():
38+>>>>>>> UpdateManager/Core/UpdateList.py
39 def __init__(self, pkg, name, icon, to_remove, sensitive=True):
40 self.icon = icon
41 self.name = name
42@@ -76,6 +80,7 @@ class UpdateGroup(UpdateItem):
43 all_items.extend(self._items)
44 return sorted(all_items, key=lambda a: a.name.lower())
45
46+<<<<<<< UpdateManager/Core/UpdateList.py
47 def add(
48 self,
49 pkg,
50@@ -84,6 +89,10 @@ class UpdateGroup(UpdateItem):
51 to_remove=False,
52 sensitive=True,
53 ):
54+=======
55+ def add(self, pkg, cache=None, eventloop_callback=None, to_remove=False,
56+ sensitive=True):
57+>>>>>>> UpdateManager/Core/UpdateList.py
58 name = utils.get_package_label(pkg)
59 icon = Gio.ThemedIcon.new("package")
60 self._items.add(UpdateItem(pkg, name, icon, to_remove, sensitive))
61@@ -168,18 +177,28 @@ class UpdateApplicationGroup(UpdateGroup):
62 def __init__(self, pkg, application, to_remove, sensitive=True):
63 name = application.get_display_name()
64 icon = application.get_icon()
65+<<<<<<< UpdateManager/Core/UpdateList.py
66 super(UpdateApplicationGroup, self).__init__(
67 pkg, name, icon, to_remove, sensitive
68 )
69+=======
70+ super(UpdateApplicationGroup, self).__init__(pkg, name, icon,
71+ to_remove, sensitive)
72+>>>>>>> UpdateManager/Core/UpdateList.py
73
74
75 class UpdatePackageGroup(UpdateGroup):
76 def __init__(self, pkg, to_remove, sensitive=True):
77 name = utils.get_package_label(pkg)
78 icon = Gio.ThemedIcon.new("package")
79+<<<<<<< UpdateManager/Core/UpdateList.py
80 super(UpdatePackageGroup, self).__init__(
81 pkg, name, icon, to_remove, sensitive
82 )
83+=======
84+ super(UpdatePackageGroup, self).__init__(pkg, name, icon, to_remove,
85+ sensitive)
86+>>>>>>> UpdateManager/Core/UpdateList.py
87
88
89 class UpdateSystemGroup(UpdateGroup):
90@@ -188,9 +207,14 @@ class UpdateSystemGroup(UpdateGroup):
91 # the core components and packages.
92 name = _("%s base") % utils.get_ubuntu_flavor_name(cache=cache)
93 icon = Gio.ThemedIcon.new("distributor-logo")
94+<<<<<<< UpdateManager/Core/UpdateList.py
95 super(UpdateSystemGroup, self).__init__(
96 None, name, icon, to_remove, sensitive
97 )
98+=======
99+ super(UpdateSystemGroup, self).__init__(None, name, icon, to_remove,
100+ sensitive)
101+>>>>>>> UpdateManager/Core/UpdateList.py
102
103
104 class UpdateOrigin:
105@@ -435,9 +459,14 @@ class UpdateList:
106 for pkg in pkgs:
107 app = self._get_application_for_package(pkg)
108 if app is not None:
109+<<<<<<< UpdateManager/Core/UpdateList.py
110 app_group = UpdateApplicationGroup(
111 pkg, app, to_remove, sensitive
112 )
113+=======
114+ app_group = UpdateApplicationGroup(pkg, app, to_remove,
115+ sensitive)
116+>>>>>>> UpdateManager/Core/UpdateList.py
117 app_groups.append(app_group)
118 else:
119 ungrouped_pkgs.append(pkg)
120@@ -458,6 +487,7 @@ class UpdateList:
121 if ungrouped_pkgs:
122 # Separate out system base packages. If we have already found an
123 # application for all updates, don't bother.
124+<<<<<<< UpdateManager/Core/UpdateList.py
125 linux_names = (
126 "linux$",
127 "linux-.*-buildinfo.*",
128@@ -488,6 +518,32 @@ class UpdateList:
129 "ubuntu-standard",
130 "ubuntu-minimal",
131 ]
132+=======
133+ linux_names = ("linux$",
134+ "linux-.*-buildinfo.*",
135+ "linux-.*-dev.*",
136+ "linux-.*-generic.*",
137+ "linux-.*-headers.*",
138+ "linux-.*-hwe.*",
139+ "linux-.*-gcp.*",
140+ "linux-.*-kernel.*",
141+ "linux-.*-lowlatency.*",
142+ "linux-.*-modules.*",
143+ "linux-.*-raspi.*",
144+ "linux-.*-tools.*",
145+ "linux-.*-virtual.*",
146+ "linux-base.*",
147+ "linux-crashdump.*",
148+ "linux-doc.*")
149+ linux_regexp = re.compile("(" + "|".join(
150+ ["^" + n for n in linux_names]) + ")")
151+ ubuntu_base_group = UpdateGroup(None, None, None, to_remove,
152+ sensitive)
153+ flavor_package = utils.get_ubuntu_flavor_package(cache=cache)
154+ ubuntu_base_pkgs = [flavor_package,
155+ "ubuntu-standard",
156+ "ubuntu-minimal"]
157+>>>>>>> UpdateManager/Core/UpdateList.py
158 for pkg in cache:
159 if linux_regexp.match(pkg.name):
160 ubuntu_base_pkgs.append(pkg.name)
161@@ -498,6 +554,7 @@ class UpdateList:
162 # which fixes LP: #1912718
163 ubuntu_base_group.add(cache[pkg])
164 for pkg in ungrouped_pkgs:
165+<<<<<<< UpdateManager/Core/UpdateList.py
166 if ubuntu_base_group.is_dependency(
167 pkg, cache, eventloop_callback
168 ):
169@@ -509,6 +566,17 @@ class UpdateList:
170 else:
171 pkg_groups.append(
172 UpdatePackageGroup(pkg, to_remove, sensitive)
173+=======
174+ if ubuntu_base_group.is_dependency(pkg, cache,
175+ eventloop_callback):
176+ if system_group is None:
177+ system_group = UpdateSystemGroup(cache, to_remove,
178+ sensitive)
179+ system_group.add(pkg)
180+ else:
181+ pkg_groups.append(UpdatePackageGroup(
182+ pkg, to_remove, sensitive)
183+>>>>>>> UpdateManager/Core/UpdateList.py
184 )
185
186 app_groups.sort(key=lambda a: a.name.lower())
187@@ -518,6 +586,7 @@ class UpdateList:
188
189 return app_groups + pkg_groups
190
191+<<<<<<< UpdateManager/Core/UpdateList.py
192 def update(
193 self,
194 cache,
195@@ -525,6 +594,10 @@ class UpdateList:
196 duplicate_packages=[],
197 ua_security_packages=[],
198 ):
199+=======
200+ def update(self, cache, eventloop_callback=None, duplicate_packages=[],
201+ ua_security_packages=[]):
202+>>>>>>> UpdateManager/Core/UpdateList.py
203 self.held_back = []
204
205 # do the upgrade
206@@ -550,9 +623,14 @@ class UpdateList:
207 class FakeUbuntuProPackage:
208 def __init__(self, package_name, version, size):
209 self.name = package_name
210+<<<<<<< UpdateManager/Core/UpdateList.py
211 self.candidate = FakeUbuntuProPackageCandidate(
212 package_name, version, size
213 )
214+=======
215+ self.candidate = FakeUbuntuProPackageCandidate(package_name,
216+ version, size)
217+>>>>>>> UpdateManager/Core/UpdateList.py
218 self.marked_install = False
219 self.marked_upgrade = False
220 self.marked_delete = False
221@@ -563,7 +641,10 @@ class UpdateList:
222
223 def mark_delete(self):
224 pass
225+<<<<<<< UpdateManager/Core/UpdateList.py
226
227+=======
228+>>>>>>> UpdateManager/Core/UpdateList.py
229 fake_ua_packages = []
230 ua_packages_names = []
231 for (
232@@ -575,9 +656,14 @@ class UpdateList:
233 if downloadable:
234 ua_packages_names.append(package_name)
235 else:
236+<<<<<<< UpdateManager/Core/UpdateList.py
237 fake_ua_packages.append(
238 FakeUbuntuProPackage(package_name, version, size)
239 )
240+=======
241+ fake_ua_packages.append(FakeUbuntuProPackage(package_name,
242+ version, size))
243+>>>>>>> UpdateManager/Core/UpdateList.py
244
245 # Find all upgradable packages
246 for pkg in cache:
247@@ -600,7 +686,11 @@ class UpdateList:
248 self.ignored_phased_updates.append(pkg)
249 continue
250
251+<<<<<<< UpdateManager/Core/UpdateList.py
252 if fnmatch.fnmatch(pkg.name, "oem-*-meta"):
253+=======
254+ if fnmatch.fnmatch(pkg.name, 'oem-*-meta'):
255+>>>>>>> UpdateManager/Core/UpdateList.py
256 oem_pkgs.append(pkg)
257 comes_from_pro = pkg.name in ua_packages_names
258 if comes_from_pro:
259@@ -636,6 +726,7 @@ class UpdateList:
260
261 if security_pkgs or upgrade_pkgs or pro_pkgs:
262 # There's updates available. Initiate the desktop file cache.
263+<<<<<<< UpdateManager/Core/UpdateList.py
264 pkg_names = [
265 p.name
266 for p in security_pkgs
267@@ -654,10 +745,26 @@ class UpdateList:
268 self.security_groups = self._make_groups(
269 cache, security_pkgs, eventloop_callback
270 )
271+=======
272+ pkg_names = [p.name for p in
273+ pro_pkgs
274+ + security_pkgs
275+ + upgrade_pkgs
276+ + kernel_autoremove_pkgs
277+ + duplicate_pkgs]
278+ self._populate_desktop_cache(pkg_names)
279+ self.oem_groups = self._make_groups(cache, oem_pkgs,
280+ eventloop_callback)
281+ self.update_groups = self._make_groups(cache, upgrade_pkgs,
282+ eventloop_callback)
283+ self.security_groups = self._make_groups(cache, security_pkgs,
284+ eventloop_callback)
285+>>>>>>> UpdateManager/Core/UpdateList.py
286 self.kernel_autoremove_groups = self._make_groups(
287 cache, kernel_autoremove_pkgs, eventloop_callback, True
288 )
289 self.duplicate_groups = self._make_groups(
290+<<<<<<< UpdateManager/Core/UpdateList.py
291 cache, duplicate_pkgs, eventloop_callback, True
292 )
293 self.ubuntu_pro_fake_groups = self._make_groups(
294@@ -666,3 +773,10 @@ class UpdateList:
295 self.ubuntu_pro_groups = self._make_groups(
296 cache, pro_pkgs, eventloop_callback
297 )
298+=======
299+ cache, duplicate_pkgs, eventloop_callback, True)
300+ self.ubuntu_pro_fake_groups = self._make_groups(
301+ cache, fake_ua_packages, eventloop_callback, sensitive=False)
302+ self.ubuntu_pro_groups = self._make_groups(
303+ cache, pro_pkgs, eventloop_callback)
304+>>>>>>> UpdateManager/Core/UpdateList.py
305diff --git a/UpdateManager/Dialogs.py b/UpdateManager/Dialogs.py
306index 304609c..8b1cbd1 100644
307--- a/UpdateManager/Dialogs.py
308+++ b/UpdateManager/Dialogs.py
309@@ -159,6 +159,7 @@ class InternalDialog(BuilderDialog):
310 self.set_desc(None)
311
312 if not active:
313+<<<<<<< UpdateManager/Dialogs.py
314 if (
315 self._is_livepatch_supported()
316 and self.settings_button
317@@ -171,6 +172,14 @@ class InternalDialog(BuilderDialog):
318 "secure between restarts."
319 )
320 )
321+=======
322+ if self._is_livepatch_supported() and \
323+ self.settings_button and \
324+ self.settings.get_int('launch-count') >= 4:
325+ self.set_desc(_("<b>Tip:</b> You can use Livepatch with "
326+ "Ubuntu Pro to keep your computer more "
327+ "secure between restarts."))
328+>>>>>>> UpdateManager/Dialogs.py
329 self.settings_button.set_label(_("Settings & Pro…"))
330 return
331
332diff --git a/UpdateManager/UpdateManager.py b/UpdateManager/UpdateManager.py
333index efe654e..7a11ebc 100644
334--- a/UpdateManager/UpdateManager.py
335+++ b/UpdateManager/UpdateManager.py
336@@ -37,6 +37,10 @@ warnings.filterwarnings(
337
338 import distro_info
339 import fnmatch
340+<<<<<<< UpdateManager/UpdateManager.py
341+=======
342+import json
343+>>>>>>> UpdateManager/UpdateManager.py
344 import os
345 import subprocess
346 import sys
347@@ -70,7 +74,12 @@ from .Core.MyCache import MyCache
348 from .Core.roam import NetworkManagerHelper
349 from .Core.UpdateList import UpdateList
350 from .Core.utils import get_arch, get_dist, SoftwarePropertiesPage
351+<<<<<<< UpdateManager/UpdateManager.py
352 from .backend import InstallBackend, get_backend
353+=======
354+from .backend import (InstallBackend,
355+ get_backend)
356+>>>>>>> UpdateManager/UpdateManager.py
357
358 # file that signals if we need to reboot
359 REBOOT_REQUIRED_FILE = "/var/run/reboot-required"
360@@ -248,12 +257,19 @@ class UpdateManager(Gtk.Window):
361 if self.cache is None:
362 return
363
364+<<<<<<< UpdateManager/UpdateManager.py
365 pane = self._make_available_pane(
366 self.cache.install_count + self.cache.del_count,
367 os.path.exists(REBOOT_REQUIRED_FILE),
368 cancelled_update,
369 error_occurred,
370 )
371+=======
372+ pane = self._make_available_pane(self.cache.install_count
373+ + self.cache.del_count,
374+ os.path.exists(REBOOT_REQUIRED_FILE),
375+ cancelled_update, error_occurred)
376+>>>>>>> UpdateManager/UpdateManager.py
377 self._start_pane(pane)
378
379 def _check_oem_metapackages(self):
380@@ -262,18 +278,28 @@ class UpdateManager(Gtk.Window):
381 lts = di.is_lts(codename)
382 if not lts:
383 return None
384+<<<<<<< UpdateManager/UpdateManager.py
385 OEM_PATH = os.path.join(
386 GLib.get_user_runtime_dir(), "ubuntu-drivers-oem.package-list"
387 )
388+=======
389+ OEM_PATH = os.path.join(GLib.get_user_runtime_dir(),
390+ "ubuntu-drivers-oem.package-list")
391+>>>>>>> UpdateManager/UpdateManager.py
392 if not os.path.exists(OEM_PATH):
393 return None
394
395 # Packages that aren't installed but apply to this system
396+<<<<<<< UpdateManager/UpdateManager.py
397 with open(OEM_PATH, "r") as f:
398+=======
399+ with open(OEM_PATH, 'r') as f:
400+>>>>>>> UpdateManager/UpdateManager.py
401 self.oem_metapackages |= set(f.read().splitlines())
402
403 # Packages that are already installed
404 for pkg in self.cache:
405+<<<<<<< UpdateManager/UpdateManager.py
406 if fnmatch.fnmatch(pkg.name, "oem-*-meta") and pkg.installed:
407 self.oem_metapackages.add(pkg)
408
409@@ -318,15 +344,61 @@ class UpdateManager(Gtk.Window):
410 ):
411 self._check_hwe_support_status()
412 if install_count != 0 or len(self.ua_security_packages) > 0:
413+=======
414+ if fnmatch.fnmatch(pkg.name, 'oem-*-meta') \
415+ and pkg.installed:
416+ self.oem_metapackages.add(pkg)
417+
418+ def _get_ua_security_status(self):
419+ self.ua_security_packages = []
420+ try:
421+ p = subprocess.Popen(['pro', 'security-status', '--format=json'],
422+ stdout=subprocess.PIPE)
423+ except OSError:
424+ pass
425+ else:
426+ while p.poll() is None:
427+ while Gtk.events_pending():
428+ Gtk.main_iteration()
429+ time.sleep(0.05)
430+ s = json.load(p.stdout)
431+ for package in s.get('packages', []):
432+ if package.get('service_name', '') == 'standard-security':
433+ continue
434+ status = package.get('status', '')
435+ if (
436+ status == 'pending_attach'
437+ or status == 'pending_enable'
438+ or status == 'upgrade_available'
439+ ):
440+ name = package.get('package', '')
441+ version = package.get('version', '')
442+ size = package.get('download_size', 0)
443+ downloadable = status == 'upgrade_available'
444+ self.ua_security_packages.append(
445+ (name, version, size, downloadable)
446+ )
447+ self.cache.create_pro_cache(self.ua_security_packages)
448+
449+ def _make_available_pane(self, install_count, need_reboot=False,
450+ cancelled_update=False, error_occurred=False):
451+ self._check_hwe_support_status()
452+ if install_count != 0:
453+>>>>>>> UpdateManager/UpdateManager.py
454 header = None
455 desc = None
456 if error_occurred:
457 desc = _("Some software couldn’t be checked for updates.")
458 elif cancelled_update:
459 header = _("You stopped the check for updates.")
460+<<<<<<< UpdateManager/UpdateManager.py
461 desc = _(
462 "Updated software is available from a previous check."
463 )
464+=======
465+ desc = _("Updated software is available from "
466+ "a previous check.")
467+>>>>>>> UpdateManager/UpdateManager.py
468 # Display HWE updates first as an old HWE stack is vulnerable
469 elif self.hwe_replacement_packages:
470 return HWEUpgradeDialog(self)
471@@ -450,22 +522,37 @@ class UpdateManager(Gtk.Window):
472 self._start_pane(PartialUpgradeDialog(self))
473 # we assert a clean cache
474 header = _("Software index is broken")
475+<<<<<<< UpdateManager/UpdateManager.py
476 desc = _(
477 "It is impossible to install or remove any software. "
478 'Please use the package manager "Synaptic" or run '
479 '"sudo apt-get install -f" in a terminal to fix '
480 "this issue at first."
481 )
482+=======
483+ desc = _("It is impossible to install or remove any software. "
484+ "Please use the package manager \"Synaptic\" or run "
485+ "\"sudo apt-get install -f\" in a terminal to fix "
486+ "this issue at first.")
487+>>>>>>> UpdateManager/UpdateManager.py
488 self.start_error(False, header, desc)
489 return
490 except SystemError as e:
491 header = _("Could not initialize the package information")
492+<<<<<<< UpdateManager/UpdateManager.py
493 desc = _(
494 "An unresolvable problem occurred while "
495 "initializing the package information.\n\n"
496 "Please report this bug against the 'update-manager' "
497 "package and include the following error message:\n"
498 ) + str(e)
499+=======
500+ desc = _("An unresolvable problem occurred while "
501+ "initializing the package information.\n\n"
502+ "Please report this bug against the 'update-manager' "
503+ "package and include the following error "
504+ "message:\n") + str(e)
505+>>>>>>> UpdateManager/UpdateManager.py
506 self.start_error(False, header, desc)
507 return
508
509@@ -489,12 +576,19 @@ class UpdateManager(Gtk.Window):
510
511 self.update_list = UpdateList(self)
512 try:
513+<<<<<<< UpdateManager/UpdateManager.py
514 self.update_list.update(
515 self.cache,
516 eventloop_callback=iterate,
517 duplicate_packages=self.duplicate_packages,
518 ua_security_packages=self.ua_security_packages,
519 )
520+=======
521+ self.update_list.update(self.cache, eventloop_callback=iterate,
522+ duplicate_packages=self.duplicate_packages,
523+ ua_security_packages=self.
524+ ua_security_packages)
525+>>>>>>> UpdateManager/UpdateManager.py
526 except SystemError as e:
527 header = _("Could not calculate the upgrade")
528 desc = _(
529diff --git a/UpdateManager/UpdatesAvailable.py b/UpdateManager/UpdatesAvailable.py
530index 75cfd33..f4f84ed 100644
531--- a/UpdateManager/UpdatesAvailable.py
532+++ b/UpdateManager/UpdatesAvailable.py
533@@ -75,6 +75,7 @@ from .UnitySupport import UnitySupport
534 # - screen reader does not say "Downloaded" for downloaded updates
535
536 # list constants
537+<<<<<<< UpdateManager/UpdatesAvailable.py
538 (
539 LIST_NAME,
540 LIST_UPDATE_DATA,
541@@ -82,6 +83,10 @@ from .UnitySupport import UnitySupport
542 LIST_TOGGLE_ACTIVE,
543 LIST_SENSITIVE,
544 ) = range(5)
545+=======
546+(LIST_NAME, LIST_UPDATE_DATA, LIST_SIZE, LIST_TOGGLE_ACTIVE,
547+ LIST_SENSITIVE) = range(5)
548+>>>>>>> UpdateManager/UpdatesAvailable.py
549
550 # NetworkManager enums
551 from .Core.roam import NetworkManagerHelper
552@@ -256,6 +261,7 @@ class UpdatesAvailable(InternalDialog):
553 # self.button_help.set_sensitive(False)
554
555 self.add_settings_button()
556+<<<<<<< UpdateManager/UpdatesAvailable.py
557 self.button_close = self.add_button(
558 Gtk.STOCK_CANCEL, self.window_main.close
559 )
560@@ -265,6 +271,14 @@ class UpdatesAvailable(InternalDialog):
561 self.button_install = self.add_button(
562 _("Install Now"), self.on_button_install_clicked
563 )
564+=======
565+ self.button_close = self.add_button(Gtk.STOCK_CANCEL,
566+ self.window_main.close)
567+ self.button_pro = self.add_button(_("Enable Ubuntu Pro..."),
568+ self.on_button_pro_clicked)
569+ self.button_install = self.add_button(_("Install Now"),
570+ self.on_button_install_clicked)
571+>>>>>>> UpdateManager/UpdatesAvailable.py
572 self.focus_button = self.button_install
573
574 # create text view
575@@ -310,6 +324,7 @@ class UpdatesAvailable(InternalDialog):
576 pkg_toggle_renderer.set_property("ypad", 2)
577 pkg_toggle_renderer.connect("toggled", self.on_update_toggled)
578 pkg_column.pack_start(pkg_toggle_renderer, False)
579+<<<<<<< UpdateManager/UpdatesAvailable.py
580 pkg_column.add_attribute(
581 pkg_toggle_renderer, "active", LIST_TOGGLE_ACTIVE
582 )
583@@ -319,6 +334,14 @@ class UpdatesAvailable(InternalDialog):
584 pkg_column.set_cell_data_func(
585 pkg_toggle_renderer, self.pkg_toggle_renderer_data_func
586 )
587+=======
588+ pkg_column.add_attribute(pkg_toggle_renderer,
589+ 'active', LIST_TOGGLE_ACTIVE)
590+ pkg_column.add_attribute(pkg_toggle_renderer,
591+ 'sensitive', LIST_SENSITIVE)
592+ pkg_column.set_cell_data_func(pkg_toggle_renderer,
593+ self.pkg_toggle_renderer_data_func)
594+>>>>>>> UpdateManager/UpdatesAvailable.py
595
596 pkg_icon_renderer = Gtk.CellRendererPixbuf()
597 pkg_icon_renderer.set_property("ypad", 2)
598@@ -346,7 +369,12 @@ class UpdatesAvailable(InternalDialog):
599 _("Download"), size_renderer, text=LIST_SIZE
600 )
601 size_column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
602+<<<<<<< UpdateManager/UpdatesAvailable.py
603 size_column.add_attribute(size_renderer, "sensitive", LIST_SENSITIVE)
604+=======
605+ size_column.add_attribute(size_renderer,
606+ 'sensitive', LIST_SENSITIVE)
607+>>>>>>> UpdateManager/UpdatesAvailable.py
608 self.treeview_update.append_column(size_column)
609
610 self.treeview_update.set_headers_visible(True)
611@@ -371,9 +399,14 @@ class UpdatesAvailable(InternalDialog):
612 self.settings.get_boolean("show-details")
613 )
614 self.expander_details.connect("activate", self.pre_activate_details)
615+<<<<<<< UpdateManager/UpdatesAvailable.py
616 self.expander_details.connect(
617 "notify::expanded", self.activate_details
618 )
619+=======
620+ self.expander_details.connect("notify::expanded",
621+ self.activate_details)
622+>>>>>>> UpdateManager/UpdatesAvailable.py
623
624 # If auto-updates are on, change cancel label
625 self.notifier_settings = Gio.Settings.new("com.ubuntu.update-notifier")
626@@ -401,6 +434,17 @@ class UpdatesAvailable(InternalDialog):
627 self.news.get_buffer().set_text(apt_news)
628 self.expander_news.set_visible(True)
629
630+ try:
631+ from uaclient.api.u.apt_news.current_news.v1 import current_news
632+ apt_news = current_news().current_news
633+ except ImportError:
634+ apt_news = self._get_apt_news(
635+ "/var/lib/ubuntu-advantage/messages/apt-news"
636+ )
637+ if apt_news:
638+ self.news.get_buffer().set_text(apt_news)
639+ self.expander_news.set_visible(True)
640+
641 def stop(self):
642 InternalDialog.stop(self)
643 self._save_state()
644@@ -584,6 +628,7 @@ class UpdatesAvailable(InternalDialog):
645 version = version_match.group(1)
646 # upload_archive = version_match.group(2).strip()
647 version_text = _("Version %s: \n") % version
648+<<<<<<< UpdateManager/UpdatesAvailable.py
649 changes_buffer.insert_with_tags_by_name(
650 end_iter, version_text, "versiontag"
651 )
652@@ -592,6 +637,14 @@ class UpdatesAvailable(InternalDialog):
653 end_iter, line + "\n", "changestag"
654 )
655 elif author_match:
656+=======
657+ changes_buffer.insert_with_tags_by_name(end_iter, version_text,
658+ "versiontag")
659+ elif changes_match:
660+ changes_buffer.insert_with_tags_by_name(end_iter, line + "\n",
661+ "changestag")
662+ elif (author_match):
663+>>>>>>> UpdateManager/UpdatesAvailable.py
664 pass
665 else:
666 changes_buffer.insert(end_iter, line + "\n")
667@@ -633,7 +686,10 @@ class UpdatesAvailable(InternalDialog):
668 # replace all multiple spaces by newlines
669 p = re.compile(r"\s\s+", re.MULTILINE)
670 long_desc = p.sub("\n", long_desc)
671+<<<<<<< UpdateManager/UpdatesAvailable.py
672 long_desc = "Package: %s\n%s" % (item.pkg.name, long_desc)
673+=======
674+>>>>>>> UpdateManager/UpdatesAvailable.py
675
676 # now do the changelog
677 name = item.pkg.name
678@@ -851,8 +907,13 @@ class UpdatesAvailable(InternalDialog):
679 self.button_pro.destroy()
680 elif (self.list.ubuntu_pro_fake_groups
681 and not self.list.ubuntu_pro_groups):
682+<<<<<<< UpdateManager/UpdatesAvailable.py
683 download_str = _("You need to enable Ubuntu Pro to install"
684 " these updates.")
685+=======
686+ download_str = _("You need to enable Ubuntu Pro to "
687+ "install these updates.")
688+>>>>>>> UpdateManager/UpdatesAvailable.py
689 self.button_install.destroy()
690 else:
691 download_str = _("There are no updates to install.")
692@@ -1140,7 +1201,11 @@ class UpdatesAvailable(InternalDialog):
693 UpdateData(groups, None, None),
694 humanize_size(total_size),
695 True,
696+<<<<<<< UpdateManager/UpdatesAvailable.py
697 sensitive,
698+=======
699+ sensitive
700+>>>>>>> UpdateManager/UpdatesAvailable.py
701 ]
702 return self.store.append(None, header_row)
703
704@@ -1163,16 +1228,23 @@ class UpdatesAvailable(InternalDialog):
705
706 if group.name == "Ubuntu base":
707 group.name = "System components"
708+<<<<<<< UpdateManager/UpdatesAvailable.py
709 name = group.name
710 if len(group.items) > 1:
711 name = '%s (%d)' % (group.name, len(group.items))
712
713+=======
714+>>>>>>> UpdateManager/UpdatesAvailable.py
715 group_row = [
716 name,
717 UpdateData(None, group, group_is_item),
718 humanize_size(group.get_total_size()),
719 True,
720+<<<<<<< UpdateManager/UpdatesAvailable.py
721 group.sensitive,
722+=======
723+ group.sensitive
724+>>>>>>> UpdateManager/UpdatesAvailable.py
725 ]
726 group_iter = self.store.append(None, group_row)
727
728@@ -1184,7 +1256,11 @@ class UpdatesAvailable(InternalDialog):
729 UpdateData(None, None, item),
730 humanize_size(getattr(item.pkg.candidate, "size", 0)),
731 True,
732+<<<<<<< UpdateManager/UpdatesAvailable.py
733 group.sensitive,
734+=======
735+ group.sensitive
736+>>>>>>> UpdateManager/UpdatesAvailable.py
737 ]
738 self.store.append(group_iter, item_row)
739
740@@ -1203,9 +1279,14 @@ class UpdatesAvailable(InternalDialog):
741
742 # add security and update groups to self.store
743 if self.list.oem_groups:
744+<<<<<<< UpdateManager/UpdatesAvailable.py
745 self._add_header(
746 _("Improved hardware support"), self.list.oem_groups
747 )
748+=======
749+ self._add_header(_("Improved hardware support"),
750+ self.list.oem_groups)
751+>>>>>>> UpdateManager/UpdatesAvailable.py
752 self._add_groups(self.list.oem_groups)
753 if self.list.security_groups:
754 self._add_header(_("Security updates"), self.list.security_groups)
755diff --git a/UpdateManager/backend/InstallBackendAptdaemon.py b/UpdateManager/backend/InstallBackendAptdaemon.py
756index 2959aa6..559faa7 100644
757--- a/UpdateManager/backend/InstallBackendAptdaemon.py
758+++ b/UpdateManager/backend/InstallBackendAptdaemon.py
759@@ -7,6 +7,7 @@ from gi.repository import Gtk
760
761 from aptdaemon import client, errors
762 from defer import inline_callbacks
763+<<<<<<< UpdateManager/backend/InstallBackendAptdaemon.py
764 from aptdaemon.gtk3widgets import (
765 AptCancelButton,
766 AptConfigFileConflictDialog,
767@@ -25,6 +26,22 @@ from aptdaemon.enums import (
768 get_error_string_from_enum,
769 get_status_string_from_enum,
770 )
771+=======
772+from aptdaemon.gtk3widgets import (AptCancelButton,
773+ AptConfigFileConflictDialog,
774+ AptDetailsExpander,
775+ AptMediumRequiredDialog,
776+ AptProgressBar)
777+from aptdaemon.enums import (EXIT_SUCCESS,
778+ EXIT_FAILED,
779+ STATUS_COMMITTING,
780+ STATUS_DOWNLOADING,
781+ STATUS_DOWNLOADING_REPO,
782+ STATUS_FINISHED,
783+ get_error_description_from_enum,
784+ get_error_string_from_enum,
785+ get_status_string_from_enum)
786+>>>>>>> UpdateManager/backend/InstallBackendAptdaemon.py
787
788 from UpdateManager.backend import InstallBackend
789 from UpdateManager.UnitySupport import UnitySupport
790@@ -39,10 +56,17 @@ import os
791 class UpdateManagerExpander(AptDetailsExpander):
792 """An AptDetailsExpander which can be used with multiple terminals.
793
794+<<<<<<< UpdateManager/backend/InstallBackendAptdaemon.py
795 The default AptDetailsExpander will shrink/hide when its transaction
796 finishes. But here we want to support "chaining" transactions. So we
797 override the status-changed handler to only do that when we are
798 running the final transaction."""
799+=======
800+ The default AptDetailsExpander will shrink/hide when its transaction
801+ finishes. But here we want to support "chaining" transactions. So we
802+ override the status-changed handler to only do that when we are
803+ running the final transaction."""
804+>>>>>>> UpdateManager/backend/InstallBackendAptdaemon.py
805
806 def __init__(self, transaction, terminal=True, final=False):
807 super().__init__(transaction, terminal)
808@@ -71,7 +95,11 @@ class UpdateManagerExpander(AptDetailsExpander):
809
810
811 class AptStackedProgressBar(Gtk.ProgressBar):
812+<<<<<<< UpdateManager/backend/InstallBackendAptdaemon.py
813 """A GtkProgressBar which represents the state of many aptdaemon
814+=======
815+ """ A GtkProgressBar which represents the state of many aptdaemon
816+>>>>>>> UpdateManager/backend/InstallBackendAptdaemon.py
817 transactions.
818
819 aptdaemon provides AptProgressBar for the state of *one* transaction to
820@@ -322,12 +350,130 @@ class InstallBackendAptdaemon(InstallBackend, BuilderDialog):
821 )
822 raise
823
824+ def _show_transaction_error(self, trans, action):
825+ error_string = get_error_string_from_enum(trans.error.code)
826+ error_desc = get_error_description_from_enum(trans.error.code)
827+ if self.trans_failed_msg:
828+ trans_failed = True
829+ error_desc = error_desc + "\n" + self.trans_failed_msg
830+ else:
831+ trans_failed = None
832+ self._action_done(action,
833+ authorized=True, success=False,
834+ error_string=error_string,
835+ error_desc=error_desc,
836+ trans_failed=trans_failed)
837+
838+ def _update_next_package(self, trans, status, action):
839+ if status == EXIT_FAILED:
840+ self._show_transaction_error(trans, action)
841+ return
842+ self._apt_update_oem()
843+
844+ @inline_callbacks
845+ def _apt_update_oem(self):
846+ assert self._oem_packages_to_update
847+ elem = self._oem_packages_to_update.pop()
848+ sources_list_file = f'/etc/apt/sources.list.d/{elem}.list'
849+
850+ try:
851+ if os.path.exists(sources_list_file):
852+ trans = yield self.client.update_cache(
853+ sources_list=sources_list_file
854+ )
855+ if self._oem_packages_to_update:
856+ finished_handler = self._update_next_package
857+ else:
858+ finished_handler = self._on_finished
859+
860+ yield self._show_transaction(
861+ trans,
862+ self.ACTION_PRE_INSTALL,
863+ _("Installing updates…"), True,
864+ on_finished_handler=finished_handler,
865+ progress_bar_max=0.1 / self._len_oem_updates
866+ )
867+ except errors.NotAuthorizedError:
868+ self._action_done(self.ACTION_PRE_INSTALL,
869+ authorized=False, success=False,
870+ error_string=None, error_desc=None)
871+ except errors.TransactionFailed as e:
872+ self.trans_failed_msg = str(e)
873+ except dbus.DBusException as e:
874+ if e.get_dbus_name() != "org.freedesktop.DBus.Error.NoReply":
875+ raise
876+ self._action_done(self.ACTION_PRE_INSTALL,
877+ authorized=False, success=False,
878+ error_string=None, error_desc=None)
879+ except Exception:
880+ self._action_done(self.ACTION_PRE_INSTALL,
881+ authorized=True, success=False,
882+ error_string=None, error_desc=None)
883+ raise
884+
885+ def _update_oem(self, trans, status, action):
886+ # This is the "finished" handler of installing an oem metapackage
887+ # What we do now is:
888+ # 1. update_cache() for the new sources.lists only
889+
890+ if status == EXIT_FAILED:
891+ self._show_transaction_error(trans, action)
892+ return
893+
894+ (install, _, _, _, _, _) = trans.packages
895+
896+ self._oem_packages_to_update = set(install)
897+ self._len_oem_updates = len(install)
898+
899+ self._apt_update_oem()
900+
901+ @inline_callbacks
902+ def commit_oem(self, pkgs_install_oem, pkgs_upgrade_oem):
903+ self.all_oem_packages = set(pkgs_install_oem) | set(pkgs_upgrade_oem)
904+ # Nothing to do? Go to the regular updates.
905+ try:
906+ if not pkgs_install_oem and not pkgs_upgrade_oem:
907+ self._action_done(self.ACTION_PRE_INSTALL,
908+ authorized=True, success=True,
909+ error_string=None, error_desc=None,
910+ trans_failed=None)
911+ return
912+
913+ if pkgs_install_oem:
914+ trans = yield self.client.install_packages(pkgs_install_oem,
915+ defer=True)
916+ yield self._show_transaction(
917+ trans,
918+ self.ACTION_PRE_INSTALL,
919+ _("Installing updates…"), True,
920+ on_finished_handler=self._update_oem,
921+ progress_bar_max=0.1
922+ )
923+ except errors.NotAuthorizedError:
924+ self._action_done(self.ACTION_PRE_INSTALL,
925+ authorized=False, success=False,
926+ error_string=None, error_desc=None)
927+ except errors.TransactionFailed as e:
928+ self.trans_failed_msg = str(e)
929+ except dbus.DBusException as e:
930+ if e.get_dbus_name() != "org.freedesktop.DBus.Error.NoReply":
931+ raise
932+ self._action_done(self.ACTION_PRE_INSTALL,
933+ authorized=False, success=False,
934+ error_string=None, error_desc=None)
935+ except Exception:
936+ self._action_done(self.ACTION_PRE_INSTALL,
937+ authorized=True, success=False,
938+ error_string=None, error_desc=None)
939+ raise
940+
941 @inline_callbacks
942 def commit(self, pkgs_install, pkgs_upgrade, pkgs_remove):
943 """Commit a list of package adds and removes"""
944 try:
945 reinstall = purge = downgrade = []
946 trans = yield self.client.commit_packages(
947+<<<<<<< UpdateManager/backend/InstallBackendAptdaemon.py
948 pkgs_install,
949 reinstall,
950 pkgs_remove,
951@@ -339,6 +485,12 @@ class InstallBackendAptdaemon(InstallBackend, BuilderDialog):
952 yield self._show_transaction(
953 trans, self.ACTION_INSTALL, _("Installing updates…"), True
954 )
955+=======
956+ pkgs_install, reinstall, pkgs_remove, purge, pkgs_upgrade,
957+ downgrade, defer=True)
958+ yield self._show_transaction(trans, self.ACTION_INSTALL,
959+ _("Installing updates…"), True)
960+>>>>>>> UpdateManager/backend/InstallBackendAptdaemon.py
961 except errors.NotAuthorizedError:
962 self._action_done(
963 self.ACTION_INSTALL,
964@@ -377,6 +529,7 @@ class InstallBackendAptdaemon(InstallBackend, BuilderDialog):
965 label_details.set_label(get_status_string_from_enum(status))
966 # Also resize the window if we switch from download details to
967 # the terminal window
968+<<<<<<< UpdateManager/backend/InstallBackendAptdaemon.py
969 if (
970 status == STATUS_COMMITTING
971 and self._expander
972@@ -394,6 +547,16 @@ class InstallBackendAptdaemon(InstallBackend, BuilderDialog):
973 progress_bar_max=1,
974 on_finished_handler=None,
975 ):
976+=======
977+ if status == STATUS_COMMITTING and self._expander \
978+ and self._expander.terminal.get_visible():
979+ self._resize_to_show_details(self._expander)
980+
981+ @inline_callbacks
982+ def _show_transaction(self, trans, action, header, show_details,
983+ progress_bar_max=1,
984+ on_finished_handler=None):
985+>>>>>>> UpdateManager/backend/InstallBackendAptdaemon.py
986
987 if on_finished_handler is None:
988 on_finished_handler = self._on_finished
989@@ -423,7 +586,12 @@ class InstallBackendAptdaemon(InstallBackend, BuilderDialog):
990 self._expander.set_vexpand(True)
991 self._expander.set_hexpand(True)
992 self._expander.show_all()
993+<<<<<<< UpdateManager/backend/InstallBackendAptdaemon.py
994 self._expander.connect("notify::expanded", self._on_expanded)
995+=======
996+ self._expander.connect("notify::expanded",
997+ self._on_expanded)
998+>>>>>>> UpdateManager/backend/InstallBackendAptdaemon.py
999 self.expander_slot.add(self._expander)
1000 self.expander_slot.show()
1001 else:
1002@@ -432,6 +600,7 @@ class InstallBackendAptdaemon(InstallBackend, BuilderDialog):
1003 elif self._expander:
1004 self._expander_slot.hide()
1005
1006+<<<<<<< UpdateManager/backend/InstallBackendAptdaemon.py
1007 trans.connect(
1008 "status-details-changed",
1009 self._on_details_changed,
1010@@ -440,6 +609,12 @@ class InstallBackendAptdaemon(InstallBackend, BuilderDialog):
1011 trans.connect(
1012 "status-changed", self._on_status_changed, self.label_details
1013 )
1014+=======
1015+ trans.connect("status-details-changed", self._on_details_changed,
1016+ self.label_details)
1017+ trans.connect("status-changed", self._on_status_changed,
1018+ self.label_details)
1019+>>>>>>> UpdateManager/backend/InstallBackendAptdaemon.py
1020 trans.connect("finished", on_finished_handler, action)
1021 trans.connect("medium-required", self._on_medium_required)
1022 trans.connect("config-file-conflict", self._on_config_file_conflict)
1023diff --git a/UpdateManager/backend/__init__.py b/UpdateManager/backend/__init__.py
1024index 72a6031..66a950f 100644
1025--- a/UpdateManager/backend/__init__.py
1026+++ b/UpdateManager/backend/__init__.py
1027@@ -50,9 +50,17 @@ class InstallBackend(Dialog):
1028 unfresh_pkg = unfresh_cache[pkg]
1029 fresh_pkg = fresh_cache[pkg]
1030
1031+<<<<<<< UpdateManager/backend/__init__.py
1032 if unfresh_pkg.marked_install and not fresh_pkg.is_installed:
1033 pkgs_install_oem.append(pkg)
1034 elif unfresh_pkg.marked_upgrade and fresh_pkg.is_upgradable:
1035+=======
1036+ if (unfresh_pkg.marked_install
1037+ and not fresh_pkg.is_installed):
1038+ pkgs_install_oem.append(pkg)
1039+ elif (unfresh_pkg.marked_upgrade
1040+ and fresh_pkg.is_upgradable):
1041+>>>>>>> UpdateManager/backend/__init__.py
1042 pkgs_upgrade_oem.append(pkg)
1043 self.commit_oem(pkgs_install_oem, pkgs_upgrade_oem)
1044 elif self.action == self.ACTION_INSTALL:
1045@@ -95,6 +103,7 @@ class InstallBackend(Dialog):
1046 raise NotImplementedError
1047
1048 def commit_oem(self, pkgs_install_oem, pkgs_upgrade_oem):
1049+<<<<<<< UpdateManager/backend/__init__.py
1050 """Install these OEM packages"""
1051 self._action_done(
1052 self.ACTION_PRE_INSTALL,
1053@@ -104,6 +113,13 @@ class InstallBackend(Dialog):
1054 error_desc=None,
1055 trans_failed=None,
1056 )
1057+=======
1058+ """ Install these OEM packages """
1059+ self._action_done(self.ACTION_PRE_INSTALL,
1060+ authorized=True, success=True,
1061+ error_string=None, error_desc=None,
1062+ trans_failed=None)
1063+>>>>>>> UpdateManager/backend/__init__.py
1064
1065 def commit(self, pkgs_install, pkgs_upgrade, pkgs_remove):
1066 """Commit the cache changes"""
1067@@ -379,18 +395,27 @@ class InstallBackend(Dialog):
1068 # close_after_install = settings.get_boolean(
1069 # "autoclose-install-window")
1070 # FIXME: confirm with mpt whether this should still be a setting
1071+<<<<<<< UpdateManager/backend/__init__.py
1072 # close_after_install = False
1073+=======
1074+ #close_after_install = False
1075+>>>>>>> UpdateManager/backend/__init__.py
1076
1077 if action == self.ACTION_PRE_INSTALL and success:
1078 # Now do the regular updates
1079 self.action = self.ACTION_INSTALL
1080 self.start()
1081 elif action == self.ACTION_INSTALL:
1082+<<<<<<< UpdateManager/backend/__init__.py
1083 if (
1084 success
1085 and os.path.exists("/usr/bin/snap")
1086 and hasattr(self, "pane_update_progress")
1087 ):
1088+=======
1089+ if (success and os.path.exists("/usr/bin/snap")
1090+ and hasattr(self, 'pane_update_progress')):
1091+>>>>>>> UpdateManager/backend/__init__.py
1092 Thread(target=self.update_snaps).start()
1093 elif success:
1094 self.window_main.start_available()
1095@@ -405,11 +430,16 @@ class InstallBackend(Dialog):
1096 else:
1097 if error_string:
1098 self.window_main.start_error(True, error_string, error_desc)
1099+<<<<<<< UpdateManager/backend/__init__.py
1100 elif (
1101 success
1102 and os.path.exists("/usr/bin/snap")
1103 and hasattr(self, "pane_update_progress")
1104 ):
1105+=======
1106+ elif (success and os.path.exists("/usr/bin/snap")
1107+ and hasattr(self, 'pane_update_progress')):
1108+>>>>>>> UpdateManager/backend/__init__.py
1109 self.window_main.duplicate_packages = self.get_deb2snap_dups()
1110 self.window_main.start_available()
1111 else:
1112diff --git a/data/gtkbuilder/UpdateManager.ui b/data/gtkbuilder/UpdateManager.ui
1113index 39daaad..6b1747e 100644
1114--- a/data/gtkbuilder/UpdateManager.ui
1115+++ b/data/gtkbuilder/UpdateManager.ui
1116@@ -7,7 +7,11 @@
1117 <property name="spacing">12</property>
1118 <!--
1119 https://launchpad.net/bugs/2045918
1120+<<<<<<< data/gtkbuilder/UpdateManager.ui
1121 Old widgets from previous version need to be kept, even though invisible,
1122+=======
1123+ Old widgets from 20.04.9 need to be kept, even though invisible, because
1124+>>>>>>> data/gtkbuilder/UpdateManager.ui
1125 otherwise updating Update Manager itself via Update Manager will crash when
1126 Update Manager recalculates itself. That is because the old Update Manager
1127 file is still the being executed, whereas this ui file will be the new one.
1128diff --git a/debian/changelog b/debian/changelog
1129index d9b2db4..7fd23be 100644
1130--- a/debian/changelog
1131+++ b/debian/changelog
1132@@ -1,3 +1,4 @@
1133+<<<<<<< debian/changelog
1134 update-manager (1:24.04.4) UNRELEASED; urgency=low
1135
1136 * d/control: Depend on ubuntu-advantage-tools >= 30~.
1137@@ -7,10 +8,22 @@ update-manager (1:24.04.4) UNRELEASED; urgency=low
1138 -- Nathan Pratta Teodosio <nathan.teodosio@canonical.com> Mon, 22 Jan 2024 08:17:25 +0100
1139
1140 update-manager (1:24.04.3) noble; urgency=medium
1141+=======
1142+update-manager (1:20.04.10.20) focal; urgency=medium
1143+
1144+ * The New Release dialog should take precedence over a list of updates dialog
1145+ if the latter would only show Ubuntu Pro updates in an unattached system.
1146+ (LP: #2051115).
1147+
1148+ -- Nathan Pratta Teodosio <nathan.teodosio@canonical.com> Thu, 25 Jan 2024 13:45:30 +0100
1149+
1150+update-manager (1:20.04.10.19) focal; urgency=medium
1151+>>>>>>> debian/changelog
1152
1153 * Add back removed widgets to UI file to fix crash when updating
1154 Upgrade Manager from inside itself (LP: #2045918).
1155
1156+<<<<<<< debian/changelog
1157 -- Nathan Pratta Teodosio <nathan.teodosio@canonical.com> Fri, 08 Dec 2023 11:25:51 +0100
1158
1159 update-manager (1:24.04.2) noble; urgency=medium
1160@@ -29,6 +42,33 @@ update-manager (1:24.04.1) noble; urgency=medium
1161 -- Nathan Pratta Teodosio <nathan.teodosio@canonical.com> Wed, 15 Nov 2023 11:45:02 +0100
1162
1163 update-manager (1:23.10.2) mantic; urgency=medium
1164+=======
1165+ -- Nathan Pratta Teodosio <nathan.teodosio@canonical.com> Fri, 08 Dec 2023 15:37:42 +0100
1166+
1167+update-manager (1:20.04.10.18) focal; urgency=medium
1168+
1169+ * Fix incorrect available version for Ubuntu Pro updates in unattached case
1170+ (LP: #2043425).
1171+
1172+ -- Nathan Pratta Teodosio <nathan.teodosio@canonical.com> Wed, 15 Nov 2023 11:28:54 +0100
1173+
1174+update-manager (1:20.04.10.17) focal; urgency=medium
1175+
1176+ * Ubuntu Pro (LP: #1990450):
1177+ - fix another linter error which was created while fixing a missing
1178+ space in the previous upload...
1179+
1180+ -- Sebastien Bacher <seb128@ubuntu.com> Fri, 06 Oct 2023 11:56:51 +0200
1181+
1182+update-manager (1:20.04.10.16) focal; urgency=medium
1183+
1184+ * Ubuntu Pro (LP: #1990450):
1185+ - Address linter errors that cause autopkgtest to fail.
1186+
1187+ -- Nathan Pratta Teodosio <nathan.teodosio@canonical.com> Wed, 04 Oct 2023 23:46:23 +0200
1188+
1189+update-manager (1:20.04.10.15) focal; urgency=medium
1190+>>>>>>> debian/changelog
1191
1192 * Ubuntu Pro (LP: #1990450):
1193 - Show Ubuntu Pro packages, whether the system is attached to Ubuntu Pro
1194@@ -39,6 +79,7 @@ update-manager (1:23.10.2) mantic; urgency=medium
1195 - Add News pane in a expander.
1196 - Replace notebook with Description and Changes tabs by a pane.
1197
1198+<<<<<<< debian/changelog
1199 -- Nathan Pratta Teodosio <nathan.teodosio@canonical.com> Mon, 25 Sep 2023 17:03:10 +0200
1200
1201 update-manager (1:23.10.1) mantic; urgency=medium
1202@@ -97,10 +138,35 @@ update-manager (1:22.10.4) kinetic; urgency=medium
1203 -- Steve Langasek <steve.langasek@ubuntu.com> Sun, 16 Oct 2022 23:26:08 -0700
1204
1205 update-manager (1:22.10.3) kinetic; urgency=medium
1206+=======
1207+ -- Nathan Pratta Teodosio <nathan.teodosio@canonical.com> Tue, 29 Aug 2023 07:47:20 +0200
1208+
1209+update-manager (1:20.04.10.14) focal; urgency=medium
1210+
1211+ * Fix Ubuntu Pro updates checkbox and expander widget from overlapping
1212+ (LP: #1990450)
1213+
1214+ -- Robert Ancell <robert.ancell@canonical.com> Fri, 03 Feb 2023 14:43:45 +1300
1215+
1216+update-manager (1:20.04.10.13) focal; urgency=medium
1217+
1218+ * Update of the parsing for pro client changes (lp: #1990450)
1219+
1220+ -- Sebastien Bacher <seb128@ubuntu.com> Thu, 26 Jan 2023 11:56:31 +0100
1221+
1222+update-manager (1:20.04.10.12) focal; urgency=medium
1223+
1224+ * Show pending Ubuntu pro packages (LP: #1990450)
1225+
1226+ -- Robert Ancell <robert.ancell@canonical.com> Wed, 18 Jan 2023 15:03:27 +1300
1227+
1228+update-manager (1:20.04.10.11) focal; urgency=medium
1229+>>>>>>> debian/changelog
1230
1231 [ Renan Rodrigo ]
1232 * ubuntu-security-status: Don't show ESM Apps information when the service
1233 is disabled, and prefer 'pro security-status' when it is available.
1234+<<<<<<< debian/changelog
1235
1236 -- Steve Langasek <steve.langasek@ubuntu.com> Mon, 03 Oct 2022 08:37:28 -0700
1237
1238@@ -182,11 +248,28 @@ update-manager (1:22.04.1) jammy; urgency=medium
1239 -- Brian Murray <brian@ubuntu.com> Mon, 18 Oct 2021 12:26:38 -0700
1240
1241 update-manager (1:21.10.4) impish; urgency=medium
1242+=======
1243+ (LP: #1991533)
1244+
1245+ -- Brian Murray <brian@ubuntu.com> Thu, 01 Dec 2022 11:10:57 -0800
1246+
1247+update-manager (1:20.04.10.10) focal; urgency=medium
1248+
1249+ * ubuntu-security-status: Check if ESM for Apps is enabled or if it is not
1250+ in beta before displaying information about the packages available from
1251+ there. Additionally, improve pluralization in a couple of locations.
1252+ (LP: #1955471)
1253+
1254+ -- Brian Murray <brian@ubuntu.com> Fri, 14 Jan 2022 10:28:42 -0800
1255+
1256+update-manager (1:20.04.10.9) focal; urgency=medium
1257+>>>>>>> debian/changelog
1258
1259 * ubuntu-security-status: use ubuntu-advantage-tools to determine whether or
1260 not livepatch or esm are enabled and if the system is attached. Thanks to
1261 Chad Smith for the patch. (LP: #1938043)
1262
1263+<<<<<<< debian/changelog
1264 -- Brian Murray <brian@ubuntu.com> Fri, 03 Sep 2021 14:43:22 -0700
1265
1266 update-manager (1:21.10.3) impish; urgency=medium
1267@@ -277,11 +360,65 @@ update-manager (1:21.04.3) hirsute; urgency=medium
1268 (LP: #1807900)
1269 * UpdateManager/backend/__init__.py: Resolve unbound local error crash with
1270 oem package lists. Thanks to Thomas Bechtold for the patch.
1271+=======
1272+ -- Brian Murray <brian@ubuntu.com> Fri, 03 Sep 2021 15:17:22 -0700
1273+
1274+update-manager (1:20.04.10.8) focal; urgency=medium
1275+
1276+ * tests/test_meta_release_core.py: switch a test from using lucid to bionic
1277+ as precise was removed from the archive. (LP: #1929865)
1278+
1279+ -- Brian Murray <brian@ubuntu.com> Thu, 27 May 2021 13:36:54 -0700
1280+
1281+update-manager (1:20.04.10.7) focal; urgency=medium
1282+
1283+ * tests/test_update_list.py: rewrite how APT::VersionedKernelPackages is set.
1284+ (LP: #1924809)
1285+ * debian/tests/control: add apt to the list of Depends.
1286+
1287+ -- Brian Murray <brian@ubuntu.com> Fri, 16 Apr 2021 16:25:21 -0700
1288+
1289+update-manager (1:20.04.10.6) focal; urgency=medium
1290+
1291+ * UpdateManager/Core/UpdateList.py: change to a regex from a static list
1292+ of packages to be grouped under Ubuntu Base (LP: #1902025)
1293+ * Clean up apt cache binary files left behind by tests
1294+ * Rename meta_pkgs to ubuntu_base_pkgs to make it more clear to the
1295+ reader which packages should be included
1296+ * Add tests in to ensure Ubuntu base packages are not grouped when
1297+ staged for removal (LP: #1912718)
1298+
1299+ -- William 'jawn-smith' Wilson <william.wilson@canonical.com> Wed, 10 Feb 2021 14:39:27 -0600
1300+
1301+update-manager (1:20.04.10.5) focal; urgency=medium
1302+
1303+ * UpdateManager/backend/__init__.py: Really make commit_oem a no-op in the
1304+ base class to avoid crash when people force synaptic backend (LP: #1913732)
1305+ * Fix typo in previous changelog
1306+
1307+ -- Julian Andres Klode <juliank@ubuntu.com> Fri, 29 Jan 2021 17:43:01 +0100
1308+
1309+update-manager (1:20.04.10.4) focal; urgency=medium
1310+
1311+ * Revert previous change to UpdateList.py, as it breaks kernel
1312+ autoremoval (LP: #1912718)
1313+ * UpdateManager/backend/__init__.py: Make commit_oem a no-op in the base
1314+ class to avoid crash when people force synaptic backend (LP: #1913732)
1315+
1316+ -- Julian Andres Klode <juliank@ubuntu.com> Fri, 29 Jan 2021 12:50:23 +0100
1317+
1318+update-manager (1:20.04.10.3) focal; urgency=medium
1319+
1320+ [ Julian Andres Klode ]
1321+ * UpdateManager/backend/__init__.py: Fix unbound local variables regression
1322+ introduced by the previous SRU (See LP 1910556), and correct comment
1323+>>>>>>> debian/changelog
1324
1325 [ William Wilson ]
1326 * UpdateManager/Core/UpdateList.py: change to a regex from a static list
1327 of packages to be grouped under Ubuntu Base (LP: #1902025)
1328
1329+<<<<<<< debian/changelog
1330 -- Brian Murray <brian@ubuntu.com> Fri, 08 Jan 2021 08:41:47 -0800
1331
1332 update-manager (1:21.04.2) hirsute; urgency=medium
1333@@ -297,10 +434,16 @@ update-manager (1:21.04.1) hirsute; urgency=medium
1334 * UpdateManager/UpdatesAvailable.py: In the technical description portion of
1335 the Software Update window display the package name in the Description
1336 tab. Thanks to Jarkko Toivonen for the patch.
1337+=======
1338+ -- Brian Murray <brian@ubuntu.com> Wed, 13 Jan 2021 08:35:58 -0800
1339+
1340+update-manager (1:20.04.10.2) focal; urgency=medium
1341+>>>>>>> debian/changelog
1342
1343 [ Iain Lane & Julian Andres Klode ]
1344 * Support post install enablement of OEM-enabled devices (LP: #1908050)
1345
1346+<<<<<<< debian/changelog
1347 -- Julian Andres Klode <juliank@ubuntu.com> Mon, 14 Dec 2020 11:32:03 +0100
1348
1349 update-manager (1:20.10.1) groovy; urgency=medium
1350@@ -319,13 +462,25 @@ update-manager (1:20.04.12) groovy; urgency=medium
1351 -- Marcus Tomlinson <marcus.tomlinson@canonical.com> Thu, 28 May 2020 10:11:51 +0100
1352
1353 update-manager (1:20.04.11) groovy; urgency=medium
1354+=======
1355+ -- Julian Andres Klode <juliank@ubuntu.com> Mon, 14 Dec 2020 12:24:18 +0100
1356+
1357+update-manager (1:20.04.10.1) focal; urgency=medium
1358+>>>>>>> debian/changelog
1359
1360 * UpdateManager/UpdateManager.py: when refreshing the cache and encountering
1361 an error return rather than trying to use the undefined cache which causes
1362 crashes. Additionally, don't present the dialog with a "Try Again" button
1363 which won't do anything. (LP: #1826213)
1364+<<<<<<< debian/changelog
1365
1366 -- Brian Murray <brian@ubuntu.com> Wed, 27 May 2020 13:29:24 -0700
1367+=======
1368+ * Fix hang in apturl-gtk. (LP: #1874591)
1369+ * Fix crash in snap updates when refreshing the cache fails. (LP: #1880987)
1370+
1371+ -- Brian Murray <brian@ubuntu.com> Wed, 03 Jun 2020 10:18:00 -0700
1372+>>>>>>> debian/changelog
1373
1374 update-manager (1:20.04.10) focal; urgency=medium
1375
1376diff --git a/debian/control b/debian/control
1377index 8acd880..27fbee5 100644
1378--- a/debian/control
1379+++ b/debian/control
1380@@ -23,6 +23,7 @@ XS-Testsuite: autopkgtest
1381 Package: update-manager-core
1382 Architecture: all
1383 Section: admin
1384+<<<<<<< debian/control
1385 Depends: distro-info-data,
1386 python3-distro-info,
1387 python3-update-manager (= ${source:Version}),
1388@@ -34,6 +35,20 @@ Recommends: libpam-modules (>= 1.0.1-9ubuntu3),
1389 Replaces: update-manager (<< 1:0.146.2),
1390 Breaks: computer-janitor (<= 1.11-0ubuntu1),
1391 update-manager (<< 1:0.146.2),
1392+=======
1393+Depends: ${python3:Depends},
1394+ ${misc:Depends},
1395+ python3-update-manager (= ${source:Version}),
1396+ python3-distro-info,
1397+ distro-info-data,
1398+ lsb-release,
1399+ ubuntu-release-upgrader-core (>= 1:18.04.9),
1400+ ubuntu-advantage-tools
1401+Recommends: libpam-modules (>= 1.0.1-9ubuntu3)
1402+Replaces: update-manager (<< 1:0.146.2)
1403+Breaks: update-manager (<< 1:0.146.2),
1404+ computer-janitor (<= 1.11-0ubuntu1)
1405+>>>>>>> debian/control
1406 Description: manage release upgrades
1407 This is the core of update-manager and the release upgrader
1408
1409@@ -56,6 +71,7 @@ Description: Python 3.x module for update-manager
1410
1411 Package: update-manager
1412 Architecture: all
1413+<<<<<<< debian/control
1414 Depends: gir1.2-gtk-3.0,
1415 gir1.2-handy-1 (>= 1.5.90),
1416 gir1.2-snapd-2,
1417@@ -64,17 +80,31 @@ Depends: gir1.2-gtk-3.0,
1418 pkexec,
1419 polkitd,
1420 python3-aptdaemon.gtk3widgets (>= 1.1.1+bzr982-0ubuntu13) | synaptic,
1421+=======
1422+Depends: ${python3:Depends}, ${misc:Depends},
1423+ update-manager-core (= ${source:Version}),
1424+ libgtk3-perl,
1425+ python3-aptdaemon.gtk3widgets (>= 1.1.1+bzr982-0ubuntu13) | synaptic,
1426+ policykit-1,
1427+>>>>>>> debian/control
1428 python3-dbus,
1429 python3-gi (>= 3.8),
1430 python3-yaml,
1431 ubuntu-release-upgrader-gtk,
1432 update-manager-core (= ${source:Version}),
1433 update-notifier,
1434+<<<<<<< debian/control
1435 ${misc:Depends},
1436 ${python3:Depends},
1437 Breaks: update-notifier (<< 3.177),
1438 Recommends: python3-launchpadlib,
1439 software-properties-gtk (>= 0.71.2),
1440+=======
1441+ gnome-shell | policykit-1-gnome | polkit-kde-agent-1 | lxpolkit | lxqt-policykit | mate-polkit | polkit-1-auth-agent
1442+Breaks: update-notifier (<< 3.177)
1443+Recommends: software-properties-gtk (>= 0.71.2),
1444+ python3-launchpadlib
1445+>>>>>>> debian/control
1446 Suggests: gir1.2-dbusmenu-glib-0.4,
1447 gir1.2-unity-5.0,
1448 Description: GNOME application that manages apt updates
1449diff --git a/debian/tests/control b/debian/tests/control
1450index 53f3d17..560af6e 100644
1451--- a/debian/tests/control
1452+++ b/debian/tests/control
1453@@ -1,4 +1,5 @@
1454 Tests: nose-tests
1455+<<<<<<< debian/tests/control
1456 Depends: apt,
1457 aptdaemon,
1458 pycodestyle,
1459@@ -7,3 +8,6 @@ Depends: apt,
1460 python3-nose,
1461 xvfb,
1462 @,
1463+=======
1464+Depends: @, apt, aptdaemon, pycodestyle, pyflakes3, python3-mock, python3-nose, xvfb
1465+>>>>>>> debian/tests/control
1466diff --git a/tests/test_cache.py b/tests/test_cache.py
1467index 432de84..f842e43 100644
1468--- a/tests/test_cache.py
1469+++ b/tests/test_cache.py
1470@@ -36,7 +36,12 @@ class TestCache(unittest.TestCase):
1471
1472 def tearDown(self):
1473 try:
1474+<<<<<<< tests/test_cache.py
1475 shutil.rmtree(os.path.join(self.aptroot, "var/cache/apt"))
1476+=======
1477+ shutil.rmtree(os.path.join(self.aptroot,
1478+ "var/cache/apt"))
1479+>>>>>>> tests/test_cache.py
1480 except OSError:
1481 pass
1482
1483diff --git a/tests/test_changelog.py b/tests/test_changelog.py
1484index 41ced26..728fb29 100644
1485--- a/tests/test_changelog.py
1486+++ b/tests/test_changelog.py
1487@@ -7,6 +7,13 @@ import os
1488 import sys
1489 import unittest
1490 import glob
1491+<<<<<<< tests/test_changelog.py
1492+=======
1493+try:
1494+ from urllib.error import HTTPError
1495+except ImportError:
1496+ from urllib2 import HTTPError
1497+>>>>>>> tests/test_changelog.py
1498
1499 from urllib.error import HTTPError
1500 from UpdateManager.Core.MyCache import MyCache
1501@@ -28,9 +35,14 @@ class TestChangelogs(unittest.TestCase):
1502
1503 self.aptroot = os.path.join(CURDIR, "aptroot-changelog")
1504
1505+<<<<<<< tests/test_changelog.py
1506 self.cache = MyCache(
1507 apt.progress.base.OpProgress(), rootdir=self.aptroot
1508 )
1509+=======
1510+ self.cache = MyCache(apt.progress.base.OpProgress(),
1511+ rootdir=self.aptroot)
1512+>>>>>>> tests/test_changelog.py
1513 self.cache.open()
1514
1515 def tearDown(self):
1516diff --git a/tests/test_meta_release_core.py b/tests/test_meta_release_core.py
1517index 954a0ba..7d15aa8 100644
1518--- a/tests/test_meta_release_core.py
1519+++ b/tests/test_meta_release_core.py
1520@@ -9,6 +9,14 @@ import os
1521 import random
1522 import sys
1523 import tempfile
1524+<<<<<<< tests/test_meta_release_core.py
1525+=======
1526+import glob
1527+try:
1528+ from test.support import EnvironmentVarGuard
1529+except ImportError:
1530+ from test.test_support import EnvironmentVarGuard
1531+>>>>>>> tests/test_meta_release_core.py
1532 import time
1533 import unittest
1534
1535@@ -81,9 +89,15 @@ class TestMetaReleaseCore(unittest.TestCase):
1536 self.httpd_process.join()
1537 install_opener(None)
1538
1539+<<<<<<< tests/test_meta_release_core.py
1540 bin_list = glob.glob(
1541 os.path.join(CURDIR, "aptroot-changelog/var/cache/apt/*.bin")
1542 )
1543+=======
1544+ bin_list = glob.glob(os.path.join(CURDIR,
1545+ "aptroot-changelog/"
1546+ "var/cache/apt/*.bin"))
1547+>>>>>>> tests/test_meta_release_core.py
1548 for bin_file in bin_list:
1549 try:
1550 os.remove(bin_file)
1551@@ -186,7 +200,11 @@ class TestMetaReleaseCore(unittest.TestCase):
1552 supported for supported in di.supported() if di.is_lts(supported)
1553 ]
1554 with EnvironmentVarGuard() as environ:
1555+<<<<<<< tests/test_meta_release_core.py
1556 environ["META_RELEASE_FAKE_CODENAME"] = ltses[-2]
1557+=======
1558+ environ["META_RELEASE_FAKE_CODENAME"] = "bionic"
1559+>>>>>>> tests/test_meta_release_core.py
1560 meta = MetaReleaseCore(forceDownload=True)
1561 while meta.downloading:
1562 time.sleep(0.1)
1563diff --git a/tests/test_update_list.py b/tests/test_update_list.py
1564index 93dfe66..ebd2b60 100644
1565--- a/tests/test_update_list.py
1566+++ b/tests/test_update_list.py
1567@@ -34,7 +34,12 @@ class PhasedTestCase(unittest.TestCase):
1568
1569 def tearDown(self):
1570 try:
1571+<<<<<<< tests/test_update_list.py
1572 shutil.rmtree(os.path.join(self.aptroot, "var/cache/apt"))
1573+=======
1574+ shutil.rmtree(os.path.join(self.aptroot,
1575+ "var/cache/apt"))
1576+>>>>>>> tests/test_update_list.py
1577 except OSError:
1578 pass
1579
1580@@ -129,8 +134,12 @@ class GroupingTestCase(unittest.TestCase):
1581 real_arch = apt.apt_pkg.config.find("APT::Architecture")
1582 apt.apt_pkg.config.set("APT::Architecture", "amd64")
1583 self.addCleanup(
1584+<<<<<<< tests/test_update_list.py
1585 lambda: apt.apt_pkg.config.set("APT::Architecture", real_arch)
1586 )
1587+=======
1588+ lambda: apt.apt_pkg.config.set("APT::Architecture", real_arch))
1589+>>>>>>> tests/test_update_list.py
1590
1591 def set_versioned_kernel_pkgs(real_versioned_kernel_pkgs):
1592 apt.apt_pkg.config.clear("APT::VersionedKernelPackages")
1593@@ -141,6 +150,7 @@ class GroupingTestCase(unittest.TestCase):
1594 real_versioned_kernel_pkgs = apt.apt_pkg.config.value_list()
1595 set_versioned_kernel_pkgs(["linux-.*"])
1596 self.addCleanup(
1597+<<<<<<< tests/test_update_list.py
1598 lambda: set_versioned_kernel_pkgs(real_versioned_kernel_pkgs)
1599 )
1600
1601@@ -148,11 +158,20 @@ class GroupingTestCase(unittest.TestCase):
1602 self.cache = MyCache(
1603 apt.progress.base.OpProgress(), rootdir=self.aptroot
1604 )
1605+=======
1606+ lambda: set_versioned_kernel_pkgs(real_versioned_kernel_pkgs))
1607+
1608+ self.aptroot = os.path.join(CURDIR,
1609+ "aptroot-grouping-test")
1610+ self.cache = MyCache(apt.progress.base.OpProgress(),
1611+ rootdir=self.aptroot)
1612+>>>>>>> tests/test_update_list.py
1613 self.cache.open()
1614 self.cache["linux-generic-to-remove"].mark_auto(True)
1615 self.cache["linux-headers-to-remove"].mark_auto(True)
1616 mock_installed.__get__ = self.fake_installed_files
1617 mock_desktop.side_effect = self.fake_desktop
1618+<<<<<<< tests/test_update_list.py
1619 self.updates_list = UpdateList.UpdateList(parent=None, dist="lucid")
1620 self.updates_list.update(
1621 self.cache,
1622@@ -162,6 +181,17 @@ class GroupingTestCase(unittest.TestCase):
1623 def tearDown(self):
1624 try:
1625 shutil.rmtree(os.path.join(self.aptroot, "var/cache/apt"))
1626+=======
1627+ self.updates_list = UpdateList.UpdateList(parent=None, dist='lucid')
1628+ self.updates_list.update(self.cache,
1629+ duplicate_packages=["linux-generic-dup1",
1630+ "linux-generic-dup2"])
1631+
1632+ def tearDown(self):
1633+ try:
1634+ shutil.rmtree(os.path.join(self.aptroot,
1635+ "var/cache/apt"))
1636+>>>>>>> tests/test_update_list.py
1637 except OSError:
1638 pass
1639
1640@@ -219,22 +249,35 @@ class GroupingTestCase(unittest.TestCase):
1641 group = self.updates_list.update_groups[3]
1642 self.assertIsInstance(group, UpdateList.UpdatePackageGroup)
1643 self.assertIsNotNone(group.core_item)
1644+<<<<<<< tests/test_update_list.py
1645 self.assertEqual(group.core_item.pkg.name, "linux-show-player")
1646 self.assertListEqual(
1647 [x.pkg.name for x in group.items], ["linux-show-player"]
1648 )
1649+=======
1650+ self.assertEqual(group.core_item.pkg.name, 'linux-show-player')
1651+ self.assertListEqual([x.pkg.name for x in group.items],
1652+ ['linux-show-player'])
1653+>>>>>>> tests/test_update_list.py
1654
1655 def test_pkg_multiple_deps(self):
1656 self.assertGreater(len(self.updates_list.update_groups), 4)
1657 group = self.updates_list.update_groups[4]
1658 self.assertIsInstance(group, UpdateList.UpdatePackageGroup)
1659 self.assertIsNotNone(group.core_item)
1660+<<<<<<< tests/test_update_list.py
1661 self.assertEqual(
1662 group.core_item.pkg.name, "installed-pkg-multiple-deps"
1663 )
1664 self.assertListEqual(
1665 [x.pkg.name for x in group.items], ["installed-pkg-multiple-deps"]
1666 )
1667+=======
1668+ self.assertEqual(group.core_item.pkg.name,
1669+ 'installed-pkg-multiple-deps')
1670+ self.assertListEqual([x.pkg.name for x in group.items],
1671+ ['installed-pkg-multiple-deps'])
1672+>>>>>>> tests/test_update_list.py
1673
1674 def test_security(self):
1675 self.assertEqual(len(self.updates_list.security_groups), 1)
1676@@ -291,6 +334,49 @@ class GroupingTestCase(unittest.TestCase):
1677 [x.pkg.name for x in group.items], ["linux-generic-dup2"]
1678 )
1679
1680+ def test_base_grouping(self):
1681+ self.assertEqual(len(self.updates_list.update_groups), 6)
1682+ group = self.updates_list.update_groups[5]
1683+ self.assertIsInstance(group, UpdateList.UpdateSystemGroup)
1684+ self.assertIsNone(group.core_item)
1685+ self.assertListEqual([x.pkg.name for x in group.items],
1686+ ['ubuntu-minimal',
1687+ 'linux-test-hwe'])
1688+
1689+ def test_autoremove_grouping(self):
1690+ # test that packages staged for removal aren't grouped if they are
1691+ # kernel autoremove packages (LP: #1912718)
1692+ self.assertGreater(len(self.updates_list.kernel_autoremove_groups), 0)
1693+ group = self.updates_list.kernel_autoremove_groups[0]
1694+ self.assertIsInstance(group, UpdateList.UpdatePackageGroup)
1695+ self.assertIsNotNone(group.core_item)
1696+ self.assertListEqual([x.pkg.name for x in group.items],
1697+ ['linux-generic-to-remove'])
1698+
1699+ self.assertEqual(len(self.updates_list.kernel_autoremove_groups), 2)
1700+ group = self.updates_list.kernel_autoremove_groups[1]
1701+ self.assertIsInstance(group, UpdateList.UpdatePackageGroup)
1702+ self.assertIsNotNone(group.core_item)
1703+ self.assertListEqual([x.pkg.name for x in group.items],
1704+ ['linux-headers-to-remove'])
1705+
1706+ def test_duplicate_grouping(self):
1707+ # test that packages staged for removal aren't grouped if they are
1708+ # duplicate packages (LP: #1912718)
1709+ self.assertGreater(len(self.updates_list.duplicate_groups), 0)
1710+ group = self.updates_list.duplicate_groups[0]
1711+ self.assertIsInstance(group, UpdateList.UpdatePackageGroup)
1712+ self.assertIsNotNone(group.core_item)
1713+ self.assertListEqual([x.pkg.name for x in group.items],
1714+ ['linux-generic-dup1'])
1715+
1716+ self.assertEqual(len(self.updates_list.duplicate_groups), 2)
1717+ group = self.updates_list.duplicate_groups[1]
1718+ self.assertIsInstance(group, UpdateList.UpdatePackageGroup)
1719+ self.assertIsNotNone(group.core_item)
1720+ self.assertListEqual([x.pkg.name for x in group.items],
1721+ ['linux-generic-dup2'])
1722+
1723
1724 if __name__ == "__main__":
1725 unittest.main()

Subscribers

People subscribed via source and target branches