~wgrant/ubuntu/natty/landscape-client/natty-updates-broken

« back to all changes in this revision

Viewing changes to landscape/monitor/monitor.py

  • Committer: Bazaar Package Importer
  • Author(s): Free Ekanayaka
  • Date: 2010-04-21 19:58:10 UTC
  • mfrom: (1.1.16 upstream)
  • Revision ID: james.westby@ubuntu.com-20100421195810-s30uv3s6i27lue38
Tags: 1.5.2-0ubuntu0.10.10.0
* New upstream version (LP: #594594):
  - A new includes information about active network devices and their
    IP address in sysinfo output (LP: #272344).
  - A new plugin collects information about network traffic (#LP :284662).
  - Report information about which packages requested a reboot (LP: #538253).
  - Fix breakage on Lucid AMIs having no ramdisk (LP: #574810).
  - Migrate the inter-process communication system from DBus to Twisted AMP.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
"""The Landscape monitor plugin system."""
2
2
 
3
3
import os
4
 
from logging import info
5
 
 
6
 
from twisted.internet.defer import succeed
7
 
 
8
 
from landscape.lib.dbus_util import method
9
 
from landscape.lib.log import log_failure
10
 
 
11
 
from landscape.log import format_object
12
 
from landscape.plugin import BrokerClientPluginRegistry, Plugin, BrokerPlugin
13
 
 
14
 
 
15
 
BUS_NAME = "com.canonical.landscape.Monitor"
16
 
OBJECT_PATH = "/com/canonical/landscape/Monitor"
17
 
IFACE_NAME = BUS_NAME
18
 
 
19
 
 
20
 
class MonitorDBusObject(BrokerPlugin):
21
 
    """A DBUS object which provides an interface to the Landscape Monitor."""
22
 
 
23
 
    bus_name = BUS_NAME
24
 
    object_path = OBJECT_PATH
25
 
 
26
 
    ping = method(IFACE_NAME)(BrokerPlugin.ping)
27
 
    exit = method(IFACE_NAME)(BrokerPlugin.exit)
28
 
    message = method(IFACE_NAME)(BrokerPlugin.message)
29
 
 
30
 
 
31
 
class MonitorPluginRegistry(BrokerClientPluginRegistry):
 
4
 
 
5
from landscape.broker.client import BrokerClient
 
6
 
 
7
 
 
8
class Monitor(BrokerClient):
32
9
    """The central point of integration in the Landscape monitor."""
33
10
 
34
 
    def __init__(self, broker, reactor, config, bus,
35
 
                 persist, persist_filename=None,
36
 
                 step_size=5*60):
37
 
        super(MonitorPluginRegistry, self).__init__(broker)
 
11
    name = "monitor"
 
12
 
 
13
    def __init__(self, reactor, config, persist, persist_filename=None,
 
14
                 step_size=5 * 60):
 
15
        super(Monitor, self).__init__(reactor)
38
16
        self.reactor = reactor
39
17
        self.config = config
40
18
        self.persist = persist
43
21
            self.persist.load(persist_filename)
44
22
        self._plugins = []
45
23
        self.step_size = step_size
46
 
        self.bus = bus
 
24
        self.reactor.call_every(self.config.flush_interval, self.flush)
47
25
 
48
26
    def flush(self):
49
27
        """Flush data to disk."""
52
30
 
53
31
    def exchange(self):
54
32
        """Call C{exchange} on all plugins."""
55
 
        super(MonitorPluginRegistry, self).exchange()
 
33
        super(Monitor, self).exchange()
56
34
        self.flush()
57
 
 
58
 
 
59
 
class MonitorPlugin(Plugin):
60
 
    """
61
 
    @cvar persist_name: If specified as a string, a C{_persist} attribute
62
 
    will be available after registration.
63
 
 
64
 
    XXX This class is no longer very useful and should be cleaned out
65
 
    at some point.
66
 
    """
67
 
 
68
 
    persist_name = None
69
 
 
70
 
    def register(self, registry):
71
 
        super(MonitorPlugin, self).register(registry)
72
 
        if self.persist_name is not None:
73
 
            self._persist = registry.persist.root_at(self.persist_name)
74
 
 
75
 
    def call_on_accepted(self, type, callable, *args, **kwargs):
76
 
 
77
 
        def acceptance_changed(acceptance):
78
 
            if acceptance:
79
 
                return callable(*args, **kwargs)
80
 
 
81
 
        self.registry.reactor.call_on(("message-type-acceptance-changed",
82
 
                                       type), acceptance_changed)
83
 
 
84
 
 
85
 
class DataWatcher(MonitorPlugin):
86
 
    """
87
 
    A utility for plugins which send data to the Landscape server
88
 
    which does not constantly change. New messages will only be sent
89
 
    when the result of get_data() has changed since the last time it
90
 
    was called.
91
 
 
92
 
    Subclasses should provide a get_data method, and message_type,
93
 
    message_key, and persist_name class attributes.
94
 
    """
95
 
 
96
 
    message_type = None
97
 
    message_key = None
98
 
 
99
 
    def get_message(self):
100
 
        """
101
 
        Construct a message with the latest data, or None, if the data
102
 
        has not changed since the last call.
103
 
        """
104
 
        data = self.get_data()
105
 
        if self._persist.get("data") != data:
106
 
            self._persist.set("data", data)
107
 
            return {"type": self.message_type, self.message_key: data}
108
 
 
109
 
    def send_message(self, urgent):
110
 
        message = self.get_message()
111
 
        if message is not None:
112
 
            info("Queueing a message with updated data watcher info "
113
 
                 "for %s.", format_object(self))
114
 
            result = self.registry.broker.send_message(message, urgent=urgent)
115
 
 
116
 
            def persist_data(message_id):
117
 
                self.persist_data()
118
 
 
119
 
            result.addCallback(persist_data)
120
 
            result.addErrback(log_failure)
121
 
            return result
122
 
        return succeed(None)
123
 
 
124
 
    def persist_data(self):
125
 
        """
126
 
        Sub-classes that need to defer the saving of persistent data
127
 
        should override this method.
128
 
        """
129
 
        pass
130
 
 
131
 
    def exchange(self, urgent=False):
132
 
        """
133
 
        Conditionally add a message to the message store if new data
134
 
        is available.
135
 
        """
136
 
        return self.registry.broker.call_if_accepted(self.message_type,
137
 
                                                     self.send_message, urgent)