##// END OF EJS Templates
Work on refactoring ipcontroller to new config system.
Brian Granger -
Show More
@@ -46,18 +46,22 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',dest='Global.ipythondir',type=str,
49 self.parser.add_argument('-ipythondir', '--ipythondir',
50 dest='Global.ipythondir',type=str,
50 help='Set to override default location of Global.ipythondir.',
51 help='Set to override default location of Global.ipythondir.',
51 default=NoConfigDefault,
52 default=NoConfigDefault,
52 metavar='Global.ipythondir')
53 metavar='Global.ipythondir')
53 self.parser.add_argument('-p','-profile',dest='Global.profile',type=str,
54 self.parser.add_argument('-p','-profile', '--profile',
55 dest='Global.profile',type=str,
54 help='The string name of the ipython profile to be used.',
56 help='The string name of the ipython profile to be used.',
55 default=NoConfigDefault,
57 default=NoConfigDefault,
56 metavar='Global.profile')
58 metavar='Global.profile')
57 self.parser.add_argument('-log_level',dest="Global.log_level",type=int,
59 self.parser.add_argument('-log_level', '--log-level',
60 dest="Global.log_level",type=int,
58 help='Set the log level (0,10,20,30,40,50). Default is 30.',
61 help='Set the log level (0,10,20,30,40,50). Default is 30.',
59 default=NoConfigDefault)
62 default=NoConfigDefault)
60 self.parser.add_argument('-config_file',dest='Global.config_file',type=str,
63 self.parser.add_argument('-config_file', '--config-file',
64 dest='Global.config_file',type=str,
61 help='Set the config file name to override default.',
65 help='Set the config file name to override default.',
62 default=NoConfigDefault,
66 default=NoConfigDefault,
63 metavar='Global.config_file')
67 metavar='Global.config_file')
@@ -46,11 +46,11 b' class DisplayTrap(Component):'
46 # Only turn off the trap when the outermost call to __exit__ is made.
46 # Only turn off the trap when the outermost call to __exit__ is made.
47 self._nested_level = 0
47 self._nested_level = 0
48
48
49 @auto_attr
49 # @auto_attr
50 def shell(self):
50 # def shell(self):
51 return Component.get_instances(
51 # return Component.get_instances(
52 root=self.root,
52 # root=self.root,
53 klass='IPython.core.iplib.InteractiveShell')[0]
53 # klass='IPython.core.iplib.InteractiveShell')[0]
54
54
55 def __enter__(self):
55 def __enter__(self):
56 if self._nested_level == 0:
56 if self._nested_level == 0:
@@ -1602,10 +1602,10 b' class InteractiveShell(Component, Magic):'
1602 else:
1602 else:
1603 magic_args = self.var_expand(magic_args,1)
1603 magic_args = self.var_expand(magic_args,1)
1604 with nested(self.builtin_trap,):
1604 with nested(self.builtin_trap,):
1605 result = fn(magic_args)
1605 return fn(magic_args)
1606 # Unfortunately, the return statement is what will trigger
1606 # Unfortunately, the return statement is what will trigger
1607 # the displayhook, but it is no longer set!
1607 # the displayhook, but it is no longer set!
1608 return result
1608 # return result
1609
1609
1610 def define_magic(self, magicname, func):
1610 def define_magic(self, magicname, func):
1611 """Expose own function as magic function for ipython
1611 """Expose own function as magic function for ipython
@@ -1268,7 +1268,6 b' Currently the magic system has the following functions:\\n"""'
1268 If you want IPython to automatically do this on every exception, see
1268 If you want IPython to automatically do this on every exception, see
1269 the %pdb magic for more details.
1269 the %pdb magic for more details.
1270 """
1270 """
1271
1272 self.shell.debugger(force=True)
1271 self.shell.debugger(force=True)
1273
1272
1274 @testdec.skip_doctest
1273 @testdec.skip_doctest
@@ -1,27 +1,56 b''
1 #!/usr/bin/env python
1 # encoding: utf-8
2 # encoding: utf-8
3 """
4 Foolscap related utilities.
5 """
2
6
3 """Foolscap related utilities."""
7 #-----------------------------------------------------------------------------
4
8 # Copyright (C) 2008-2009 The IPython Development Team
5 __docformat__ = "restructuredtext en"
6
7 #-------------------------------------------------------------------------------
8 # Copyright (C) 2008 The IPython Development Team
9 #
9 #
10 # Distributed under the terms of the BSD License. The full license is in
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
11 # the file COPYING, distributed as part of this software.
12 #-------------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13
13
14 #-------------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 # Imports
15 # Imports
16 #-------------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 import os
18 import os
19 import tempfile
20
21 from twisted.internet import reactor, defer
22 from twisted.python import log
19
23
20 from foolscap import Tub, UnauthenticatedTub
24 from foolscap import Tub, UnauthenticatedTub
21
25
26 from IPython.config.loader import Config
27
28 from IPython.kernel.configobjfactory import AdaptedConfiguredObjectFactory
29
30 from IPython.kernel.error import SecurityError
31
32 from IPython.utils.traitlets import Int, Str, Bool, Instance
33 from IPython.utils.importstring import import_item
34
35 #-----------------------------------------------------------------------------
36 # Code
37 #-----------------------------------------------------------------------------
38
39
40 # We do this so if a user doesn't have OpenSSL installed, it will try to use
41 # an UnauthenticatedTub. But, they will still run into problems if they
42 # try to use encrypted furls.
43 try:
44 import OpenSSL
45 except:
46 Tub = UnauthenticatedTub
47 have_crypto = False
48 else:
49 have_crypto = True
50
51
22 def check_furl_file_security(furl_file, secure):
52 def check_furl_file_security(furl_file, secure):
23 """Remove the old furl_file if changing security modes."""
53 """Remove the old furl_file if changing security modes."""
24
25 if os.path.isfile(furl_file):
54 if os.path.isfile(furl_file):
26 f = open(furl_file, 'r')
55 f = open(furl_file, 'r')
27 oldfurl = f.read().strip()
56 oldfurl = f.read().strip()
@@ -29,7 +58,9 b' def check_furl_file_security(furl_file, secure):'
29 if (oldfurl.startswith('pb://') and not secure) or (oldfurl.startswith('pbu://') and secure):
58 if (oldfurl.startswith('pb://') and not secure) or (oldfurl.startswith('pbu://') and secure):
30 os.remove(furl_file)
59 os.remove(furl_file)
31
60
61
32 def is_secure(furl):
62 def is_secure(furl):
63 """Is the given FURL secure or not."""
33 if is_valid(furl):
64 if is_valid(furl):
34 if furl.startswith("pb://"):
65 if furl.startswith("pb://"):
35 return True
66 return True
@@ -38,14 +69,18 b' def is_secure(furl):'
38 else:
69 else:
39 raise ValueError("invalid furl: %s" % furl)
70 raise ValueError("invalid furl: %s" % furl)
40
71
72
41 def is_valid(furl):
73 def is_valid(furl):
74 """Is the str a valid furl or not."""
42 if isinstance(furl, str):
75 if isinstance(furl, str):
43 if furl.startswith("pb://") or furl.startswith("pbu://"):
76 if furl.startswith("pb://") or furl.startswith("pbu://"):
44 return True
77 return True
45 else:
78 else:
46 return False
79 return False
47
80
81
48 def find_furl(furl_or_file):
82 def find_furl(furl_or_file):
83 """Find, validate and return a FURL in a string or file."""
49 if isinstance(furl_or_file, str):
84 if isinstance(furl_or_file, str):
50 if is_valid(furl_or_file):
85 if is_valid(furl_or_file):
51 return furl_or_file
86 return furl_or_file
@@ -55,15 +90,120 b' def find_furl(furl_or_file):'
55 return furl
90 return furl
56 raise ValueError("not a furl or a file containing a furl: %s" % furl_or_file)
91 raise ValueError("not a furl or a file containing a furl: %s" % furl_or_file)
57
92
58 # We do this so if a user doesn't have OpenSSL installed, it will try to use
59 # an UnauthenticatedTub. But, they will still run into problems if they
60 # try to use encrypted furls.
61 try:
62 import OpenSSL
63 except:
64 Tub = UnauthenticatedTub
65 have_crypto = False
66 else:
67 have_crypto = True
68
93
94 def get_temp_furlfile(filename):
95 """Return a temporary furl file."""
96 return tempfile.mktemp(dir=os.path.dirname(filename),
97 prefix=os.path.basename(filename))
98
99
100 def make_tub(ip, port, secure, cert_file):
101 """Create a listening tub given an ip, port, and cert_file location.
102
103 Parameters
104 ----------
105 ip : str
106 The ip address or hostname that the tub should listen on.
107 Empty means all interfaces.
108 port : int
109 The port that the tub should listen on. A value of 0 means
110 pick a random port
111 secure: bool
112 Will the connection be secure (in the Foolscap sense).
113 cert_file: str
114 A filename of a file to be used for theSSL certificate.
115
116 Returns
117 -------
118 A tub, listener tuple.
119 """
120 if secure:
121 if have_crypto:
122 tub = Tub(certFile=cert_file)
123 else:
124 raise SecurityError("OpenSSL/pyOpenSSL is not available, so we "
125 "can't run in secure mode. Try running without "
126 "security using 'ipcontroller -xy'.")
127 else:
128 tub = UnauthenticatedTub()
129
130 # Set the strport based on the ip and port and start listening
131 if ip == '':
132 strport = "tcp:%i" % port
133 else:
134 strport = "tcp:%i:interface=%s" % (port, ip)
135 listener = tub.listenOn(strport)
136
137 return tub, listener
138
139
140 class FCServiceFactory(AdaptedConfiguredObjectFactory):
141 """This class creates a tub with various services running in it.
142
143 The basic idea is that :meth:`create` returns a running :class:`Tub`
144 instance that has a number of Foolscap references registered in it.
145 This class is a subclass of :class:`IPython.core.component.Component`
146 so the IPython configuration and component system are used.
147
148 Attributes
149 ----------
150 Interfaces : Config
151 A Config instance whose values are sub-Config objects having two
152 keys: furl_file and interface_chain.
153
154 The other attributes are the standard ones for Foolscap.
155 """
156
157 ip = Str('', config=True)
158 port = Int(0, config=True)
159 secure = Bool(True, config=True)
160 cert_file = Str('', config=True)
161 location = Str('', config=True)
162 Interfaces = Instance(klass=Config, kw={}, allow_none=False, config=True)
163
164 def _ip_changed(self, name, old, new):
165 if new == 'localhost' or new == '127.0.0.1':
166 self.location = '127.0.0.1'
167
168 def create(self):
169 """Create and return the Foolscap tub with everything running."""
170
171 self.tub, self.listener = make_tub(
172 self.ip, self.port, self.secure, self.cert_file)
173 if not self.secure:
174 log.msg("WARNING: running with no security: %s" % self.__class__.__name__)
175 reactor.callWhenRunning(self.set_location_and_register)
176 return self.tub
177
178 def set_location_and_register(self):
179 """Set the location for the tub and return a deferred."""
180
181 if self.location == '':
182 d = self.tub.setLocationAutomatically()
183 else:
184 d = defer.maybeDeferred(self.tub.setLocation,
185 "%s:%i" % (self.location, self.listener.getPortnum()))
186 self.adapt_to_interfaces(d)
187
188 def adapt_to_interfaces(self, d):
189 """Run through the interfaces, adapt and register."""
190
191 for ifname, ifconfig in self.Interfaces.iteritems():
192 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))
194 check_furl_file_security(ifconfig.furl_file, self.secure)
195 adaptee = self.adaptee
196 for i in ifconfig.interface_chain:
197 adaptee = import_item(i)(adaptee)
198 d.addCallback(self.register, adaptee, furl_file=ifconfig.furl_file)
199
200 def register(self, empty, ref, furl_file):
201 """Register the reference with the FURL file.
202
203 The FURL file is created and then moved to make sure that when the
204 file appears, the buffer has been flushed and the file closed.
205 """
206 temp_furl_file = get_temp_furlfile(furl_file)
207 self.tub.registerReference(ref, furlFile=temp_furl_file)
208 os.rename(temp_furl_file, furl_file)
69
209
@@ -151,6 +151,26 b' class _SimpleTest:'
151 return self.__repr__()
151 return self.__repr__()
152
152
153
153
154 def getmembers(object, predicate=None):
155 """A safe version of inspect.getmembers that handles missing attributes.
156
157 This is useful when there are descriptor based attributes that for
158 some reason raise AttributeError even though they exist. This happens
159 in zope.inteface with the __provides__ attribute.
160 """
161 results = []
162 for key in dir(object):
163 try:
164 value = getattr(object, key)
165 except AttributeError:
166 pass
167 else:
168 if not predicate or predicate(value):
169 results.append((key, value))
170 results.sort()
171 return results
172
173
154 #-----------------------------------------------------------------------------
174 #-----------------------------------------------------------------------------
155 # Base TraitletType for all traitlets
175 # Base TraitletType for all traitlets
156 #-----------------------------------------------------------------------------
176 #-----------------------------------------------------------------------------
@@ -316,6 +336,9 b' class MetaHasTraitlets(type):'
316 This instantiates all TraitletTypes in the class dict and sets their
336 This instantiates all TraitletTypes in the class dict and sets their
317 :attr:`name` attribute.
337 :attr:`name` attribute.
318 """
338 """
339 # print "MetaHasTraitlets (mcls, name): ", mcls, name
340 # print "MetaHasTraitlets (bases): ", bases
341 # print "MetaHasTraitlets (classdict): ", classdict
319 for k,v in classdict.iteritems():
342 for k,v in classdict.iteritems():
320 if isinstance(v, TraitletType):
343 if isinstance(v, TraitletType):
321 v.name = k
344 v.name = k
@@ -354,9 +377,16 b' class HasTraitlets(object):'
354 # Here we tell all the TraitletType instances to set their default
377 # Here we tell all the TraitletType instances to set their default
355 # values on the instance.
378 # values on the instance.
356 for key in dir(cls):
379 for key in dir(cls):
357 value = getattr(cls, key)
380 # Some descriptors raise AttributeError like zope.interface's
358 if isinstance(value, TraitletType):
381 # __provides__ attributes even though they exist. This causes
359 value.instance_init(inst)
382 # AttributeErrors even though they are listed in dir(cls).
383 try:
384 value = getattr(cls, key)
385 except AttributeError:
386 pass
387 else:
388 if isinstance(value, TraitletType):
389 value.instance_init(inst)
360 return inst
390 return inst
361
391
362 # def __init__(self):
392 # def __init__(self):
@@ -475,7 +505,7 b' class HasTraitlets(object):'
475 exists, but has any value. This is because get_metadata returns
505 exists, but has any value. This is because get_metadata returns
476 None if a metadata key doesn't exist.
506 None if a metadata key doesn't exist.
477 """
507 """
478 traitlets = dict([memb for memb in inspect.getmembers(self.__class__) if \
508 traitlets = dict([memb for memb in getmembers(self.__class__) if \
479 isinstance(memb[1], TraitletType)])
509 isinstance(memb[1], TraitletType)])
480
510
481 if len(metadata) == 0:
511 if len(metadata) == 0:
General Comments 0
You need to be logged in to leave comments. Login now