1 | Thu Jul 22 00:15:07 GMT Daylight Time 2010 david-sarah@jacaranda.org |
---|
2 | * util.fileutil, test.test_util: add abspath_expanduser_unicode function, to work around <http://bugs.python.org/issue3426>. util.encodingutil: add a convenience function argv_to_abspath. |
---|
3 | |
---|
4 | Thu Jul 22 01:14:18 GMT Daylight Time 2010 david-sarah@jacaranda.org |
---|
5 | * Replace uses of os.path.abspath with abspath_expanduser_unicode where necessary. This makes basedir paths consistently represented as Unicode. |
---|
6 | |
---|
7 | New patches: |
---|
8 | |
---|
9 | [util.fileutil, test.test_util: add abspath_expanduser_unicode function, to work around <http://bugs.python.org/issue3426>. util.encodingutil: add a convenience function argv_to_abspath. |
---|
10 | david-sarah@jacaranda.org**20100721231507 |
---|
11 | Ignore-this: eee6904d1f65a733ff35190879844d08 |
---|
12 | ] { |
---|
13 | hunk ./src/allmydata/test/test_util.py 4 |
---|
14 | |
---|
15 | def foo(): pass # keep the line number constant |
---|
16 | |
---|
17 | -import os, time |
---|
18 | +import os, time, sys |
---|
19 | from StringIO import StringIO |
---|
20 | from twisted.trial import unittest |
---|
21 | from twisted.internet import defer, reactor |
---|
22 | hunk ./src/allmydata/test/test_util.py 473 |
---|
23 | used = fileutil.du(basedir) |
---|
24 | self.failUnlessEqual(10+11+12+13, used) |
---|
25 | |
---|
26 | + def test_abspath_expanduser_unicode(self): |
---|
27 | + self.failUnlessRaises(AssertionError, fileutil.abspath_expanduser_unicode, "bytestring") |
---|
28 | + |
---|
29 | + saved_cwd = os.path.normpath(os.getcwdu()) |
---|
30 | + abspath_cwd = fileutil.abspath_expanduser_unicode(u".") |
---|
31 | + self.failUnless(isinstance(saved_cwd, unicode), saved_cwd) |
---|
32 | + self.failUnless(isinstance(abspath_cwd, unicode), abspath_cwd) |
---|
33 | + self.failUnlessEqual(abspath_cwd, saved_cwd) |
---|
34 | + |
---|
35 | + # adapted from <http://svn.python.org/view/python/branches/release26-maint/Lib/test/test_posixpath.py?view=markup&pathrev=78279#test_abspath> |
---|
36 | + |
---|
37 | + self.failUnlessIn(u"foo", fileutil.abspath_expanduser_unicode(u"foo")) |
---|
38 | + self.failIfIn(u"~", fileutil.abspath_expanduser_unicode(u"~")) |
---|
39 | + |
---|
40 | + cwds = ['cwd'] |
---|
41 | + try: |
---|
42 | + cwds.append(u'\xe7w\xf0'.encode(sys.getfilesystemencoding() |
---|
43 | + or 'ascii')) |
---|
44 | + except UnicodeEncodeError: |
---|
45 | + pass # the cwd can't be encoded -- test with ascii cwd only |
---|
46 | + |
---|
47 | + for cwd in cwds: |
---|
48 | + try: |
---|
49 | + os.mkdir(cwd) |
---|
50 | + os.chdir(cwd) |
---|
51 | + for upath in (u'', u'fuu', u'f\xf9\xf9', u'/fuu', u'U:\\', u'~'): |
---|
52 | + uabspath = fileutil.abspath_expanduser_unicode(upath) |
---|
53 | + self.failUnless(isinstance(uabspath, unicode), uabspath) |
---|
54 | + finally: |
---|
55 | + os.chdir(saved_cwd) |
---|
56 | + |
---|
57 | class PollMixinTests(unittest.TestCase): |
---|
58 | def setUp(self): |
---|
59 | self.pm = pollmixin.PollMixin() |
---|
60 | hunk ./src/allmydata/util/encodingutil.py 13 |
---|
61 | from twisted.python import usage |
---|
62 | import locale |
---|
63 | from allmydata.util import log |
---|
64 | +from allmydata.util.fileutil import abspath_expanduser_unicode |
---|
65 | |
---|
66 | |
---|
67 | def _canonical_encoding(encoding): |
---|
68 | hunk ./src/allmydata/util/encodingutil.py 95 |
---|
69 | raise usage.UsageError("Argument %s cannot be decoded as %s." % |
---|
70 | (quote_output(s), argv_encoding)) |
---|
71 | |
---|
72 | +def argv_to_abspath(s): |
---|
73 | + """ |
---|
74 | + Convenience function to decode an argv element to an absolute path, with ~ expanded. |
---|
75 | + If this fails, raise a UsageError. |
---|
76 | + """ |
---|
77 | + return abspath_expanduser_unicode(argv_to_unicode(s)) |
---|
78 | + |
---|
79 | def unicode_to_url(s): |
---|
80 | """ |
---|
81 | Encode an unicode object used in an URL. |
---|
82 | hunk ./src/allmydata/util/fileutil.py 276 |
---|
83 | finally: |
---|
84 | outf.close() |
---|
85 | |
---|
86 | + |
---|
87 | +# Work around <http://bugs.python.org/issue3426>. This code is adapted from |
---|
88 | +# <http://svn.python.org/view/python/trunk/Lib/ntpath.py?revision=78247&view=markup> |
---|
89 | +# with some simplifications. |
---|
90 | + |
---|
91 | +_getfullpathname = None |
---|
92 | +try: |
---|
93 | + from nt import _getfullpathname |
---|
94 | +except ImportError: |
---|
95 | + pass |
---|
96 | + |
---|
97 | +def abspath_expanduser_unicode(path): |
---|
98 | + """Return the absolute version of a path.""" |
---|
99 | + assert isinstance(path, unicode), path |
---|
100 | + |
---|
101 | + path = os.path.expanduser(path) |
---|
102 | + |
---|
103 | + if _getfullpathname: |
---|
104 | + # On Windows, os.path.isabs will return True for paths without a drive letter, |
---|
105 | + # e.g. "\\". See <http://bugs.python.org/issue1669539>. |
---|
106 | + try: |
---|
107 | + path = _getfullpathname(path or u".") |
---|
108 | + except WindowsError: |
---|
109 | + pass |
---|
110 | + |
---|
111 | + if not os.path.isabs(path): |
---|
112 | + path = os.path.join(os.getcwdu(), path) |
---|
113 | + |
---|
114 | + # We won't hit <http://bugs.python.org/issue5827> because |
---|
115 | + # there is always at least one Unicode path component. |
---|
116 | + return os.path.normpath(path) |
---|
117 | + |
---|
118 | } |
---|
119 | [Replace uses of os.path.abspath with abspath_expanduser_unicode where necessary. This makes basedir paths consistently represented as Unicode. |
---|
120 | david-sarah@jacaranda.org**20100722001418 |
---|
121 | Ignore-this: 9f8cb706540e695550e0dbe303c01f52 |
---|
122 | ] { |
---|
123 | hunk ./src/allmydata/node.py 14 |
---|
124 | from allmydata.util import log |
---|
125 | from allmydata.util import fileutil, iputil, observer |
---|
126 | from allmydata.util.assertutil import precondition, _assert |
---|
127 | +from allmydata.util.fileutil import abspath_expanduser_unicode |
---|
128 | +from allmydata.util.encodingutil import get_filesystem_encoding |
---|
129 | |
---|
130 | # Add our application versions to the data that Foolscap's LogPublisher |
---|
131 | # reports. |
---|
132 | hunk ./src/allmydata/node.py 54 |
---|
133 | PORTNUMFILE = None |
---|
134 | CERTFILE = "node.pem" |
---|
135 | |
---|
136 | - def __init__(self, basedir="."): |
---|
137 | + def __init__(self, basedir=u"."): |
---|
138 | service.MultiService.__init__(self) |
---|
139 | hunk ./src/allmydata/node.py 56 |
---|
140 | - self.basedir = os.path.abspath(basedir) |
---|
141 | + self.basedir = abspath_expanduser_unicode(unicode(basedir)) |
---|
142 | self._portnumfile = os.path.join(self.basedir, self.PORTNUMFILE) |
---|
143 | self._tub_ready_observerlist = observer.OneShotObserverList() |
---|
144 | fileutil.make_dirs(os.path.join(self.basedir, "private"), 0700) |
---|
145 | hunk ./src/allmydata/node.py 79 |
---|
146 | iputil.increase_rlimits() |
---|
147 | |
---|
148 | def init_tempdir(self): |
---|
149 | - local_tempdir = "tmp" # default is NODEDIR/tmp/ |
---|
150 | - tempdir = self.get_config("node", "tempdir", local_tempdir) |
---|
151 | + local_tempdir_utf8 = "tmp" # default is NODEDIR/tmp/ |
---|
152 | + tempdir = self.get_config("node", "tempdir", local_tempdir_utf8).decode('utf-8') |
---|
153 | tempdir = os.path.join(self.basedir, tempdir) |
---|
154 | if not os.path.exists(tempdir): |
---|
155 | fileutil.make_dirs(tempdir) |
---|
156 | hunk ./src/allmydata/node.py 84 |
---|
157 | - tempfile.tempdir = os.path.abspath(tempdir) |
---|
158 | + tempfile.tempdir = abspath_expanduser_unicode(tempdir) |
---|
159 | # this should cause twisted.web.http (which uses |
---|
160 | # tempfile.TemporaryFile) to put large request bodies in the given |
---|
161 | # directory. Without this, the default temp dir is usually /tmp/, |
---|
162 | hunk ./src/allmydata/node.py 172 |
---|
163 | def setup_ssh(self): |
---|
164 | ssh_port = self.get_config("node", "ssh.port", "") |
---|
165 | if ssh_port: |
---|
166 | - ssh_keyfile = self.get_config("node", "ssh.authorized_keys_file") |
---|
167 | + ssh_keyfile = self.get_config("node", "ssh.authorized_keys_file").decode('utf-8') |
---|
168 | from allmydata import manhole |
---|
169 | hunk ./src/allmydata/node.py 174 |
---|
170 | - m = manhole.AuthorizedKeysManhole(ssh_port, ssh_keyfile) |
---|
171 | + m = manhole.AuthorizedKeysManhole(ssh_port, ssh_keyfile.encode(get_filesystem_encoding())) |
---|
172 | m.setServiceParent(self) |
---|
173 | self.log("AuthorizedKeysManhole listening on %s" % ssh_port) |
---|
174 | |
---|
175 | hunk ./src/allmydata/scripts/backupdb.py 12 |
---|
176 | from allmydata.util.netstring import netstring |
---|
177 | from allmydata.util.hashutil import backupdb_dirhash |
---|
178 | from allmydata.util import base32 |
---|
179 | +from allmydata.util.fileutil import abspath_expanduser_unicode |
---|
180 | +from allmydata.util.encodingutil import to_str |
---|
181 | |
---|
182 | DAY = 24*60*60 |
---|
183 | MONTH = 30*DAY |
---|
184 | hunk ./src/allmydata/scripts/backupdb.py 208 |
---|
185 | current working directory. The database stores absolute pathnames. |
---|
186 | """ |
---|
187 | |
---|
188 | - path = os.path.abspath(path) |
---|
189 | + path = abspath_expanduser_unicode(path) |
---|
190 | s = os.stat(path) |
---|
191 | size = s[stat.ST_SIZE] |
---|
192 | ctime = s[stat.ST_CTIME] |
---|
193 | hunk ./src/allmydata/scripts/backupdb.py 251 |
---|
194 | probability = min(max(probability, 0.0), 1.0) |
---|
195 | should_check = bool(random.random() < probability) |
---|
196 | |
---|
197 | - return FileResult(self, str(filecap), should_check, |
---|
198 | + return FileResult(self, to_str(filecap), should_check, |
---|
199 | path, mtime, ctime, size) |
---|
200 | |
---|
201 | def get_or_allocate_fileid_for_cap(self, filecap): |
---|
202 | hunk ./src/allmydata/scripts/backupdb.py 354 |
---|
203 | probability = min(max(probability, 0.0), 1.0) |
---|
204 | should_check = bool(random.random() < probability) |
---|
205 | |
---|
206 | - return DirectoryResult(self, dirhash_s, str(dircap), should_check) |
---|
207 | + return DirectoryResult(self, dirhash_s, to_str(dircap), should_check) |
---|
208 | |
---|
209 | def did_create_directory(self, dircap, dirhash): |
---|
210 | now = time.time() |
---|
211 | hunk ./src/allmydata/scripts/create_node.py 87 |
---|
212 | |
---|
213 | |
---|
214 | def create_node(basedir, config, out=sys.stdout, err=sys.stderr): |
---|
215 | + # This should always be called with an absolute Unicode basedir. |
---|
216 | + precondition(isinstance(basedir, unicode), basedir) |
---|
217 | + |
---|
218 | if os.path.exists(basedir): |
---|
219 | hunk ./src/allmydata/scripts/create_node.py 91 |
---|
220 | - if os.listdir(basedir): |
---|
221 | - print >>err, "The base directory \"%s\", which is \"%s\" is not empty." % (basedir, os.path.abspath(basedir)) |
---|
222 | + if listdir_unicode(basedir): |
---|
223 | + print >>err, "The base directory %s is not empty." % quote_output(basedir) |
---|
224 | print >>err, "To avoid clobbering anything, I am going to quit now." |
---|
225 | print >>err, "Please use a different directory, or empty this one." |
---|
226 | return -1 |
---|
227 | hunk ./src/allmydata/scripts/create_node.py 135 |
---|
228 | |
---|
229 | from allmydata.util import fileutil |
---|
230 | fileutil.make_dirs(os.path.join(basedir, "private"), 0700) |
---|
231 | - print >>out, "Node created in %s" % basedir |
---|
232 | + print >>out, "Node created in %s" % quote_output(basedir) |
---|
233 | if not config.get("introducer", ""): |
---|
234 | print >>out, " Please set [client]introducer.furl= in tahoe.cfg!" |
---|
235 | print >>out, " The node cannot connect to a grid without it." |
---|
236 | hunk ./src/allmydata/scripts/create_node.py 149 |
---|
237 | |
---|
238 | |
---|
239 | def create_introducer(basedir, config, out=sys.stdout, err=sys.stderr): |
---|
240 | + # This should always be called with an absolute Unicode basedir. |
---|
241 | + precondition(isinstance(basedir, unicode), basedir) |
---|
242 | + |
---|
243 | if os.path.exists(basedir): |
---|
244 | hunk ./src/allmydata/scripts/create_node.py 153 |
---|
245 | - if os.listdir(basedir): |
---|
246 | - print >>err, "The base directory \"%s\", which is \"%s\" is not empty." % (basedir, os.path.abspath(basedir)) |
---|
247 | + if listdir_unicode(basedir): |
---|
248 | + print >>err, "The base directory %s is not empty." % quote_output(basedir) |
---|
249 | print >>err, "To avoid clobbering anything, I am going to quit now." |
---|
250 | print >>err, "Please use a different directory, or empty this one." |
---|
251 | return -1 |
---|
252 | hunk ./src/allmydata/scripts/create_node.py 169 |
---|
253 | write_node_config(c, config) |
---|
254 | c.close() |
---|
255 | |
---|
256 | - print >>out, "Introducer created in %s" % basedir |
---|
257 | + print >>out, "Introducer created in %s" % quote_output(basedir) |
---|
258 | |
---|
259 | |
---|
260 | subCommands = [ |
---|
261 | hunk ./src/allmydata/scripts/debug.py 8 |
---|
262 | from twisted.python import usage, failure |
---|
263 | from twisted.internet import defer |
---|
264 | |
---|
265 | + |
---|
266 | class DumpOptions(usage.Options): |
---|
267 | def getSynopsis(self): |
---|
268 | return "Usage: tahoe debug dump-share SHARE_FILENAME" |
---|
269 | hunk ./src/allmydata/scripts/debug.py 32 |
---|
270 | return t |
---|
271 | |
---|
272 | def parseArgs(self, filename): |
---|
273 | - self['filename'] = filename |
---|
274 | + from allmydata.util.encodingutil import argv_to_abspath |
---|
275 | + self['filename'] = argv_to_abspath(filename) |
---|
276 | |
---|
277 | def dump_share(options): |
---|
278 | from allmydata.storage.mutable import MutableShareFile |
---|
279 | hunk ./src/allmydata/scripts/debug.py 37 |
---|
280 | + from allmydata.util.encodingutil import quote_output |
---|
281 | |
---|
282 | out = options.stdout |
---|
283 | |
---|
284 | hunk ./src/allmydata/scripts/debug.py 42 |
---|
285 | # check the version, to see if we have a mutable or immutable share |
---|
286 | - print >>out, "share filename: %s" % options['filename'] |
---|
287 | + print >>out, "share filename: %s" % quote_output(options['filename']) |
---|
288 | |
---|
289 | f = open(options['filename'], "rb") |
---|
290 | prefix = f.read(32) |
---|
291 | hunk ./src/allmydata/scripts/debug.py 67 |
---|
292 | from allmydata import uri |
---|
293 | from allmydata.util import base32 |
---|
294 | from allmydata.immutable.layout import ReadBucketProxy |
---|
295 | + from allmydata.util.encodingutil import quote_output, to_str |
---|
296 | + |
---|
297 | # use a ReadBucketProxy to parse the bucket and find the uri extension |
---|
298 | bp = ReadBucketProxy(None, '', '') |
---|
299 | offsets = bp._parse_offsets(f.read_share_data(0, 0x44)) |
---|
300 | hunk ./src/allmydata/scripts/debug.py 112 |
---|
301 | # the storage index isn't stored in the share itself, so we depend upon |
---|
302 | # knowing the parent directory name to get it |
---|
303 | pieces = options['filename'].split(os.sep) |
---|
304 | - if len(pieces) >= 2 and base32.could_be_base32_encoded(pieces[-2]): |
---|
305 | - storage_index = base32.a2b(pieces[-2]) |
---|
306 | - uri_extension_hash = base32.a2b(unpacked["UEB_hash"]) |
---|
307 | - u = uri.CHKFileVerifierURI(storage_index, uri_extension_hash, |
---|
308 | - unpacked["needed_shares"], |
---|
309 | - unpacked["total_shares"], unpacked["size"]) |
---|
310 | - verify_cap = u.to_string() |
---|
311 | - print >>out, "%20s: %s" % ("verify-cap", verify_cap) |
---|
312 | + if len(pieces) >= 2: |
---|
313 | + piece = to_str(pieces[-2]) |
---|
314 | + if base32.could_be_base32_encoded(piece): |
---|
315 | + storage_index = base32.a2b(piece) |
---|
316 | + uri_extension_hash = base32.a2b(unpacked["UEB_hash"]) |
---|
317 | + u = uri.CHKFileVerifierURI(storage_index, uri_extension_hash, |
---|
318 | + unpacked["needed_shares"], |
---|
319 | + unpacked["total_shares"], unpacked["size"]) |
---|
320 | + verify_cap = u.to_string() |
---|
321 | + print >>out, "%20s: %s" % ("verify-cap", quote_output(verify_cap, quotemarks=False)) |
---|
322 | |
---|
323 | sizes = {} |
---|
324 | sizes['data'] = (offsets['plaintext_hash_tree'] - |
---|
325 | hunk ./src/allmydata/scripts/debug.py 220 |
---|
326 | from allmydata.mutable.common import NeedMoreDataError |
---|
327 | from allmydata.util import base32, hashutil |
---|
328 | from allmydata.uri import SSKVerifierURI |
---|
329 | + from allmydata.util.encodingutil import quote_output, to_str |
---|
330 | |
---|
331 | offset = m.DATA_OFFSET |
---|
332 | |
---|
333 | hunk ./src/allmydata/scripts/debug.py 267 |
---|
334 | # the storage index isn't stored in the share itself, so we depend upon |
---|
335 | # knowing the parent directory name to get it |
---|
336 | pieces = options['filename'].split(os.sep) |
---|
337 | - if len(pieces) >= 2 and base32.could_be_base32_encoded(pieces[-2]): |
---|
338 | - storage_index = base32.a2b(pieces[-2]) |
---|
339 | - fingerprint = hashutil.ssk_pubkey_fingerprint_hash(pubkey) |
---|
340 | - u = SSKVerifierURI(storage_index, fingerprint) |
---|
341 | - verify_cap = u.to_string() |
---|
342 | - print >>out, " verify-cap:", verify_cap |
---|
343 | + if len(pieces) >= 2: |
---|
344 | + piece = to_str(pieces[-2]) |
---|
345 | + if base32.could_be_base32_encoded(piece): |
---|
346 | + storage_index = base32.a2b(piece) |
---|
347 | + fingerprint = hashutil.ssk_pubkey_fingerprint_hash(pubkey) |
---|
348 | + u = SSKVerifierURI(storage_index, fingerprint) |
---|
349 | + verify_cap = u.to_string() |
---|
350 | + print >>out, " verify-cap:", quote_output(verify_cap, quotemarks=False) |
---|
351 | |
---|
352 | if options['offsets']: |
---|
353 | # NOTE: this offset-calculation code is fragile, and needs to be |
---|
354 | hunk ./src/allmydata/scripts/debug.py 393 |
---|
355 | from allmydata import uri |
---|
356 | from allmydata.storage.server import si_b2a |
---|
357 | from allmydata.util import base32, hashutil |
---|
358 | + from allmydata.util.encodingutil import quote_output |
---|
359 | |
---|
360 | if isinstance(u, uri.CHKFileURI): |
---|
361 | if show_header: |
---|
362 | hunk ./src/allmydata/scripts/debug.py 415 |
---|
363 | elif isinstance(u, uri.LiteralFileURI): |
---|
364 | if show_header: |
---|
365 | print >>out, "Literal File URI:" |
---|
366 | - print >>out, " data:", u.data |
---|
367 | + print >>out, " data:", quote_output(u.data) |
---|
368 | |
---|
369 | elif isinstance(u, uri.WriteableSSKFileURI): |
---|
370 | if show_header: |
---|
371 | hunk ./src/allmydata/scripts/debug.py 461 |
---|
372 | class FindSharesOptions(usage.Options): |
---|
373 | def getSynopsis(self): |
---|
374 | return "Usage: tahoe debug find-shares STORAGE_INDEX NODEDIRS.." |
---|
375 | + |
---|
376 | def parseArgs(self, storage_index_s, *nodedirs): |
---|
377 | hunk ./src/allmydata/scripts/debug.py 463 |
---|
378 | + from allmydata.util.encodingutil import argv_to_abspath |
---|
379 | self.si_s = storage_index_s |
---|
380 | hunk ./src/allmydata/scripts/debug.py 465 |
---|
381 | - self.nodedirs = nodedirs |
---|
382 | + self.nodedirs = map(argv_to_abspath, nodedirs) |
---|
383 | + |
---|
384 | def getUsage(self, width=None): |
---|
385 | t = usage.Options.getUsage(self, width) |
---|
386 | t += """ |
---|
387 | hunk ./src/allmydata/scripts/debug.py 495 |
---|
388 | /home/warner/testnet/node-2/storage/shares/44k/44kai1tui348689nrw8fjegc8c/2 |
---|
389 | """ |
---|
390 | from allmydata.storage.server import si_a2b, storage_index_to_dir |
---|
391 | + from allmydata.util.encodingutil import listdir_unicode |
---|
392 | |
---|
393 | out = options.stdout |
---|
394 | sharedir = storage_index_to_dir(si_a2b(options.si_s)) |
---|
395 | hunk ./src/allmydata/scripts/debug.py 500 |
---|
396 | for d in options.nodedirs: |
---|
397 | - d = os.path.join(os.path.expanduser(d), "storage/shares", sharedir) |
---|
398 | + d = os.path.join(d, "storage/shares", sharedir) |
---|
399 | if os.path.exists(d): |
---|
400 | hunk ./src/allmydata/scripts/debug.py 502 |
---|
401 | - for shnum in os.listdir(d): |
---|
402 | + for shnum in listdir_unicode(d): |
---|
403 | print >>out, os.path.join(d, shnum) |
---|
404 | |
---|
405 | return 0 |
---|
406 | hunk ./src/allmydata/scripts/debug.py 513 |
---|
407 | |
---|
408 | """ |
---|
409 | def parseArgs(self, *nodedirs): |
---|
410 | - self.nodedirs = nodedirs |
---|
411 | + from allmydata.util.encodingutil import argv_to_abspath |
---|
412 | + self.nodedirs = map(argv_to_abspath, nodedirs) |
---|
413 | if not nodedirs: |
---|
414 | raise usage.UsageError("must specify at least one node directory") |
---|
415 | |
---|
416 | hunk ./src/allmydata/scripts/debug.py 562 |
---|
417 | from allmydata.mutable.common import NeedMoreDataError |
---|
418 | from allmydata.immutable.layout import ReadBucketProxy |
---|
419 | from allmydata.util import base32 |
---|
420 | + from allmydata.util.encodingutil import quote_output |
---|
421 | import struct |
---|
422 | |
---|
423 | f = open(abs_sharefile, "rb") |
---|
424 | hunk ./src/allmydata/scripts/debug.py 602 |
---|
425 | print >>out, "SDMF %s %d/%d %d #%d:%s %d %s" % \ |
---|
426 | (si_s, k, N, datalen, |
---|
427 | seqnum, base32.b2a(root_hash), |
---|
428 | - expiration, abs_sharefile) |
---|
429 | + expiration, quote_output(abs_sharefile)) |
---|
430 | else: |
---|
431 | hunk ./src/allmydata/scripts/debug.py 604 |
---|
432 | - print >>out, "UNKNOWN mutable %s" % (abs_sharefile,) |
---|
433 | + print >>out, "UNKNOWN mutable %s" % quote_output(abs_sharefile) |
---|
434 | |
---|
435 | elif struct.unpack(">L", prefix[:4]) == (1,): |
---|
436 | # immutable |
---|
437 | hunk ./src/allmydata/scripts/debug.py 636 |
---|
438 | |
---|
439 | print >>out, "CHK %s %d/%d %d %s %d %s" % (si_s, k, N, filesize, |
---|
440 | ueb_hash, expiration, |
---|
441 | - abs_sharefile) |
---|
442 | + quote_output(abs_sharefile)) |
---|
443 | |
---|
444 | else: |
---|
445 | hunk ./src/allmydata/scripts/debug.py 639 |
---|
446 | - print >>out, "UNKNOWN really-unknown %s" % (abs_sharefile,) |
---|
447 | + print >>out, "UNKNOWN really-unknown %s" % quote_output(abs_sharefile) |
---|
448 | |
---|
449 | f.close() |
---|
450 | |
---|
451 | hunk ./src/allmydata/scripts/debug.py 644 |
---|
452 | def catalog_shares(options): |
---|
453 | + from allmydata.util.encodingutil import listdir_unicode, quote_output |
---|
454 | + |
---|
455 | out = options.stdout |
---|
456 | err = options.stderr |
---|
457 | now = time.time() |
---|
458 | hunk ./src/allmydata/scripts/debug.py 650 |
---|
459 | for d in options.nodedirs: |
---|
460 | - d = os.path.join(os.path.expanduser(d), "storage/shares") |
---|
461 | + d = os.path.join(d, "storage/shares") |
---|
462 | try: |
---|
463 | hunk ./src/allmydata/scripts/debug.py 652 |
---|
464 | - abbrevs = os.listdir(d) |
---|
465 | + abbrevs = listdir_unicode(d) |
---|
466 | except EnvironmentError: |
---|
467 | # ignore nodes that have storage turned off altogether |
---|
468 | pass |
---|
469 | hunk ./src/allmydata/scripts/debug.py 662 |
---|
470 | continue |
---|
471 | abbrevdir = os.path.join(d, abbrevdir) |
---|
472 | # this tool may get run against bad disks, so we can't assume |
---|
473 | - # that os.listdir will always succeed. Try to catalog as much |
---|
474 | + # that listdir_unicode will always succeed. Try to catalog as much |
---|
475 | # as possible. |
---|
476 | try: |
---|
477 | hunk ./src/allmydata/scripts/debug.py 665 |
---|
478 | - sharedirs = os.listdir(abbrevdir) |
---|
479 | + sharedirs = listdir_unicode(abbrevdir) |
---|
480 | for si_s in sharedirs: |
---|
481 | si_dir = os.path.join(abbrevdir, si_s) |
---|
482 | catalog_shares_one_abbrevdir(si_s, si_dir, now, out,err) |
---|
483 | hunk ./src/allmydata/scripts/debug.py 670 |
---|
484 | except: |
---|
485 | - print >>err, "Error processing %s" % abbrevdir |
---|
486 | + print >>err, "Error processing %s" % quote_output(abbrevdir) |
---|
487 | failure.Failure().printTraceback(err) |
---|
488 | |
---|
489 | return 0 |
---|
490 | hunk ./src/allmydata/scripts/debug.py 676 |
---|
491 | |
---|
492 | def catalog_shares_one_abbrevdir(si_s, si_dir, now, out, err): |
---|
493 | + from allmydata.util.encodingutil import listdir_unicode, quote_output |
---|
494 | + |
---|
495 | try: |
---|
496 | hunk ./src/allmydata/scripts/debug.py 679 |
---|
497 | - for shnum_s in os.listdir(si_dir): |
---|
498 | + for shnum_s in listdir_unicode(si_dir): |
---|
499 | abs_sharefile = os.path.join(si_dir, shnum_s) |
---|
500 | hunk ./src/allmydata/scripts/debug.py 681 |
---|
501 | - abs_sharefile = os.path.abspath(abs_sharefile) |
---|
502 | assert os.path.isfile(abs_sharefile) |
---|
503 | try: |
---|
504 | describe_share(abs_sharefile, si_s, shnum_s, now, |
---|
505 | hunk ./src/allmydata/scripts/debug.py 686 |
---|
506 | out) |
---|
507 | except: |
---|
508 | - print >>err, "Error processing %s" % abs_sharefile |
---|
509 | + print >>err, "Error processing %s" % quote_output(abs_sharefile) |
---|
510 | failure.Failure().printTraceback(err) |
---|
511 | except: |
---|
512 | hunk ./src/allmydata/scripts/debug.py 689 |
---|
513 | - print >>err, "Error processing %s" % si_dir |
---|
514 | + print >>err, "Error processing %s" % quote_output(si_dir) |
---|
515 | failure.Failure().printTraceback(err) |
---|
516 | |
---|
517 | class CorruptShareOptions(usage.Options): |
---|
518 | hunk ./src/allmydata/scripts/keygen.py 32 |
---|
519 | print >>err, "a basedir was not provided, please use --basedir or -C" |
---|
520 | return -1 |
---|
521 | if os.path.exists(basedir): |
---|
522 | - if os.listdir(basedir): |
---|
523 | - print >>err, "The base directory \"%s\", which is \"%s\" is not empty." % (basedir, os.path.abspath(basedir)) |
---|
524 | + if listdir_unicode(basedir): |
---|
525 | + print >>err, "The base directory %s is not empty." % quote_output(basedir) |
---|
526 | print >>err, "To avoid clobbering anything, I am going to quit now." |
---|
527 | print >>err, "Please use a different directory, or empty this one." |
---|
528 | return -1 |
---|
529 | hunk ./src/allmydata/scripts/tahoe_backup.py 14 |
---|
530 | from allmydata.scripts import backupdb |
---|
531 | from allmydata.util.encodingutil import listdir_unicode, quote_output, to_str, FilenameEncodingError |
---|
532 | from allmydata.util.assertutil import precondition |
---|
533 | +from allmydata.util.fileutil import abspath_expanduser_unicode |
---|
534 | |
---|
535 | |
---|
536 | def get_local_metadata(path): |
---|
537 | hunk ./src/allmydata/scripts/tahoe_backup.py 88 |
---|
538 | self.backupdb = None |
---|
539 | bdbfile = os.path.join(options["node-directory"], |
---|
540 | "private", "backupdb.sqlite") |
---|
541 | - bdbfile = os.path.abspath(bdbfile) |
---|
542 | + bdbfile = abspath_expanduser_unicode(bdbfile) |
---|
543 | self.backupdb = backupdb.get_backupdb(bdbfile, stderr) |
---|
544 | if not self.backupdb: |
---|
545 | print >>stderr, "ERROR: Unable to load backup db." |
---|
546 | hunk ./src/allmydata/scripts/tahoe_cp.py 12 |
---|
547 | from allmydata.scripts.common_http import do_http, HTTPError |
---|
548 | from allmydata import uri |
---|
549 | from allmydata.util import fileutil |
---|
550 | +from allmydata.util.fileutil import abspath_expanduser_unicode |
---|
551 | from allmydata.util.encodingutil import unicode_to_url, listdir_unicode, quote_output, to_str |
---|
552 | from allmydata.util.assertutil import precondition |
---|
553 | |
---|
554 | hunk ./src/allmydata/scripts/tahoe_cp.py 515 |
---|
555 | rootcap, path = get_alias(self.aliases, destination_spec, None) |
---|
556 | if rootcap == DefaultAliasMarker: |
---|
557 | # no alias, so this is a local file |
---|
558 | - pathname = os.path.abspath(os.path.expanduser(path.decode('utf-8'))) |
---|
559 | + pathname = abspath_expanduser_unicode(path.decode('utf-8')) |
---|
560 | if not os.path.exists(pathname): |
---|
561 | t = LocalMissingTarget(pathname) |
---|
562 | elif os.path.isdir(pathname): |
---|
563 | hunk ./src/allmydata/scripts/tahoe_cp.py 555 |
---|
564 | rootcap, path = get_alias(self.aliases, source_spec, None) |
---|
565 | if rootcap == DefaultAliasMarker: |
---|
566 | # no alias, so this is a local file |
---|
567 | - pathname = os.path.abspath(os.path.expanduser(path.decode('utf-8'))) |
---|
568 | + pathname = abspath_expanduser_unicode(path.decode('utf-8')) |
---|
569 | name = os.path.basename(pathname) |
---|
570 | if not os.path.exists(pathname): |
---|
571 | raise MissingSourceError(source_spec) |
---|
572 | hunk ./src/allmydata/test/check_grid.py 68 |
---|
573 | ] |
---|
574 | |
---|
575 | def parseArgs(self, nodedir, tahoe): |
---|
576 | - self.nodedir = nodedir |
---|
577 | - self.tahoe = os.path.abspath(tahoe) |
---|
578 | + # Note: does not support Unicode arguments. |
---|
579 | + self.nodedir = os.path.expanduser(nodedir) |
---|
580 | + self.tahoe = os.path.abspath(os.path.expanduser(tahoe)) |
---|
581 | |
---|
582 | class CommandFailed(Exception): |
---|
583 | pass |
---|
584 | hunk ./src/allmydata/test/check_memory.py 12 |
---|
585 | from allmydata.immutable import upload |
---|
586 | from allmydata.scripts import create_node |
---|
587 | from allmydata.util import fileutil, pollmixin |
---|
588 | +from allmydata.util.fileutil import abspath_expanduser_unicode |
---|
589 | +from allmydata.util.encodingutil import get_filesystem_encoding |
---|
590 | from foolscap.api import Tub, fireEventually, flushEventualQueue |
---|
591 | from twisted.python import log |
---|
592 | |
---|
593 | hunk ./src/allmydata/test/check_memory.py 68 |
---|
594 | numnodes = 7 |
---|
595 | |
---|
596 | def __init__(self, basedir, mode): |
---|
597 | - self.basedir = basedir = os.path.abspath(basedir) |
---|
598 | - if not basedir.startswith(os.path.abspath(".")): |
---|
599 | + self.basedir = basedir = abspath_expanduser_unicode(unicode(basedir)) |
---|
600 | + if not (basedir + os.path.sep).startswith(abspath_expanduser_unicode(u".") + os.path.sep): |
---|
601 | raise AssertionError("safety issue: basedir must be a subdir") |
---|
602 | self.testdir = testdir = os.path.join(basedir, "test") |
---|
603 | if os.path.exists(testdir): |
---|
604 | hunk ./src/allmydata/test/check_memory.py 231 |
---|
605 | def start_client(self): |
---|
606 | # this returns a Deferred that fires with the client's control.furl |
---|
607 | log.msg("MAKING CLIENT") |
---|
608 | - clientdir = self.clientdir = os.path.join(self.testdir, "client") |
---|
609 | + # self.testdir is an absolute Unicode path |
---|
610 | + clientdir = self.clientdir = os.path.join(self.testdir, u"client") |
---|
611 | + clientdir_str = clientdir.encode(get_filesystem_encoding()) |
---|
612 | quiet = StringIO() |
---|
613 | create_node.create_node(clientdir, {}, out=quiet) |
---|
614 | log.msg("DONE MAKING CLIENT") |
---|
615 | hunk ./src/allmydata/test/check_memory.py 272 |
---|
616 | logfile = os.path.join(self.basedir, "client.log") |
---|
617 | cmd = ["twistd", "-n", "-y", "tahoe-client.tac", "-l", logfile] |
---|
618 | env = os.environ.copy() |
---|
619 | - self.proc = reactor.spawnProcess(pp, cmd[0], cmd, env, path=clientdir) |
---|
620 | + self.proc = reactor.spawnProcess(pp, cmd[0], cmd, env, path=clientdir_str) |
---|
621 | log.msg("CLIENT STARTED") |
---|
622 | |
---|
623 | # now we wait for the client to get started. we're looking for the |
---|
624 | hunk ./src/allmydata/test/test_cli.py 36 |
---|
625 | from allmydata.util.assertutil import precondition |
---|
626 | from allmydata.util.encodingutil import listdir_unicode, unicode_platform, \ |
---|
627 | quote_output, get_output_encoding, get_argv_encoding, get_filesystem_encoding, \ |
---|
628 | - unicode_to_output, to_str |
---|
629 | + unicode_to_output, to_str, to_argv |
---|
630 | +from allmydata.util.fileutil import abspath_expanduser_unicode |
---|
631 | |
---|
632 | timeout = 480 # deep_check takes 360s on Zandr's linksys box, others take > 240s |
---|
633 | |
---|
634 | hunk ./src/allmydata/test/test_cli.py 185 |
---|
635 | u = uri.LiteralFileURI("this is some data") |
---|
636 | output = self._dump_cap(u.to_string()) |
---|
637 | self.failUnless("Literal File URI:" in output, output) |
---|
638 | - self.failUnless("data: this is some data" in output, output) |
---|
639 | + self.failUnless("data: 'this is some data'" in output, output) |
---|
640 | |
---|
641 | def test_dump_cap_ssk(self): |
---|
642 | writekey = "\x01" * 16 |
---|
643 | hunk ./src/allmydata/test/test_cli.py 778 |
---|
644 | self.set_up_grid() |
---|
645 | |
---|
646 | rel_fn = os.path.join(self.basedir, "DATAFILE") |
---|
647 | - abs_fn = os.path.abspath(rel_fn) |
---|
648 | + abs_fn = to_argv(abspath_expanduser_unicode(unicode(rel_fn))) |
---|
649 | # we make the file small enough to fit in a LIT file, for speed |
---|
650 | fileutil.write(rel_fn, "short file") |
---|
651 | d = self.do_cli("put", rel_fn) |
---|
652 | hunk ./src/allmydata/test/test_encodingutil.py 262 |
---|
653 | raise unittest.SkipTest("%r\nIt is possible that the filesystem on which this test is being run " |
---|
654 | "does not support Unicode, even though the platform does." % (e,)) |
---|
655 | |
---|
656 | - fn = lumiere_nfc + '/' + lumiere_nfc + '.txt' |
---|
657 | + fn = lumiere_nfc + u'/' + lumiere_nfc + u'.txt' |
---|
658 | open(fn, 'wb').close() |
---|
659 | self.failUnless(os.path.exists(fn)) |
---|
660 | hunk ./src/allmydata/test/test_encodingutil.py 265 |
---|
661 | - self.failUnless(os.path.exists(os.path.abspath(fn))) |
---|
662 | + self.failUnless(os.path.exists(os.path.join(os.getcwdu(), fn))) |
---|
663 | filenames = listdir_unicode(lumiere_nfc) |
---|
664 | |
---|
665 | # We only require that the listing includes a filename that is canonically equivalent |
---|
666 | hunk ./src/allmydata/test/test_runner.py 196 |
---|
667 | rc, out, err = self.run_tahoe(argv) |
---|
668 | self.failIfEqual(rc, 0, str((out, err, rc))) |
---|
669 | self.failUnlessEqual(out, "") |
---|
670 | - self.failUnless("is not empty." in err) |
---|
671 | + self.failUnlessIn("is not empty.", err) |
---|
672 | |
---|
673 | # make sure it rejects too many arguments |
---|
674 | argv = ["create-key-generator", "basedir", "extraarg"] |
---|
675 | hunk ./src/allmydata/test/test_system.py 15 |
---|
676 | from allmydata.immutable.filenode import ImmutableFileNode, LiteralFileNode |
---|
677 | from allmydata.util import idlib, mathutil |
---|
678 | from allmydata.util import log, base32 |
---|
679 | +from allmydata.util.encodingutil import quote_output |
---|
680 | +from allmydata.util.fileutil import abspath_expanduser_unicode |
---|
681 | from allmydata.util.consumer import MemoryConsumer, download_to_data |
---|
682 | from allmydata.scripts import runner |
---|
683 | from allmydata.interfaces import IDirectoryNode, IFileNode, \ |
---|
684 | hunk ./src/allmydata/test/test_system.py 1290 |
---|
685 | if magic == '\x00\x00\x00\x01': |
---|
686 | break |
---|
687 | else: |
---|
688 | - self.fail("unable to find any uri_extension files in %s" |
---|
689 | + self.fail("unable to find any uri_extension files in %r" |
---|
690 | % self.basedir) |
---|
691 | hunk ./src/allmydata/test/test_system.py 1292 |
---|
692 | - log.msg("test_system.SystemTest._test_runner using %s" % filename) |
---|
693 | + log.msg("test_system.SystemTest._test_runner using %r" % filename) |
---|
694 | |
---|
695 | out,err = StringIO(), StringIO() |
---|
696 | rc = runner.runner(["debug", "dump-share", "--offsets", |
---|
697 | hunk ./src/allmydata/test/test_system.py 1303 |
---|
698 | |
---|
699 | # we only upload a single file, so we can assert some things about |
---|
700 | # its size and shares. |
---|
701 | - self.failUnless(("share filename: %s" % filename) in output) |
---|
702 | - self.failUnless("size: %d\n" % len(self.data) in output) |
---|
703 | - self.failUnless("num_segments: 1\n" in output) |
---|
704 | + self.failUnlessIn("share filename: %s" % quote_output(abspath_expanduser_unicode(filename)), output) |
---|
705 | + self.failUnlessIn("size: %d\n" % len(self.data), output) |
---|
706 | + self.failUnlessIn("num_segments: 1\n", output) |
---|
707 | # segment_size is always a multiple of needed_shares |
---|
708 | hunk ./src/allmydata/test/test_system.py 1307 |
---|
709 | - self.failUnless("segment_size: %d\n" % mathutil.next_multiple(len(self.data), 3) in output) |
---|
710 | - self.failUnless("total_shares: 10\n" in output) |
---|
711 | + self.failUnlessIn("segment_size: %d\n" % mathutil.next_multiple(len(self.data), 3), output) |
---|
712 | + self.failUnlessIn("total_shares: 10\n", output) |
---|
713 | # keys which are supposed to be present |
---|
714 | for key in ("size", "num_segments", "segment_size", |
---|
715 | "needed_shares", "total_shares", |
---|
716 | hunk ./src/allmydata/test/test_system.py 1316 |
---|
717 | #"plaintext_hash", "plaintext_root_hash", |
---|
718 | "crypttext_hash", "crypttext_root_hash", |
---|
719 | "share_root_hash", "UEB_hash"): |
---|
720 | - self.failUnless("%s: " % key in output, key) |
---|
721 | - self.failUnless(" verify-cap: URI:CHK-Verifier:" in output) |
---|
722 | + self.failUnlessIn("%s: " % key, output) |
---|
723 | + self.failUnlessIn(" verify-cap: URI:CHK-Verifier:", output) |
---|
724 | |
---|
725 | # now use its storage index to find the other shares using the |
---|
726 | # 'find-shares' tool |
---|
727 | } |
---|
728 | |
---|
729 | Context: |
---|
730 | |
---|
731 | [__init__.py: silence DeprecationWarning about BaseException.message globally. fixes #1129 |
---|
732 | david-sarah@jacaranda.org**20100720011939 |
---|
733 | Ignore-this: 38808986ba79cb2786b010504a22f89 |
---|
734 | ] |
---|
735 | [test_runner: test that 'tahoe --version' outputs no noise (e.g. DeprecationWarnings). |
---|
736 | david-sarah@jacaranda.org**20100720011345 |
---|
737 | Ignore-this: dd358b7b2e5d57282cbe133e8069702e |
---|
738 | ] |
---|
739 | [TAG allmydata-tahoe-1.7.1 |
---|
740 | zooko@zooko.com**20100719131352 |
---|
741 | Ignore-this: 6942056548433dc653a746703819ad8c |
---|
742 | ] |
---|
743 | Patch bundle hash: |
---|
744 | 7701b52497cb185827602a19acd985d87395e356 |
---|