##// END OF EJS Templates
General work on the kernel config.
Brian Granger -
Show More
@@ -6,10 +6,14 b' c = get_config()'
6 # Global configuration
6 # Global configuration
7 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
8
8
9 c.Global.logfile = ''
9 c.Global.log_to_file = False
10 c.Global.import_statement = ''
10 c.Global.import_statements = []
11 c.Global.reuse_furls = False
11 c.Global.reuse_furls = False
12
12
13 # You shouldn't have to edit these
14 c.Global.log_dir_name = 'log'
15 c.Global.security_dir_name = 'security'
16
13
17
14 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
15 # Configure the client services
19 # Configure the client services
@@ -19,18 +23,23 b" c.FCClientServiceFactory.ip = ''"
19 c.FCClientServiceFactory.port = 0
23 c.FCClientServiceFactory.port = 0
20 c.FCClientServiceFactory.location = ''
24 c.FCClientServiceFactory.location = ''
21 c.FCClientServiceFactory.secure = True
25 c.FCClientServiceFactory.secure = True
26 c.FCClientServiceFactory.reuse_furls = False
22 c.FCClientServiceFactory.cert_file = 'ipcontroller-client.pem'
27 c.FCClientServiceFactory.cert_file = 'ipcontroller-client.pem'
23
28
24 c.FCClientServiceFactory.Interfaces.Task.interface_chain = [
29 c.FCClientServiceFactory.Interfaces.Task.interface_chain = [
25 'IPython.kernel.task.ITaskController',
30 'IPython.kernel.task.ITaskController',
26 'IPython.kernel.taskfc.IFCTaskController'
31 'IPython.kernel.taskfc.IFCTaskController'
27 ]
32 ]
33 # This is just the filename of the furl file. The path is always the
34 # security dir of the cluster directory.
28 c.FCClientServiceFactory.Interfaces.Task.furl_file = 'ipcontroller-tc.furl'
35 c.FCClientServiceFactory.Interfaces.Task.furl_file = 'ipcontroller-tc.furl'
29
36
30 c.FCClientServiceFactory.Interfaces.MultiEngine.interface_chain = [
37 c.FCClientServiceFactory.Interfaces.MultiEngine.interface_chain = [
31 'IPython.kernel.multiengine.IMultiEngine',
38 'IPython.kernel.multiengine.IMultiEngine',
32 'IPython.kernel.multienginefc.IFCSynchronousMultiEngine'
39 'IPython.kernel.multienginefc.IFCSynchronousMultiEngine'
33 ]
40 ]
41 # This is just the filename of the furl file. The path is always the
42 # security dir of the cluster directory.
34 c.FCClientServiceFactory.Interfaces.MultiEngine.furl_file = 'ipcontroller-mec.furl'
43 c.FCClientServiceFactory.Interfaces.MultiEngine.furl_file = 'ipcontroller-mec.furl'
35
44
36
45
@@ -42,19 +51,17 b" c.FCEngineServiceFactory.ip = ''"
42 c.FCEngineServiceFactory.port = 0
51 c.FCEngineServiceFactory.port = 0
43 c.FCEngineServiceFactory.location = ''
52 c.FCEngineServiceFactory.location = ''
44 c.FCEngineServiceFactory.secure = True
53 c.FCEngineServiceFactory.secure = True
54 c.FCEngineServiceFactory.reuse_furls = False
45 c.FCEngineServiceFactory.cert_file = 'ipcontroller-engine.pem'
55 c.FCEngineServiceFactory.cert_file = 'ipcontroller-engine.pem'
46
56
47 engine_config = Config()
57 c.FCEngineServiceFactory.Intefaces.Default.interface_chain = [
48 engine_config.furl_file =
58 'IPython.kernel.enginefc.IFCControllerBase'
49 c.Global.engine_furl_file = 'ipcontroller-engine.furl'
59 ]
50 c.Global.engine_fc_interface = 'IPython.kernel.enginefc.IFCControllerBase'
51
52
60
61 # This is just the filename of the furl file. The path is always the
62 # security dir of the cluster directory.
63 c.FCEngineServiceFactory.Intefaces.Default.furl_file = 'ipcontroller-engine.furl'
53
64
54
65
55
66
56 CLIENT_INTERFACES = dict(
57 TASK = dict(FURL_FILE = 'ipcontroller-tc.furl'),
58 MULTIENGINE = dict(FURLFILE='ipcontroller-mec.furl')
59 )
60
67
@@ -46,7 +46,7 b' class IPythonArgParseConfigLoader(ArgParseConfigLoader):'
46 """Default command line options for IPython based applications."""
46 """Default command line options for IPython based applications."""
47
47
48 def _add_other_arguments(self):
48 def _add_other_arguments(self):
49 self.parser.add_argument('-ipythondir', '--ipythondir',
49 self.parser.add_argument('-ipythondir', '--ipython-dir',
50 dest='Global.ipythondir',type=str,
50 dest='Global.ipythondir',type=str,
51 help='Set to override default location of Global.ipythondir.',
51 help='Set to override default location of Global.ipythondir.',
52 default=NoConfigDefault,
52 default=NoConfigDefault,
@@ -77,6 +77,8 b' class Application(object):'
77
77
78 config_file_name = 'ipython_config.py'
78 config_file_name = 'ipython_config.py'
79 name = 'ipython'
79 name = 'ipython'
80 default_log_level = logging.WARN
81
80
82
81 def __init__(self):
83 def __init__(self):
82 self.init_logger()
84 self.init_logger()
@@ -85,7 +87,7 b' class Application(object):'
85 def init_logger(self):
87 def init_logger(self):
86 self.log = logging.getLogger(self.__class__.__name__)
88 self.log = logging.getLogger(self.__class__.__name__)
87 # This is used as the default until the command line arguments are read.
89 # This is used as the default until the command line arguments are read.
88 self.log.setLevel(logging.WARN)
90 self.log.setLevel(self.default_log_level)
89 self._log_handler = logging.StreamHandler()
91 self._log_handler = logging.StreamHandler()
90 self._log_formatter = logging.Formatter("[%(name)s] %(message)s")
92 self._log_formatter = logging.Formatter("[%(name)s] %(message)s")
91 self._log_handler.setFormatter(self._log_formatter)
93 self._log_handler.setFormatter(self._log_formatter)
@@ -102,16 +104,23 b' class Application(object):'
102 def start(self):
104 def start(self):
103 """Start the application."""
105 """Start the application."""
104 self.attempt(self.create_default_config)
106 self.attempt(self.create_default_config)
107 self.log_default_config()
108 self.set_default_config_log_level()
105 self.attempt(self.pre_load_command_line_config)
109 self.attempt(self.pre_load_command_line_config)
106 self.attempt(self.load_command_line_config, action='abort')
110 self.attempt(self.load_command_line_config, action='abort')
111 self.set_command_line_config_log_level()
107 self.attempt(self.post_load_command_line_config)
112 self.attempt(self.post_load_command_line_config)
113 self.log_command_line_config()
108 self.attempt(self.find_ipythondir)
114 self.attempt(self.find_ipythondir)
109 self.attempt(self.find_config_file_name)
115 self.attempt(self.find_config_file_name)
110 self.attempt(self.find_config_file_paths)
116 self.attempt(self.find_config_file_paths)
111 self.attempt(self.pre_load_file_config)
117 self.attempt(self.pre_load_file_config)
112 self.attempt(self.load_file_config)
118 self.attempt(self.load_file_config)
119 self.set_file_config_log_level()
113 self.attempt(self.post_load_file_config)
120 self.attempt(self.post_load_file_config)
121 self.log_file_config()
114 self.attempt(self.merge_configs)
122 self.attempt(self.merge_configs)
123 self.log_master_config()
115 self.attempt(self.pre_construct)
124 self.attempt(self.pre_construct)
116 self.attempt(self.construct)
125 self.attempt(self.construct)
117 self.attempt(self.post_construct)
126 self.attempt(self.post_construct)
@@ -132,9 +141,18 b' class Application(object):'
132 """
141 """
133 self.default_config = Config()
142 self.default_config = Config()
134 self.default_config.Global.ipythondir = get_ipython_dir()
143 self.default_config.Global.ipythondir = get_ipython_dir()
144
145 def log_default_config(self):
135 self.log.debug('Default config loaded:')
146 self.log.debug('Default config loaded:')
136 self.log.debug(repr(self.default_config))
147 self.log.debug(repr(self.default_config))
137
148
149 def set_default_config_log_level(self):
150 try:
151 self.log_level = self.default_config.Global.log_level
152 except AttributeError:
153 # Fallback to the default_log_level class attribute
154 pass
155
138 def create_command_line_config(self):
156 def create_command_line_config(self):
139 """Create and return a command line config loader."""
157 """Create and return a command line config loader."""
140 return IPythonArgParseConfigLoader(description=self.name)
158 return IPythonArgParseConfigLoader(description=self.name)
@@ -144,26 +162,25 b' class Application(object):'
144 pass
162 pass
145
163
146 def load_command_line_config(self):
164 def load_command_line_config(self):
147 """Load the command line config.
165 """Load the command line config."""
148
149 This method also sets ``self.debug``.
150 """
151
152 loader = self.create_command_line_config()
166 loader = self.create_command_line_config()
153 self.command_line_config = loader.load_config()
167 self.command_line_config = loader.load_config()
154 self.extra_args = loader.get_extra_args()
168 self.extra_args = loader.get_extra_args()
155
169
170 def set_command_line_config_log_level(self):
156 try:
171 try:
157 self.log_level = self.command_line_config.Global.log_level
172 self.log_level = self.command_line_config.Global.log_level
158 except AttributeError:
173 except AttributeError:
159 pass # Use existing value which is set in Application.init_logger.
174 pass
160 self.log.debug("Command line config loaded:")
161 self.log.debug(repr(self.command_line_config))
162
175
163 def post_load_command_line_config(self):
176 def post_load_command_line_config(self):
164 """Do actions just after loading the command line config."""
177 """Do actions just after loading the command line config."""
165 pass
178 pass
166
179
180 def log_command_line_config(self):
181 self.log.debug("Command line config loaded:")
182 self.log.debug(repr(self.command_line_config))
183
167 def find_ipythondir(self):
184 def find_ipythondir(self):
168 """Set the IPython directory.
185 """Set the IPython directory.
169
186
@@ -180,16 +197,19 b' class Application(object):'
180 self.ipythondir = self.default_config.Global.ipythondir
197 self.ipythondir = self.default_config.Global.ipythondir
181 sys.path.append(os.path.abspath(self.ipythondir))
198 sys.path.append(os.path.abspath(self.ipythondir))
182 if not os.path.isdir(self.ipythondir):
199 if not os.path.isdir(self.ipythondir):
183 os.makedirs(self.ipythondir, mode = 0777)
200 os.makedirs(self.ipythondir, mode=0777)
184 self.log.debug("IPYTHONDIR set to: %s" % self.ipythondir)
201 self.log.debug("IPYTHONDIR set to: %s" % self.ipythondir)
185
202
186 def find_config_file_name(self):
203 def find_config_file_name(self):
187 """Find the config file name for this application.
204 """Find the config file name for this application.
188
205
206 This must set ``self.config_file_name`` to the filename of the
207 config file to use (just the filename). The search paths for the
208 config file are set in :meth:`find_config_file_paths` and then passed
209 to the config file loader where they are resolved to an absolute path.
210
189 If a profile has been set at the command line, this will resolve
211 If a profile has been set at the command line, this will resolve
190 it. The search paths for the config file are set in
212 it.
191 :meth:`find_config_file_paths` and then passed to the config file
192 loader where they are resolved to an absolute path.
193 """
213 """
194
214
195 try:
215 try:
@@ -206,7 +226,11 b' class Application(object):'
206 pass
226 pass
207
227
208 def find_config_file_paths(self):
228 def find_config_file_paths(self):
209 """Set the search paths for resolving the config file."""
229 """Set the search paths for resolving the config file.
230
231 This must set ``self.config_file_paths`` to a sequence of search
232 paths to pass to the config file loader.
233 """
210 self.config_file_paths = (os.getcwd(), self.ipythondir)
234 self.config_file_paths = (os.getcwd(), self.ipythondir)
211
235
212 def pre_load_file_config(self):
236 def pre_load_file_config(self):
@@ -236,12 +260,11 b' class Application(object):'
236 self.log.warn("Error loading config file: <%s>" % \
260 self.log.warn("Error loading config file: <%s>" % \
237 self.config_file_name, exc_info=True)
261 self.config_file_name, exc_info=True)
238 self.file_config = Config()
262 self.file_config = Config()
239 else:
263
240 self.log.debug("Config file loaded: <%s>" % loader.full_filename)
264 def set_file_config_log_level(self):
241 self.log.debug(repr(self.file_config))
242 # We need to keeep self.log_level updated. But we only use the value
265 # We need to keeep self.log_level updated. But we only use the value
243 # of the file_config if a value was not specified at the command
266 # of the file_config if a value was not specified at the command
244 # line.
267 # line, because the command line overrides everything.
245 if not hasattr(self.command_line_config.Global, 'log_level'):
268 if not hasattr(self.command_line_config.Global, 'log_level'):
246 try:
269 try:
247 self.log_level = self.file_config.Global.log_level
270 self.log_level = self.file_config.Global.log_level
@@ -252,6 +275,11 b' class Application(object):'
252 """Do actions after the config file is loaded."""
275 """Do actions after the config file is loaded."""
253 pass
276 pass
254
277
278 def log_file_config(self):
279 if hasattr(self.file_config.Global, 'config_file'):
280 self.log.debug("Config file loaded: <%s>" % self.file_config.Global.config_file)
281 self.log.debug(repr(self.file_config))
282
255 def merge_configs(self):
283 def merge_configs(self):
256 """Merge the default, command line and file config objects."""
284 """Merge the default, command line and file config objects."""
257 config = Config()
285 config = Config()
@@ -259,6 +287,8 b' class Application(object):'
259 config._merge(self.file_config)
287 config._merge(self.file_config)
260 config._merge(self.command_line_config)
288 config._merge(self.command_line_config)
261 self.master_config = config
289 self.master_config = config
290
291 def log_master_config(self):
262 self.log.debug("Master config created:")
292 self.log.debug("Master config created:")
263 self.log.debug(repr(self.master_config))
293 self.log.debug(repr(self.master_config))
264
294
@@ -41,7 +41,7 b' from IPython.kernel.twistedutil import blockingCallFromThread'
41
41
42 # These enable various things
42 # These enable various things
43 from IPython.kernel import codeutil
43 from IPython.kernel import codeutil
44 import IPython.kernel.magic
44 # import IPython.kernel.magic
45
45
46 # Other things that the user will need
46 # Other things that the user will need
47 from IPython.kernel.task import MapTask, StringTask
47 from IPython.kernel.task import MapTask, StringTask
@@ -152,24 +152,42 b' class FCServiceFactory(AdaptedConfiguredObjectFactory):'
152 keys: furl_file and interface_chain.
152 keys: furl_file and interface_chain.
153
153
154 The other attributes are the standard ones for Foolscap.
154 The other attributes are the standard ones for Foolscap.
155 """
155 """
156
156
157 ip = Str('', config=True)
157 ip = Str('', config=True)
158 port = Int(0, config=True)
158 port = Int(0, config=True)
159 secure = Bool(True, config=True)
159 secure = Bool(True, config=True)
160 cert_file = Str('', config=True)
160 cert_file = Str('', config=True)
161 location = Str('', config=True)
161 location = Str('', config=True)
162 reuse_furls = Bool(False, config=True)
162 Interfaces = Instance(klass=Config, kw={}, allow_none=False, config=True)
163 Interfaces = Instance(klass=Config, kw={}, allow_none=False, config=True)
163
164
165 def __init__(self, config, adaptee):
166 super(FCServiceFactory, self).__init__(config, adaptee)
167 self._check_reuse_furls()
168
164 def _ip_changed(self, name, old, new):
169 def _ip_changed(self, name, old, new):
165 if new == 'localhost' or new == '127.0.0.1':
170 if new == 'localhost' or new == '127.0.0.1':
166 self.location = '127.0.0.1'
171 self.location = '127.0.0.1'
167
172
173 def _check_reuse_furls(self):
174 if not self.reuse_furls:
175 furl_files = [i.furl_file for i in self.Interfaces.values()]
176 for ff in furl_files:
177 fullfile = self._get_security_file(ff)
178 if os.path.isfile(fullfile):
179 os.remove(fullfile)
180
181 def _get_security_file(self, filename):
182 return os.path.join(self.config.Global.security_dir, filename)
183
168 def create(self):
184 def create(self):
169 """Create and return the Foolscap tub with everything running."""
185 """Create and return the Foolscap tub with everything running."""
170
186
171 self.tub, self.listener = make_tub(
187 self.tub, self.listener = make_tub(
172 self.ip, self.port, self.secure, self.cert_file)
188 self.ip, self.port, self.secure, self._get_security_file(self.cert_file))
189 log.msg("Created a tub and listener [%r]: %r, %r" % (self.__class__, self.tub, self.listener))
190 log.msg("Interfaces to register [%r]: %r" % (self.__class__, self.Interfaces))
173 if not self.secure:
191 if not self.secure:
174 log.msg("WARNING: running with no security: %s" % self.__class__.__name__)
192 log.msg("WARNING: running with no security: %s" % self.__class__.__name__)
175 reactor.callWhenRunning(self.set_location_and_register)
193 reactor.callWhenRunning(self.set_location_and_register)
@@ -189,13 +207,14 b' class FCServiceFactory(AdaptedConfiguredObjectFactory):'
189 """Run through the interfaces, adapt and register."""
207 """Run through the interfaces, adapt and register."""
190
208
191 for ifname, ifconfig in self.Interfaces.iteritems():
209 for ifname, ifconfig in self.Interfaces.iteritems():
210 ff = self._get_security_file(ifconfig.furl_file)
192 log.msg("Adapting %r to interface: %s" % (self.adaptee, ifname))
211 log.msg("Adapting %r to interface: %s" % (self.adaptee, ifname))
193 log.msg("Saving furl for interface [%s] to file: %s" % (ifname, ifconfig.furl_file))
212 log.msg("Saving furl for interface [%s] to file: %s" % (ifname, ff))
194 check_furl_file_security(ifconfig.furl_file, self.secure)
213 check_furl_file_security(ff, self.secure)
195 adaptee = self.adaptee
214 adaptee = self.adaptee
196 for i in ifconfig.interface_chain:
215 for i in ifconfig.interface_chain:
197 adaptee = import_item(i)(adaptee)
216 adaptee = import_item(i)(adaptee)
198 d.addCallback(self.register, adaptee, furl_file=ifconfig.furl_file)
217 d.addCallback(self.register, adaptee, furl_file=ff)
199
218
200 def register(self, empty, ref, furl_file):
219 def register(self, empty, ref, furl_file):
201 """Register the reference with the FURL file.
220 """Register the reference with the FURL file.
@@ -16,6 +16,7 b' The IPython controller application'
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 import copy
18 import copy
19 import logging
19 import os
20 import os
20 import sys
21 import sys
21
22
@@ -40,7 +41,7 b' from IPython.kernel.configobjfactory import ('
40 from IPython.kernel.fcutil import FCServiceFactory
41 from IPython.kernel.fcutil import FCServiceFactory
41
42
42 #-----------------------------------------------------------------------------
43 #-----------------------------------------------------------------------------
43 # Components for creating services
44 # Default interfaces
44 #-----------------------------------------------------------------------------
45 #-----------------------------------------------------------------------------
45
46
46
47
@@ -50,11 +51,13 b' default_client_interfaces.Task.interface_chain = ['
50 'IPython.kernel.task.ITaskController',
51 'IPython.kernel.task.ITaskController',
51 'IPython.kernel.taskfc.IFCTaskController'
52 'IPython.kernel.taskfc.IFCTaskController'
52 ]
53 ]
54
53 default_client_interfaces.Task.furl_file = 'ipcontroller-tc.furl'
55 default_client_interfaces.Task.furl_file = 'ipcontroller-tc.furl'
54 default_client_interfaces.MultiEngine.interface_chain = [
56 default_client_interfaces.MultiEngine.interface_chain = [
55 'IPython.kernel.multiengine.IMultiEngine',
57 'IPython.kernel.multiengine.IMultiEngine',
56 'IPython.kernel.multienginefc.IFCSynchronousMultiEngine'
58 'IPython.kernel.multienginefc.IFCSynchronousMultiEngine'
57 ]
59 ]
60
58 default_client_interfaces.MultiEngine.furl_file = 'ipcontroller-mec.furl'
61 default_client_interfaces.MultiEngine.furl_file = 'ipcontroller-mec.furl'
59
62
60 # Make this a dict we can pass to Config.__init__ for the default
63 # Make this a dict we can pass to Config.__init__ for the default
@@ -67,12 +70,17 b' default_engine_interfaces = Config()'
67 default_engine_interfaces.Default.interface_chain = [
70 default_engine_interfaces.Default.interface_chain = [
68 'IPython.kernel.enginefc.IFCControllerBase'
71 'IPython.kernel.enginefc.IFCControllerBase'
69 ]
72 ]
73
70 default_engine_interfaces.Default.furl_file = 'ipcontroller-engine.furl'
74 default_engine_interfaces.Default.furl_file = 'ipcontroller-engine.furl'
71
75
72 # Make this a dict we can pass to Config.__init__ for the default
76 # Make this a dict we can pass to Config.__init__ for the default
73 default_engine_interfaces = dict(copy.deepcopy(default_engine_interfaces.items()))
77 default_engine_interfaces = dict(copy.deepcopy(default_engine_interfaces.items()))
74
78
75
79
80 #-----------------------------------------------------------------------------
81 # Service factories
82 #-----------------------------------------------------------------------------
83
76
84
77 class FCClientServiceFactory(FCServiceFactory):
85 class FCClientServiceFactory(FCServiceFactory):
78 """A Foolscap implementation of the client services."""
86 """A Foolscap implementation of the client services."""
@@ -86,7 +94,7 b' class FCEngineServiceFactory(FCServiceFactory):'
86 """A Foolscap implementation of the engine services."""
94 """A Foolscap implementation of the engine services."""
87
95
88 cert_file = Str('ipcontroller-engine.pem', config=True)
96 cert_file = Str('ipcontroller-engine.pem', config=True)
89 interfaces = Instance(klass=dict, kw=default_engine_interfaces,
97 Interfaces = Instance(klass=dict, kw=default_engine_interfaces,
90 allow_none=False, config=True)
98 allow_none=False, config=True)
91
99
92
100
@@ -116,21 +124,6 b' cl_args = ('
116 action='store_false', dest='FCClientServiceFactory.secure', default=NoConfigDefault,
124 action='store_false', dest='FCClientServiceFactory.secure', default=NoConfigDefault,
117 help='Turn off all client security.')
125 help='Turn off all client security.')
118 ),
126 ),
119 (('--client-cert-file',), dict(
120 type=str, dest='FCClientServiceFactory.cert_file', default=NoConfigDefault,
121 help='File to store the client SSL certificate in.',
122 metavar='FCClientServiceFactory.cert_file')
123 ),
124 (('--task-furl-file',), dict(
125 type=str, dest='FCClientServiceFactory.Interfaces.Task.furl_file', default=NoConfigDefault,
126 help='File to store the FURL in for task clients to connect with.',
127 metavar='FCClientServiceFactory.Interfaces.Task.furl_file')
128 ),
129 (('--multiengine-furl-file',), dict(
130 type=str, dest='FCClientServiceFactory.Interfaces.MultiEngine.furl_file', default=NoConfigDefault,
131 help='File to store the FURL in for multiengine clients to connect with.',
132 metavar='FCClientServiceFactory.Interfaces.MultiEngine.furl_file')
133 ),
134 # Engine config
127 # Engine config
135 (('--engine-ip',), dict(
128 (('--engine-ip',), dict(
136 type=str, dest='FCEngineServiceFactory.ip', default=NoConfigDefault,
129 type=str, dest='FCEngineServiceFactory.ip', default=NoConfigDefault,
@@ -151,26 +144,20 b' cl_args = ('
151 action='store_false', dest='FCEngineServiceFactory.secure', default=NoConfigDefault,
144 action='store_false', dest='FCEngineServiceFactory.secure', default=NoConfigDefault,
152 help='Turn off all engine security.')
145 help='Turn off all engine security.')
153 ),
146 ),
154 (('--engine-cert-file',), dict(
155 type=str, dest='FCEngineServiceFactory.cert_file', default=NoConfigDefault,
156 help='File to store the client SSL certificate in.',
157 metavar='FCEngineServiceFactory.cert_file')
158 ),
159 (('--engine-furl-file',), dict(
160 type=str, dest='FCEngineServiceFactory.Interfaces.Default.furl_file', default=NoConfigDefault,
161 help='File to store the FURL in for engines to connect with.',
162 metavar='FCEngineServiceFactory.Interfaces.Default.furl_file')
163 ),
164 # Global config
147 # Global config
165 (('-l','--logfile'), dict(
148 (('--log-to-file',), dict(
166 type=str, dest='Global.logfile', default=NoConfigDefault,
149 action='store_true', dest='Global.log_to_file', default=NoConfigDefault,
167 help='Log file name (default is stdout)',
150 help='Log to a file in the log directory (default is stdout)')
168 metavar='Global.logfile')
169 ),
151 ),
170 (('-r',), dict(
152 (('-r','--reuse-furls'), dict(
171 action='store_true', dest='Global.reuse_furls', default=NoConfigDefault,
153 action='store_true', dest='Global.reuse_furls', default=NoConfigDefault,
172 help='Try to reuse all FURL files.')
154 help='Try to reuse all FURL files.')
173 )
155 ),
156 (('-cluster_dir', '--cluster-dir',), dict(
157 type=str, dest='Global.cluster_dir', default=NoConfigDefault,
158 help='Absolute or relative path to the cluster directory.',
159 metavar='Global.cluster_dir')
160 ),
174 )
161 )
175
162
176
163
@@ -185,12 +172,18 b' class IPControllerApp(Application):'
185
172
186 name = 'ipcontroller'
173 name = 'ipcontroller'
187 config_file_name = _default_config_file_name
174 config_file_name = _default_config_file_name
175 default_log_level = logging.DEBUG
188
176
189 def create_default_config(self):
177 def create_default_config(self):
190 super(IPControllerApp, self).create_default_config()
178 super(IPControllerApp, self).create_default_config()
191 self.default_config.Global.logfile = ''
192 self.default_config.Global.reuse_furls = False
179 self.default_config.Global.reuse_furls = False
193 self.default_config.Global.import_statements = []
180 self.default_config.Global.import_statements = []
181 self.default_config.Global.profile = 'default'
182 self.default_config.Global.log_dir_name = 'log'
183 self.default_config.Global.security_dir_name = 'security'
184 self.default_config.Global.log_to_file = False
185 # Resolve the default cluster_dir using the default profile
186 self.default_config.Global.cluster_dir = ''
194
187
195 def create_command_line_config(self):
188 def create_command_line_config(self):
196 """Create and return a command line config loader."""
189 """Create and return a command line config loader."""
@@ -199,6 +192,75 b' class IPControllerApp(Application):'
199 description="Start an IPython controller",
192 description="Start an IPython controller",
200 version=release.version)
193 version=release.version)
201
194
195 def find_config_file_name(self):
196 """Find the config file name for this application."""
197 self.find_cluster_dir()
198 self.create_cluster_dir()
199
200 def find_cluster_dir(self):
201 """This resolves into full paths, the various cluster directories.
202
203 This method must set ``self.cluster_dir`` to the full paths of
204 the directory.
205 """
206 # Ignore self.command_line_config.Global.config_file
207 # Instead, first look for an explicit cluster_dir
208 try:
209 self.cluster_dir = self.command_line_config.Global.cluster_dir
210 except AttributeError:
211 self.cluster_dir = self.default_config.Global.cluster_dir
212 self.cluster_dir = os.path.expandvars(os.path.expanduser(self.cluster_dir))
213 if not self.cluster_dir:
214 # Then look for a profile
215 try:
216 self.profile = self.command_line_config.Global.profile
217 except AttributeError:
218 self.profile = self.default_config.Global.profile
219 cluster_dir_name = 'cluster_' + self.profile
220 try_this = os.path.join(os.getcwd(), cluster_dir_name)
221 if os.path.isdir(try_this):
222 self.cluster_dir = try_this
223 else:
224 self.cluster_dir = os.path.join(self.ipythondir, cluster_dir_name)
225 # These have to be set because they could be different from the one
226 # that we just computed. Because command line has the highest
227 # priority, this will always end up in the master_config.
228 self.default_config.Global.cluster_dir = self.cluster_dir
229 self.command_line_config.Global.cluster_dir = self.cluster_dir
230
231 def create_cluster_dir(self):
232 """Make sure that the cluster, security and log dirs exist."""
233 if not os.path.isdir(self.cluster_dir):
234 os.makedirs(self.cluster_dir, mode=0777)
235
236 def find_config_file_paths(self):
237 """Set the search paths for resolving the config file."""
238 self.config_file_paths = (self.cluster_dir,)
239
240 def pre_construct(self):
241 # Now set the security_dir and log_dir and create them. We use
242 # the names an construct the absolute paths.
243 security_dir = os.path.join(self.master_config.Global.cluster_dir,
244 self.master_config.Global.security_dir_name)
245 log_dir = os.path.join(self.master_config.Global.cluster_dir,
246 self.master_config.Global.log_dir_name)
247 if not os.path.isdir(security_dir):
248 os.mkdir(security_dir, 0700)
249 else:
250 os.chmod(security_dir, 0700)
251 if not os.path.isdir(log_dir):
252 os.mkdir(log_dir, 0777)
253
254 self.security_dir = self.master_config.Global.security_dir = security_dir
255 self.log_dir = self.master_config.Global.log_dir = log_dir
256
257 # Now setup reuse_furls
258 if hasattr(self.master_config.Global.reuse_furls):
259 self.master_config.FCClientServiceFactory.reuse_furls = \
260 self.master_config.Global.reuse_furls
261 self.master_config.FCEngineServiceFactory.reuse_furls = \
262 self.master_config.Global.reuse_furls
263
202 def construct(self):
264 def construct(self):
203 # I am a little hesitant to put these into InteractiveShell itself.
265 # I am a little hesitant to put these into InteractiveShell itself.
204 # But that might be the place for them
266 # But that might be the place for them
@@ -206,7 +268,6 b' class IPControllerApp(Application):'
206
268
207 self.start_logging()
269 self.start_logging()
208 self.import_statements()
270 self.import_statements()
209 self.reuse_furls()
210
271
211 # Create the service hierarchy
272 # Create the service hierarchy
212 self.main_service = service.MultiService()
273 self.main_service = service.MultiService()
@@ -223,16 +284,13 b' class IPControllerApp(Application):'
223 engine_service.setServiceParent(self.main_service)
284 engine_service.setServiceParent(self.main_service)
224
285
225 def start_logging(self):
286 def start_logging(self):
226 logfile = self.master_config.Global.logfile
287 if self.master_config.Global.log_to_file:
227 if logfile:
288 log_filename = self.name + '-' + str(os.getpid()) + '.log'
228 logfile = logfile + str(os.getpid()) + '.log'
289 logfile = os.path.join(self.log_dir, log_filename)
229 try:
290 open_log_file = open(logfile, 'w')
230 openLogFile = open(logfile, 'w')
231 except:
232 openLogFile = sys.stdout
233 else:
291 else:
234 openLogFile = sys.stdout
292 open_log_file = sys.stdout
235 log.startLogging(openLogFile)
293 log.startLogging(open_log_file)
236
294
237 def import_statements(self):
295 def import_statements(self):
238 statements = self.master_config.Global.import_statements
296 statements = self.master_config.Global.import_statements
@@ -242,20 +300,6 b' class IPControllerApp(Application):'
242 except:
300 except:
243 log.msg("Error running import statement: %s" % s)
301 log.msg("Error running import statement: %s" % s)
244
302
245 def reuse_furls(self):
246 # This logic might need to be moved into the components
247 # Delete old furl files unless the reuse_furls is set
248 reuse = self.master_config.Global.reuse_furls
249 # if not reuse:
250 # paths = (
251 # self.master_config.FCEngineServiceFactory.Interfaces.Default.furl_file,
252 # self.master_config.FCClientServiceFactory.Interfaces.Task.furl_file,
253 # self.master_config.FCClientServiceFactory.Interfaces.MultiEngine.furl_file
254 # )
255 # for p in paths:
256 # if os.path.isfile(p):
257 # os.remove(p)
258
259 def start_app(self):
303 def start_app(self):
260 # Start the controller service and set things running
304 # Start the controller service and set things running
261 self.main_service.startService()
305 self.main_service.startService()
General Comments 0
You need to be logged in to leave comments. Login now