/
start.py
212 lines (189 loc) · 7.42 KB
/
start.py
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
import os
import sys
import urlparse
from orbited import __version__ as version
from orbited import config
from orbited import logging
# NB: this is set after we load the configuration at "main".
logger = None
def _import(name):
module_import = name.rsplit('.', 1)[0]
return reduce(getattr, name.split('.')[1:], __import__(module_import))
def _setup_protocols(root):
from twisted.internet import reactor
protocols = [
#child_path config_key port_class_import, factory_class_import
('tcp', 'proxy', 'orbited.cometsession.Port', 'orbited.proxy.ProxyFactory'),
]
for child_path, config_key, port_class_import, factory_class_import in protocols:
if config.map['[global]'].get('%s.enabled' % config_key) == '1':
port_class = _import(port_class_import)
factory_class = _import(factory_class_import)
reactor.listenWith(port_class, factory=factory_class(), resource=root, childName=child_path)
logger.info('%s protocol active' % config_key)
def _setup_static(root, config):
from twisted.web import static
for key, val in config['[static]'].items():
if key == 'INDEX':
key = ''
if root.getStaticEntity(key):
logger.error("cannot mount static directory with reserved name %s" % key)
sys.exit(-1)
root.putChild(key, static.File(val))
def main():
from optparse import OptionParser
parser = OptionParser()
parser.add_option(
"-c",
"--config",
dest="config",
default=None,
help="path to configuration file"
)
parser.add_option(
"-v",
"--version",
dest="version",
action="store_true",
default=False,
help="print Orbited version"
)
parser.add_option(
"-p",
"--profile",
dest="profile",
action="store_true",
default=False,
help="run Orbited with a profiler"
)
parser.add_option(
"-q",
"--quickstart",
dest="quickstart",
action="store_true",
default=False,
help="run Orbited on port 8000 and MorbidQ on port 61613"
)
(options, args) = parser.parse_args()
if options.version:
print "Orbited version: %s" % (version,)
sys.exit(0)
if options.quickstart:
config.map['[listen]'].append('http://:8000')
config.map['[listen]'].append('stomp://:61613')
config.map['[access]'][('localhost',61613)] = ['*']
print "Quickstarting Orbited"
else:
# load configuration from configuration
# file and from command line arguments.
config.setup(options=options)
logging.setup(config.map)
# we can now safely get loggers.
global logger; logger = logging.get_logger('orbited.start')
# NB: we need to install the reactor before using twisted.
reactor_name = config.map['[global]'].get('reactor')
if reactor_name:
install = _import('twisted.internet.%sreactor.install' % reactor_name)
install()
logger.info('using %s reactor' % reactor_name)
from twisted.internet import reactor
from twisted.web import resource
from twisted.web import server
from twisted.web import static
import orbited.system
root = resource.Resource()
static_files = static.File(os.path.join(os.path.dirname(__file__), 'static'))
root.putChild('static', static_files)
root.putChild('system', orbited.system.SystemResource())
if config.map['[test]']['stompdispatcher.enabled'] == '1':
logger.info('stompdispatcher enabled')
#static_files.putChild('orbited.swf', static.File(os.path.join(os.path.dirname(__file__), 'flash', 'orbited.swf')))
site = server.Site(root)
_setup_protocols(root)
_setup_static(root, config.map)
start_listening(site, config.map, logger)
# switch uid and gid to configured user and group.
if os.name == 'posix' and os.getuid() == 0:
user = config.map['[global]'].get('user')
group = config.map['[global]'].get('group')
if user:
import pwd
import grp
try:
pw = pwd.getpwnam(user)
uid = pw.pw_uid
if group:
gr = grp.getgrnam(group)
gid = gr.gr_gid
else:
gid = pw.pw_gid
gr = grp.getgrgid(gid)
group = gr.gr_name
except Exception, e:
logger.error('Aborting; Unknown user or group: %s' % e)
sys.exit(-1)
logger.info('switching to user %s (uid=%d) and group %s (gid=%d)' % (user, uid, group, gid))
os.setgid(gid)
os.setuid(uid)
else:
logger.error('Aborting; You must define a user (and optionally a group) in the configuration file.')
sys.exit(-1)
if options.profile:
import hotshot
prof = hotshot.Profile("orbited.profile")
logger.info("running Orbited in profile mode")
logger.info("for information on profiler, see http://orbited.org/wiki/Profiler")
prof.runcall(reactor.run)
prof.close()
else:
reactor.run()
def start_listening(site, config, logger):
from twisted.internet import reactor
from twisted.internet import protocol as protocol_module
# allow stomp:// URIs to be parsed by urlparse
urlparse.uses_netloc.append("stomp")
# allow test server URIs to be parsed by urlparse
from orbited.servers import test_servers
for protocol in test_servers:
urlparse.uses_netloc.append(protocol)
for addr in config['[listen]']:
if addr.startswith("stomp"):
stompConfig = ""
if " " in addr:
addr, stompConfig = addr.split(" ",1)
url = urlparse.urlparse(addr)
hostname = url.hostname or ''
if url.scheme == 'stomp':
logger.info('Listening stomp@%s' % url.port)
from morbid import get_stomp_factory
morbid_instance = get_stomp_factory(stompConfig)
config['morbid_instance'] = morbid_instance
reactor.listenTCP(url.port, morbid_instance, interface=hostname)
elif url.scheme == 'http':
logger.info('Listening http@%s' % url.port)
reactor.listenTCP(url.port, site, interface=hostname)
elif url.scheme == 'https':
from twisted.internet import ssl
crt = config['[ssl]']['crt']
key = config['[ssl]']['key']
try:
ssl_context = ssl.DefaultOpenSSLContextFactory(key, crt)
except ImportError:
raise
except:
logger.error("Error opening key or crt file: %s, %s" % (key, crt))
sys.exit(-1)
logger.info('Listening https@%s (%s, %s)' % (url.port, key, crt))
reactor.listenSSL(url.port, site, ssl_context, interface=hostname)
elif url.scheme in test_servers:
test_factory = protocol_module.ServerFactory()
test_factory.protocol = test_servers[url.scheme]
logger.info("Listening %s@%s"%(url.scheme, url.port))
reactor.listenTCP(url.port, test_factory)
if url.scheme == 'monitor':
config['globalVars']['monitoring'] = url.port
else:
logger.error("Invalid Listen URI: %s" % addr)
sys.exit(-1)
if __name__ == "__main__":
main()