~ack/landscape-client/sources.list-preserve-old-permissions

« back to all changes in this revision

Viewing changes to landscape/broker/deployment.py

  • Committer: Christopher Armstrong
  • Date: 2008-06-10 10:56:01 UTC
  • Revision ID: radix@twistedmatrix.com-20080610105601-l9qfvqjf88e7j8b6
Import landscape-client into public branch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""Deployment code for the broker."""
 
2
 
 
3
import os
 
4
 
 
5
from landscape.deployment import (LandscapeService, Configuration,
 
6
                                  run_landscape_service)
 
7
from landscape.broker.store import get_default_message_store
 
8
from landscape.broker.transport import HTTPTransport
 
9
from landscape.broker.exchange import MessageExchange
 
10
from landscape.broker.registration import RegistrationHandler, Identity
 
11
from landscape.broker.broker import BrokerDBusObject
 
12
from landscape.broker.ping import Pinger
 
13
 
 
14
 
 
15
class BrokerConfiguration(Configuration):
 
16
    """Specialized configuration for the Landscape Broker."""
 
17
 
 
18
    required_options = ["url"]
 
19
 
 
20
    def __init__(self):
 
21
        super(BrokerConfiguration, self).__init__()
 
22
        self._original_http_proxy = os.environ.get("http_proxy")
 
23
        self._original_https_proxy = os.environ.get("https_proxy")
 
24
 
 
25
    def make_parser(self):
 
26
        """
 
27
        Specialize L{Configuration.make_parser}, adding many
 
28
        broker-specific options.
 
29
        """
 
30
        parser = super(BrokerConfiguration, self).make_parser()
 
31
 
 
32
        parser.add_option("-a", "--account-name", metavar="NAME",
 
33
                          help="The account this computer belongs to.")
 
34
        parser.add_option("-p", "--registration-password", metavar="PASSWORD",
 
35
                          help="The account-wide password used for registering "
 
36
                               "clients.")
 
37
        parser.add_option("-t", "--computer-title", metavar="TITLE",
 
38
                          help="The title of this computer")
 
39
        parser.add_option("-u", "--url", help="The server URL to connect to.")
 
40
        parser.add_option("-k", "--ssl-public-key",
 
41
                          help="The public SSL key to verify the server. "
 
42
                               "Only used if the given URL is https.")
 
43
        parser.add_option("--exchange-interval", default=15*60, type="int",
 
44
                          metavar="INTERVAL",
 
45
                          help="The number of seconds between server "
 
46
                               "exchanges.")
 
47
        parser.add_option("--urgent-exchange-interval", default=1*60,
 
48
                          type="int",
 
49
                          metavar="INTERVAL",
 
50
                          help="The number of seconds between urgent server "
 
51
                               "exchanges.")
 
52
        parser.add_option("--ping-url",
 
53
                          help="The URL to perform lightweight exchange "
 
54
                               "initiation with.")
 
55
        parser.add_option("--http-proxy", metavar="URL",
 
56
                          help="The URL of the HTTP proxy, if one is needed.")
 
57
        parser.add_option("--https-proxy", metavar="URL",
 
58
                          help="The URL of the HTTPS proxy, if one is needed.")
 
59
        parser.add_option("-n", "--no-start", action="store_true")
 
60
        return parser
 
61
 
 
62
    @property
 
63
    def message_store_path(self):
 
64
        return os.path.join(self.data_path, "messages")
 
65
 
 
66
    def load(self, args, accept_unexistent_config=False):
 
67
        """
 
68
        Load the configuration with L{Configuration.load}, and then set
 
69
        http_proxy and https_proxy environment variables based on that config
 
70
        data.
 
71
        """
 
72
        super(BrokerConfiguration, self).load(
 
73
            args, accept_unexistent_config=accept_unexistent_config)
 
74
        if self.http_proxy:
 
75
            os.environ["http_proxy"] = self.http_proxy
 
76
        elif self._original_http_proxy:
 
77
            os.environ["http_proxy"] = self._original_http_proxy
 
78
 
 
79
        if self.https_proxy:
 
80
            os.environ["https_proxy"] = self.https_proxy
 
81
        elif self._original_https_proxy:
 
82
            os.environ["https_proxy"] = self._original_https_proxy
 
83
 
 
84
 
 
85
class BrokerService(LandscapeService):
 
86
    """
 
87
    The core Twisted Service which creates and runs all necessary
 
88
    components when started.
 
89
    """
 
90
 
 
91
    transport_factory = HTTPTransport
 
92
 
 
93
    service_name = "broker"
 
94
 
 
95
    def __init__(self, config):
 
96
        self.persist_filename = os.path.join(
 
97
            config.data_path, "%s.bpickle" % (self.service_name,))
 
98
        super(BrokerService, self).__init__(config)
 
99
        self.transport = self.transport_factory(config.url,
 
100
                                                config.ssl_public_key)
 
101
 
 
102
        self.message_store = get_default_message_store(
 
103
            self.persist, config.message_store_path)
 
104
        self.identity = Identity(self.config, self.persist)
 
105
        self.exchanger = MessageExchange(self.reactor, self.message_store,
 
106
                                         self.transport, self.identity,
 
107
                                         config.exchange_interval,
 
108
                                         config.urgent_exchange_interval)
 
109
 
 
110
        self.registration = RegistrationHandler(self.identity, self.reactor,
 
111
                                                self.exchanger,
 
112
                                                self.message_store)
 
113
        self.pinger = Pinger(self.reactor, config.ping_url, self.identity,
 
114
                             self.exchanger)
 
115
 
 
116
        self.reactor.call_on("post-exit", self._exit)
 
117
 
 
118
    def _exit(self):
 
119
        # Our reactor calls the Twisted reactor's crash() method rather
 
120
        # than the real stop.  As a consequence, if we use it here, normal
 
121
        # termination doesn't happen, and stopService() would never get
 
122
        # called.
 
123
        from twisted.internet import reactor
 
124
        reactor.stop()
 
125
 
 
126
    def startService(self):
 
127
        """
 
128
        Set up the persist, message store, transport, reactor, and
 
129
        dbus message exchange service.
 
130
 
 
131
        If the configuration specifies the bus as 'session', the DBUS
 
132
        message exchange service will use the DBUS Session Bus.
 
133
        """
 
134
        super(BrokerService, self).startService()
 
135
        self.dbus_object = BrokerDBusObject(self.config, self.reactor,
 
136
                                            self.exchanger, self.registration,
 
137
                                            self.message_store, self.bus)
 
138
 
 
139
        self.exchanger.start()
 
140
        self.pinger.start()
 
141
 
 
142
    def stopService(self):
 
143
        """Stop the broker."""
 
144
        self.exchanger.stop()
 
145
        super(BrokerService, self).stopService()
 
146
 
 
147
 
 
148
def run(args):
 
149
    """Run the application, given some command line arguments."""
 
150
    run_landscape_service(BrokerConfiguration, BrokerService, args,
 
151
                          BrokerDBusObject.bus_name)