~ubuntu-branches/ubuntu/quantal/landscape-client/quantal-proposed

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/usr/bin/env python
"""
This script is needed in case the client is upgrading from a pre-AMP version
using Dbus as the messaging mechanism (like the landscape-client package from
the lucid archives).
This allows the package changer to send package changes to the broker using
Dbus.

This will only be run for old packages depending on DBus, we don't need to
depend on DBus in the current version.
"""

import os
import dbus
import dbus.service
import dbus.glib # This as side effects, don't remove it!

from dbus.service import Object, BusName, method

from twisted.internet import glib2reactor
glib2reactor.install()
from twisted.internet import reactor

from landscape.lib.bpickle import loads
from landscape.lib.lock import lock_path, LockError
from landscape.reactor import LandscapeReactor
from landscape.deployment import Configuration
from landscape.broker.amp import RemoteBrokerConnector


BUS_NAME = "com.canonical.landscape.Broker"
OBJECT_PATH = "/com/canonical/landscape/Broker"


def array_to_string(array):
    """Convert an L{Array} of L{Byte}s (or integers) to a Python str."""
    result = []
    for item in array:
        if item < 0:
            item = item + 256
        result.append(chr(item))
    return "".join(result)


class BrokerDBusObject(Object):
    """A DBus-published object proxying L{RemoteBroker.send_message}.

    It is used when upgrading from a DBus-based version of the Landscape client
    to the newer AMP-based one, for letting the old package-changer process
    performing the upgrade communicate with the new version of the client.
    """
    bus_name = BUS_NAME
    object_path = OBJECT_PATH

    def __init__(self, config):
        super(BrokerDBusObject, self).__init__(BusName(
            self.bus_name, dbus.SystemBus()), object_path=self.object_path)
        self.config = config

    @method(BUS_NAME)
    def send_message(self, message, urgent=True):
        """Queue the given message in the message exchange."""
        message = loads(array_to_string(message))

        def cb_connected(broker):
            result = broker.send_message(message, urgent=True)
            return result.addCallback(cb_done)

        def cb_done(ignored):
            return reactor.stop()

        landscape_reactor = LandscapeReactor()
        connector = RemoteBrokerConnector(landscape_reactor, self.config)
        connected = connector.connect()
        connected.addCallback(cb_connected)


if __name__ == "__main__":
    config = Configuration()
    lock_dir = os.path.join(config.data_path, "package")
    if os.path.isdir(lock_dir):
        lock_filename = os.path.join(lock_dir, "changer.lock")
        try:
            lock_path(lock_filename)
        except LockError:
            # The package-changer is running, this means that we're upgrading from
            # a non-AMP version and that the upgrade is Landscape driven, so let's
            # expose the DBus broker proxy to give a chance to the package-changer
            # to send its result message.
            remote = BrokerDBusObject(config)
            reactor.run()