Merge ~nteodosio/update-manager:bionic-ua into update-manager:main

Proposed by Nathan Teodosio
Status: Superseded
Proposed branch: ~nteodosio/update-manager:bionic-ua
Merge into: update-manager:main
Diff against target: 2128 lines (+863/-137) (has conflicts)
21 files modified
.gitignore (+2/-0)
HweSupportStatus/consts.py (+26/-0)
UpdateManager/Core/MetaRelease.py (+14/-0)
UpdateManager/Core/UpdateList.py (+129/-0)
UpdateManager/Core/utils.py (+17/-0)
UpdateManager/Dialogs.py (+28/-1)
UpdateManager/UpdateManager.py (+120/-14)
UpdateManager/UpdateManagerVersion.py (+4/-0)
UpdateManager/UpdatesAvailable.py (+105/-17)
UpdateManager/backend/InstallBackendAptdaemon.py (+30/-0)
UpdateManager/backend/__init__.py (+56/-0)
data/gtkbuilder/UpdateManager.ui (+44/-105)
debian/changelog (+133/-0)
debian/control (+3/-0)
hwe-support-status (+5/-0)
tests/test_backend_error.py (+36/-0)
tests/test_hwe_support_status.py (+8/-0)
tests/test_meta_release_core.py (+22/-0)
tests/test_pep8.py (+42/-0)
tests/test_proxy.py (+31/-0)
tests/test_update_error.py (+8/-0)
Conflict in HweSupportStatus/consts.py
Conflict in UpdateManager/Core/MetaRelease.py
Conflict in UpdateManager/Core/UpdateList.py
Conflict in UpdateManager/Core/utils.py
Conflict in UpdateManager/Dialogs.py
Conflict in UpdateManager/UpdateManager.py
Conflict in UpdateManager/UpdateManagerVersion.py
Conflict in UpdateManager/UpdatesAvailable.py
Conflict in UpdateManager/backend/InstallBackendAptdaemon.py
Conflict in UpdateManager/backend/__init__.py
Conflict in debian/changelog
Conflict in debian/control
Conflict in hwe-support-status
Conflict in tests/test_backend_error.py
Conflict in tests/test_hwe_support_status.py
Conflict in tests/test_meta_release_core.py
Conflict in tests/test_pep8.py
Conflict in tests/test_proxy.py
Conflict in tests/test_pycodestyle.py
Conflict in tests/test_update_error.py
Reviewer Review Type Date Requested Status
Elio Qoshi Pending
Sebastien Bacher Pending
Review via email: mp+446967@code.launchpad.net

Description of the change

Implement the redesign of Ubuntu Pro in Update Manager.

PPA: https://launchpad.net/~nteodosio/+archive/ubuntu/ubuntu-pro/+packages

Still doesn't display Ubuntu Pro packages as such when already attached, rather they're listed as normal updates.

Main differences are:

    - Fuse the description and changes tabs into a single view, which is
      now separated with a GtkPaned widget from the tree widget above.
    - Add button to attach to enable Ubuntu Pro if it is the only action
      available.
    - Ubuntu base -> System components.
    - Fix Ubuntu Pro item not being a parent group of its corresponding
      packages.

To post a comment you must log in.

Unmerged commits

aa9b49f... by Nathan Teodosio

Add gitignore file.

2a11578... by Nathan Teodosio

Update change log.

bd22c4a... by Nathan Teodosio

Implement the new Ubuntu Pro design.

- Fuse the description and changes tabs into a single view.
- Add button to attach to enable Ubuntu Pro if it is the only action
  available.
- Ubuntu base -> System components.
- Fix Ubuntu Pro item not being a parent group of its corresponding
  packages.

48d6735... by Robert Ancell

releasing package update-manager version 1:18.04.11.17

1ab7416... by Robert Ancell

Fix Ubuntu Pro updates checkbox and expander widget from overlapping

67a1fd6... by Sebastien Bacher

releasing package update-manager version 1:18.04.11.16

1a006d9... by Sebastien Bacher

Update of the parsing for pro client changes (lp: #1990450)

b181652... by Robert Ancell

Show pending Ubuntu pro packages (LP: #1990450)

1f906b8... by Brian Murray

tests/test_meta_release_core.py: switch a test from using lucid to bionic as precise was removed from the archive. (LP: #1929865)

9dbf545... by Brian Murray

UpdateManager/UpdateManager.py: when refreshing the cache and encountering an error return rather than trying to use the undefined cache which causes crashes. Additionally, don't present the dialog with a "Try Again" button which won't do anything. (LP: #1826213)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/.gitignore b/.gitignore
2new file mode 100644
3index 0000000..0370a5e
4--- /dev/null
5+++ b/.gitignore
6@@ -0,0 +1,2 @@
7+tags
8+__pycache__
9diff --git a/HweSupportStatus/consts.py b/HweSupportStatus/consts.py
10index 433b5b5..9dd7c56 100644
11--- a/HweSupportStatus/consts.py
12+++ b/HweSupportStatus/consts.py
13@@ -6,6 +6,7 @@ from gettext import gettext as _
14
15
16 # the day on which the short support HWE stack goes EoL
17+<<<<<<< HweSupportStatus/consts.py
18 HWE_EOL_DATE = datetime.date(2027, 4, 30)
19
20 # the day on which the next LTS first point release is available
21@@ -14,6 +15,16 @@ NEXT_LTS_DOT1_DATE = datetime.date(2024, 7, 15)
22
23 # end of the month in which this LTS goes EoL
24 LTS_EOL_DATE = datetime.date(2027, 4, 30)
25+=======
26+HWE_EOL_DATE = datetime.date(2023, 4, 30)
27+
28+# the day on which the next LTS first point release is available
29+# used to propose a release upgrade
30+NEXT_LTS_DOT1_DATE = datetime.date(2020, 7, 21)
31+
32+# end of the month in which this LTS goes EoL
33+LTS_EOL_DATE = datetime.date(2023, 4, 30)
34+>>>>>>> HweSupportStatus/consts.py
35
36
37 class Messages:
38@@ -33,7 +44,11 @@ in the Dash.
39 """
40 To upgrade to a supported (or longer-supported) configuration:
41
42+<<<<<<< HweSupportStatus/consts.py
43 * Upgrade from Ubuntu 20.04 LTS to Ubuntu 22.04 LTS by running:
44+=======
45+* Upgrade from Ubuntu 16.04 LTS to Ubuntu 18.04 LTS by running:
46+>>>>>>> HweSupportStatus/consts.py
47 sudo do-release-upgrade %s
48
49 OR
50@@ -69,6 +84,7 @@ on %s. After this date security updates for critical parts (kernel
51 and graphics stack) of your system will no longer be available.
52
53 For more information, please see:
54+<<<<<<< HweSupportStatus/consts.py
55 http://wiki.ubuntu.com/2204_HWE_EOL
56 """
57 )
58@@ -85,3 +101,13 @@ Stack ended on %s:
59 )
60 % HWE_EOL_DATE.isoformat()
61 )
62+=======
63+http://wiki.ubuntu.com/1604_HWE_EOL
64+""") % HWE_EOL_DATE.isoformat()
65+
66+ HWE_SUPPORT_HAS_ENDED = _("""
67+WARNING: Security updates for your current Hardware Enablement
68+Stack ended on %s:
69+ * http://wiki.ubuntu.com/1604_HWE_EOL
70+""") % HWE_EOL_DATE.isoformat()
71+>>>>>>> HweSupportStatus/consts.py
72diff --git a/UpdateManager/Core/MetaRelease.py b/UpdateManager/Core/MetaRelease.py
73index 9a485c4..ce90be0 100644
74--- a/UpdateManager/Core/MetaRelease.py
75+++ b/UpdateManager/Core/MetaRelease.py
76@@ -155,13 +155,20 @@ class MetaReleaseCore(object):
77 return
78 # now check which specific url to use
79 if parser.has_option("DEFAULT", "Prompt"):
80+<<<<<<< UpdateManager/Core/MetaRelease.py
81 prompt = parser.get("DEFAULT", "Prompt").lower()
82 if prompt == "never" or prompt == "no":
83 self.prompt = "never"
84+=======
85+ type = parser.get("DEFAULT", "Prompt").lower()
86+ if (type == "never" or type == "no"):
87+ self.prompt = 'never'
88+>>>>>>> UpdateManager/Core/MetaRelease.py
89 # nothing to do for this object
90 # FIXME: what about no longer supported?
91 self.downloaded.set()
92 return
93+<<<<<<< UpdateManager/Core/MetaRelease.py
94 elif prompt == "lts":
95 self.prompt = "lts"
96 # the Prompt=lts setting only makes sense when running on
97@@ -174,6 +181,13 @@ class MetaReleaseCore(object):
98 self._debug("Prompt=lts for non-LTS, ignoring")
99 else:
100 self.prompt = "normal"
101+=======
102+ elif type == "lts":
103+ self.prompt = 'lts'
104+ self.METARELEASE_URI = self.METARELEASE_URI_LTS
105+ else:
106+ self.prompt = 'normal'
107+>>>>>>> UpdateManager/Core/MetaRelease.py
108 # needed for the _tryUpgradeSelf() code in DistUpgradeController
109 if forceLTS:
110 self.METARELEASE_URI = self.METARELEASE_URI_LTS
111diff --git a/UpdateManager/Core/UpdateList.py b/UpdateManager/Core/UpdateList.py
112index 80b900b..d902561 100644
113--- a/UpdateManager/Core/UpdateList.py
114+++ b/UpdateManager/Core/UpdateList.py
115@@ -43,7 +43,11 @@ from gi.repository import Gio
116 from UpdateManager.Core import utils
117
118
119+<<<<<<< UpdateManager/Core/UpdateList.py
120 class UpdateItem:
121+=======
122+class UpdateItem():
123+>>>>>>> UpdateManager/Core/UpdateList.py
124 def __init__(self, pkg, name, icon, to_remove, sensitive=True):
125 self.icon = icon
126 self.name = name
127@@ -76,6 +80,7 @@ class UpdateGroup(UpdateItem):
128 all_items.extend(self._items)
129 return sorted(all_items, key=lambda a: a.name.lower())
130
131+<<<<<<< UpdateManager/Core/UpdateList.py
132 def add(
133 self,
134 pkg,
135@@ -84,6 +89,10 @@ class UpdateGroup(UpdateItem):
136 to_remove=False,
137 sensitive=True,
138 ):
139+=======
140+ def add(self, pkg, cache=None, eventloop_callback=None, to_remove=False,
141+ sensitive=True):
142+>>>>>>> UpdateManager/Core/UpdateList.py
143 name = utils.get_package_label(pkg)
144 icon = Gio.ThemedIcon.new("package")
145 self._items.add(UpdateItem(pkg, name, icon, to_remove, sensitive))
146@@ -168,18 +177,28 @@ class UpdateApplicationGroup(UpdateGroup):
147 def __init__(self, pkg, application, to_remove, sensitive=True):
148 name = application.get_display_name()
149 icon = application.get_icon()
150+<<<<<<< UpdateManager/Core/UpdateList.py
151 super(UpdateApplicationGroup, self).__init__(
152 pkg, name, icon, to_remove, sensitive
153 )
154+=======
155+ super(UpdateApplicationGroup, self).__init__(pkg, name, icon,
156+ to_remove, sensitive)
157+>>>>>>> UpdateManager/Core/UpdateList.py
158
159
160 class UpdatePackageGroup(UpdateGroup):
161 def __init__(self, pkg, to_remove, sensitive=True):
162 name = utils.get_package_label(pkg)
163 icon = Gio.ThemedIcon.new("package")
164+<<<<<<< UpdateManager/Core/UpdateList.py
165 super(UpdatePackageGroup, self).__init__(
166 pkg, name, icon, to_remove, sensitive
167 )
168+=======
169+ super(UpdatePackageGroup, self).__init__(pkg, name, icon, to_remove,
170+ sensitive)
171+>>>>>>> UpdateManager/Core/UpdateList.py
172
173
174 class UpdateSystemGroup(UpdateGroup):
175@@ -188,9 +207,14 @@ class UpdateSystemGroup(UpdateGroup):
176 # the core components and packages.
177 name = _("%s base") % utils.get_ubuntu_flavor_name(cache=cache)
178 icon = Gio.ThemedIcon.new("distributor-logo")
179+<<<<<<< UpdateManager/Core/UpdateList.py
180 super(UpdateSystemGroup, self).__init__(
181 None, name, icon, to_remove, sensitive
182 )
183+=======
184+ super(UpdateSystemGroup, self).__init__(None, name, icon, to_remove,
185+ sensitive)
186+>>>>>>> UpdateManager/Core/UpdateList.py
187
188
189 class UpdateOrigin:
190@@ -233,7 +257,10 @@ class UpdateList:
191 self.update_groups = []
192 self.security_groups = []
193 self.kernel_autoremove_groups = []
194+<<<<<<< UpdateManager/Core/UpdateList.py
195 self.duplicate_groups = []
196+=======
197+>>>>>>> UpdateManager/Core/UpdateList.py
198 self.ubuntu_pro_groups = []
199 self.num_updates = 0
200 self.random = random.Random()
201@@ -423,9 +450,50 @@ class UpdateList:
202 return True
203 return False
204
205+<<<<<<< UpdateManager/Core/UpdateList.py
206 def _make_groups(
207 self, cache, pkgs, eventloop_callback, to_remove=False, sensitive=True
208 ):
209+=======
210+ def _get_linux_packages(self):
211+ "Return all binary packages made by the linux-meta source package"
212+ # Hard code this rather than generate from source info in cache because
213+ # that might only be available if we have deb-src lines. I think we
214+ # could also generate it by iterating over all the binary package info
215+ # we have, but that is costly. These don't change often.
216+ return ['linux',
217+ 'linux-cloud-tools-generic',
218+ 'linux-cloud-tools-lowlatency',
219+ 'linux-cloud-tools-virtual',
220+ 'linux-crashdump',
221+ 'linux-generic',
222+ 'linux-generic-lpae',
223+ 'linux-headers-generic',
224+ 'linux-headers-generic-lpae',
225+ 'linux-headers-lowlatency',
226+ 'linux-headers-lowlatency-lpae',
227+ 'linux-headers-server',
228+ 'linux-headers-virtual',
229+ 'linux-image',
230+ 'linux-image-extra-virtual',
231+ 'linux-image-generic',
232+ 'linux-image-generic-lpae',
233+ 'linux-image-lowlatency',
234+ 'linux-image-virtual',
235+ 'linux-lowlatency',
236+ 'linux-signed-generic',
237+ 'linux-signed-image-generic',
238+ 'linux-signed-image-lowlatency',
239+ 'linux-signed-lowlatency',
240+ 'linux-source',
241+ 'linux-tools-generic',
242+ 'linux-tools-generic-lpae',
243+ 'linux-tools-lowlatency',
244+ 'linux-tools-virtual',
245+ 'linux-virtual']
246+
247+ def _make_groups(self, cache, pkgs, eventloop_callback, to_remove=False, sensitive=True):
248+>>>>>>> UpdateManager/Core/UpdateList.py
249 if not pkgs:
250 return []
251 ungrouped_pkgs = []
252@@ -435,9 +503,13 @@ class UpdateList:
253 for pkg in pkgs:
254 app = self._get_application_for_package(pkg)
255 if app is not None:
256+<<<<<<< UpdateManager/Core/UpdateList.py
257 app_group = UpdateApplicationGroup(
258 pkg, app, to_remove, sensitive
259 )
260+=======
261+ app_group = UpdateApplicationGroup(pkg, app, to_remove, sensitive)
262+>>>>>>> UpdateManager/Core/UpdateList.py
263 app_groups.append(app_group)
264 else:
265 ungrouped_pkgs.append(pkg)
266@@ -458,6 +530,7 @@ class UpdateList:
267 if ungrouped_pkgs:
268 # Separate out system base packages. If we have already found an
269 # application for all updates, don't bother.
270+<<<<<<< UpdateManager/Core/UpdateList.py
271 linux_names = (
272 "linux$",
273 "linux-.*-buildinfo.*",
274@@ -482,6 +555,9 @@ class UpdateList:
275 ubuntu_base_group = UpdateGroup(
276 None, None, None, to_remove, sensitive
277 )
278+=======
279+ meta_group = UpdateGroup(None, None, None, to_remove, sensitive)
280+>>>>>>> UpdateManager/Core/UpdateList.py
281 flavor_package = utils.get_ubuntu_flavor_package(cache=cache)
282 ubuntu_base_pkgs = [
283 flavor_package,
284@@ -502,6 +578,7 @@ class UpdateList:
285 pkg, cache, eventloop_callback
286 ):
287 if system_group is None:
288+<<<<<<< UpdateManager/Core/UpdateList.py
289 system_group = UpdateSystemGroup(
290 cache, to_remove, sensitive
291 )
292@@ -510,6 +587,12 @@ class UpdateList:
293 pkg_groups.append(
294 UpdatePackageGroup(pkg, to_remove, sensitive)
295 )
296+=======
297+ system_group = UpdateSystemGroup(cache, to_remove, sensitive)
298+ system_group.add(pkg)
299+ else:
300+ pkg_groups.append(UpdatePackageGroup(pkg, to_remove, sensitive))
301+>>>>>>> UpdateManager/Core/UpdateList.py
302
303 app_groups.sort(key=lambda a: a.name.lower())
304 pkg_groups.sort(key=lambda a: a.name.lower())
305@@ -518,6 +601,7 @@ class UpdateList:
306
307 return app_groups + pkg_groups
308
309+<<<<<<< UpdateManager/Core/UpdateList.py
310 def update(
311 self,
312 cache,
313@@ -525,6 +609,9 @@ class UpdateList:
314 duplicate_packages=[],
315 ua_security_packages=[],
316 ):
317+=======
318+ def update(self, cache, eventloop_callback=None, ua_security_packages=[]):
319+>>>>>>> UpdateManager/Core/UpdateList.py
320 self.held_back = []
321
322 # do the upgrade
323@@ -569,6 +656,36 @@ class UpdateList:
324 FakeUbuntuProPackage(package_name, version, size)
325 )
326
327+ class FakeUbuntuProPackageCandidate:
328+ def __init__(self, source_name, version, size):
329+ self.source_name = source_name
330+ self.summary = source_name
331+ self.description = source_name
332+ self.version = version
333+ self.size = size
334+ self.downloadable = False
335+ self.record = {}
336+
337+ class FakeUbuntuProPackage:
338+ def __init__(self, package_name, version, size):
339+ self.name = package_name
340+ self.candidate = FakeUbuntuProPackageCandidate(package_name,
341+ version, size)
342+ self.marked_install = False
343+ self.marked_upgrade = False
344+ self.marked_delete = False
345+ self.installed_files = []
346+
347+ def mark_install(self):
348+ pass
349+
350+ def mark_delete(self):
351+ pass
352+ fake_ua_packages = []
353+ for (package_name, version, size) in ua_security_packages:
354+ fake_ua_packages.append(FakeUbuntuProPackage(package_name,
355+ version, size))
356+
357 # Find all upgradable packages
358 for pkg in cache:
359 if pkg.is_upgradable or pkg.marked_install:
360@@ -609,15 +726,21 @@ class UpdateList:
361 and not cache.running_kernel_pkgs_regexp.match(pkg.name)
362 ):
363 kernel_autoremove_pkgs.append(pkg)
364+<<<<<<< UpdateManager/Core/UpdateList.py
365 if pkg.name in duplicate_packages:
366 duplicate_pkgs.append(pkg)
367+=======
368+>>>>>>> UpdateManager/Core/UpdateList.py
369
370 # perform operations after the loop to not skip packages which
371 # changed state due to the resolver
372 for pkg in kernel_autoremove_pkgs:
373 pkg.mark_delete()
374+<<<<<<< UpdateManager/Core/UpdateList.py
375 for pkg in duplicate_pkgs:
376 pkg.mark_delete()
377+=======
378+>>>>>>> UpdateManager/Core/UpdateList.py
379 for pkg in self.ignored_phased_updates:
380 pkg.mark_keep()
381
382@@ -641,6 +764,7 @@ class UpdateList:
383 cache, security_pkgs, eventloop_callback
384 )
385 self.kernel_autoremove_groups = self._make_groups(
386+<<<<<<< UpdateManager/Core/UpdateList.py
387 cache, kernel_autoremove_pkgs, eventloop_callback, True
388 )
389 self.duplicate_groups = self._make_groups(
390@@ -649,3 +773,8 @@ class UpdateList:
391 self.ubuntu_pro_groups = self._make_groups(
392 cache, fake_ua_packages, eventloop_callback, sensitive=False
393 )
394+=======
395+ cache, kernel_autoremove_pkgs, eventloop_callback, True)
396+ self.ubuntu_pro_groups = self._make_groups(
397+ cache, fake_ua_packages, eventloop_callback, sensitive=False)
398+>>>>>>> UpdateManager/Core/UpdateList.py
399diff --git a/UpdateManager/Core/utils.py b/UpdateManager/Core/utils.py
400index 3ca01cd..de22382 100644
401--- a/UpdateManager/Core/utils.py
402+++ b/UpdateManager/Core/utils.py
403@@ -234,10 +234,15 @@ def url_downloadable(uri, debug_func=None):
404 lambda x: True
405 debug_func("url_downloadable: %s" % uri)
406 (scheme, netloc, path, querry, fragment) = urlsplit(uri)
407+<<<<<<< UpdateManager/Core/utils.py
408 debug_func(
409 "s='%s' n='%s' p='%s' q='%s' f='%s'"
410 % (scheme, netloc, path, querry, fragment)
411 )
412+=======
413+ debug_func("s='%s' n='%s' p='%s' q='%s' f='%s'" % (scheme, netloc, path,
414+ querry, fragment))
415+>>>>>>> UpdateManager/Core/utils.py
416 if scheme in ("http", "https"):
417 try:
418 http_file = urlopen(HeadRequest(uri))
419@@ -279,7 +284,11 @@ def init_proxy(gsettings=None):
420 SYNAPTIC_CONF_FILE = "/root/.synaptic/synaptic.conf"
421 proxies = {}
422 # generic apt config wins
423+<<<<<<< UpdateManager/Core/utils.py
424 if apt_pkg.config.find("Acquire::http::Proxy") != "":
425+=======
426+ if apt_pkg.config.find("Acquire::http::Proxy") != '':
427+>>>>>>> UpdateManager/Core/utils.py
428 proxies["http"] = apt_pkg.config.find("Acquire::http::Proxy")
429 # then synaptic
430 elif os.path.exists(SYNAPTIC_CONF_FILE):
431@@ -291,7 +300,11 @@ def init_proxy(gsettings=None):
432 proxy_port = str(cnf.find_i("Synaptic::httpProxyPort"))
433 if proxy_host and proxy_port:
434 proxies["http"] = "http://%s:%s/" % (proxy_host, proxy_port)
435+<<<<<<< UpdateManager/Core/utils.py
436 if apt_pkg.config.find("Acquire::https::Proxy") != "":
437+=======
438+ if apt_pkg.config.find("Acquire::https::Proxy") != '':
439+>>>>>>> UpdateManager/Core/utils.py
440 proxies["https"] = apt_pkg.config.find("Acquire::https::Proxy")
441 elif "http" in proxies:
442 proxies["https"] = proxies["http"]
443@@ -299,7 +312,11 @@ def init_proxy(gsettings=None):
444 if proxies:
445 # basic verification
446 for proxy in proxies.values():
447+<<<<<<< UpdateManager/Core/utils.py
448 if not re.match("https?://\\w+", proxy):
449+=======
450+ if not re.match("https?://\w+", proxy):
451+>>>>>>> UpdateManager/Core/utils.py
452 print("proxy '%s' looks invalid" % proxy, file=sys.stderr)
453 return
454 proxy_support = ProxyHandler(proxies)
455diff --git a/UpdateManager/Dialogs.py b/UpdateManager/Dialogs.py
456index 304609c..5f3f9af 100644
457--- a/UpdateManager/Dialogs.py
458+++ b/UpdateManager/Dialogs.py
459@@ -107,6 +107,7 @@ class InternalDialog(BuilderDialog):
460 self.connect("realize", self._on_realize)
461
462 def _on_realize(self, user_data):
463+ self.paned.set_position(self.paned.get_allocation().height * 0.6)
464 if self.focus_button:
465 self.focus_button.set_can_default(True)
466 self.focus_button.set_can_focus(True)
467@@ -131,7 +132,7 @@ class InternalDialog(BuilderDialog):
468 return None
469
470 def on_settings_button_clicked(self):
471- self.window_main.show_settings()
472+ self.window_main.show_settings(2)
473
474 def set_header(self, label):
475 if label:
476@@ -159,6 +160,7 @@ class InternalDialog(BuilderDialog):
477 self.set_desc(None)
478
479 if not active:
480+<<<<<<< UpdateManager/Dialogs.py
481 if (
482 self._is_livepatch_supported()
483 and self.settings_button
484@@ -171,6 +173,14 @@ class InternalDialog(BuilderDialog):
485 "secure between restarts."
486 )
487 )
488+=======
489+ if self._is_livepatch_supported() and \
490+ self.settings_button and \
491+ self.settings.get_int('launch-count') >= 4:
492+ self.set_desc(_("<b>Tip:</b> You can use Livepatch with "
493+ "Ubuntu Pro to keep your computer more "
494+ "secure between restarts."))
495+>>>>>>> UpdateManager/Dialogs.py
496 self.settings_button.set_label(_("Settings & Pro…"))
497 return
498
499@@ -236,9 +246,14 @@ class NoUpdatesDialog(InternalDialog):
500 else:
501 self.set_header(_("The software on this computer is up to date."))
502 self.settings_button = self.add_settings_button()
503+<<<<<<< UpdateManager/Dialogs.py
504 self.focus_button = self.add_button(
505 Gtk.STOCK_OK, self.window_main.close
506 )
507+=======
508+ self.focus_button = self.add_button(Gtk.STOCK_OK,
509+ self.window_main.close)
510+>>>>>>> UpdateManager/Dialogs.py
511 self.check_livepatch_status()
512
513
514@@ -326,6 +341,7 @@ class NoUpgradeForYouDialog(InternalDialog):
515 InternalDialog.__init__(self, window_main)
516 self.set_header(_("Sorry, there are no more upgrades for this system"))
517 # Translators: this is an Ubuntu version name like "Ubuntu 12.04"
518+<<<<<<< UpdateManager/Dialogs.py
519 self.set_desc(
520 _(
521 "\nThere will not be any further Ubuntu releases "
522@@ -339,6 +355,17 @@ class NoUpgradeForYouDialog(InternalDialog):
523 self.focus_button = self.add_button(
524 Gtk.STOCK_OK, self.window_main.close
525 )
526+=======
527+ self.set_desc(_("\nThere will not be any further Ubuntu releases "
528+ "for this system's '%s' architecture.\n\n"
529+ "Updates for Ubuntu %s will continue until "
530+ "2023-04-26.\n\nIf you reinstall Ubuntu from "
531+ "ubuntu.com/download, future upgrades will "
532+ "be available.") %
533+ (arch, meta_release.current_dist_version))
534+ self.focus_button = self.add_button(Gtk.STOCK_OK,
535+ self.window_main.close)
536+>>>>>>> UpdateManager/Dialogs.py
537
538
539 class PartialUpgradeDialog(InternalDialog):
540diff --git a/UpdateManager/UpdateManager.py b/UpdateManager/UpdateManager.py
541index 6dcdab6..780c587 100644
542--- a/UpdateManager/UpdateManager.py
543+++ b/UpdateManager/UpdateManager.py
544@@ -35,7 +35,11 @@ warnings.filterwarnings(
545 )
546
547 import distro_info
548+<<<<<<< UpdateManager/UpdateManager.py
549 import fnmatch
550+=======
551+import json
552+>>>>>>> UpdateManager/UpdateManager.py
553 import os
554 import subprocess
555 import sys
556@@ -50,6 +54,7 @@ from dbus.mainloop.glib import DBusGMainLoop
557 DBusGMainLoop(set_as_default=True)
558
559 from .UnitySupport import UnitySupport
560+<<<<<<< UpdateManager/UpdateManager.py
561 from .Dialogs import (
562 DistUpgradeDialog,
563 ErrorDialog,
564@@ -62,6 +67,18 @@ from .Dialogs import (
565 UnsupportedDialog,
566 UpdateErrorDialog,
567 )
568+=======
569+from .Dialogs import (DistUpgradeDialog,
570+ ErrorDialog,
571+ HWEUpgradeDialog,
572+ NeedRestartDialog,
573+ NoUpdatesDialog,
574+ NoUpgradeForYouDialog,
575+ PartialUpgradeDialog,
576+ StoppedUpdatesDialog,
577+ UnsupportedDialog,
578+ UpdateErrorDialog)
579+>>>>>>> UpdateManager/UpdateManager.py
580 from .MetaReleaseGObject import MetaRelease
581 from .UpdatesAvailable import UpdatesAvailable
582 from .Core.AlertWatcher import AlertWatcher
583@@ -69,7 +86,12 @@ from .Core.MyCache import MyCache
584 from .Core.roam import NetworkManagerHelper
585 from .Core.UpdateList import UpdateList
586 from .Core.utils import get_arch, get_dist
587+<<<<<<< UpdateManager/UpdateManager.py
588 from .backend import InstallBackend, get_backend
589+=======
590+from .backend import (InstallBackend,
591+ get_backend)
592+>>>>>>> UpdateManager/UpdateManager.py
593
594 # file that signals if we need to reboot
595 REBOOT_REQUIRED_FILE = "/var/run/reboot-required"
596@@ -92,8 +114,11 @@ class UpdateManager(Gtk.Window):
597 self.update_list = None
598 self.meta_release = None
599 self.hwe_replacement_packages = None
600+<<<<<<< UpdateManager/UpdateManager.py
601 self.oem_metapackages = set()
602 self.duplicate_packages = []
603+=======
604+>>>>>>> UpdateManager/UpdateManager.py
605 self.arch = get_arch()
606
607 # Basic GTK+ parameters
608@@ -103,9 +128,15 @@ class UpdateManager(Gtk.Window):
609
610 # Keep window at a constant size
611 ctx = self.get_style_context()
612+<<<<<<< UpdateManager/UpdateManager.py
613 self.style_changed = ctx.connect(
614 "changed", lambda ctx: self.resize_to_standard_width()
615 )
616+=======
617+ self.style_changed = ctx.connect("changed",
618+ lambda ctx:
619+ self.resize_to_standard_width())
620+>>>>>>> UpdateManager/UpdateManager.py
621
622 # Signals
623 self.connect("delete-event", self._on_close)
624@@ -202,8 +233,18 @@ class UpdateManager(Gtk.Window):
625 self._start_pane(None)
626 sys.exit(0)
627
628+<<<<<<< UpdateManager/UpdateManager.py
629 def show_settings(self):
630 cmd = ["/usr/bin/software-properties-gtk", "--open-tab", "2"]
631+=======
632+ def show_settings(self, page_number):
633+ try:
634+ apt_pkg.pkgsystem_unlock()
635+ except SystemError:
636+ pass
637+ cmd = ["/usr/bin/software-properties-gtk",
638+ "--open-tab", str(page_number)]
639+>>>>>>> UpdateManager/UpdateManager.py
640
641 if "WAYLAND_DISPLAY" not in os.environ:
642 cmd += ["--toplevel", "%s" % self.get_window().get_xid()]
643@@ -246,6 +287,7 @@ class UpdateManager(Gtk.Window):
644 if self.cache is None:
645 return
646
647+<<<<<<< UpdateManager/UpdateManager.py
648 pane = self._make_available_pane(
649 self.cache.install_count + self.cache.del_count,
650 os.path.exists(REBOOT_REQUIRED_FILE),
651@@ -294,21 +336,38 @@ class UpdateManager(Gtk.Window):
652 cancelled_update=False,
653 error_occurred=False,
654 ):
655- self._check_hwe_support_status()
656- if install_count == 0:
657- # Need Restart > New Release > No Updates
658- if need_reboot:
659- return NeedRestartDialog(self)
660- dist_upgrade = self._check_meta_release()
661- if dist_upgrade:
662- return dist_upgrade
663- elif cancelled_update:
664- return StoppedUpdatesDialog(self)
665- elif self.hwe_replacement_packages:
666- return HWEUpgradeDialog(self)
667- else:
668- return NoUpdatesDialog(self, error_occurred=error_occurred)
669+=======
670+ pane = self._make_available_pane(self.cache.install_count,
671+ os.path.exists(REBOOT_REQUIRED_FILE),
672+ cancelled_update, error_occurred)
673+ self._start_pane(pane)
674+
675+ def _get_ua_security_status(self):
676+ self.ua_security_packages = []
677+ try:
678+ p = subprocess.Popen(['pro', 'security-status', '--format=json'],
679+ stdout=subprocess.PIPE)
680+ except OSError:
681+ pass
682 else:
683+ while p.poll() is None:
684+ while Gtk.events_pending():
685+ Gtk.main_iteration()
686+ time.sleep(0.05)
687+ s = json.load(p.stdout)
688+ for package in s.get('packages', []):
689+ status = package.get('status', '')
690+ if status == 'pending_attach' or status == 'pending_enable':
691+ name = package.get('package', '')
692+ version = package.get('version', '')
693+ size = package.get('download_size', 0)
694+ self.ua_security_packages.append((name, version, size))
695+
696+ def _make_available_pane(self, install_count, need_reboot=False,
697+ cancelled_update=False, error_occurred=False):
698+>>>>>>> UpdateManager/UpdateManager.py
699+ self._check_hwe_support_status()
700+ if install_count != 0 or len(self.ua_security_packages) > 0:
701 header = None
702 desc = None
703 if error_occurred:
704@@ -322,6 +381,19 @@ class UpdateManager(Gtk.Window):
705 elif self.hwe_replacement_packages:
706 return HWEUpgradeDialog(self)
707 return UpdatesAvailable(self, header, desc, need_reboot)
708+ else:
709+ # Need Restart > New Release > No Updates
710+ if need_reboot:
711+ return NeedRestartDialog(self)
712+ dist_upgrade = self._check_meta_release()
713+ if dist_upgrade:
714+ return dist_upgrade
715+ elif cancelled_update:
716+ return StoppedUpdatesDialog(self)
717+ elif self.hwe_replacement_packages:
718+ return HWEUpgradeDialog(self)
719+ else:
720+ return NoUpdatesDialog(self, error_occurred=error_occurred)
721
722 def start_error(self, update_and_retry, header, desc):
723 if update_and_retry:
724@@ -360,6 +432,7 @@ class UpdateManager(Gtk.Window):
725
726 # Check for new fresh release
727 settings = Gio.Settings.new("com.ubuntu.update-manager")
728+<<<<<<< UpdateManager/UpdateManager.py
729 if self.meta_release.new_dist and (
730 self.options.check_dist_upgrades
731 or settings.get_boolean("check-dist-upgrades")
732@@ -368,6 +441,14 @@ class UpdateManager(Gtk.Window):
733 return NoUpgradeForYouDialog(
734 self, self.meta_release, self.arch
735 )
736+=======
737+ if (self.meta_release.new_dist and
738+ (self.options.check_dist_upgrades or
739+ settings.get_boolean("check-dist-upgrades"))):
740+ if self.arch == 'i386':
741+ return NoUpgradeForYouDialog(self, self.meta_release,
742+ self.arch)
743+>>>>>>> UpdateManager/UpdateManager.py
744 return DistUpgradeDialog(self, self.meta_release)
745
746 return None
747@@ -428,22 +509,37 @@ class UpdateManager(Gtk.Window):
748 self._start_pane(PartialUpgradeDialog(self))
749 # we assert a clean cache
750 header = _("Software index is broken")
751+<<<<<<< UpdateManager/UpdateManager.py
752 desc = _(
753 "It is impossible to install or remove any software. "
754 'Please use the package manager "Synaptic" or run '
755 '"sudo apt-get install -f" in a terminal to fix '
756 "this issue at first."
757 )
758+=======
759+ desc = _("It is impossible to install or remove any software. "
760+ "Please use the package manager \"Synaptic\" or run "
761+ "\"sudo apt-get install -f\" in a terminal to fix "
762+ "this issue at first.")
763+>>>>>>> UpdateManager/UpdateManager.py
764 self.start_error(False, header, desc)
765 return
766 except SystemError as e:
767 header = _("Could not initialize the package information")
768+<<<<<<< UpdateManager/UpdateManager.py
769 desc = _(
770 "An unresolvable problem occurred while "
771 "initializing the package information.\n\n"
772 "Please report this bug against the 'update-manager' "
773 "package and include the following error message:\n"
774 ) + str(e)
775+=======
776+ desc = _("An unresolvable problem occurred while "
777+ "initializing the package information.\n\n"
778+ "Please report this bug against the 'update-manager' "
779+ "package and include the following error "
780+ "message:\n") + str(e)
781+>>>>>>> UpdateManager/UpdateManager.py
782 self.start_error(False, header, desc)
783 return
784
785@@ -454,6 +550,7 @@ class UpdateManager(Gtk.Window):
786
787 iterate()
788
789+<<<<<<< UpdateManager/UpdateManager.py
790 self._check_oem_metapackages()
791
792 self._get_ua_security_status()
793@@ -473,6 +570,15 @@ class UpdateManager(Gtk.Window):
794 duplicate_packages=self.duplicate_packages,
795 ua_security_packages=self.ua_security_packages,
796 )
797+=======
798+ self._get_ua_security_status()
799+
800+ self.update_list = UpdateList(self)
801+ try:
802+ self.update_list.update(self.cache, eventloop_callback=iterate,
803+ ua_security_packages=self.
804+ ua_security_packages)
805+>>>>>>> UpdateManager/UpdateManager.py
806 except SystemError as e:
807 header = _("Could not calculate the upgrade")
808 desc = _(
809diff --git a/UpdateManager/UpdateManagerVersion.py b/UpdateManager/UpdateManagerVersion.py
810index 09c2fb6..2b23708 100644
811--- a/UpdateManager/UpdateManagerVersion.py
812+++ b/UpdateManager/UpdateManagerVersion.py
813@@ -1,3 +1,7 @@
814+<<<<<<< UpdateManager/UpdateManagerVersion.py
815 # This file isn't used except in local checkouts, but one like it is written
816 # out in the build directory by setup.py
817 VERSION = "bzr"
818+=======
819+VERSION = '1:18.04.11.17'
820+>>>>>>> UpdateManager/UpdateManagerVersion.py
821diff --git a/UpdateManager/UpdatesAvailable.py b/UpdateManager/UpdatesAvailable.py
822index e081e1f..6c16802 100644
823--- a/UpdateManager/UpdatesAvailable.py
824+++ b/UpdateManager/UpdatesAvailable.py
825@@ -75,6 +75,7 @@ from .UnitySupport import UnitySupport
826 # - screen reader does not say "Downloaded" for downloaded updates
827
828 # list constants
829+<<<<<<< UpdateManager/UpdatesAvailable.py
830 (
831 LIST_NAME,
832 LIST_UPDATE_DATA,
833@@ -82,6 +83,10 @@ from .UnitySupport import UnitySupport
834 LIST_TOGGLE_ACTIVE,
835 LIST_SENSITIVE,
836 ) = range(5)
837+=======
838+(LIST_NAME, LIST_UPDATE_DATA, LIST_SIZE, LIST_TOGGLE_ACTIVE,
839+ LIST_SENSITIVE) = range(5)
840+>>>>>>> UpdateManager/UpdatesAvailable.py
841
842 # NetworkManager enums
843 from .Core.roam import NetworkManagerHelper
844@@ -256,20 +261,32 @@ class UpdatesAvailable(InternalDialog):
845 # self.button_help.set_sensitive(False)
846
847 self.add_settings_button()
848+<<<<<<< UpdateManager/UpdatesAvailable.py
849 self.button_close = self.add_button(
850 Gtk.STOCK_CANCEL, self.window_main.close
851 )
852 self.button_install = self.add_button(
853 _("Install Now"), self.on_button_install_clicked
854 )
855+=======
856+ self.button_close = self.add_button(Gtk.STOCK_CANCEL,
857+ self.window_main.close)
858+ self.button_pro = self.add_button(_("Enable Ubuntu Pro..."),
859+ self.on_button_pro_clicked)
860+ self.button_install = self.add_button(_("Install Now"),
861+ self.on_button_install_clicked)
862+>>>>>>> UpdateManager/UpdatesAvailable.py
863 self.focus_button = self.button_install
864
865 # create text view
866 self.textview_changes = ChangelogViewer()
867+ self.textview_changes.set_wrap_mode(Gtk.WrapMode.WORD)
868 self.textview_changes.show()
869 self.scrolledwindow_changes.add(self.textview_changes)
870 changes_buffer = self.textview_changes.get_buffer()
871 changes_buffer.create_tag("versiontag", weight=Pango.Weight.BOLD)
872+ changes_buffer.create_tag("changestag", weight=Pango.Weight.BOLD)
873+ changes_buffer.create_tag("descriptiontag", weight=Pango.Weight.BOLD)
874
875 # the treeview (move into it's own code!)
876 self.store = Gtk.TreeStore(str, GObject.TYPE_PYOBJECT, str, bool, bool)
877@@ -304,6 +321,7 @@ class UpdatesAvailable(InternalDialog):
878 pkg_toggle_renderer.set_property("ypad", 2)
879 pkg_toggle_renderer.connect("toggled", self.on_update_toggled)
880 pkg_column.pack_start(pkg_toggle_renderer, False)
881+<<<<<<< UpdateManager/UpdatesAvailable.py
882 pkg_column.add_attribute(
883 pkg_toggle_renderer, "active", LIST_TOGGLE_ACTIVE
884 )
885@@ -313,6 +331,14 @@ class UpdatesAvailable(InternalDialog):
886 pkg_column.set_cell_data_func(
887 pkg_toggle_renderer, self.pkg_toggle_renderer_data_func
888 )
889+=======
890+ pkg_column.add_attribute(pkg_toggle_renderer,
891+ 'active', LIST_TOGGLE_ACTIVE)
892+ pkg_column.add_attribute(pkg_toggle_renderer,
893+ 'sensitive', LIST_SENSITIVE)
894+ pkg_column.set_cell_data_func(pkg_toggle_renderer,
895+ self.pkg_toggle_renderer_data_func)
896+>>>>>>> UpdateManager/UpdatesAvailable.py
897
898 pkg_icon_renderer = Gtk.CellRendererPixbuf()
899 pkg_icon_renderer.set_property("ypad", 2)
900@@ -340,7 +366,12 @@ class UpdatesAvailable(InternalDialog):
901 _("Download"), size_renderer, text=LIST_SIZE
902 )
903 size_column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
904+<<<<<<< UpdateManager/UpdatesAvailable.py
905 size_column.add_attribute(size_renderer, "sensitive", LIST_SENSITIVE)
906+=======
907+ size_column.add_attribute(size_renderer,
908+ 'sensitive', LIST_SENSITIVE)
909+>>>>>>> UpdateManager/UpdatesAvailable.py
910 self.treeview_update.append_column(size_column)
911
912 self.treeview_update.set_headers_visible(True)
913@@ -365,10 +396,15 @@ class UpdatesAvailable(InternalDialog):
914 self.settings.get_boolean("show-details")
915 )
916 self.expander_details.connect("activate", self.pre_activate_details)
917+<<<<<<< UpdateManager/UpdatesAvailable.py
918 self.expander_details.connect(
919 "notify::expanded", self.activate_details
920 )
921 self.expander_desc.connect("notify::expanded", self.activate_desc)
922+=======
923+ self.expander_details.connect("notify::expanded",
924+ self.activate_details)
925+>>>>>>> UpdateManager/UpdatesAvailable.py
926
927 # If auto-updates are on, change cancel label
928 self.notifier_settings = Gio.Settings.new("com.ubuntu.update-notifier")
929@@ -385,6 +421,8 @@ class UpdatesAvailable(InternalDialog):
930 "network-3g-alert", self._on_network_3g_alert
931 )
932
933+ self._get_apt_news("/var/lib/ubuntu-advantage/messages/apt-news")
934+
935 def stop(self):
936 InternalDialog.stop(self)
937 self._save_state()
938@@ -539,8 +577,16 @@ class UpdatesAvailable(InternalDialog):
939
940 renderer.set_property("markup", markup)
941
942- def set_changes_buffer(self, changes_buffer, text, name, srcpkg):
943- changes_buffer.set_text("")
944+ def set_changes_buffer(self, changes_buffer, long_desc, text, name, srcpkg):
945+ changes_buffer.set_text("") # Clear "downloading list of changes..."
946+
947+ # Write the technical description section
948+ changes_buffer.insert_with_tags_by_name(changes_buffer.get_end_iter(),
949+ "Technical description\n",
950+ "descriptiontag")
951+ changes_buffer.insert(changes_buffer.get_end_iter(), long_desc + "\n\n")
952+
953+ # Write the changes section
954 lines = text.split("\n")
955 if len(lines) == 1:
956 changes_buffer.set_text(text)
957@@ -553,14 +599,24 @@ class UpdatesAvailable(InternalDialog):
958 )
959 # bullet_match = re.match("^.*[\*-]", line)
960 author_match = re.match("^.*--.*<.*@.*>.*$", line)
961+ changes_match = re.match(r'^Changes for [^ ]+ versions:$', line)
962 if version_match:
963 version = version_match.group(1)
964 # upload_archive = version_match.group(2).strip()
965 version_text = _("Version %s: \n") % version
966+<<<<<<< UpdateManager/UpdatesAvailable.py
967 changes_buffer.insert_with_tags_by_name(
968 end_iter, version_text, "versiontag"
969 )
970 elif author_match:
971+=======
972+ changes_buffer.insert_with_tags_by_name(end_iter, version_text,
973+ "versiontag")
974+ elif changes_match:
975+ changes_buffer.insert_with_tags_by_name(end_iter, line + "\n",
976+ "changestag")
977+ elif (author_match):
978+>>>>>>> UpdateManager/UpdatesAvailable.py
979 pass
980 else:
981 changes_buffer.insert(end_iter, line + "\n")
982@@ -590,12 +646,8 @@ class UpdatesAvailable(InternalDialog):
983 ):
984 changes_buffer = self.textview_changes.get_buffer()
985 changes_buffer.set_text("")
986- desc_buffer = self.textview_descr.get_buffer()
987- desc_buffer.set_text("")
988- self.notebook_details.set_sensitive(False)
989 return
990 long_desc = item.pkg.candidate.description
991- self.notebook_details.set_sensitive(True)
992 # do some regular expression magic on the description
993 # Add a newline before each bullet
994 p = re.compile(r"^(\s|\t)*(\*|0|-)", re.MULTILINE)
995@@ -608,9 +660,6 @@ class UpdatesAvailable(InternalDialog):
996 long_desc = p.sub("\n", long_desc)
997 long_desc = "Package: %s\n%s" % (item.pkg.name, long_desc)
998
999- desc_buffer = self.textview_descr.get_buffer()
1000- desc_buffer.set_text(long_desc)
1001-
1002 # now do the changelog
1003 name = item.pkg.name
1004 if name is None:
1005@@ -623,7 +672,7 @@ class UpdatesAvailable(InternalDialog):
1006 if name in self.cache.all_changes:
1007 changes = self.cache.all_changes[name]
1008 srcpkg = self.cache[name].candidate.source_name
1009- self.set_changes_buffer(changes_buffer, changes, name, srcpkg)
1010+ self.set_changes_buffer(changes_buffer, long_desc, changes, name, srcpkg)
1011 # if not connected, do not even attempt to get the changes
1012 elif not self.connected:
1013 changes_buffer.set_text(
1014@@ -674,8 +723,9 @@ class UpdatesAvailable(InternalDialog):
1015 changes += self.cache.all_news[name]
1016 if name in self.cache.all_changes:
1017 changes += self.cache.all_changes[name]
1018- if changes:
1019- self.set_changes_buffer(changes_buffer, changes, name, srcpkg)
1020+
1021+ if changes or long_desc:
1022+ self.set_changes_buffer(changes_buffer, long_desc, changes, name, srcpkg)
1023
1024 def on_treeview_button_press(self, widget, event):
1025 """
1026@@ -704,6 +754,14 @@ class UpdatesAvailable(InternalDialog):
1027 menu.show()
1028 return True
1029
1030+ def _get_apt_news(self, apt_news_file):
1031+ if os.access(apt_news_file, os.R_OK):
1032+ with open(apt_news_file) as f:
1033+ apt_news = f.read()
1034+ if apt_news:
1035+ self.news.get_buffer().set_text(apt_news)
1036+ self.expander_news.set_visible(True)
1037+
1038 # we need this for select all/unselect all
1039 def _toggle_group_headers(self, new_selection_value):
1040 """small helper that will set/unset the group headers"""
1041@@ -806,6 +864,7 @@ class UpdatesAvailable(InternalDialog):
1042 # self.button_install.set_sensitive(True)
1043 self.button_install.set_sensitive(True)
1044 self.unity.set_install_menuitem_visible(True)
1045+ self.button_pro.destroy()
1046 else:
1047 if inst_count > 0:
1048 download_str = ngettext(
1049@@ -815,10 +874,15 @@ class UpdatesAvailable(InternalDialog):
1050 )
1051 self.button_install.set_sensitive(True)
1052 self.unity.set_install_menuitem_visible(True)
1053+ self.button_pro.destroy()
1054+ elif self.list.ubuntu_pro_groups:
1055+ download_str = _("You need to enable Ubuntu Pro to install these updates.")
1056+ self.button_install.destroy()
1057 else:
1058 download_str = _("There are no updates to install.")
1059 self.button_install.set_sensitive(False)
1060 self.unity.set_install_menuitem_visible(False)
1061+ self.button_pro.destroy()
1062 self.image_downsize.set_sensitive(False)
1063 self.label_downsize.set_text(download_str)
1064 self.hbox_downsize.show()
1065@@ -868,7 +932,6 @@ class UpdatesAvailable(InternalDialog):
1066 "to finish installing previous updates."
1067 )
1068
1069- self.notebook_details.set_sensitive(True)
1070 self.treeview_update.set_sensitive(True)
1071 self.set_header(text_header)
1072 self.set_desc(text_desc)
1073@@ -889,8 +952,10 @@ class UpdatesAvailable(InternalDialog):
1074 self._restore_state()
1075
1076 def activate_desc(self, expander, data):
1077- expanded = self.expander_desc.get_expanded()
1078- self.expander_desc.set_vexpand(expanded)
1079+ return
1080+
1081+ def on_button_pro_clicked(self):
1082+ self.window_main.show_settings(6)
1083
1084 def on_button_install_clicked(self):
1085 self.unity.set_install_menuitem_visible(False)
1086@@ -1099,11 +1164,15 @@ class UpdatesAvailable(InternalDialog):
1087 UpdateData(groups, None, None),
1088 humanize_size(total_size),
1089 True,
1090+<<<<<<< UpdateManager/UpdatesAvailable.py
1091 sensitive,
1092+=======
1093+ sensitive
1094+>>>>>>> UpdateManager/UpdatesAvailable.py
1095 ]
1096 return self.store.append(None, header_row)
1097
1098- def _add_groups(self, groups):
1099+ def _add_groups(self, groups, parent = None):
1100 # Each row contains:
1101 # row label (for screen reader),
1102 # update data tuple (is_toplevel, group object, package object),
1103@@ -1120,18 +1189,27 @@ class UpdatesAvailable(InternalDialog):
1104 ):
1105 group_is_item = group.items[0]
1106
1107+<<<<<<< UpdateManager/UpdatesAvailable.py
1108 name = group.name
1109 if len(group.items) > 1:
1110 name = '%s (%d)' % (group.name, len(group.items))
1111
1112+=======
1113+ if group.name == "Ubuntu base":
1114+ group.name = "System components"
1115+>>>>>>> UpdateManager/UpdatesAvailable.py
1116 group_row = [
1117 name,
1118 UpdateData(None, group, group_is_item),
1119 humanize_size(group.get_total_size()),
1120 True,
1121+<<<<<<< UpdateManager/UpdatesAvailable.py
1122 group.sensitive,
1123+=======
1124+ group.sensitive
1125+>>>>>>> UpdateManager/UpdatesAvailable.py
1126 ]
1127- group_iter = self.store.append(None, group_row)
1128+ group_iter = self.store.append(parent, group_row)
1129
1130 if group_is_item:
1131 continue
1132@@ -1141,7 +1219,11 @@ class UpdatesAvailable(InternalDialog):
1133 UpdateData(None, None, item),
1134 humanize_size(getattr(item.pkg.candidate, "size", 0)),
1135 True,
1136+<<<<<<< UpdateManager/UpdatesAvailable.py
1137 group.sensitive,
1138+=======
1139+ group.sensitive
1140+>>>>>>> UpdateManager/UpdatesAvailable.py
1141 ]
1142 self.store.append(group_iter, item_row)
1143
1144@@ -1183,6 +1265,7 @@ class UpdatesAvailable(InternalDialog):
1145 self.list.kernel_autoremove_groups,
1146 )
1147 self._add_groups(self.list.kernel_autoremove_groups)
1148+<<<<<<< UpdateManager/UpdatesAvailable.py
1149 if self.list.duplicate_groups:
1150 self._add_header(
1151 _("Duplicate packages to be removed"),
1152@@ -1196,6 +1279,11 @@ class UpdatesAvailable(InternalDialog):
1153 sensitive=False,
1154 )
1155 self._add_groups(self.list.ubuntu_pro_groups)
1156+=======
1157+ if self.list.ubuntu_pro_groups:
1158+ header = self._add_header(_("Ubuntu Pro security updates (enable in Settings…)"), self.list.ubuntu_pro_groups, sensitive=False)
1159+ self._add_groups(self.list.ubuntu_pro_groups, header)
1160+>>>>>>> UpdateManager/UpdatesAvailable.py
1161
1162 self.treeview_update.set_model(self.store)
1163 self.pkg_cell_area.indent_toplevel = (
1164diff --git a/UpdateManager/backend/InstallBackendAptdaemon.py b/UpdateManager/backend/InstallBackendAptdaemon.py
1165index 2959aa6..aed2548 100644
1166--- a/UpdateManager/backend/InstallBackendAptdaemon.py
1167+++ b/UpdateManager/backend/InstallBackendAptdaemon.py
1168@@ -129,9 +129,12 @@ class InstallBackendAptdaemon(InstallBackend, BuilderDialog):
1169 self._expanded_size = None
1170 self.button_cancel = None
1171 self.trans_failed_msg = None
1172+<<<<<<< UpdateManager/backend/InstallBackendAptdaemon.py
1173 self.progressbar = None
1174 self._active_transaction = None
1175 self._expander = None
1176+=======
1177+>>>>>>> UpdateManager/backend/InstallBackendAptdaemon.py
1178
1179 def close(self):
1180 if self.button_cancel and self.button_cancel.get_sensitive():
1181@@ -328,6 +331,7 @@ class InstallBackendAptdaemon(InstallBackend, BuilderDialog):
1182 try:
1183 reinstall = purge = downgrade = []
1184 trans = yield self.client.commit_packages(
1185+<<<<<<< UpdateManager/backend/InstallBackendAptdaemon.py
1186 pkgs_install,
1187 reinstall,
1188 pkgs_remove,
1189@@ -347,6 +351,17 @@ class InstallBackendAptdaemon(InstallBackend, BuilderDialog):
1190 error_string=None,
1191 error_desc=None,
1192 )
1193+=======
1194+ pkgs_install, reinstall, pkgs_remove, purge, pkgs_upgrade,
1195+ downgrade, defer=True)
1196+ trans.connect("progress-changed", self._on_progress_changed)
1197+ yield self._show_transaction(trans, self.ACTION_INSTALL,
1198+ _("Installing updates…"), True)
1199+ except errors.NotAuthorizedError as e:
1200+ self._action_done(self.ACTION_INSTALL,
1201+ authorized=False, success=False,
1202+ error_string=None, error_desc=None)
1203+>>>>>>> UpdateManager/backend/InstallBackendAptdaemon.py
1204 except errors.TransactionFailed as e:
1205 self.trans_failed_msg = str(e)
1206 except dbus.DBusException as e:
1207@@ -524,6 +539,7 @@ class InstallBackendAptdaemon(InstallBackend, BuilderDialog):
1208 error_desc = error_desc + "\n" + self.trans_failed_msg
1209 # tell unity to hide the progress again
1210 self.unity.set_progress(-1)
1211+<<<<<<< UpdateManager/backend/InstallBackendAptdaemon.py
1212 is_success = status == EXIT_SUCCESS
1213 try:
1214 self._action_done(
1215@@ -534,10 +550,19 @@ class InstallBackendAptdaemon(InstallBackend, BuilderDialog):
1216 error_desc=error_desc,
1217 trans_failed=trans_failed,
1218 )
1219+=======
1220+ is_success = (status == EXIT_SUCCESS)
1221+ try:
1222+ self._action_done(action,
1223+ authorized=True, success=is_success,
1224+ error_string=error_string, error_desc=error_desc,
1225+ trans_failed=trans_failed)
1226+>>>>>>> UpdateManager/backend/InstallBackendAptdaemon.py
1227 except TypeError:
1228 # this module used to be be lazily imported and in older code
1229 # trans_failed= is not accepted
1230 # TODO: this workaround can be dropped in Ubuntu 20.10
1231+<<<<<<< UpdateManager/backend/InstallBackendAptdaemon.py
1232 self._action_done(
1233 action,
1234 authorized=True,
1235@@ -545,6 +570,11 @@ class InstallBackendAptdaemon(InstallBackend, BuilderDialog):
1236 error_string=error_string,
1237 error_desc=error_desc,
1238 )
1239+=======
1240+ self._action_done(action,
1241+ authorized=True, success=is_success,
1242+ error_string=error_string, error_desc=error_desc)
1243+>>>>>>> UpdateManager/backend/InstallBackendAptdaemon.py
1244
1245
1246 if __name__ == "__main__":
1247diff --git a/UpdateManager/backend/__init__.py b/UpdateManager/backend/__init__.py
1248index 72a6031..9c669e6 100644
1249--- a/UpdateManager/backend/__init__.py
1250+++ b/UpdateManager/backend/__init__.py
1251@@ -11,8 +11,11 @@ gi.require_version("Snapd", "2")
1252 from gi.repository import GLib, Gtk, Snapd
1253
1254 from apt import Cache
1255+<<<<<<< UpdateManager/backend/__init__.py
1256 import json
1257 import logging
1258+=======
1259+>>>>>>> UpdateManager/backend/__init__.py
1260 import os
1261 import re
1262 import subprocess
1263@@ -65,14 +68,20 @@ class InstallBackend(Dialog):
1264 fresh_cache = Cache(rootdir=self.window_main.cache.rootdir)
1265 for pkg in self.window_main.cache:
1266 try:
1267+<<<<<<< UpdateManager/backend/__init__.py
1268 if (
1269 pkg.marked_install
1270 and not fresh_cache[pkg.name].is_installed
1271 ):
1272+=======
1273+ if pkg.marked_install and \
1274+ not fresh_cache[pkg.name].is_installed:
1275+>>>>>>> UpdateManager/backend/__init__.py
1276 pkgname = pkg.name
1277 if pkg.is_auto_installed:
1278 pkgname += "#auto"
1279 pkgs_install.append(pkgname)
1280+<<<<<<< UpdateManager/backend/__init__.py
1281 elif (
1282 pkg.marked_upgrade
1283 and fresh_cache[pkg.name].is_upgradable
1284@@ -82,6 +91,13 @@ class InstallBackend(Dialog):
1285 pkg.marked_delete
1286 and fresh_cache[pkg.name].is_installed
1287 ):
1288+=======
1289+ elif (pkg.marked_upgrade and
1290+ fresh_cache[pkg.name].is_upgradable):
1291+ pkgs_upgrade.append(pkg.name)
1292+ elif (pkg.marked_delete and
1293+ fresh_cache[pkg.name].is_installed):
1294+>>>>>>> UpdateManager/backend/__init__.py
1295 pkgs_remove.append(pkg.name)
1296 except KeyError:
1297 # pkg missing from fresh_cache can't be modified
1298@@ -247,6 +263,7 @@ class InstallBackend(Dialog):
1299 plug = conn_cols[1]
1300 slot = conn_cols[2]
1301
1302+<<<<<<< UpdateManager/backend/__init__.py
1303 if slot.startswith(snap + ":"):
1304 plug_snap = plug.split(":")[0]
1305 if (
1306@@ -373,6 +390,10 @@ class InstallBackend(Dialog):
1307 error_desc,
1308 trans_failed=False,
1309 ):
1310+=======
1311+ def _action_done(self, action, authorized, success, error_string,
1312+ error_desc, trans_failed=False):
1313+>>>>>>> UpdateManager/backend/__init__.py
1314
1315 # If the progress dialog should be closed automatically afterwards
1316 # settings = Gio.Settings.new("com.ubuntu.update-manager")
1317@@ -395,9 +416,14 @@ class InstallBackend(Dialog):
1318 elif success:
1319 self.window_main.start_available()
1320 elif error_string:
1321+<<<<<<< UpdateManager/backend/__init__.py
1322 self.window_main.start_error(
1323 trans_failed, error_string, error_desc
1324 )
1325+=======
1326+ self.window_main.start_error(trans_failed, error_string,
1327+ error_desc)
1328+>>>>>>> UpdateManager/backend/__init__.py
1329 else:
1330 # exit gracefuly, we can't just exit as this will trigger
1331 # a crash if system.exit() is called in a exception handler
1332@@ -418,14 +444,20 @@ class InstallBackend(Dialog):
1333
1334
1335 # try aptdaemon
1336+<<<<<<< UpdateManager/backend/__init__.py
1337 if (
1338 os.path.exists("/usr/sbin/aptd")
1339 and "UPDATE_MANAGER_FORCE_BACKEND_SYNAPTIC" not in os.environ
1340 ):
1341+=======
1342+if os.path.exists("/usr/sbin/aptd") \
1343+ and "UPDATE_MANAGER_FORCE_BACKEND_SYNAPTIC" not in os.environ:
1344+>>>>>>> UpdateManager/backend/__init__.py
1345 # check if the gtkwidgets are installed as well
1346 try:
1347 from .InstallBackendAptdaemon import InstallBackendAptdaemon
1348 except ImportError:
1349+<<<<<<< UpdateManager/backend/__init__.py
1350 logging.exception("importing aptdaemon")
1351 # try synaptic
1352 if (
1353@@ -435,6 +467,17 @@ if (
1354 try:
1355 from .InstallBackendSynaptic import InstallBackendSynaptic
1356 except ImportError:
1357+=======
1358+ import logging
1359+ logging.exception("importing aptdaemon")
1360+# try synaptic
1361+if os.path.exists("/usr/sbin/synaptic") \
1362+ and "UPDATE_MANAGER_FORCE_BACKEND_APTDAEMON" not in os.environ:
1363+ try:
1364+ from .InstallBackendSynaptic import InstallBackendSynaptic
1365+ except ImportError:
1366+ import logging
1367+>>>>>>> UpdateManager/backend/__init__.py
1368 logging.exception("importing synaptic")
1369
1370
1371@@ -449,18 +492,31 @@ def get_backend(*args, **kwargs):
1372 try:
1373 return InstallBackendAptdaemon(*args, **kwargs)
1374 except NameError:
1375+<<<<<<< UpdateManager/backend/__init__.py
1376 logging.exception("using aptdaemon failed")
1377 # try synaptic
1378 if (
1379 os.path.exists("/usr/sbin/synaptic")
1380 and "UPDATE_MANAGER_FORCE_BACKEND_APTDAEMON" not in os.environ
1381 ):
1382+=======
1383+ import logging
1384+ logging.exception("using aptdaemon failed")
1385+ # try synaptic
1386+ if (os.path.exists("/usr/sbin/synaptic")
1387+ and "UPDATE_MANAGER_FORCE_BACKEND_APTDAEMON" not in os.environ):
1388+>>>>>>> UpdateManager/backend/__init__.py
1389 try:
1390 return InstallBackendSynaptic(*args, **kwargs)
1391 except NameError:
1392 pass
1393 # nothing found, raise
1394+<<<<<<< UpdateManager/backend/__init__.py
1395 raise Exception(
1396 "No working backend found, please try installing "
1397 "aptdaemon or synaptic"
1398 )
1399+=======
1400+ raise Exception("No working backend found, please try installing "
1401+ "aptdaemon or synaptic")
1402+>>>>>>> UpdateManager/backend/__init__.py
1403diff --git a/data/gtkbuilder/UpdateManager.ui b/data/gtkbuilder/UpdateManager.ui
1404index d38eeaf..e7b9dee 100644
1405--- a/data/gtkbuilder/UpdateManager.ui
1406+++ b/data/gtkbuilder/UpdateManager.ui
1407@@ -6,17 +6,47 @@
1408 <property name="can_focus">False</property>
1409 <property name="spacing">12</property>
1410 <child>
1411+ <object class="GtkExpander" id="expander_news">
1412+ <property name="visible">False</property>
1413+ <property name="can_focus">True</property>
1414+ <property name="label">News</property>
1415+ <property name="spacing">6</property>
1416+ <child>
1417+ <object class="GtkScrolledWindow">
1418+ <property name="visible">True</property>
1419+ <property name="can_focus">True</property>
1420+ <property name="shadow_type">in</property>
1421+ <property name="min_content_height">80</property>
1422+ <child>
1423+ <object class="GtkTextView" id="news">
1424+ <property name="visible">True</property>
1425+ <property name="editable">False</property>
1426+ <property name="pixels_above_lines">6</property>
1427+ <property name="left_margin">6</property>
1428+ <property name="right_margin">6</property>
1429+ <property name="wrap_mode">word</property>
1430+ <property name="cursor_visible">False</property>
1431+ <property name="accepts_tab">False</property>
1432+ </object>
1433+ </child>
1434+ </object>
1435+ </child>
1436+ </object>
1437+ <packing>
1438+ <property name="expand">False</property>
1439+ <property name="position">0</property>
1440+ </packing>
1441+ </child>
1442+ <child>
1443 <object class="GtkExpander" id="expander_details">
1444 <property name="visible">True</property>
1445 <property name="can_focus">True</property>
1446 <property name="spacing">6</property>
1447 <property name="resize_toplevel">True</property>
1448 <child>
1449- <object class="GtkVBox" id="vbox4">
1450+ <object class="GtkPaned" id="paned">
1451 <property name="visible">True</property>
1452- <property name="can_focus">False</property>
1453- <property name="vexpand">True</property>
1454- <property name="spacing">6</property>
1455+ <property name="orientation">vertical</property>
1456 <child>
1457 <object class="GtkScrolledWindow" id="scrolledwindow_update">
1458 <property name="visible">True</property>
1459@@ -44,113 +74,21 @@
1460 </child>
1461 </object>
1462 <packing>
1463- <property name="expand">True</property>
1464- <property name="fill">True</property>
1465- <property name="position">0</property>
1466+ <property name="shrink">False</property>
1467+ <property name="resize">True</property>
1468 </packing>
1469 </child>
1470 <child>
1471- <object class="GtkExpander" id="expander_desc">
1472+ <object class="GtkScrolledWindow" id="scrolledwindow_changes">
1473 <property name="visible">True</property>
1474 <property name="can_focus">True</property>
1475+ <property name="shadow_type">in</property>
1476 <child>
1477- <object class="GtkNotebook" id="notebook_details">
1478- <property name="visible">True</property>
1479- <property name="can_focus">True</property>
1480- <property name="show_border">False</property>
1481- <child>
1482- <object class="GtkVBox" id="vbox5">
1483- <property name="visible">True</property>
1484- <property name="can_focus">False</property>
1485- <property name="border_width">6</property>
1486- <property name="spacing">6</property>
1487- <child>
1488- <object class="GtkScrolledWindow" id="scrolledwindow_changes">
1489- <property name="visible">True</property>
1490- <property name="can_focus">True</property>
1491- <property name="shadow_type">in</property>
1492- <child>
1493- <placeholder/>
1494- </child>
1495- </object>
1496- <packing>
1497- <property name="expand">True</property>
1498- <property name="fill">True</property>
1499- <property name="position">0</property>
1500- </packing>
1501- </child>
1502- </object>
1503- </child>
1504- <child type="tab">
1505- <object class="GtkLabel" id="label8">
1506- <property name="visible">True</property>
1507- <property name="can_focus">False</property>
1508- <property name="label" translatable="yes">Changes</property>
1509- </object>
1510- <packing>
1511- <property name="tab_fill">False</property>
1512- </packing>
1513- </child>
1514- <child>
1515- <object class="GtkScrolledWindow" id="scrolledwindow3">
1516- <property name="visible">True</property>
1517- <property name="can_focus">True</property>
1518- <property name="border_width">6</property>
1519- <property name="shadow_type">in</property>
1520- <property name="min_content_height">80</property>
1521- <child>
1522- <object class="GtkTextView" id="textview_descr">
1523- <property name="visible">True</property>
1524- <property name="can_focus">True</property>
1525- <property name="pixels_above_lines">6</property>
1526- <property name="editable">False</property>
1527- <property name="wrap_mode">word</property>
1528- <property name="left_margin">6</property>
1529- <property name="right_margin">6</property>
1530- <property name="cursor_visible">False</property>
1531- <property name="accepts_tab">False</property>
1532- <child internal-child="accessible">
1533- <object class="AtkObject" id="textview_descr-atkobject">
1534- <property name="AtkObject::accessible-name" translatable="yes">Description</property>
1535- </object>
1536- </child>
1537- </object>
1538- </child>
1539- </object>
1540- <packing>
1541- <property name="position">1</property>
1542- </packing>
1543- </child>
1544- <child type="tab">
1545- <object class="GtkLabel" id="label9">
1546- <property name="visible">True</property>
1547- <property name="can_focus">False</property>
1548- <property name="label" translatable="yes">Description</property>
1549- <child internal-child="accessible">
1550- <object class="AtkObject" id="label9-atkobject">
1551- <property name="AtkObject::accessible-name" translatable="yes">Description</property>
1552- </object>
1553- </child>
1554- </object>
1555- <packing>
1556- <property name="position">1</property>
1557- <property name="tab_fill">False</property>
1558- </packing>
1559- </child>
1560- </object>
1561- </child>
1562- <child type="label">
1563- <object class="GtkLabel" id="label13">
1564- <property name="visible">True</property>
1565- <property name="can_focus">False</property>
1566- <property name="label" translatable="yes">Technical description</property>
1567- </object>
1568+ <placeholder/>
1569 </child>
1570 </object>
1571 <packing>
1572- <property name="expand">False</property>
1573- <property name="fill">True</property>
1574- <property name="position">1</property>
1575+ <property name="resize">True</property>
1576 </packing>
1577 </child>
1578 </object>
1579@@ -167,7 +105,7 @@
1580 <packing>
1581 <property name="expand">True</property>
1582 <property name="fill">True</property>
1583- <property name="position">2</property>
1584+ <property name="position">1</property>
1585 </packing>
1586 </child>
1587 <child>
1588@@ -177,13 +115,14 @@
1589 <child>
1590 <object class="GtkHBox" id="hbox_downsize">
1591 <property name="can_focus">False</property>
1592- <property name="spacing">12</property>
1593+ <property name="spacing">8</property>
1594 <child>
1595 <object class="GtkImage" id="image_downsize">
1596 <property name="visible">True</property>
1597 <property name="can_focus">False</property>
1598 <property name="pixel-size">16</property>
1599 <property name="icon_name">aptdaemon-download</property>
1600+ <property name="pixel_size">16</property>
1601 </object>
1602 <packing>
1603 <property name="expand">False</property>
1604@@ -401,7 +340,7 @@
1605 <packing>
1606 <property name="expand">False</property>
1607 <property name="fill">True</property>
1608- <property name="position">3</property>
1609+ <property name="position">2</property>
1610 </packing>
1611 </child>
1612 </object>
1613diff --git a/debian/changelog b/debian/changelog
1614index e8e7e44..55ae22c 100644
1615--- a/debian/changelog
1616+++ b/debian/changelog
1617@@ -1,3 +1,4 @@
1618+<<<<<<< debian/changelog
1619 update-manager (1:23.10.1) mantic; urgency=medium
1620
1621 * When displaying updates also include the quantity of updates in each
1622@@ -276,12 +277,54 @@ update-manager (1:20.04.12) groovy; urgency=medium
1623 -- Marcus Tomlinson <marcus.tomlinson@canonical.com> Thu, 28 May 2020 10:11:51 +0100
1624
1625 update-manager (1:20.04.11) groovy; urgency=medium
1626+=======
1627+update-manager (1:18.04.11.18) unreleased; urgency=medium
1628+
1629+ * Implement the new Ubuntu Pro design.
1630+ - Fuse the description and changes tabs into a single view.
1631+ - Add button to attach to enable Ubuntu Pro if it is the only action
1632+ available.
1633+ - Ubuntu base -> System components.
1634+ - Fix Ubuntu Pro item not being a parent group of its corresponding
1635+ packages.
1636+
1637+ -- Nathan Pratta Teodosio <nathan.teodosio@canonical.com> Mon, 17 Jul 2023 15:45:42 +0200
1638+
1639+update-manager (1:18.04.11.17) bionic; urgency=medium
1640+
1641+ * Fix Ubuntu Pro updates checkbox and expander widget from overlapping
1642+ (LP: #1990450)
1643+
1644+ -- Robert Ancell <robert.ancell@canonical.com> Fri, 03 Feb 2023 14:55:56 +1300
1645+
1646+update-manager (1:18.04.11.16) bionic; urgency=medium
1647+
1648+ * Update of the parsing for pro client changes (lp: #1990450)
1649+
1650+ -- Sebastien Bacher <seb128@ubuntu.com> Thu, 26 Jan 2023 12:05:05 +0100
1651+
1652+update-manager (1:18.04.11.15) bionic; urgency=medium
1653+
1654+ * Show pending Ubuntu pro packages (LP: #1990450)
1655+
1656+ -- Robert Ancell <robert.ancell@canonical.com> Wed, 18 Jan 2023 15:09:17 +1300
1657+
1658+update-manager (1:18.04.11.14) bionic; urgency=medium
1659+
1660+ * tests/test_meta_release_core.py: switch a test from using lucid to bionic
1661+ as precise was removed from the archive. (LP: #1929865)
1662+
1663+ -- Brian Murray <brian@ubuntu.com> Thu, 27 May 2021 13:54:14 -0700
1664+
1665+update-manager (1:18.04.11.13) bionic; urgency=medium
1666+>>>>>>> debian/changelog
1667
1668 * UpdateManager/UpdateManager.py: when refreshing the cache and encountering
1669 an error return rather than trying to use the undefined cache which causes
1670 crashes. Additionally, don't present the dialog with a "Try Again" button
1671 which won't do anything. (LP: #1826213)
1672
1673+<<<<<<< debian/changelog
1674 -- Brian Murray <brian@ubuntu.com> Wed, 27 May 2020 13:29:24 -0700
1675
1676 update-manager (1:20.04.10) focal; urgency=medium
1677@@ -409,11 +452,37 @@ update-manager (1:19.04.3) disco; urgency=medium
1678 -- Jeremy Bicha <jbicha@ubuntu.com> Sun, 10 Feb 2019 13:23:47 -0500
1679
1680 update-manager (1:19.04.2) disco; urgency=medium
1681+=======
1682+ -- Brian Murray <brian@ubuntu.com> Wed, 03 Jun 2020 11:41:50 -0700
1683+
1684+update-manager (1:18.04.11.12) bionic; urgency=medium
1685+
1686+ * Resolve pep8 failures.
1687+
1688+ -- Brian Murray <brian@ubuntu.com> Tue, 21 Apr 2020 07:27:24 -0700
1689+
1690+update-manager (1:18.04.11.11) bionic; urgency=medium
1691+
1692+ * UpdateManager/UpdateManager.py: Do not offer to upgrade systems running on
1693+ an i386 host architecture to another release. (LP: #1845690)
1694+
1695+ -- Brian Murray <brian@ubuntu.com> Thu, 09 Apr 2020 13:39:04 -0700
1696+
1697+update-manager (1:18.04.11.10) bionic; urgency=medium
1698+
1699+ * UpdateManager/Core/utils.py: when testing to see if a url is downloadable
1700+ support https in addition to http and ftp. (LP: #1823410)
1701+
1702+ -- Brian Murray <brian@ubuntu.com> Tue, 09 Apr 2019 16:03:46 -0700
1703+
1704+update-manager (1:18.04.11.9) bionic; urgency=medium
1705+>>>>>>> debian/changelog
1706
1707 * UpdateManager/Core/MetaRelease.py: set prompt in MetaReleaseCore so that
1708 do-release-upgrade can provide more informative error messages.
1709 (LP: #1798618, LP: #1795024)
1710
1711+<<<<<<< debian/changelog
1712 -- Brian Murray <brian@ubuntu.com> Wed, 28 Nov 2018 09:49:44 -0800
1713
1714 update-manager (1:19.04.1) disco; urgency=medium
1715@@ -449,6 +518,39 @@ update-manager (1:18.10.9) cosmic; urgency=medium
1716 -- Balint Reczey <rbalint@ubuntu.com> Mon, 01 Oct 2018 18:00:40 +0200
1717
1718 update-manager (1:18.10.8) cosmic; urgency=medium
1719+=======
1720+ -- Brian Murray <brian@ubuntu.com> Mon, 14 Jan 2019 13:40:08 -0800
1721+
1722+update-manager (1:18.04.11.8) bionic; urgency=medium
1723+
1724+ * Do not show the livepatch reminder if update-manager is running
1725+ on a distribution without software-properties-gtk. (LP: #1805118)
1726+
1727+ -- Andrea Azzarone <andrea.azzarone@canonical.com> Tue, 27 Nov 2018 13:26:00 +0000
1728+
1729+update-manager (1:18.04.11.7) bionic; urgency=medium
1730+
1731+ * Add a reminder to enable Livepatch (LP: #1787553).
1732+ * Build-Depends on python3-distro-info.
1733+
1734+ -- Andrea Azzarone <andrea.azzarone@canonical.com> Fri, 07 Sep 2018 10:41:28 +0200
1735+
1736+update-manager (1:18.04.11.6) bionic; urgency=medium
1737+
1738+ * Keep or delete packages after looping over all of them.
1739+ This prevents the resolver from changing the packages in the loop resulting
1740+ in not keeping some phased packages back from being upgraded. (LP: #1072136)
1741+ * Stop lazy import of InstallBackends.
1742+ Lazy imports made update-manager crash when an update-manager
1743+ update changed the backend API and an updated incompatible backend
1744+ was loaded to the not updated running update-manager process. (LP: #1795898)
1745+ * Cancel transaction on exit only when Cancel button is active.
1746+ Also ignore exception when cancellation fails. (LP: #1790670)
1747+
1748+ -- Balint Reczey <rbalint@ubuntu.com> Thu, 04 Oct 2018 21:33:57 +0200
1749+
1750+update-manager (1:18.04.11.5) bionic; urgency=medium
1751+>>>>>>> debian/changelog
1752
1753 * Print transaction error and let the user try again applying updates
1754 (LP: #1317164)
1755@@ -460,6 +562,7 @@ update-manager (1:18.10.8) cosmic; urgency=medium
1756 a race condition where packages to be removed are already removed.
1757 (LP: #1791931)
1758
1759+<<<<<<< debian/changelog
1760 -- Balint Reczey <rbalint@ubuntu.com> Tue, 11 Sep 2018 13:40:57 +0200
1761
1762 update-manager (1:18.10.7) cosmic; urgency=medium
1763@@ -492,10 +595,22 @@ update-manager (1:18.10.4) cosmic; urgency=medium
1764 -- Brian Murray <brian@ubuntu.com> Fri, 31 Aug 2018 15:38:33 -0700
1765
1766 update-manager (1:18.10.3) cosmic; urgency=medium
1767+=======
1768+ -- Balint Reczey <rbalint@ubuntu.com> Mon, 17 Sep 2018 17:16:38 +0200
1769+
1770+update-manager (1:18.04.11.4) bionic; urgency=medium
1771+
1772+ * Adjust dates in hwe-support-status for bionic (LP: #1775236)
1773+
1774+ -- Julian Andres Klode <juliank@ubuntu.com> Fri, 20 Jul 2018 12:26:28 +0200
1775+
1776+update-manager (1:18.04.11.3) bionic; urgency=medium
1777+>>>>>>> debian/changelog
1778
1779 * Add support for HTTPS proxies; this breaks UpdateManager.Core.utils.init_proxy()
1780 API - the return value is now a dict, rather than a string (LP: #1771914).
1781
1782+<<<<<<< debian/changelog
1783 -- Julian Andres Klode <juliank@ubuntu.com> Wed, 27 Jun 2018 14:16:45 +0200
1784
1785 update-manager (1:18.10.2) cosmic; urgency=medium
1786@@ -511,6 +626,24 @@ update-manager (1:18.10.1) cosmic; urgency=medium
1787 initial analysis of this bug. (LP: #1637180)
1788
1789 -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Mon, 28 May 2018 10:03:52 -0400
1790+=======
1791+ -- Julian Andres Klode <juliank@ubuntu.com> Fri, 29 Jun 2018 14:44:16 +0200
1792+
1793+update-manager (1:18.04.11.2) bionic; urgency=medium
1794+
1795+ * Fix my embarassing typo that makes update-manager report crashes, when
1796+ instanciating the "reboot" dialog and mangling signals. (LP: #1774131)
1797+
1798+ -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Fri, 08 Jun 2018 11:50:10 -0700
1799+
1800+update-manager (1:18.04.11.1) bionic; urgency=medium
1801+
1802+ * Block style context changed signal while enforcing the main window's
1803+ constant size. Thanks to Thomas Waldmann and Sebastien Bacher for the
1804+ initial analysis of this bug. (LP: #1637180)
1805+
1806+ -- Mathieu Trudel-Lapierre <cyphermox@ubuntu.com> Mon, 28 May 2018 10:13:12 -0400
1807+>>>>>>> debian/changelog
1808
1809 update-manager (1:18.04.11) bionic; urgency=medium
1810
1811diff --git a/debian/control b/debian/control
1812index c481028..aaf080a 100644
1813--- a/debian/control
1814+++ b/debian/control
1815@@ -9,8 +9,11 @@ Build-Depends: debhelper (>= 9),
1816 python3-all (>= 3.3.0-2),
1817 python3-dbus,
1818 python3-distro-info,
1819+<<<<<<< debian/control
1820 python3-distupgrade,
1821 python3-distutils-extra (>= 2.38),
1822+=======
1823+>>>>>>> debian/control
1824 python3-gi (>= 3.8),
1825 python3-yaml,
1826 Build-Depends-Indep: intltool,
1827diff --git a/hwe-support-status b/hwe-support-status
1828index fd484a3..fa14477 100755
1829--- a/hwe-support-status
1830+++ b/hwe-support-status
1831@@ -42,8 +42,13 @@ UNSUPPORTED_KERNEL_IMAGE_REGEX = (
1832 )
1833
1834 # HWE stack with a long support period
1835+<<<<<<< hwe-support-status
1836 HWE_SUPPORTED_BACKPORT = "-hwe-22.04"
1837 SUPPORTED_KERNEL_IMAGE_REGEX = r"^$" # No fixed backported kernel yet
1838+=======
1839+HWE_SUPPORTED_BACKPORT = "-hwe-18.04"
1840+SUPPORTED_KERNEL_IMAGE_REGEX = r'^$' # No fixed backported kernel yet
1841+>>>>>>> hwe-support-status
1842
1843
1844 KERNEL_METAPKGS = (
1845diff --git a/tests/test_backend_error.py b/tests/test_backend_error.py
1846index 38785cb..611bf0f 100644
1847--- a/tests/test_backend_error.py
1848+++ b/tests/test_backend_error.py
1849@@ -5,14 +5,26 @@ import logging
1850 import mock
1851 import sys
1852 import unittest
1853+<<<<<<< tests/test_backend_error.py
1854 from mock import patch
1855
1856 import os
1857
1858+=======
1859+from gettext import gettext as _
1860+from mock import patch
1861+
1862+from UpdateManager.Dialogs import NoUpdatesDialog
1863+from UpdateManager.UpdateManager import UpdateManager
1864+from UpdateManager.UpdatesAvailable import UpdatesAvailable
1865+
1866+import os
1867+>>>>>>> tests/test_backend_error.py
1868 CURDIR = os.path.dirname(os.path.abspath(__file__))
1869
1870
1871 class TestBackendError(unittest.TestCase):
1872+<<<<<<< tests/test_backend_error.py
1873 def setUp(self):
1874 os.environ["UPDATE_MANAGER_FORCE_BACKEND_APTDAEMON"] = "1"
1875
1876@@ -32,11 +44,35 @@ class TestBackendError(unittest.TestCase):
1877 update.side_effect = lambda: update_backend._action_done(
1878 InstallBackend.ACTION_UPDATE, True, False, "string", "desc"
1879 )
1880+=======
1881+
1882+ def setUp(self):
1883+ os.environ['UPDATE_MANAGER_FORCE_BACKEND_APTDAEMON'] = '1'
1884+
1885+ def clear_environ():
1886+ del os.environ['UPDATE_MANAGER_FORCE_BACKEND_APTDAEMON']
1887+
1888+ self.addCleanup(clear_environ)
1889+
1890+ @patch('UpdateManager.backend.InstallBackendAptdaemon.update')
1891+ def test_backend_error(self, update):
1892+ main = mock.MagicMock()
1893+ main.datadir = os.path.join(CURDIR, '..', 'data')
1894+
1895+ from UpdateManager.backend import (InstallBackend, get_backend)
1896+ update_backend = get_backend(main, InstallBackend.ACTION_UPDATE)
1897+ update.side_effect = lambda: update_backend._action_done(
1898+ InstallBackend.ACTION_UPDATE, True, False, "string", "desc")
1899+>>>>>>> tests/test_backend_error.py
1900 update_backend.start()
1901 main.start_error.assert_called_once_with(True, "string", "desc")
1902
1903
1904+<<<<<<< tests/test_backend_error.py
1905 if __name__ == "__main__":
1906+=======
1907+if __name__ == '__main__':
1908+>>>>>>> tests/test_backend_error.py
1909 if len(sys.argv) > 1 and sys.argv[1] == "-v":
1910 logging.basicConfig(level=logging.DEBUG)
1911 unittest.main()
1912diff --git a/tests/test_hwe_support_status.py b/tests/test_hwe_support_status.py
1913index e811ef9..a4449eb 100644
1914--- a/tests/test_hwe_support_status.py
1915+++ b/tests/test_hwe_support_status.py
1916@@ -153,8 +153,12 @@ class HweSupportStatusTestCase(TestCase):
1917 text = mock_print.call_args[0][0]
1918 print("43242343243", mock_print.call_count)
1919 self.assertIn(
1920+<<<<<<< tests/test_hwe_support_status.py
1921 "Your system is supported until April 2027", text
1922 )
1923+=======
1924+ "Your system is supported until April 2023", text)
1925+>>>>>>> tests/test_hwe_support_status.py
1926
1927 def test_advice_about_hwe_status_supported_hwe_stack(self):
1928 with patch("hwe_support_status.is_unsupported_hwe_running") as m:
1929@@ -174,9 +178,13 @@ class HweSupportStatusTestCase(TestCase):
1930 text = mock_print.call_args[0][0]
1931 self.assertIn(
1932 "Your Hardware Enablement Stack (HWE) is supported "
1933+<<<<<<< tests/test_hwe_support_status.py
1934 "until April 2027",
1935 text,
1936 )
1937+=======
1938+ "until April 2023", text)
1939+>>>>>>> tests/test_hwe_support_status.py
1940
1941
1942 if __name__ == "__main__":
1943diff --git a/tests/test_meta_release_core.py b/tests/test_meta_release_core.py
1944index 954a0ba..37af4ae 100644
1945--- a/tests/test_meta_release_core.py
1946+++ b/tests/test_meta_release_core.py
1947@@ -121,6 +121,18 @@ class TestMetaReleaseCore(unittest.TestCase):
1948 "download https with no proxy failed",
1949 )
1950
1951+ @unittest.skipUnless(url_downloadable(
1952+ "https://ubuntu.com", logging.debug),
1953+ "Could not reach https test site")
1954+ def test_https_url_downloadable(self):
1955+ with EnvironmentVarGuard() as environ:
1956+ logging.debug("no proxy, https address")
1957+ del environ["http_proxy"]
1958+ install_opener(None)
1959+ self.assertTrue(url_downloadable("https://ubuntu.com",
1960+ logging.debug),
1961+ "download https with no proxy failed")
1962+
1963 def test_url_downloadable(self):
1964 from UpdateManager.Core.utils import url_downloadable
1965
1966@@ -154,12 +166,18 @@ class TestMetaReleaseCore(unittest.TestCase):
1967 )
1968
1969 logging.debug("no proxy, no valid address")
1970+<<<<<<< tests/test_meta_release_core.py
1971 self.assertFalse(
1972 url_downloadable(
1973 "http://archive.ubuntu.com/xxx", logging.debug
1974 ),
1975 "download with no proxy failed",
1976 )
1977+=======
1978+ self.assertFalse(url_downloadable("http://archive.ubuntu.com/xxx",
1979+ logging.debug),
1980+ "download with no proxy failed")
1981+>>>>>>> tests/test_meta_release_core.py
1982
1983 logging.debug("proxy, no valid address")
1984 environ["http_proxy"] = "http://localhost:%s" % self.port
1985@@ -186,7 +204,11 @@ class TestMetaReleaseCore(unittest.TestCase):
1986 supported for supported in di.supported() if di.is_lts(supported)
1987 ]
1988 with EnvironmentVarGuard() as environ:
1989+<<<<<<< tests/test_meta_release_core.py
1990 environ["META_RELEASE_FAKE_CODENAME"] = ltses[-2]
1991+=======
1992+ environ["META_RELEASE_FAKE_CODENAME"] = "bionic"
1993+>>>>>>> tests/test_meta_release_core.py
1994 meta = MetaReleaseCore(forceDownload=True)
1995 while meta.downloading:
1996 time.sleep(0.1)
1997diff --git a/tests/test_pep8.py b/tests/test_pep8.py
1998new file mode 100644
1999index 0000000..5127dfe
2000--- /dev/null
2001+++ b/tests/test_pep8.py
2002@@ -0,0 +1,42 @@
2003+<<<<<<< tests/test_pep8.py
2004+=======
2005+#!/usr/bin/python3
2006+# -*- Mode: Python; indent-tabs-mode: nil; tab-width: 4; coding: utf-8 -*-
2007+
2008+import os
2009+import subprocess
2010+import unittest
2011+
2012+# pep8 is overdoing it a bit IMO
2013+IGNORE_PEP8 = "E265,E402,W503"
2014+IGNORE_FILES = (
2015+)
2016+
2017+
2018+class TestPep8Clean(unittest.TestCase):
2019+ """ ensure that the tree is pep8 clean """
2020+
2021+ def test_pep8_clean(self):
2022+ CURDIR = os.path.dirname(os.path.abspath(__file__))
2023+ py_files = set()
2024+ for dirpath, dirs, files in os.walk(os.path.join(CURDIR, "..")):
2025+ for f in files:
2026+ if os.path.splitext(f)[1] != ".py":
2027+ continue
2028+ # islink to avoid running pep8 on imported files
2029+ # that are symlinks to other packages
2030+ if os.path.islink(os.path.join(dirpath, f)):
2031+ continue
2032+ if f in IGNORE_FILES:
2033+ continue
2034+ py_files.add(os.path.join(dirpath, f))
2035+ ret_code = subprocess.call(
2036+ ["pep8", "--ignore={0}".format(IGNORE_PEP8)] + list(py_files))
2037+ self.assertEqual(0, ret_code)
2038+
2039+
2040+if __name__ == "__main__":
2041+ import logging
2042+ logging.basicConfig(level=logging.DEBUG)
2043+ unittest.main()
2044+>>>>>>> tests/test_pep8.py
2045diff --git a/tests/test_proxy.py b/tests/test_proxy.py
2046index 266f173..1146fb4 100644
2047--- a/tests/test_proxy.py
2048+++ b/tests/test_proxy.py
2049@@ -31,16 +31,24 @@ class TestInitProxy(unittest.TestCase):
2050 apt_pkg.config.set("Acquire::http::proxy", self.proxy)
2051 apt_pkg.config.set("Acquire::https::proxy", self.https_proxy)
2052 from gi.repository import Gio
2053+<<<<<<< tests/test_proxy.py
2054
2055 settings = Gio.Settings.new("com.ubuntu.update-manager")
2056 detected_proxy = init_proxy(settings)
2057 self.assertEqual(
2058 detected_proxy, {"http": self.proxy, "https": self.https_proxy}
2059 )
2060+=======
2061+ settings = Gio.Settings.new("com.ubuntu.update-manager")
2062+ detected_proxy = init_proxy(settings)
2063+ self.assertEqual(detected_proxy, {"http": self.proxy,
2064+ "https": self.https_proxy})
2065+>>>>>>> tests/test_proxy.py
2066
2067 def testinitproxyHttpOnly(self):
2068 apt_pkg.config.set("Acquire::http::proxy", self.proxy)
2069 from gi.repository import Gio
2070+<<<<<<< tests/test_proxy.py
2071
2072 settings = Gio.Settings.new("com.ubuntu.update-manager")
2073 detected_proxy = init_proxy(settings)
2074@@ -50,6 +58,29 @@ class TestInitProxy(unittest.TestCase):
2075
2076 def testinitproxyHttpOnlyWithHttpsUri(self):
2077 apt_pkg.config.set("Acquire::http::proxy", self.https_proxy)
2078+=======
2079+ settings = Gio.Settings.new("com.ubuntu.update-manager")
2080+ detected_proxy = init_proxy(settings)
2081+ self.assertEqual(detected_proxy, {"http": self.proxy,
2082+ "https": self.proxy})
2083+
2084+ def testinitproxyHttpOnlyWithHttpsUri(self):
2085+ apt_pkg.config.set("Acquire::http::proxy", self.https_proxy)
2086+ from gi.repository import Gio
2087+ settings = Gio.Settings.new("com.ubuntu.update-manager")
2088+ detected_proxy = init_proxy(settings)
2089+ self.assertEqual(detected_proxy, {"http": self.https_proxy,
2090+ "https": self.https_proxy})
2091+
2092+ def testinitproxyHttpsOnly(self):
2093+ apt_pkg.config.set("Acquire::https::proxy", self.https_proxy)
2094+ from gi.repository import Gio
2095+ settings = Gio.Settings.new("com.ubuntu.update-manager")
2096+ detected_proxy = init_proxy(settings)
2097+ self.assertEqual(detected_proxy, {"https": self.https_proxy})
2098+
2099+ def testinitproxyNoProxy(self):
2100+>>>>>>> tests/test_proxy.py
2101 from gi.repository import Gio
2102
2103 settings = Gio.Settings.new("com.ubuntu.update-manager")
2104diff --git a/tests/test_update_error.py b/tests/test_update_error.py
2105index c7b2eda..1daa99f 100644
2106--- a/tests/test_update_error.py
2107+++ b/tests/test_update_error.py
2108@@ -41,12 +41,20 @@ class TestUpdateManagerError(unittest.TestCase):
2109 self.manager, 1, error_occurred=True
2110 )
2111 self.assertIsInstance(p, UpdatesAvailable)
2112+<<<<<<< tests/test_update_error.py
2113 self.assertEqual(
2114 p.custom_desc, _("Some software couldn’t be checked for updates.")
2115 )
2116
2117
2118 if __name__ == "__main__":
2119+=======
2120+ self.assertEqual(p.custom_desc,
2121+ _("Some software couldn’t be checked for updates."))
2122+
2123+
2124+if __name__ == '__main__':
2125+>>>>>>> tests/test_update_error.py
2126 if len(sys.argv) > 1 and sys.argv[1] == "-v":
2127 logging.basicConfig(level=logging.DEBUG)
2128 unittest.main()

Subscribers

People subscribed via source and target branches