##// 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 46 """Default command line options for IPython based applications."""
47 47
48 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 51 help='Set to override default location of Global.ipythondir.',
51 52 default=NoConfigDefault,
52 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 56 help='The string name of the ipython profile to be used.',
55 57 default=NoConfigDefault,
56 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 61 help='Set the log level (0,10,20,30,40,50). Default is 30.',
59 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 65 help='Set the config file name to override default.',
62 66 default=NoConfigDefault,
63 67 metavar='Global.config_file')
@@ -46,11 +46,11 b' class DisplayTrap(Component):'
46 46 # Only turn off the trap when the outermost call to __exit__ is made.
47 47 self._nested_level = 0
48 48
49 @auto_attr
50 def shell(self):
51 return Component.get_instances(
52 root=self.root,
53 klass='IPython.core.iplib.InteractiveShell')[0]
49 # @auto_attr
50 # def shell(self):
51 # return Component.get_instances(
52 # root=self.root,
53 # klass='IPython.core.iplib.InteractiveShell')[0]
54 54
55 55 def __enter__(self):
56 56 if self._nested_level == 0:
@@ -1602,10 +1602,10 b' class InteractiveShell(Component, Magic):'
1602 1602 else:
1603 1603 magic_args = self.var_expand(magic_args,1)
1604 1604 with nested(self.builtin_trap,):
1605 result = fn(magic_args)
1605 return fn(magic_args)
1606 1606 # Unfortunately, the return statement is what will trigger
1607 1607 # the displayhook, but it is no longer set!
1608 return result
1608 # return result
1609 1609
1610 1610 def define_magic(self, magicname, func):
1611 1611 """Expose own function as magic function for ipython
@@ -1268,7 +1268,6 b' Currently the magic system has the following functions:\\n"""'
1268 1268 If you want IPython to automatically do this on every exception, see
1269 1269 the %pdb magic for more details.
1270 1270 """
1271
1272 1271 self.shell.debugger(force=True)
1273 1272
1274 1273 @testdec.skip_doctest
@@ -1,27 +1,56 b''
1 #!/usr/bin/env python
1 2 # encoding: utf-8
3 """
4 Foolscap related utilities.
5 """
2 6
3 """Foolscap related utilities."""
4
5 __docformat__ = "restructuredtext en"
6
7 #-------------------------------------------------------------------------------
8 # Copyright (C) 2008 The IPython Development Team
7 #-----------------------------------------------------------------------------
8 # Copyright (C) 2008-2009 The IPython Development Team
9 9 #
10 10 # Distributed under the terms of the BSD License. The full license is in
11 11 # the file COPYING, distributed as part of this software.
12 #-------------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 13
14 #-------------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 15 # Imports
16 #-------------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17 17
18 18 import os
19 import tempfile
20
21 from twisted.internet import reactor, defer
22 from twisted.python import log
19 23
20 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 52 def check_furl_file_security(furl_file, secure):
23 53 """Remove the old furl_file if changing security modes."""
24
25 54 if os.path.isfile(furl_file):
26 55 f = open(furl_file, 'r')
27 56 oldfurl = f.read().strip()
@@ -29,7 +58,9 b' def check_furl_file_security(furl_file, secure):'
29 58 if (oldfurl.startswith('pb://') and not secure) or (oldfurl.startswith('pbu://') and secure):
30 59 os.remove(furl_file)
31 60
61
32 62 def is_secure(furl):
63 """Is the given FURL secure or not."""
33 64 if is_valid(furl):
34 65 if furl.startswith("pb://"):
35 66 return True
@@ -38,14 +69,18 b' def is_secure(furl):'
38 69 else:
39 70 raise ValueError("invalid furl: %s" % furl)
40 71
72
41 73 def is_valid(furl):
74 """Is the str a valid furl or not."""
42 75 if isinstance(furl, str):
43 76 if furl.startswith("pb://") or furl.startswith("pbu://"):
44 77 return True
45 78 else:
46 79 return False
47 80
81
48 82 def find_furl(furl_or_file):
83 """Find, validate and return a FURL in a string or file."""
49 84 if isinstance(furl_or_file, str):
50 85 if is_valid(furl_or_file):
51 86 return furl_or_file
@@ -55,15 +90,120 b' def find_furl(furl_or_file):'
55 90 return furl
56 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
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)
66 123 else:
67 have_crypto = True
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.
68 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 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 175 # Base TraitletType for all traitlets
156 176 #-----------------------------------------------------------------------------
@@ -316,6 +336,9 b' class MetaHasTraitlets(type):'
316 336 This instantiates all TraitletTypes in the class dict and sets their
317 337 :attr:`name` attribute.
318 338 """
339 # print "MetaHasTraitlets (mcls, name): ", mcls, name
340 # print "MetaHasTraitlets (bases): ", bases
341 # print "MetaHasTraitlets (classdict): ", classdict
319 342 for k,v in classdict.iteritems():
320 343 if isinstance(v, TraitletType):
321 344 v.name = k
@@ -354,7 +377,14 b' class HasTraitlets(object):'
354 377 # Here we tell all the TraitletType instances to set their default
355 378 # values on the instance.
356 379 for key in dir(cls):
380 # Some descriptors raise AttributeError like zope.interface's
381 # __provides__ attributes even though they exist. This causes
382 # AttributeErrors even though they are listed in dir(cls).
383 try:
357 384 value = getattr(cls, key)
385 except AttributeError:
386 pass
387 else:
358 388 if isinstance(value, TraitletType):
359 389 value.instance_init(inst)
360 390 return inst
@@ -475,7 +505,7 b' class HasTraitlets(object):'
475 505 exists, but has any value. This is because get_metadata returns
476 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 509 isinstance(memb[1], TraitletType)])
480 510
481 511 if len(metadata) == 0:
General Comments 0
You need to be logged in to leave comments. Login now