~ubuntu-branches/debian/sid/aptdaemon/sid

« back to all changes in this revision

Viewing changes to aptdaemon/core.py

  • Committer: Package Import Robot
  • Author(s): Julian Andres Klode
  • Date: 2012-03-05 16:03:14 UTC
  • mfrom: (18.1.73 precise)
  • Revision ID: package-import@ubuntu.com-20120305160314-zhwgowgtnu14tlc2
Tags: 0.43+bzr769-1
* New upstream snapshot
  - Works without pkcompat (Closes: #652644)
* Merge with Ubuntu; remaining changes:
  - debian/control: Changes of Vcs, Maintainer stuff
  - Do not use dh-translations

Show diffs side-by-side

added added

removed removed

Lines of Context:
49
49
import time
50
50
import uuid
51
51
 
52
 
import gobject
 
52
from gi.repository import GObject
53
53
import dbus.exceptions
54
54
import dbus.service
55
55
import dbus.mainloop.glib
57
57
from softwareproperties.AptAuth import AptAuth
58
58
import apt_pkg
59
59
 
60
 
from config import ConfigWriter
61
 
import errors
62
 
import enums
63
 
from defer import inline_callbacks, return_value
 
60
from .config import ConfigWriter
 
61
from . import errors
 
62
from . import enums
 
63
from defer import inline_callbacks, return_value, Deferred
64
64
from defer.utils import dbus_deferred_method
65
 
import policykit1
66
 
from worker import AptWorker, DummyWorker
67
 
from loop import mainloop
 
65
from . import policykit1
 
66
from .worker import AptWorker, DummyWorker
 
67
from .loop import mainloop
68
68
 
69
69
# Setup i18n
70
70
_ = lambda msg: gettext.dgettext("aptdaemon", msg)
389
389
        self._unauthenticated = dbus.Array([], signature=dbus.Signature('s'))
390
390
        # Add a timeout which removes the transaction from the bus if it
391
391
        # hasn't been setup and run for the TRANSACTION_IDLE_TIMEOUT period
392
 
        self._idle_watch = gobject.timeout_add_seconds(
 
392
        self._idle_watch = GObject.timeout_add_seconds(
393
393
            TRANSACTION_IDLE_TIMEOUT, self._remove_from_connection_no_raise)
394
394
        # Handle a disconnect of the client application
395
395
        self.sender_alive = True
401
401
        self.sender = sender
402
402
        self.output = ""
403
403
        self.simulated = None
 
404
        self._simulated_cb = None
404
405
 
405
406
    def _sender_owner_changed(self, connection):
406
407
        """Callback if the owner of the original sender changed, e.g.
415
416
        log_trans.debug("Removing transaction")
416
417
        try:
417
418
            self.remove_from_connection()
418
 
        except LookupError, error:
 
419
        except LookupError as error:
419
420
            log_trans.debug("remove_from_connection() raised LookupError: "
420
421
                            "'%s'" % error)
421
422
        # Forget a not yet queued transaction
447
448
                else:
448
449
                    raise Exception("Value %s with unknown signature %s" % \
449
450
                                    (item, signature[num]))
450
 
            except Exception, error:
 
451
            except Exception as error:
451
452
                raise error.__class__("Failed to convert item %s of %s with "
452
453
                                      "signature %s: %s" % (num, lst,
453
454
                                                            signature,
461
462
        if not isinstance(data, dbus.Dictionary):
462
463
            raise errors.InvalidMetaDataError("The data value has to be a "
463
464
                                              "dictionary: %s" % data)
 
465
        if not data.signature.startswith("s"):
 
466
            raise errors.InvalidMetaDataError("Only strings are accepted "
 
467
                                              "as keys.")
464
468
        for key, value in data.iteritems():
465
469
            if key in self._meta_data:
466
470
                raise errors.InvalidMetaDataError("The key %s already "
529
533
            self._sender_watch.cancel()
530
534
        # Remove the transaction from the Bus after it is complete. A short
531
535
        # timeout helps lazy clients
532
 
        gobject.timeout_add_seconds(TRANSACTION_DEL_TIMEOUT,
 
536
        GObject.timeout_add_seconds(TRANSACTION_DEL_TIMEOUT,
533
537
                                    self._remove_from_connection_no_raise)
534
538
 
535
539
    def _get_exit(self):
868
872
    def _run(self, sender):
869
873
        yield self._check_foreign_user(sender)
870
874
        yield self._check_auth()
871
 
        self.queue.put(self.tid)
 
875
        yield self.queue.put(self.tid)
872
876
        self.status = enums.STATUS_WAITING
873
877
        next_trans = self.after
874
878
        while next_trans:
875
879
            yield next_trans._check_auth()
876
 
            self.queue.put(next_trans.tid)
 
880
            yield self.queue.put(next_trans.tid)
877
881
            next_trans.status = enums.STATUS_WAITING
878
882
            next_trans = next_trans.after
879
883
 
919
923
                                                             action,
920
924
                                                             bus=self.bus,
921
925
                                                             flags=flags)
922
 
            except errors.NotAuthorizedError, error:
 
926
            except errors.NotAuthorizedError as error:
923
927
                continue
924
928
            else:
925
929
                return_value(True)
975
979
 
976
980
    @inline_callbacks
977
981
    def _simulate(self, sender):
 
982
        if self._simulated_cb:
 
983
            raise errors.TransactionAlreadySimulating()
978
984
        if self.status != enums.STATUS_SETTING_UP:
979
985
            raise errors.TransactionAlreadyRunning()
980
986
        yield self._check_foreign_user(sender)
981
987
        self.queue.worker.simulate(self)
 
988
        deferred = Deferred()
982
989
        if self._idle_watch is not None:
983
 
            gobject.source_remove(self._idle_watch)
984
 
            self._idle_watch = None
 
990
            GObject.source_remove(self._idle_watch)
 
991
        self._idle_watch = None
 
992
        self._simulated_cb = self.queue.worker.connect("transaction-simulated",
 
993
                                                self._on_transaction_simulated,
 
994
                                                deferred)
 
995
        yield deferred
 
996
 
 
997
    def _on_transaction_simulated(self, worker, trans, deferred):
 
998
        if trans is not self:
 
999
            return
 
1000
        self.queue.worker.disconnect(self._simulated_cb)
 
1001
        self._simualted_cb = None
 
1002
        if trans.error:
 
1003
            deferred.errback(trans.error)
 
1004
        else:
 
1005
            deferred.callback()
985
1006
 
986
1007
    def _set_terminal(self, ttyname):
987
1008
        """Set the controlling terminal.
1192
1213
            return gettext.ngettext(singular, plural, count)
1193
1214
 
1194
1215
 
1195
 
class TransactionQueue(gobject.GObject):
 
1216
class TransactionQueue(GObject.GObject):
1196
1217
 
1197
1218
    """Queue for transactions."""
1198
1219
 
1199
 
    __gsignals__ = {"queue-changed":(gobject.SIGNAL_RUN_FIRST,
1200
 
                                     gobject.TYPE_NONE,
 
1220
    __gsignals__ = {"queue-changed":(GObject.SignalFlags.RUN_FIRST,
 
1221
                                     None,
1201
1222
                                     ())}
1202
1223
 
1203
1224
    def __init__(self, worker):
1204
1225
        """Intialize a new TransactionQueue instance."""
1205
 
        gobject.GObject.__init__(self)
 
1226
        GObject.GObject.__init__(self)
1206
1227
        self._queue = collections.deque()
1207
1228
        self._proc_count = 0
1208
1229
        self.worker = worker
1218
1239
        log.debug("emitting queue changed")
1219
1240
        self.emit("queue-changed")
1220
1241
 
 
1242
    @inline_callbacks
1221
1243
    def put(self, tid):
1222
1244
        """Add an item to the queue."""
1223
1245
        trans = self.limbo.pop(tid)
1231
1253
            # the transaction has been started
1232
1254
            if not self.worker.trans:
1233
1255
                trans.progress = 9
1234
 
            self.worker.simulate(trans)
 
1256
            yield self.worker.simulate(trans)
1235
1257
 
1236
1258
        if trans._idle_watch is not None:
1237
 
            gobject.source_remove(trans._idle_watch)
 
1259
            GObject.source_remove(trans._idle_watch)
1238
1260
        if self.worker.trans:
1239
1261
            trans.status = enums.STATUS_WAITING
1240
1262
            self._queue.append(trans)
1337
1359
        if options.dummy:
1338
1360
            self.worker = DummyWorker()
1339
1361
        else:
 
1362
            load_plugins = not options.disable_plugins
1340
1363
            try:
1341
 
                import pkcompat
 
1364
                from . import pkcompat
1342
1365
            except ImportError:
1343
 
                self.worker = AptWorker(options.chroot)
 
1366
                self.worker = AptWorker(options.chroot, load_plugins)
1344
1367
            else:
1345
 
                self.worker = pkcompat.PackageKitWorker(options.chroot)
 
1368
                self.worker = pkcompat.PackageKitWorker(options.chroot,
 
1369
                                                        load_plugins)
1346
1370
        self.queue = TransactionQueue(self.worker)
1347
1371
        self.queue.connect("queue-changed", self._on_queue_changed)
1348
1372
        # keep state of the last information about reboot required
1349
1373
        self._reboot_required = self._get_is_reboot_required()
1350
1374
        try:
1351
 
            import pkcompat
1352
1375
            self.packagekit = pkcompat.PackageKit(self.queue, connect, bus)
1353
1376
        except dbus.exceptions.NameExistsException:
1354
1377
            log.warn("PackageKit is already running")
1355
 
            #FIXME: What to do?
1356
 
            raise
 
1378
        except NameError:
 
1379
            pass
1357
1380
        log.debug("Daemon was initialized")
1358
1381
 
1359
1382
    def _on_queue_changed(self, queue):
1404
1427
        """Start the daemon and listen for calls."""
1405
1428
        if self.options.disable_timeout == False:
1406
1429
            log.debug("Using inactivity check")
1407
 
            gobject.timeout_add_seconds(APTDAEMON_IDLE_CHECK_INTERVAL,
 
1430
            GObject.timeout_add_seconds(APTDAEMON_IDLE_CHECK_INTERVAL,
1408
1431
                                        self._check_for_inactivity)
1409
1432
        log.debug("Waiting for calls")
1410
1433
        try:
2066
2089
        log.debug("Checking for inactivity")
2067
2090
        timestamp = self.queue.worker.last_action_timestamp
2068
2091
        if not self.queue.worker.trans and \
2069
 
           not gobject.main_context_default().pending() and \
 
2092
           not GObject.main_context_default().pending() and \
2070
2093
           time.time() - timestamp > APTDAEMON_IDLE_TIMEOUT and \
2071
2094
           not self.queue:
2072
2095
            log.info("Quitting due to inactivity")
2094
2117
                      action="store_true", dest="disable_timeout",
2095
2118
                      help=_("Do not shutdown the daemon because of "
2096
2119
                             "inactivity").decode(enc))
 
2120
    parser.add_option("", "--disable-plugins",
 
2121
                      default=False,
 
2122
                      action="store_true", dest="disable_plugins",
 
2123
                      help=_("Do not load any plugins").decode(enc))
2097
2124
    parser.add_option("-d", "--debug",
2098
2125
                      default=False,
2099
2126
                      action="store_true", dest="debug",