##// END OF EJS Templates
Prevents crash on some systems where chmod fails (e.g. sshfs on Windows)....
MinRK -
Show More
@@ -1,207 +1,213 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 An object for managing IPython profile directories.
3 An object for managing IPython profile directories.
4
4
5 Authors:
5 Authors:
6
6
7 * Brian Granger
7 * Brian Granger
8 * Fernando Perez
8 * Fernando Perez
9 * Min RK
9 * Min RK
10
10
11 """
11 """
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Copyright (C) 2008-2011 The IPython Development Team
14 # Copyright (C) 2008-2011 The IPython Development Team
15 #
15 #
16 # Distributed under the terms of the BSD License. The full license is in
16 # Distributed under the terms of the BSD License. The full license is in
17 # the file COPYING, distributed as part of this software.
17 # the file COPYING, distributed as part of this software.
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19
19
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 # Imports
21 # Imports
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23
23
24 import os
24 import os
25 import shutil
25 import shutil
26 import sys
26 import sys
27
27
28 from IPython.config.configurable import Configurable
28 from IPython.config.configurable import LoggingConfigurable
29 from IPython.config.loader import Config
29 from IPython.config.loader import Config
30 from IPython.utils.path import get_ipython_package_dir, expand_path
30 from IPython.utils.path import get_ipython_package_dir, expand_path
31 from IPython.utils.traitlets import List, Unicode, Bool
31 from IPython.utils.traitlets import List, Unicode, Bool
32
32
33 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
34 # Classes and functions
34 # Classes and functions
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36
36
37
37
38 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
39 # Module errors
39 # Module errors
40 #-----------------------------------------------------------------------------
40 #-----------------------------------------------------------------------------
41
41
42 class ProfileDirError(Exception):
42 class ProfileDirError(Exception):
43 pass
43 pass
44
44
45
45
46 #-----------------------------------------------------------------------------
46 #-----------------------------------------------------------------------------
47 # Class for managing profile directories
47 # Class for managing profile directories
48 #-----------------------------------------------------------------------------
48 #-----------------------------------------------------------------------------
49
49
50 class ProfileDir(Configurable):
50 class ProfileDir(LoggingConfigurable):
51 """An object to manage the profile directory and its resources.
51 """An object to manage the profile directory and its resources.
52
52
53 The profile directory is used by all IPython applications, to manage
53 The profile directory is used by all IPython applications, to manage
54 configuration, logging and security.
54 configuration, logging and security.
55
55
56 This object knows how to find, create and manage these directories. This
56 This object knows how to find, create and manage these directories. This
57 should be used by any code that wants to handle profiles.
57 should be used by any code that wants to handle profiles.
58 """
58 """
59
59
60 security_dir_name = Unicode('security')
60 security_dir_name = Unicode('security')
61 log_dir_name = Unicode('log')
61 log_dir_name = Unicode('log')
62 pid_dir_name = Unicode('pid')
62 pid_dir_name = Unicode('pid')
63 security_dir = Unicode(u'')
63 security_dir = Unicode(u'')
64 log_dir = Unicode(u'')
64 log_dir = Unicode(u'')
65 pid_dir = Unicode(u'')
65 pid_dir = Unicode(u'')
66
66
67 location = Unicode(u'', config=True,
67 location = Unicode(u'', config=True,
68 help="""Set the profile location directly. This overrides the logic used by the
68 help="""Set the profile location directly. This overrides the logic used by the
69 `profile` option.""",
69 `profile` option.""",
70 )
70 )
71
71
72 _location_isset = Bool(False) # flag for detecting multiply set location
72 _location_isset = Bool(False) # flag for detecting multiply set location
73
73
74 def _location_changed(self, name, old, new):
74 def _location_changed(self, name, old, new):
75 if self._location_isset:
75 if self._location_isset:
76 raise RuntimeError("Cannot set profile location more than once.")
76 raise RuntimeError("Cannot set profile location more than once.")
77 self._location_isset = True
77 self._location_isset = True
78 if not os.path.isdir(new):
78 if not os.path.isdir(new):
79 os.makedirs(new)
79 os.makedirs(new)
80
80
81 # ensure config files exist:
81 # ensure config files exist:
82 self.security_dir = os.path.join(new, self.security_dir_name)
82 self.security_dir = os.path.join(new, self.security_dir_name)
83 self.log_dir = os.path.join(new, self.log_dir_name)
83 self.log_dir = os.path.join(new, self.log_dir_name)
84 self.pid_dir = os.path.join(new, self.pid_dir_name)
84 self.pid_dir = os.path.join(new, self.pid_dir_name)
85 self.check_dirs()
85 self.check_dirs()
86
86
87 def _log_dir_changed(self, name, old, new):
87 def _log_dir_changed(self, name, old, new):
88 self.check_log_dir()
88 self.check_log_dir()
89
89
90 def check_log_dir(self):
90 def check_log_dir(self):
91 if not os.path.isdir(self.log_dir):
91 if not os.path.isdir(self.log_dir):
92 os.mkdir(self.log_dir)
92 os.mkdir(self.log_dir)
93
93
94 def _security_dir_changed(self, name, old, new):
94 def _security_dir_changed(self, name, old, new):
95 self.check_security_dir()
95 self.check_security_dir()
96
96
97 def check_security_dir(self):
97 def check_security_dir(self):
98 if not os.path.isdir(self.security_dir):
98 if not os.path.isdir(self.security_dir):
99 os.mkdir(self.security_dir, 0700)
99 os.mkdir(self.security_dir, 0700)
100 else:
100 else:
101 try:
101 os.chmod(self.security_dir, 0700)
102 os.chmod(self.security_dir, 0700)
103 except OSError:
104 self.log.warn("Could not set security dir permissions to private.")
102
105
103 def _pid_dir_changed(self, name, old, new):
106 def _pid_dir_changed(self, name, old, new):
104 self.check_pid_dir()
107 self.check_pid_dir()
105
108
106 def check_pid_dir(self):
109 def check_pid_dir(self):
107 if not os.path.isdir(self.pid_dir):
110 if not os.path.isdir(self.pid_dir):
108 os.mkdir(self.pid_dir, 0700)
111 os.mkdir(self.pid_dir, 0700)
109 else:
112 else:
113 try:
110 os.chmod(self.pid_dir, 0700)
114 os.chmod(self.pid_dir, 0700)
115 except OSError:
116 self.log.warn("Could not set pid dir permissions to private.")
111
117
112 def check_dirs(self):
118 def check_dirs(self):
113 self.check_security_dir()
119 self.check_security_dir()
114 self.check_log_dir()
120 self.check_log_dir()
115 self.check_pid_dir()
121 self.check_pid_dir()
116
122
117 def copy_config_file(self, config_file, path=None, overwrite=False):
123 def copy_config_file(self, config_file, path=None, overwrite=False):
118 """Copy a default config file into the active profile directory.
124 """Copy a default config file into the active profile directory.
119
125
120 Default configuration files are kept in :mod:`IPython.config.default`.
126 Default configuration files are kept in :mod:`IPython.config.default`.
121 This function moves these from that location to the working profile
127 This function moves these from that location to the working profile
122 directory.
128 directory.
123 """
129 """
124 dst = os.path.join(self.location, config_file)
130 dst = os.path.join(self.location, config_file)
125 if os.path.isfile(dst) and not overwrite:
131 if os.path.isfile(dst) and not overwrite:
126 return False
132 return False
127 if path is None:
133 if path is None:
128 path = os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
134 path = os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
129 src = os.path.join(path, config_file)
135 src = os.path.join(path, config_file)
130 shutil.copy(src, dst)
136 shutil.copy(src, dst)
131 return True
137 return True
132
138
133 @classmethod
139 @classmethod
134 def create_profile_dir(cls, profile_dir, config=None):
140 def create_profile_dir(cls, profile_dir, config=None):
135 """Create a new profile directory given a full path.
141 """Create a new profile directory given a full path.
136
142
137 Parameters
143 Parameters
138 ----------
144 ----------
139 profile_dir : str
145 profile_dir : str
140 The full path to the profile directory. If it does exist, it will
146 The full path to the profile directory. If it does exist, it will
141 be used. If not, it will be created.
147 be used. If not, it will be created.
142 """
148 """
143 return cls(location=profile_dir, config=config)
149 return cls(location=profile_dir, config=config)
144
150
145 @classmethod
151 @classmethod
146 def create_profile_dir_by_name(cls, path, name=u'default', config=None):
152 def create_profile_dir_by_name(cls, path, name=u'default', config=None):
147 """Create a profile dir by profile name and path.
153 """Create a profile dir by profile name and path.
148
154
149 Parameters
155 Parameters
150 ----------
156 ----------
151 path : unicode
157 path : unicode
152 The path (directory) to put the profile directory in.
158 The path (directory) to put the profile directory in.
153 name : unicode
159 name : unicode
154 The name of the profile. The name of the profile directory will
160 The name of the profile. The name of the profile directory will
155 be "profile_<profile>".
161 be "profile_<profile>".
156 """
162 """
157 if not os.path.isdir(path):
163 if not os.path.isdir(path):
158 raise ProfileDirError('Directory not found: %s' % path)
164 raise ProfileDirError('Directory not found: %s' % path)
159 profile_dir = os.path.join(path, u'profile_' + name)
165 profile_dir = os.path.join(path, u'profile_' + name)
160 return cls(location=profile_dir, config=config)
166 return cls(location=profile_dir, config=config)
161
167
162 @classmethod
168 @classmethod
163 def find_profile_dir_by_name(cls, ipython_dir, name=u'default', config=None):
169 def find_profile_dir_by_name(cls, ipython_dir, name=u'default', config=None):
164 """Find an existing profile dir by profile name, return its ProfileDir.
170 """Find an existing profile dir by profile name, return its ProfileDir.
165
171
166 This searches through a sequence of paths for a profile dir. If it
172 This searches through a sequence of paths for a profile dir. If it
167 is not found, a :class:`ProfileDirError` exception will be raised.
173 is not found, a :class:`ProfileDirError` exception will be raised.
168
174
169 The search path algorithm is:
175 The search path algorithm is:
170 1. ``os.getcwdu()``
176 1. ``os.getcwdu()``
171 2. ``ipython_dir``
177 2. ``ipython_dir``
172
178
173 Parameters
179 Parameters
174 ----------
180 ----------
175 ipython_dir : unicode or str
181 ipython_dir : unicode or str
176 The IPython directory to use.
182 The IPython directory to use.
177 name : unicode or str
183 name : unicode or str
178 The name of the profile. The name of the profile directory
184 The name of the profile. The name of the profile directory
179 will be "profile_<profile>".
185 will be "profile_<profile>".
180 """
186 """
181 dirname = u'profile_' + name
187 dirname = u'profile_' + name
182 paths = [os.getcwdu(), ipython_dir]
188 paths = [os.getcwdu(), ipython_dir]
183 for p in paths:
189 for p in paths:
184 profile_dir = os.path.join(p, dirname)
190 profile_dir = os.path.join(p, dirname)
185 if os.path.isdir(profile_dir):
191 if os.path.isdir(profile_dir):
186 return cls(location=profile_dir, config=config)
192 return cls(location=profile_dir, config=config)
187 else:
193 else:
188 raise ProfileDirError('Profile directory not found in paths: %s' % dirname)
194 raise ProfileDirError('Profile directory not found in paths: %s' % dirname)
189
195
190 @classmethod
196 @classmethod
191 def find_profile_dir(cls, profile_dir, config=None):
197 def find_profile_dir(cls, profile_dir, config=None):
192 """Find/create a profile dir and return its ProfileDir.
198 """Find/create a profile dir and return its ProfileDir.
193
199
194 This will create the profile directory if it doesn't exist.
200 This will create the profile directory if it doesn't exist.
195
201
196 Parameters
202 Parameters
197 ----------
203 ----------
198 profile_dir : unicode or str
204 profile_dir : unicode or str
199 The path of the profile directory. This is expanded using
205 The path of the profile directory. This is expanded using
200 :func:`IPython.utils.genutils.expand_path`.
206 :func:`IPython.utils.genutils.expand_path`.
201 """
207 """
202 profile_dir = expand_path(profile_dir)
208 profile_dir = expand_path(profile_dir)
203 if not os.path.isdir(profile_dir):
209 if not os.path.isdir(profile_dir):
204 raise ProfileDirError('Profile directory not found: %s' % profile_dir)
210 raise ProfileDirError('Profile directory not found: %s' % profile_dir)
205 return cls(location=profile_dir, config=config)
211 return cls(location=profile_dir, config=config)
206
212
207
213
General Comments 0
You need to be logged in to leave comments. Login now