ipcontrollerapp.py
266 lines
| 10.0 KiB
| text/x-python
|
PythonLexer
Brian Granger
|
r2288 | #!/usr/bin/env python | ||
# encoding: utf-8 | ||||
""" | ||||
The IPython controller application | ||||
""" | ||||
#----------------------------------------------------------------------------- | ||||
# Copyright (C) 2008-2009 The IPython Development Team | ||||
# | ||||
# Distributed under the terms of the BSD License. The full license is in | ||||
# the file COPYING, distributed as part of this software. | ||||
#----------------------------------------------------------------------------- | ||||
#----------------------------------------------------------------------------- | ||||
# Imports | ||||
#----------------------------------------------------------------------------- | ||||
import copy | ||||
import os | ||||
import sys | ||||
from twisted.application import service | ||||
from twisted.internet import reactor, defer | ||||
from twisted.python import log | ||||
from IPython.config.loader import Config, NoConfigDefault | ||||
from IPython.core.application import Application, IPythonArgParseConfigLoader | ||||
from IPython.core import release | ||||
from IPython.utils.traitlets import Int, Str, Bool, Instance | ||||
from IPython.utils.importstring import import_item | ||||
from IPython.kernel import controllerservice | ||||
from IPython.kernel.configobjfactory import ( | ||||
ConfiguredObjectFactory, | ||||
AdaptedConfiguredObjectFactory | ||||
) | ||||
from IPython.kernel.fcutil import FCServiceFactory | ||||
#----------------------------------------------------------------------------- | ||||
# Components for creating services | ||||
#----------------------------------------------------------------------------- | ||||
# The default client interfaces for FCClientServiceFactory.Interfaces | ||||
default_client_interfaces = Config() | ||||
default_client_interfaces.Task.interface_chain = [ | ||||
'IPython.kernel.task.ITaskController', | ||||
'IPython.kernel.taskfc.IFCTaskController' | ||||
] | ||||
default_client_interfaces.Task.furl_file = 'ipcontroller-tc.furl' | ||||
default_client_interfaces.MultiEngine.interface_chain = [ | ||||
'IPython.kernel.multiengine.IMultiEngine', | ||||
'IPython.kernel.multienginefc.IFCSynchronousMultiEngine' | ||||
] | ||||
default_client_interfaces.MultiEngine.furl_file = 'ipcontroller-mec.furl' | ||||
# Make this a dict we can pass to Config.__init__ for the default | ||||
default_client_interfaces = dict(copy.deepcopy(default_client_interfaces.items())) | ||||
# The default engine interfaces for FCEngineServiceFactory.Interfaces | ||||
default_engine_interfaces = Config() | ||||
default_engine_interfaces.Default.interface_chain = [ | ||||
'IPython.kernel.enginefc.IFCControllerBase' | ||||
] | ||||
default_engine_interfaces.Default.furl_file = 'ipcontroller-engine.furl' | ||||
# Make this a dict we can pass to Config.__init__ for the default | ||||
default_engine_interfaces = dict(copy.deepcopy(default_engine_interfaces.items())) | ||||
class FCClientServiceFactory(FCServiceFactory): | ||||
"""A Foolscap implementation of the client services.""" | ||||
cert_file = Str('ipcontroller-client.pem', config=True) | ||||
Interfaces = Instance(klass=Config, kw=default_client_interfaces, | ||||
allow_none=False, config=True) | ||||
class FCEngineServiceFactory(FCServiceFactory): | ||||
"""A Foolscap implementation of the engine services.""" | ||||
cert_file = Str('ipcontroller-engine.pem', config=True) | ||||
interfaces = Instance(klass=dict, kw=default_engine_interfaces, | ||||
allow_none=False, config=True) | ||||
#----------------------------------------------------------------------------- | ||||
# The main application | ||||
#----------------------------------------------------------------------------- | ||||
cl_args = ( | ||||
# Client config | ||||
(('--client-ip',), dict( | ||||
type=str, dest='FCClientServiceFactory.ip', default=NoConfigDefault, | ||||
help='The IP address or hostname the controller will listen on for client connections.', | ||||
metavar='FCClientServiceFactory.ip') | ||||
), | ||||
(('--client-port',), dict( | ||||
type=int, dest='FCClientServiceFactory.port', default=NoConfigDefault, | ||||
help='The port the controller will listen on for client connections.', | ||||
metavar='FCClientServiceFactory.port') | ||||
), | ||||
(('--client-location',), dict( | ||||
type=str, dest='FCClientServiceFactory.location', default=NoConfigDefault, | ||||
help='The hostname or ip that clients should connect to.', | ||||
metavar='FCClientServiceFactory.location') | ||||
), | ||||
(('-x',), dict( | ||||
action='store_false', dest='FCClientServiceFactory.secure', default=NoConfigDefault, | ||||
help='Turn off all client security.') | ||||
), | ||||
(('--client-cert-file',), dict( | ||||
type=str, dest='FCClientServiceFactory.cert_file', default=NoConfigDefault, | ||||
help='File to store the client SSL certificate in.', | ||||
metavar='FCClientServiceFactory.cert_file') | ||||
), | ||||
(('--task-furl-file',), dict( | ||||
type=str, dest='FCClientServiceFactory.Interfaces.Task.furl_file', default=NoConfigDefault, | ||||
help='File to store the FURL in for task clients to connect with.', | ||||
metavar='FCClientServiceFactory.Interfaces.Task.furl_file') | ||||
), | ||||
(('--multiengine-furl-file',), dict( | ||||
type=str, dest='FCClientServiceFactory.Interfaces.MultiEngine.furl_file', default=NoConfigDefault, | ||||
help='File to store the FURL in for multiengine clients to connect with.', | ||||
metavar='FCClientServiceFactory.Interfaces.MultiEngine.furl_file') | ||||
), | ||||
# Engine config | ||||
(('--engine-ip',), dict( | ||||
type=str, dest='FCEngineServiceFactory.ip', default=NoConfigDefault, | ||||
help='The IP address or hostname the controller will listen on for engine connections.', | ||||
metavar='FCEngineServiceFactory.ip') | ||||
), | ||||
(('--engine-port',), dict( | ||||
type=int, dest='FCEngineServiceFactory.port', default=NoConfigDefault, | ||||
help='The port the controller will listen on for engine connections.', | ||||
metavar='FCEngineServiceFactory.port') | ||||
), | ||||
(('--engine-location',), dict( | ||||
type=str, dest='FCEngineServiceFactory.location', default=NoConfigDefault, | ||||
help='The hostname or ip that engines should connect to.', | ||||
metavar='FCEngineServiceFactory.location') | ||||
), | ||||
(('-y',), dict( | ||||
action='store_false', dest='FCEngineServiceFactory.secure', default=NoConfigDefault, | ||||
help='Turn off all engine security.') | ||||
), | ||||
(('--engine-cert-file',), dict( | ||||
type=str, dest='FCEngineServiceFactory.cert_file', default=NoConfigDefault, | ||||
help='File to store the client SSL certificate in.', | ||||
metavar='FCEngineServiceFactory.cert_file') | ||||
), | ||||
(('--engine-furl-file',), dict( | ||||
type=str, dest='FCEngineServiceFactory.Interfaces.Default.furl_file', default=NoConfigDefault, | ||||
help='File to store the FURL in for engines to connect with.', | ||||
metavar='FCEngineServiceFactory.Interfaces.Default.furl_file') | ||||
), | ||||
# Global config | ||||
(('-l','--logfile'), dict( | ||||
type=str, dest='Global.logfile', default=NoConfigDefault, | ||||
help='Log file name (default is stdout)', | ||||
metavar='Global.logfile') | ||||
), | ||||
(('-r',), dict( | ||||
action='store_true', dest='Global.reuse_furls', default=NoConfigDefault, | ||||
help='Try to reuse all FURL files.') | ||||
) | ||||
) | ||||
class IPControllerAppCLConfigLoader(IPythonArgParseConfigLoader): | ||||
arguments = cl_args | ||||
_default_config_file_name = 'ipcontroller_config.py' | ||||
class IPControllerApp(Application): | ||||
name = 'ipcontroller' | ||||
config_file_name = _default_config_file_name | ||||
def create_default_config(self): | ||||
super(IPControllerApp, self).create_default_config() | ||||
self.default_config.Global.logfile = '' | ||||
self.default_config.Global.reuse_furls = False | ||||
self.default_config.Global.import_statements = [] | ||||
def create_command_line_config(self): | ||||
"""Create and return a command line config loader.""" | ||||
return IPControllerAppCLConfigLoader( | ||||
description="Start an IPython controller", | ||||
version=release.version) | ||||
def construct(self): | ||||
# I am a little hesitant to put these into InteractiveShell itself. | ||||
# But that might be the place for them | ||||
sys.path.insert(0, '') | ||||
self.start_logging() | ||||
self.import_statements() | ||||
self.reuse_furls() | ||||
# Create the service hierarchy | ||||
self.main_service = service.MultiService() | ||||
# The controller service | ||||
controller_service = controllerservice.ControllerService() | ||||
controller_service.setServiceParent(self.main_service) | ||||
# The client tub and all its refereceables | ||||
csfactory = FCClientServiceFactory(self.master_config, controller_service) | ||||
client_service = csfactory.create() | ||||
client_service.setServiceParent(self.main_service) | ||||
# The engine tub | ||||
esfactory = FCEngineServiceFactory(self.master_config, controller_service) | ||||
engine_service = esfactory.create() | ||||
engine_service.setServiceParent(self.main_service) | ||||
def start_logging(self): | ||||
logfile = self.master_config.Global.logfile | ||||
if logfile: | ||||
logfile = logfile + str(os.getpid()) + '.log' | ||||
try: | ||||
openLogFile = open(logfile, 'w') | ||||
except: | ||||
openLogFile = sys.stdout | ||||
else: | ||||
openLogFile = sys.stdout | ||||
log.startLogging(openLogFile) | ||||
def import_statements(self): | ||||
statements = self.master_config.Global.import_statements | ||||
for s in statements: | ||||
try: | ||||
exec s in globals(), locals() | ||||
except: | ||||
log.msg("Error running import statement: %s" % s) | ||||
def reuse_furls(self): | ||||
# This logic might need to be moved into the components | ||||
# Delete old furl files unless the reuse_furls is set | ||||
reuse = self.master_config.Global.reuse_furls | ||||
# if not reuse: | ||||
# paths = ( | ||||
# self.master_config.FCEngineServiceFactory.Interfaces.Default.furl_file, | ||||
# self.master_config.FCClientServiceFactory.Interfaces.Task.furl_file, | ||||
# self.master_config.FCClientServiceFactory.Interfaces.MultiEngine.furl_file | ||||
# ) | ||||
# for p in paths: | ||||
# if os.path.isfile(p): | ||||
# os.remove(p) | ||||
def start_app(self): | ||||
# Start the controller service and set things running | ||||
self.main_service.startService() | ||||
reactor.run() | ||||
if __name__ == '__main__': | ||||
app = IPControllerApp() | ||||
app.start() | ||||