#761 closed defect (fixed)
"tahoe cp $DIRCAP/$PATH $LOCAL" raises AttributeError
Reported by: | zooko | Owned by: | warner |
---|---|---|---|
Priority: | major | Milestone: | 1.6.0 |
Component: | code-frontend-cli | Version: | 1.4.1 |
Keywords: | news-done | Cc: | |
Launchpad Bug: |
Description
tahoe cp --help suggests that I try:
You can also use a dircap as either FROM or TO target: tahoe cp URI:DIR2-RO:j74uhg25nwdpjpacl6rkat2yhm:kav7ijeft5h7r7rxdp5bgtlt3viv32yabqajkrdykozia5544jqa/wiki.html ./ # copy Zooko's wiki page to a local file
But when I try it, I get an exception:
$ time ~/playground/allmydata/tahoe/trunk-hashedformat/bin/tahoe cp -r --node-url http://testgrid.allmydata.org:3567 URI:DIR2-RO:j74uhg25nwdpjpacl6rkat2yhm:kav7ijeft5h7r7rxdp5bgtlt3viv32yabqajkrdykozia5544jqa/wiki.html foo Traceback (most recent call last): File "/data2/homezooko/playground/allmydata/tahoe/trunk-hashedformat/support/bin/tahoe", line 8, in <module> load_entry_point('allmydata-tahoe==1.4.1-r3989', 'console_scripts', 'tahoe')() File "/data2/homezooko/playground/allmydata/tahoe/trunk-hashedformat/src/allmydata/scripts/runner.py", line 91, in run rc = runner(sys.argv[1:]) File "/data2/homezooko/playground/allmydata/tahoe/trunk-hashedformat/src/allmydata/scripts/runner.py", line 78, in runner rc = cli.dispatch[command](so) File "/data2/homezooko/playground/allmydata/tahoe/trunk-hashedformat/src/allmydata/scripts/cli.py", line 429, in cp rc = tahoe_cp.copy(options) File "/data2/homezooko/playground/allmydata/tahoe/trunk-hashedformat/src/allmydata/scripts/tahoe_cp.py", line 759, in copy return Copier().do_copy(options) File "/data2/homezooko/playground/allmydata/tahoe/trunk-hashedformat/src/allmydata/scripts/tahoe_cp.py", line 444, in do_copy self.try_copy() File "/data2/homezooko/playground/allmydata/tahoe/trunk-hashedformat/src/allmydata/scripts/tahoe_cp.py", line 501, in try_copy return self.copy_to_directory(sources, target) File "/data2/homezooko/playground/allmydata/tahoe/trunk-hashedformat/src/allmydata/scripts/tahoe_cp.py", line 661, in copy_to_directory self.copy_files_to_target(self.targetmap[target], target) File "/data2/homezooko/playground/allmydata/tahoe/trunk-hashedformat/src/allmydata/scripts/tahoe_cp.py", line 692, in copy_files_to_target self.copy_file_into(source, name, target) File "/data2/homezooko/playground/allmydata/tahoe/trunk-hashedformat/src/allmydata/scripts/tahoe_cp.py", line 737, in copy_file_into target.put_file(name, f) File "/data2/homezooko/playground/allmydata/tahoe/trunk-hashedformat/src/allmydata/scripts/tahoe_cp.py", line 163, in put_file pathname = os.path.join(self.pathname, name) File "/usr/lib/python2.5/posixpath.py", line 60, in join if b.startswith('/'): AttributeError: 'NoneType' object has no attribute 'startswith'
Attachments (2)
Change History (9)
comment:1 Changed at 2009-09-04T23:06:45Z by kevan
Changed at 2009-09-06T09:01:49Z by kevan
Changed at 2009-09-06T09:02:02Z by kevan
comment:2 Changed at 2009-09-06T09:07:47Z by kevan
These changes passed all of the tests that I could think to throw at them. Comments?
comment:3 Changed at 2009-09-08T02:27:47Z by zooko
- Keywords review added
comment:4 Changed at 2009-11-28T21:30:07Z by warner
- Owner set to warner
- Status changed from new to assigned
comment:5 Changed at 2009-11-30T20:54:22Z by warner
One comment about the original issue that zooko described: the help text suggested running "cp DIRCAP/filename ./" (note that the target is "./"), but the failing example actually ran "cp -r DIRCAP/filename filename2" (note the -r and "filename2" target). The command in the help text works correctly.
Kevan: thanks for the comprehensive testing! If I might compress the cases down to a brief list, I think it looks like this:
- cp -r DIRCAP/filename1 filename2 : EXCEPTION (zooko's example)
- cp FILECAP dirname : EXCEPTION
- cp DIRCAP/filename dirname : EXCEPTION
- cp FILECAP filename : OK
- cp DIRCAP/filename filename : OK
- cp FILECAP filename : OK (overwrite)
- cp DIRCAP/filename filename : OK (overwrite)
- cp -r FILECAP dirname : OK
- cp -r DIRCAP dirname : OK
The behavior of plain old /bin/cp, with or without -r, is pretty ugly, and there are a lot of variables: source has-or-does-not-have trailing slash, dest trailing slash, dest not-exists/is-file/is-dir, -r-or-not. Other programs that try to look kind of like /bin/cp (like rsync and scp) have slightly different semantics.
I like your conclusions, that the first case ("cp FILECAP dirname") should complain cleanly, and the second case ("cp DIRCAP/filename dirname") should result in dirname/filename being created.
I don't know what "cp -r FILECAP dirname" should do (it seems plausible that -r should assert that the source argument is a directory), but I think the current behavior is acceptable. Given that, it seems like zooko's "cp -r DIRCAP/filename1 filename2" ought to behave just like the non-recursive "cp DIRCAP/filename1 filename2".
Anyways, those are my feelings. I'll go review your patch now.
comment:6 Changed at 2009-11-30T21:17:33Z by warner
- Milestone changed from eventually to 1.6.0
- Resolution set to fixed
- Status changed from assigned to closed
The patch looks great. I've applied it in 74974b27fe044438, along with an additional test (of the cp -r DIRCAP/filename1 filename2 case), and some cleanups to have it only put files in the per-test subdirectory (instead of directly under _trial_temp/).
thanks!
comment:7 Changed at 2010-02-02T05:52:41Z by davidsarah
- Keywords news-done added; review removed
Testing:
copying a filecap to a local directory
copying a file by means of a dircap and a path to a local directory
copying a filecap to a local file that doesn't exist
copying a file by means of a dircap and a path to a local file that doesn't exist
copying a filecap to a local file that does exist
copying a file by means of a dircap and a path to a local file that does exist.
copying a dircap to a local directory
(it copies the contents of the directory on the grid to thedir)
copying a dircap to a local directory that doesn't exist
(don't worry -- the files and directories I use for testing were, when not taken from tahoe cp --help, generated for the purposes of the testing, so I'm not leaking anything by not censoring caps)
From what I gather, those two errors are happening because the code in tahoe_cp.py isn't attempting to deduce a destination filename within the directory to use when copying. It doesn't have a lot to go on in the first case (since the filecap doesn't know what its name might be), but it seems like it should be able to infer that wiki.html should be the destination name in the second case, and continue. I have a patch that implements this behavior (complaining in the first failure case, working in the second), but I want to test it more thoroughly before I upload it.