1
"""Deployment code for the broker."""
5
from landscape.deployment import (LandscapeService, Configuration,
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
15
class BrokerConfiguration(Configuration):
16
"""Specialized configuration for the Landscape Broker."""
18
required_options = ["url"]
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")
25
def make_parser(self):
27
Specialize L{Configuration.make_parser}, adding many
28
broker-specific options.
30
parser = super(BrokerConfiguration, self).make_parser()
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 "
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",
45
help="The number of seconds between server "
47
parser.add_option("--urgent-exchange-interval", default=1*60,
50
help="The number of seconds between urgent server "
52
parser.add_option("--ping-url",
53
help="The URL to perform lightweight exchange "
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")
63
def message_store_path(self):
64
return os.path.join(self.data_path, "messages")
66
def load(self, args, accept_unexistent_config=False):
68
Load the configuration with L{Configuration.load}, and then set
69
http_proxy and https_proxy environment variables based on that config
72
super(BrokerConfiguration, self).load(
73
args, accept_unexistent_config=accept_unexistent_config)
75
os.environ["http_proxy"] = self.http_proxy
76
elif self._original_http_proxy:
77
os.environ["http_proxy"] = self._original_http_proxy
80
os.environ["https_proxy"] = self.https_proxy
81
elif self._original_https_proxy:
82
os.environ["https_proxy"] = self._original_https_proxy
85
class BrokerService(LandscapeService):
87
The core Twisted Service which creates and runs all necessary
88
components when started.
91
transport_factory = HTTPTransport
93
service_name = "broker"
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)
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)
110
self.registration = RegistrationHandler(self.identity, self.reactor,
113
self.pinger = Pinger(self.reactor, config.ping_url, self.identity,
116
self.reactor.call_on("post-exit", self._exit)
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
123
from twisted.internet import reactor
126
def startService(self):
128
Set up the persist, message store, transport, reactor, and
129
dbus message exchange service.
131
If the configuration specifies the bus as 'session', the DBUS
132
message exchange service will use the DBUS Session Bus.
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)
139
self.exchanger.start()
142
def stopService(self):
143
"""Stop the broker."""
144
self.exchanger.stop()
145
super(BrokerService, self).stopService()
149
"""Run the application, given some command line arguments."""
150
run_landscape_service(BrokerConfiguration, BrokerService, args,
151
BrokerDBusObject.bus_name)