Merge lp://qastaging/~glatzor/update-manager/ubuntu-glatzor into lp://qastaging/update-manager
- ubuntu-glatzor
- Merge into main
Proposed by
Sebastian Heinlein
Status: | Merged |
---|---|
Merged at revision: | 1828 |
Proposed branch: | lp://qastaging/~glatzor/update-manager/ubuntu-glatzor |
Merge into: | lp://qastaging/update-manager |
Diff against target: |
366 lines (+128/-144) 4 files modified
UpdateManager/UpdateManager.py (+34/-13) UpdateManager/backend/InstallBackend.py (+12/-1) UpdateManager/backend/InstallBackendAptdaemon.py (+42/-76) UpdateManager/backend/InstallBackendSynaptic.py (+40/-54) |
To merge this branch: | bzr merge lp://qastaging/~glatzor/update-manager/ubuntu-glatzor |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Core Development Team | Pending | ||
Review via email: mp+16123@code.qastaging.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Sebastian Heinlein (glatzor) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'UpdateManager/UpdateManager.py' | |||
2 | --- UpdateManager/UpdateManager.py 2009-11-23 11:09:20 +0000 | |||
3 | +++ UpdateManager/UpdateManager.py 2009-12-14 12:35:26 +0000 | |||
4 | @@ -121,6 +121,12 @@ | |||
5 | 121 | except: | 121 | except: |
6 | 122 | logging.exception("setlocale failed") | 122 | logging.exception("setlocale failed") |
7 | 123 | 123 | ||
8 | 124 | # Used for inhibiting power management | ||
9 | 125 | self.sleep_cookie = None | ||
10 | 126 | self.sleep_dev = None | ||
11 | 127 | |||
12 | 128 | self.reboot_required = False | ||
13 | 129 | |||
14 | 124 | self.image_logo.set_from_icon_name("update-manager", gtk.ICON_SIZE_DIALOG) | 130 | self.image_logo.set_from_icon_name("update-manager", gtk.ICON_SIZE_DIALOG) |
15 | 125 | self.window_main.set_sensitive(False) | 131 | self.window_main.set_sensitive(False) |
16 | 126 | self.window_main.grab_focus() | 132 | self.window_main.grab_focus() |
17 | @@ -213,7 +219,7 @@ | |||
18 | 213 | self.window_main.show() | 219 | self.window_main.show() |
19 | 214 | # get the install backend | 220 | # get the install backend |
20 | 215 | self.install_backend = backend.backend_factory(self.window_main) | 221 | self.install_backend = backend.backend_factory(self.window_main) |
22 | 216 | 222 | self.install_backend.connect("action-done", self._on_backend_done) | |
23 | 217 | # it can only the iconified *after* it is shown (even if the docs | 223 | # it can only the iconified *after* it is shown (even if the docs |
24 | 218 | # claim otherwise) | 224 | # claim otherwise) |
25 | 219 | if options.no_focus_on_map: | 225 | if options.no_focus_on_map: |
26 | @@ -615,29 +621,44 @@ | |||
27 | 615 | os.environ["APT_LISTCHANGES_FRONTEND"]="none" | 621 | os.environ["APT_LISTCHANGES_FRONTEND"]="none" |
28 | 616 | 622 | ||
29 | 617 | # Do not suspend during the update process | 623 | # Do not suspend during the update process |
31 | 618 | (dev, cookie) = inhibit_sleep() | 624 | (self.sleep_dev, self.sleep_cookie) = inhibit_sleep() |
32 | 619 | 625 | ||
33 | 620 | # set window to insensitive | 626 | # set window to insensitive |
34 | 621 | self.window_main.set_sensitive(False) | 627 | self.window_main.set_sensitive(False) |
35 | 622 | self.window_main.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) | 628 | self.window_main.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) |
37 | 623 | 629 | # | |
38 | 624 | # do it | 630 | # do it |
39 | 625 | if action == UPDATE: | 631 | if action == UPDATE: |
40 | 626 | self.install_backend.update() | 632 | self.install_backend.update() |
41 | 627 | elif action == INSTALL: | 633 | elif action == INSTALL: |
50 | 628 | has_reboot = os.path.exists(REBOOT_REQUIRED_FILE) | 634 | # If the progress dialog should be closed automatically afterwards |
51 | 629 | # do it | 635 | gconfclient = gconf.client_get_default() |
52 | 630 | self.install_backend.commit(self.cache) | 636 | close_on_done = gconfclient.get_bool("/apps/update-manager/" |
53 | 631 | # check if there is a new reboot required notification | 637 | "autoclose_install_window") |
54 | 632 | if not has_reboot and os.path.exists(REBOOT_REQUIRED_FILE): | 638 | # Get the packages which should be installed and update |
55 | 633 | self.show_reboot_required_dialog() | 639 | pkgs_install = [] |
56 | 634 | s = _("Reading package information") | 640 | pkgs_upgrade = [] |
57 | 635 | self.label_cache_progress_title.set_label("<b><big>%s</big></b>" % s) | 641 | for pkg in self.cache: |
58 | 642 | if pkg.markedInstall: | ||
59 | 643 | pkgs_install.append(pkg.name) | ||
60 | 644 | elif pkg.markedUpgrade: | ||
61 | 645 | pkgs_upgrade.append(pkg.name) | ||
62 | 646 | self.reboot_required = os.path.exists(REBOOT_REQUIRED_FILE) | ||
63 | 647 | self.install_backend.commit(pkgs_install, pkgs_upgrade, close_on_done) | ||
64 | 648 | |||
65 | 649 | def _on_backend_done(self, backend, action): | ||
66 | 650 | # check if there is a new reboot required notification | ||
67 | 651 | if action == INSTALL and not self.reboot_required and \ | ||
68 | 652 | os.path.exists(REBOOT_REQUIRED_FILE): | ||
69 | 653 | self.show_reboot_required_dialog() | ||
70 | 654 | msg = _("Reading package information") | ||
71 | 655 | self.label_cache_progress_title.set_label("<b><big>%s</big></b>" % msg) | ||
72 | 636 | self.fillstore() | 656 | self.fillstore() |
73 | 637 | 657 | ||
74 | 638 | # Allow suspend after synaptic is finished | 658 | # Allow suspend after synaptic is finished |
77 | 639 | if cookie != False: | 659 | if self.sleep_cookie: |
78 | 640 | allow_sleep(dev, cookie) | 660 | allow_sleep(self.sleep_dev, self.sleep_cookie) |
79 | 661 | self.sleep_cookie = self.sleep_dev = None | ||
80 | 641 | self.window_main.set_sensitive(True) | 662 | self.window_main.set_sensitive(True) |
81 | 642 | self.window_main.window.set_cursor(None) | 663 | self.window_main.window.set_cursor(None) |
82 | 643 | 664 | ||
83 | 644 | 665 | ||
84 | === modified file 'UpdateManager/backend/InstallBackend.py' | |||
85 | --- UpdateManager/backend/InstallBackend.py 2009-07-24 14:17:02 +0000 | |||
86 | +++ UpdateManager/backend/InstallBackend.py 2009-12-14 12:35:26 +0000 | |||
87 | @@ -1,18 +1,29 @@ | |||
88 | 1 | # (c) 2005-2009 Canonical, GPL | 1 | # (c) 2005-2009 Canonical, GPL |
89 | 2 | # | 2 | # |
90 | 3 | 3 | ||
92 | 4 | class InstallBackend(object): | 4 | import gobject |
93 | 5 | |||
94 | 6 | class InstallBackend(gobject.GObject): | ||
95 | 5 | """The abstract backend that can install/remove packages""" | 7 | """The abstract backend that can install/remove packages""" |
96 | 8 | |||
97 | 9 | __gsignals__ = {"action-done": (gobject.SIGNAL_RUN_FIRST, | ||
98 | 10 | gobject.TYPE_NONE, (gobject.TYPE_INT,))} | ||
99 | 11 | |||
100 | 12 | (INSTALL, UPDATE) = range(2) | ||
101 | 13 | |||
102 | 6 | def __init__(self, window_main): | 14 | def __init__(self, window_main): |
103 | 7 | """init backend | 15 | """init backend |
104 | 8 | takes a gtk main window as parameter | 16 | takes a gtk main window as parameter |
105 | 9 | """ | 17 | """ |
106 | 18 | gobject.GObject.__init__(self) | ||
107 | 10 | self.window_main = window_main | 19 | self.window_main = window_main |
108 | 11 | 20 | ||
109 | 12 | def commit(self, cache): | 21 | def commit(self, cache): |
110 | 13 | """Commit the cache changes """ | 22 | """Commit the cache changes """ |
111 | 23 | raise NotImplemented | ||
112 | 14 | 24 | ||
113 | 15 | def update(self): | 25 | def update(self): |
114 | 16 | """Run a update to refresh the package list""" | 26 | """Run a update to refresh the package list""" |
115 | 27 | raise NotImplemented | ||
116 | 17 | 28 | ||
117 | 18 | 29 | ||
118 | 19 | 30 | ||
119 | === modified file 'UpdateManager/backend/InstallBackendAptdaemon.py' | |||
120 | --- UpdateManager/backend/InstallBackendAptdaemon.py 2009-10-08 07:51:51 +0000 | |||
121 | +++ UpdateManager/backend/InstallBackendAptdaemon.py 2009-12-14 12:35:26 +0000 | |||
122 | @@ -1,87 +1,53 @@ | |||
123 | 1 | # (c) 2005-2009 Canonical, GPL | 1 | # (c) 2005-2009 Canonical, GPL |
124 | 2 | # | 2 | # |
125 | 3 | 3 | ||
136 | 4 | import apt_pkg | 4 | from aptdaemon import client, enums |
137 | 5 | import gobject | 5 | from aptdaemon.gtkwidgets import AptProgressDialog |
128 | 6 | import gtk | ||
129 | 7 | |||
130 | 8 | import dbus | ||
131 | 9 | from aptdaemon import client | ||
132 | 10 | from aptdaemon.enums import * | ||
133 | 11 | from aptdaemon.gtkwidgets import (AptErrorDialog, | ||
134 | 12 | AptProgressDialog, | ||
135 | 13 | AptMessageDialog) | ||
138 | 14 | 6 | ||
139 | 15 | from InstallBackend import InstallBackend | 7 | from InstallBackend import InstallBackend |
140 | 16 | 8 | ||
141 | 9 | POLKIT_ERROR_NOT_AUTHORIZED = "org.freedesktop.PolicyKit.Error.NotAuthorized" | ||
142 | 17 | 10 | ||
143 | 18 | class InstallBackendAptdaemon(InstallBackend): | 11 | class InstallBackendAptdaemon(InstallBackend): |
152 | 19 | """The abstract backend that can install/remove packages""" | 12 | |
153 | 20 | 13 | """Makes use of aptdaemon to refresh the cache and to install updates.""" | |
154 | 21 | def _get_icon(self): | 14 | |
155 | 22 | theme = gtk.icon_theme_get_default () | 15 | def update(self): |
156 | 23 | icon = theme.load_icon("update-manager", 16, 0) | 16 | """Run a update to refresh the package list""" |
157 | 24 | return icon | 17 | ac = client.AptClient() |
158 | 25 | 18 | ac.update_cache(reply_handler=self._run_transaction, | |
159 | 26 | def commit(self, cache): | 19 | error_handler=self._on_error) |
160 | 20 | |||
161 | 21 | def commit(self, pkgs_install, pkgs_upgrade, close_on_done): | ||
162 | 27 | """Commit a list of package adds and removes""" | 22 | """Commit a list of package adds and removes""" |
175 | 28 | try: | 23 | ac = client.AptClient() |
164 | 29 | apt_pkg.PkgSystemUnLock() | ||
165 | 30 | except SystemError: | ||
166 | 31 | pass | ||
167 | 32 | self.ac = client.AptClient() | ||
168 | 33 | add = [] | ||
169 | 34 | upgrade = [] | ||
170 | 35 | for pkg in cache: | ||
171 | 36 | if pkg.markedInstall: | ||
172 | 37 | add.append(pkg.name) | ||
173 | 38 | elif pkg.markedUpgrade: | ||
174 | 39 | upgrade.append(pkg.name) | ||
176 | 40 | # parameter order: install, reinstall, remove, purge, upgrade | 24 | # parameter order: install, reinstall, remove, purge, upgrade |
196 | 41 | t = self.ac.commit_packages(add, [], [], [], upgrade, | 25 | _reply_handler = lambda trans: self._run_transaction(trans, |
197 | 42 | exit_handler=self._on_exit) | 26 | close_on_done) |
198 | 43 | dia = AptProgressDialog(t, parent=self.window_main) | 27 | ac.commit_packages(pkgs_install, [], [], [], pkgs_upgrade, |
199 | 44 | dia.set_icon(self._get_icon()) | 28 | reply_handler=_reply_handler, |
200 | 45 | try: | 29 | error_handler=self._on_error) |
201 | 46 | dia.run() | 30 | |
202 | 47 | except dbus.exceptions.DBusException, e: | 31 | def _run_transaction(self, trans, close=True): |
203 | 48 | if e._dbus_error_name == "org.freedesktop.PolicyKit.Error.NotAuthorized": | 32 | dia = AptProgressDialog(trans, parent=self.window_main) |
204 | 49 | pass | 33 | dia.set_icon_name("update-manager") |
205 | 50 | else: | 34 | dia.connect("finished", self._on_finished) |
206 | 51 | raise | 35 | dia.run(show_error=True, close_on_finished=close, |
207 | 52 | dia.hide() | 36 | reply_handler=lambda: True, |
208 | 53 | self._show_messages(t) | 37 | error_handler=self._on_error) |
209 | 54 | 38 | ||
210 | 55 | def update(self): | 39 | def _on_finished(self, dialog): |
211 | 56 | """Run a update to refresh the package list""" | 40 | dialog.destroy() |
212 | 57 | try: | 41 | if dialog._transaction.role == enums.ROLE_UPDATE_CACHE: |
213 | 58 | apt_pkg.PkgSystemUnLock() | 42 | action = self.UPDATE |
214 | 59 | except SystemError: | 43 | else: |
215 | 44 | action = self.INSTALL | ||
216 | 45 | self.emit("action-done", action) | ||
217 | 46 | |||
218 | 47 | def _on_error(self, error): | ||
219 | 48 | if error.get_dbus_name() == POLKIT_ERROR_NOT_AUTHORIZED: | ||
220 | 49 | # Should already be handled by the polkit agent | ||
221 | 60 | pass | 50 | pass |
249 | 61 | self.ac = client.AptClient() | 51 | else: |
250 | 62 | t = self.ac.update_cache(exit_handler=self._on_exit) | 52 | #FIXME: Show an error dialog |
251 | 63 | dia = AptProgressDialog(t, parent=self.window_main, terminal=False) | 53 | raise error |
225 | 64 | dia.set_icon(self._get_icon()) | ||
226 | 65 | try: | ||
227 | 66 | dia.run() | ||
228 | 67 | except dbus.exceptions.DBusException, e: | ||
229 | 68 | if e._dbus_error_name == "org.freedesktop.PolicyKit.Error.NotAuthorized": | ||
230 | 69 | pass | ||
231 | 70 | else: | ||
232 | 71 | raise | ||
233 | 72 | dia.hide() | ||
234 | 73 | self._show_messages(t) | ||
235 | 74 | |||
236 | 75 | def _on_exit(self, trans, exit): | ||
237 | 76 | if exit == EXIT_FAILED: | ||
238 | 77 | d = AptErrorDialog(trans.get_error(), parent=self.window_main) | ||
239 | 78 | d.run() | ||
240 | 79 | d.hide() | ||
241 | 80 | |||
242 | 81 | def _show_messages(self, trans): | ||
243 | 82 | while gtk.events_pending(): | ||
244 | 83 | gtk.main_iteration() | ||
245 | 84 | for msg in trans._messages: | ||
246 | 85 | d = AptMessageDialog(msg.enum, msg.details, parent=self.window_main) | ||
247 | 86 | d.run() | ||
248 | 87 | d.hide() | ||
252 | 88 | 54 | ||
253 | === modified file 'UpdateManager/backend/InstallBackendSynaptic.py' | |||
254 | --- UpdateManager/backend/InstallBackendSynaptic.py 2009-07-24 14:17:02 +0000 | |||
255 | +++ UpdateManager/backend/InstallBackendSynaptic.py 2009-12-14 12:35:26 +0000 | |||
256 | @@ -12,15 +12,14 @@ | |||
257 | 12 | import gconf | 12 | import gconf |
258 | 13 | from gettext import gettext as _ | 13 | from gettext import gettext as _ |
259 | 14 | 14 | ||
260 | 15 | import gobject | ||
261 | 16 | |||
262 | 15 | from InstallBackend import InstallBackend | 17 | from InstallBackend import InstallBackend |
263 | 16 | 18 | ||
264 | 17 | class InstallBackendSynaptic(InstallBackend): | 19 | class InstallBackendSynaptic(InstallBackend): |
265 | 18 | """ Install backend based on synaptic """ | 20 | """ Install backend based on synaptic """ |
266 | 19 | |||
267 | 20 | # synaptic actions | ||
268 | 21 | (INSTALL, UPDATE) = range(2) | ||
269 | 22 | 21 | ||
271 | 23 | def _run_synaptic(self, id, lock, cache=None, action=INSTALL): | 22 | def _run_synaptic(self, action, opt, tempf): |
272 | 24 | try: | 23 | try: |
273 | 25 | apt_pkg.PkgSystemUnLock() | 24 | apt_pkg.PkgSystemUnLock() |
274 | 26 | except SystemError: | 25 | except SystemError: |
275 | @@ -28,54 +27,41 @@ | |||
276 | 28 | cmd = ["/usr/bin/gksu", | 27 | cmd = ["/usr/bin/gksu", |
277 | 29 | "--desktop", "/usr/share/applications/update-manager.desktop", | 28 | "--desktop", "/usr/share/applications/update-manager.desktop", |
278 | 30 | "--", "/usr/sbin/synaptic", "--hide-main-window", | 29 | "--", "/usr/sbin/synaptic", "--hide-main-window", |
322 | 31 | "--non-interactive", "--parent-window-id", "%s" % (id) ] | 30 | "--non-interactive", "--parent-window-id", |
323 | 32 | if action == self.INSTALL: | 31 | "%s" % self.window_main.window.xid ] |
324 | 33 | # close when update was successful (its ok to use a Synaptic:: | 32 | cmd.extend(opt) |
325 | 34 | # option here, it will not get auto-saved, because synaptic does | 33 | flags = gobject.SPAWN_DO_NOT_REAP_CHILD |
326 | 35 | # not save options in non-interactive mode) | 34 | (pid, stdin, stdout, stderr) = gobject.spawn_async(cmd, flags=flags) |
327 | 36 | gconfclient = gconf.client_get_default() | 35 | gobject.child_watch_add(pid, self._on_synaptic_exit, (action, tempf)) |
328 | 37 | if gconfclient.get_bool("/apps/update-manager/autoclose_install_window"): | 36 | |
329 | 38 | cmd.append("-o") | 37 | def _on_synaptic_exit(self, pid, condition, data): |
330 | 39 | cmd.append("Synaptic::closeZvt=true") | 38 | action, tempf = data |
331 | 40 | # custom progress strings | 39 | if tempf: |
332 | 41 | cmd.append("--progress-str") | 40 | tempf.close() |
333 | 42 | cmd.append("%s" % _("Please wait, this can take some time.")) | 41 | self.emit("action-done", action) |
334 | 43 | cmd.append("--finish-str") | 42 | |
292 | 44 | cmd.append("%s" % _("Update is complete")) | ||
293 | 45 | f = tempfile.NamedTemporaryFile() | ||
294 | 46 | for pkg in cache: | ||
295 | 47 | if pkg.markedInstall or pkg.markedUpgrade: | ||
296 | 48 | f.write("%s\tinstall\n" % pkg.name) | ||
297 | 49 | cmd.append("--set-selections-file") | ||
298 | 50 | cmd.append("%s" % f.name) | ||
299 | 51 | f.flush() | ||
300 | 52 | self.return_code = subprocess.call(cmd) | ||
301 | 53 | f.close() | ||
302 | 54 | elif action == self.UPDATE: | ||
303 | 55 | cmd.append("--update-at-startup") | ||
304 | 56 | self.return_code = subprocess.call(cmd) | ||
305 | 57 | else: | ||
306 | 58 | print "run_synaptic() called with unknown action" | ||
307 | 59 | return False | ||
308 | 60 | lock.release() | ||
309 | 61 | |||
310 | 62 | def _perform_action(self, action, cache=None): | ||
311 | 63 | lock = thread.allocate_lock() | ||
312 | 64 | lock.acquire() | ||
313 | 65 | t = thread.start_new_thread(self._run_synaptic, | ||
314 | 66 | (self.window_main.window.xid, | ||
315 | 67 | lock, cache, action)) | ||
316 | 68 | while lock.locked(): | ||
317 | 69 | while gtk.events_pending(): | ||
318 | 70 | gtk.main_iteration() | ||
319 | 71 | time.sleep(0.05) | ||
320 | 72 | return self.return_code | ||
321 | 73 | |||
335 | 74 | def update(self): | 43 | def update(self): |
343 | 75 | return self._perform_action(self.UPDATE) | 44 | opt = ["--update-at-startup"] |
344 | 76 | 45 | tempf = None | |
345 | 77 | def commit(self, cache): | 46 | self._run_synaptic(self.UPDATE, opt, tempf) |
346 | 78 | return self._perform_action(self.INSTALL, cache) | 47 | |
347 | 79 | 48 | def commit(self, pkgs_install, pkgs_upgrade, close_on_done): | |
348 | 80 | 49 | # close when update was successful (its ok to use a Synaptic:: | |
349 | 81 | 50 | # option here, it will not get auto-saved, because synaptic does | |
350 | 51 | # not save options in non-interactive mode) | ||
351 | 52 | opt = [] | ||
352 | 53 | if close_on_done: | ||
353 | 54 | opt.append("-o") | ||
354 | 55 | opt.append("Synaptic::closeZvt=true") | ||
355 | 56 | # custom progress strings | ||
356 | 57 | opt.append("--progress-str") | ||
357 | 58 | opt.append("%s" % _("Please wait, this can take some time.")) | ||
358 | 59 | opt.append("--finish-str") | ||
359 | 60 | opt.append("%s" % _("Update is complete")) | ||
360 | 61 | tempf = tempfile.NamedTemporaryFile() | ||
361 | 62 | for pkg_name in pkgs_install + pkgs_upgrade: | ||
362 | 63 | tempf.write("%s\tinstall\n" % pkg_name) | ||
363 | 64 | opt.append("--set-selections-file") | ||
364 | 65 | opt.append("%s" % tempf.name) | ||
365 | 66 | tempf.flush() | ||
366 | 67 | self._run_synaptic(self.INSTALL, opt, tempf) |
Ported to latest aptdaemon API and simplified the InstallBackends