Merge lp:~rbalint/update-manager/retry-after-failed-transaction into lp:update-manager

Proposed by Balint Reczey
Status: Merged
Merged at revision: 2836
Proposed branch: lp:~rbalint/update-manager/retry-after-failed-transaction
Merge into: lp:update-manager
Diff against target: 159 lines (+50/-14)
5 files modified
UpdateManager/Core/MyCache.py (+2/-0)
UpdateManager/UpdateManager.py (+2/-2)
UpdateManager/backend/InstallBackendAptdaemon.py (+9/-1)
UpdateManager/backend/__init__.py (+23/-11)
debian/changelog (+14/-0)
To merge this branch: bzr merge lp:~rbalint/update-manager/retry-after-failed-transaction
Reviewer Review Type Date Requested Status
Julian Andres Klode Approve
Brian Murray Pending
Review via email: mp+354648@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Balint Reczey (rbalint) wrote :

Since update-manager does not hold a lock unattended-upgrades can change installed packages behind its back and u-m gets a failed transaction due to holding an outdated cache.
The user is now notified about the problem and can try again.

Revision history for this message
Julian Andres Klode (juliank) wrote :

bug 1702083 is

  File "/usr/lib/python3/dist-packages/UpdateManager/Core/UpdateList.py", line 471, in update
    self.distUpgradeWouldDelete = cache.saveDistUpgrade()
AttributeError: 'NoneType' object has no attribute 'saveDistUpgrade'

I don't see how that's relevant here.

Revision history for this message
Balint Reczey (rbalint) wrote :

> bug 1702083 is
>
> File "/usr/lib/python3/dist-packages/UpdateManager/Core/UpdateList.py", line
> 471, in update
> self.distUpgradeWouldDelete = cache.saveDistUpgrade()
> AttributeError: 'NoneType' object has no attribute 'saveDistUpgrade'
>
> I don't see how that's relevant here.

Ah, yes, sorry, fixed to LP: #1791931

Revision history for this message
Julian Andres Klode (juliank) wrote :

Needs some fixing

review: Needs Fixing
2837. By Balint Reczey

Don't ask backend to do package operations aready done

Aptdaemon cancels the transaction when asked to remove packages already
removed which results the failure being shown to the user. This
is unnecessary as update-manager can just filter the package operations to
be done using a fresh cache and decrease the likelyhood of hitting
a race condition where packages to be removed are already removed.

LP: #1791931

2838. By Balint Reczey

Update changelog

Revision history for this message
Balint Reczey (rbalint) wrote :

> Needs some fixing

Thanks, fixed those.

Revision history for this message
Julian Andres Klode (juliank) wrote :

lgtm

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'UpdateManager/Core/MyCache.py'
--- UpdateManager/Core/MyCache.py 2018-03-18 21:43:58 +0000
+++ UpdateManager/Core/MyCache.py 2018-09-11 14:59:42 +0000
@@ -68,6 +68,8 @@
6868
69 def __init__(self, progress, rootdir=None):69 def __init__(self, progress, rootdir=None):
70 apt.Cache.__init__(self, progress, rootdir)70 apt.Cache.__init__(self, progress, rootdir)
71 # save for later
72 self.rootdir = rootdir
71 # raise if we have packages in reqreinst state73 # raise if we have packages in reqreinst state
72 # and let the caller deal with that (runs partial upgrade)74 # and let the caller deal with that (runs partial upgrade)
73 assert len(self.req_reinstall_pkgs) == 075 assert len(self.req_reinstall_pkgs) == 0
7476
=== modified file 'UpdateManager/UpdateManager.py'
--- UpdateManager/UpdateManager.py 2018-06-08 06:35:03 +0000
+++ UpdateManager/UpdateManager.py 2018-09-11 14:59:42 +0000
@@ -272,8 +272,8 @@
272 return HWEUpgradeDialog(self)272 return HWEUpgradeDialog(self)
273 return UpdatesAvailable(self, header, desc, need_reboot)273 return UpdatesAvailable(self, header, desc, need_reboot)
274274
275 def start_error(self, is_update_error, header, desc):275 def start_error(self, update_and_retry, header, desc):
276 if is_update_error:276 if update_and_retry:
277 self._start_pane(UpdateErrorDialog(self, header, desc))277 self._start_pane(UpdateErrorDialog(self, header, desc))
278 else:278 else:
279 self._start_pane(ErrorDialog(self, header, desc))279 self._start_pane(ErrorDialog(self, header, desc))
280280
=== modified file 'UpdateManager/backend/InstallBackendAptdaemon.py'
--- UpdateManager/backend/InstallBackendAptdaemon.py 2018-03-26 12:33:11 +0000
+++ UpdateManager/backend/InstallBackendAptdaemon.py 2018-09-11 14:59:42 +0000
@@ -46,6 +46,7 @@
46 self.unity = UnitySupport()46 self.unity = UnitySupport()
47 self._expanded_size = None47 self._expanded_size = None
48 self.button_cancel = None48 self.button_cancel = None
49 self.trans_failed_msg = None
4950
50 def close(self):51 def close(self):
51 if self.button_cancel:52 if self.button_cancel:
@@ -94,6 +95,8 @@
94 self._action_done(self.ACTION_INSTALL,95 self._action_done(self.ACTION_INSTALL,
95 authorized=False, success=False,96 authorized=False, success=False,
96 error_string=None, error_desc=None)97 error_string=None, error_desc=None)
98 except errors.TransactionFailed as e:
99 self.trans_failed_msg = str(e)
97 except dbus.DBusException as e:100 except dbus.DBusException as e:
98 #print(e, e.get_dbus_name())101 #print(e, e.get_dbus_name())
99 if e.get_dbus_name() != "org.freedesktop.DBus.Error.NoReply":102 if e.get_dbus_name() != "org.freedesktop.DBus.Error.NoReply":
@@ -223,15 +226,20 @@
223 def _on_finished(self, trans, status, action):226 def _on_finished(self, trans, status, action):
224 error_string = None227 error_string = None
225 error_desc = None228 error_desc = None
229 trans_failed = False
226 if status == EXIT_FAILED:230 if status == EXIT_FAILED:
227 error_string = get_error_string_from_enum(trans.error.code)231 error_string = get_error_string_from_enum(trans.error.code)
228 error_desc = get_error_description_from_enum(trans.error.code)232 error_desc = get_error_description_from_enum(trans.error.code)
233 if self.trans_failed_msg:
234 trans_failed = True
235 error_desc = error_desc + "\n" + self.trans_failed_msg
229 # tell unity to hide the progress again236 # tell unity to hide the progress again
230 self.unity.set_progress(-1)237 self.unity.set_progress(-1)
231 is_success = (status == EXIT_SUCCESS)238 is_success = (status == EXIT_SUCCESS)
232 self._action_done(action,239 self._action_done(action,
233 authorized=True, success=is_success,240 authorized=True, success=is_success,
234 error_string=error_string, error_desc=error_desc)241 error_string=error_string, error_desc=error_desc,
242 trans_failed=trans_failed)
235243
236244
237if __name__ == "__main__":245if __name__ == "__main__":
238246
=== modified file 'UpdateManager/backend/__init__.py'
--- UpdateManager/backend/__init__.py 2018-03-26 12:33:11 +0000
+++ UpdateManager/backend/__init__.py 2018-09-11 14:59:42 +0000
@@ -8,6 +8,7 @@
88
9from gi.repository import GLib9from gi.repository import GLib
1010
11from apt import Cache
11import os12import os
1213
13from UpdateManager.Core.utils import inhibit_sleep14from UpdateManager.Core.utils import inhibit_sleep
@@ -34,16 +35,26 @@
34 pkgs_install = []35 pkgs_install = []
35 pkgs_upgrade = []36 pkgs_upgrade = []
36 pkgs_remove = []37 pkgs_remove = []
38 # Get a fresh cache in case update-manager's is outdated to
39 # skip operations that already took place
40 fresh_cache = Cache(rootdir=self.window_main.cache.rootdir)
37 for pkg in self.window_main.cache:41 for pkg in self.window_main.cache:
38 if pkg.marked_install:42 try:
39 pkgname = pkg.name43 if pkg.marked_install and \
40 if pkg.is_auto_installed:44 not fresh_cache[pkg.name].is_installed:
41 pkgname += "#auto"45 pkgname = pkg.name
42 pkgs_install.append(pkgname)46 if pkg.is_auto_installed:
43 elif pkg.marked_upgrade:47 pkgname += "#auto"
44 pkgs_upgrade.append(pkg.name)48 pkgs_install.append(pkgname)
45 elif pkg.marked_delete:49 elif (pkg.marked_upgrade and
46 pkgs_remove.append(pkg.name)50 fresh_cache[pkg.name].is_upgradable):
51 pkgs_upgrade.append(pkg.name)
52 elif (pkg.marked_delete and
53 fresh_cache[pkg.name].is_installed):
54 pkgs_remove.append(pkg.name)
55 except KeyError:
56 # pkg missing from fresh_cache can't be modified
57 pass
47 self.commit(pkgs_install, pkgs_upgrade, pkgs_remove)58 self.commit(pkgs_install, pkgs_upgrade, pkgs_remove)
48 else:59 else:
49 self.update()60 self.update()
@@ -57,7 +68,7 @@
57 raise NotImplemented68 raise NotImplemented
5869
59 def _action_done(self, action, authorized, success, error_string,70 def _action_done(self, action, authorized, success, error_string,
60 error_desc):71 error_desc, trans_failed=False):
6172
62 # If the progress dialog should be closed automatically afterwards73 # If the progress dialog should be closed automatically afterwards
63 #settings = Gio.Settings.new("com.ubuntu.update-manager")74 #settings = Gio.Settings.new("com.ubuntu.update-manager")
@@ -70,7 +81,8 @@
70 if success:81 if success:
71 self.window_main.start_available()82 self.window_main.start_available()
72 elif error_string:83 elif error_string:
73 self.window_main.start_error(False, error_string, error_desc)84 self.window_main.start_error(trans_failed, error_string,
85 error_desc)
74 else:86 else:
75 # exit gracefuly, we can't just exit as this will trigger87 # exit gracefuly, we can't just exit as this will trigger
76 # a crash if system.exit() is called in a exception handler88 # a crash if system.exit() is called in a exception handler
7789
=== modified file 'debian/changelog'
--- debian/changelog 2018-09-06 07:10:42 +0000
+++ debian/changelog 2018-09-11 14:59:42 +0000
@@ -1,3 +1,17 @@
1update-manager (1:18.10.8) UNRELEASED; urgency=medium
2
3 * Print transaction error and let the user try again applying updates
4 (LP: #1317164)
5 * Don't ask backend to do package operations aready done.
6 Aptdaemon cancels the transaction when asked to remove packages already
7 removed which results the failure being shown to the user. This
8 is unnecessary as update-manager can just filter the package operations to
9 be done using a fresh cache and decrease the likelyhood of hitting
10 a race condition where packages to be removed are already removed.
11 (LP: #1791931)
12
13 -- Balint Reczey <rbalint@ubuntu.com> Tue, 11 Sep 2018 13:40:57 +0200
14
1update-manager (1:18.10.7) cosmic; urgency=medium15update-manager (1:18.10.7) cosmic; urgency=medium
216
3 * Fix PEP8 regression from 18.10.4 to allow autopkgtest to pass17 * Fix PEP8 regression from 18.10.4 to allow autopkgtest to pass

Subscribers

People subscribed via source and target branches

to status/vote changes: