~ahasenack/landscape-client/landscape-client-1.5.5-0ubuntu0.9.04.0

« back to all changes in this revision

Viewing changes to landscape/plugin.py

  • Committer: Bazaar Package Importer
  • Author(s): Rick Clark
  • Date: 2008-09-08 16:35:57 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080908163557-l3ixzj5dxz37wnw2
Tags: 1.0.18-0ubuntu1
New upstream release 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
from logging import info, exception
 
2
 
 
3
from landscape.lib.bpickle import loads
 
4
from landscape.lib.dbus_util import Object, array_to_string
 
5
from landscape.log import format_object
 
6
 
 
7
 
 
8
class HandlerNotFoundError(Exception):
 
9
    """A handler for the given message type was not found."""
 
10
 
 
11
 
 
12
class PluginConfigError(Exception):
 
13
    """There was an error registering or configuring a plugin."""
 
14
 
 
15
 
 
16
class PluginRegistry(object):
 
17
    """A central integration point for plugins."""
 
18
 
 
19
    def __init__(self):
 
20
        self._plugins = []
 
21
        self._plugin_names = {}
 
22
        self._registered_messages = {}
 
23
 
 
24
    def add(self, plugin):
 
25
        """Register a plugin.
 
26
 
 
27
        The plugin's C{register} method will be called with this registry as
 
28
        its argument.
 
29
 
 
30
        If the plugin has a C{plugin_name} attribute, it will be possible to
 
31
        look up the plugin later with L{get_plugin}.
 
32
        """
 
33
        info("Registering plugin %s.", format_object(plugin))
 
34
        self._plugins.append(plugin)
 
35
        if hasattr(plugin, 'plugin_name'):
 
36
            self._plugin_names[plugin.plugin_name] = plugin
 
37
        plugin.register(self)
 
38
 
 
39
    def get_plugins(self):
 
40
        """Get the list of plugins."""
 
41
        return self._plugins
 
42
 
 
43
    def get_plugin(self, name):
 
44
        """Get a particular plugin by name."""
 
45
        return self._plugin_names[name]
 
46
 
 
47
    def register_message(self, type, handler):
 
48
        """
 
49
        Register interest in a particular type of Landscape server->client
 
50
        message.
 
51
        """
 
52
        self._registered_messages[type] = handler
 
53
 
 
54
    def dispatch_message(self, message):
 
55
        type = message["type"]
 
56
        handler = self._registered_messages.get(type)
 
57
        if handler is not None:
 
58
            try:
 
59
                return handler(message)
 
60
            except:
 
61
                exception("Error running message handler for type %r: %r"
 
62
                          % (type, handler))
 
63
        else:
 
64
            raise HandlerNotFoundError(type)
 
65
 
 
66
 
 
67
class Plugin(object):
 
68
    """A convenience for writing plugins.
 
69
 
 
70
    This provides a register method which will set up a bunch of
 
71
    reactor handlers in the idiomatic way.
 
72
 
 
73
    If C{run} is defined on subclasses, it will be called every C{run_interval}
 
74
    seconds after being registered.
 
75
 
 
76
    @cvar run_interval: The interval, in seconds, to execute the
 
77
    C{run} method. If set to C{None}, then C{run} will not be
 
78
    scheduled.
 
79
    """
 
80
 
 
81
    run_interval = 5
 
82
 
 
83
    def register(self, registry):
 
84
        self.registry = registry
 
85
        if hasattr(self, "run") and self.run_interval is not None:
 
86
            registry.reactor.call_every(self.run_interval, self.run)
 
87
 
 
88
 
 
89
 
 
90
class BrokerPlugin(Object):
 
91
    """
 
92
    A DBus object which exposes the 'plugin' interface that the Broker expects
 
93
    of its clients.
 
94
    """
 
95
    def __init__(self, bus, registry):
 
96
        Object.__init__(self, bus)
 
97
        self.registry = registry
 
98
 
 
99
    def ping(self):
 
100
        return True
 
101
 
 
102
    def exit(self):
 
103
        from twisted.internet import reactor
 
104
        reactor.callLater(0.1, reactor.stop)
 
105
 
 
106
    def dispatch_message(self, blob):
 
107
        """
 
108
        Call the L{PluginRegistry}'s C{dispatch_message} method and return True
 
109
        if a message handler was found and False otherwise.
 
110
        """
 
111
        message = loads(array_to_string(blob))
 
112
        try:
 
113
            self.registry.dispatch_message(message)
 
114
            return True
 
115
        except HandlerNotFoundError:
 
116
            return False
 
117
 
 
118
    def message(self, blob):
 
119
        """
 
120
        Call L{dispatch_message} with C{blob} and return the result.
 
121
        """
 
122
        return self.dispatch_message(blob)