Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option -L to allow docker cp follow symbol link #16613

Merged
merged 1 commit into from
Nov 21, 2015

Conversation

WeiZhang555
Copy link
Contributor

fixes #16555

When user try to cp a symbol link to/from a container, what the user
really want is to copy the link target but not the symbol link, as the
symbol link is only valid and useful in host/container's scope.
All in all, who will need a symbol link copied to container which points
to some file on host? That's meaningless.

And this is also the default behavior of a unix cp command.

Signed-off-by: Zhang Wei [email protected]

@WeiZhang555
Copy link
Contributor Author

docker exec test failed, I have no idea about this:

----------------------------------------------------------------------
FAIL: docker_cli_exec_test.go:615: DockerSuite.TestExecStartFails

docker_cli_exec_test.go:622:
    c.Fatal("exec error message not received. The daemon might had crashed")
... Error: exec error message not received. The daemon might had crashed


----------------------------------------------------------------------

@calavera
Copy link
Contributor

Removing a whole test without adding a new one makes me quite uncomfortable.

I'd like to know what @jlhawn thinks about this change before giving it my 👍

@WeiZhang555
Copy link
Contributor Author

@calavera Understand, that test case is wholly removed because it's totally inappropriate.
I'll add one more testcases after we make a deal about the cp behaviour. :)

@WeiZhang555
Copy link
Contributor Author

@calavera
Is there any way to run some specific integration test file instead of all? It's quite slow and inconvenient to run all the integration scripts. :)

@tonistiigi
Copy link
Member

Like pointed out in #16555 docker cp currently uses cp -a syntax. This isn't accidental, but documented, together with symlink following rules. We can consider supporting both, but probably not switching the behavior as we also have opposite issues from the time before refactoring took place(#13157).

More importantly, there is an API for pulling and pushing files to/from containers and there is a cli tool. IMHO if we allow following of the source we should do it in the client side and not change API. This is also how we do it currently when you copy local files into a symlink inside a container. We resolve the actual target directory in the client side and start upload to that.

@WeiZhang555
Copy link
Contributor Author

@tonistiigi
All right, how about that we reserve the default docker cp behaviour, but add more options such as -L(following symbol link) and -r (copy directory recursely), this will also need a little change to the API, e.g. GET "/containers/{name:.*}/archive?recurse=true&linkFollow=false".
Of course we can make default behaviour unchanged, but it's hard to change cp behaviour without modifying REST API. For example, the TARed file will contain file name, if we don't pass linkFollow param through to daemon, daemon can't choose a correct rebaseName.

What do you think of extra option of -L and -r ? Is that acceptable?

@tonistiigi
Copy link
Member

@WeiZhang555 I'm not sure if its better to add -L or make the current behavior docker cp -a but I'd really like if this would be client side change only. Take a look how we handle remote symlink targets. Also I think current rebasing all happens on client side anyway.

@WeiZhang555
Copy link
Contributor Author

@tonistiigi
We can make origal REST API GET "/containers/{name:.*}/archive" behave like GET "/containers/{name:.*}/archive?recurse=true&linkFollow=false", so it won't impact exsiting tools. And IMO it's better.

But it's also OK to change client only if you really feel uncomfortable with API change, I can take a look at what I can do for that.

@tonistiigi
Copy link
Member

@WeiZhang555 I think the current API has the correct behavior. /archive does not assume any special handling for symlinks. We can reconsider if client-only change turns out to be impossible but I think its doable. Also make sure that copy-from-container and copy-to-container always work the same way.

@WeiZhang555
Copy link
Contributor Author

@tonistiigi All right, I can try to find a way to make client-only change, maybe need a couple of days. :)

@WeiZhang555
Copy link
Contributor Author

Just refreshed my PR, add one '-L' option to allow following symbol links.
e.g.
docker cp xxx:xxx xxx means copy symbol link file itself;
doker cp -L xxx:xxx xxx means copy target file.

Let's see how it works.
I'm still working on test cases and docs thing.

@WeiZhang555 WeiZhang555 force-pushed the docker-cp-symlink branch 2 times, most recently from 4815599 to 3871588 Compare October 1, 2015 08:30
@WeiZhang555 WeiZhang555 changed the title Fix bug that docker cp can't follow symbol link Add option -L to allow docker cp follow symbol link Oct 2, 2015
@WeiZhang555
Copy link
Contributor Author

@tonistiigi @calavera @jlhawn
Just add some unit tests, I will keep working on integration test.
Please tell me what do you think of the -L option, is this OK for you?

One more thing, the reason why I use the -L instead of -a is that -a is an option which is combined of -d and -R(reference unix cp command), but -L is kind of a standalone option, And also -L can keep original behavior of docker cp so it won't influence existing tools which makes use of docker cp.

Let me know whether this is acceptable for you in case I write too many codes that will never be merged. :)

@tonistiigi
Copy link
Member

@WeiZhang555 I didn't look at the code too carefully atm but the approach looks good to me. Tests look good as well but yes, inctegration-cli and docs are also needed. I wonder if -R would be a better flag because -L usually means resolve all symlinks but this is for resolving the source only.

func TestCopyCaseC(t *testing.T) {
// C.1 SRC specifies a file and DST exists as a file. This should overwrite
// the file at DST with the contents of the source file.
func TestCopyCaseC1(t *testing.T) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd use TestCopyCaseCFollowSymlink or TestCopyCaseCFSym instead the 1/2 suffix.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I can fix this.

@WeiZhang555
Copy link
Contributor Author

@tonistiigi We can find a nice option together, but -R seems easy to be mixed with -r(recursively) and may not be a good choice. :)

I'll go on adding the integration testa and docs, also more tests to see if this change works correctly. :)

@WeiZhang555 WeiZhang555 force-pushed the docker-cp-symlink branch 2 times, most recently from ed655e7 to 2b152cb Compare October 3, 2015 02:23
@WeiZhang555
Copy link
Contributor Author

@tonistiigi updated, please help review :)

@vdemeester
Copy link
Member

@WeiZhang555 sorry, needs a rebase 😓

a tar archive to `STDOUT` if `-` is specified).
The `docker cp` utility copies the contents of `SRC_PATH` to the `DEST_PATH`.
You can copy from the container's file system to the local machine or the
reverse, from the local filesystem to the container. if If `-` is specified for
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

double "if" here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, you are right! 👍

@thaJeztah
Copy link
Member

Thanks @WeiZhang555, I added my comments inline

@WeiZhang555
Copy link
Contributor Author

@thaJeztah Very detailed suggestion, I'll do it now 👍

@WeiZhang555
Copy link
Contributor Author

@thaJeztah @moxiegirl updated.

If - is specified for
either the SRC_PATH or DEST_PATH, you can also stream a tar archive to
STDOUT.

I think it's not very accurate. How about

If `-` is specified for
either the `SRC_PATH` or `DEST_PATH`, you can also stream a tar archive from `STDIN` or to
`STDOUT`.

Maybe this is better? WDYT?

@thaJeztah
Copy link
Member

Hm, yes, I think that makes sense

Fixes moby#16555

Original docker `cp` always copy symbol link itself instead of target,
now we provide '-L' option to allow docker to follow symbol link to real
target.

Signed-off-by: Zhang Wei <[email protected]>
@WeiZhang555
Copy link
Contributor Author

@thaJeztah updated. 😄

@moxiegirl
Copy link
Contributor

LGTM! Thank you @WeiZhang555 :-D

@thaJeztah
Copy link
Member

Thanks @WeiZhang555 for your contribution!

LGTM

@thaJeztah
Copy link
Member

restarting Windows build

@vdemeester
Copy link
Member

Windows builds are definitely in holidays.. 😅

runcom added a commit that referenced this pull request Nov 21, 2015
Add option `-L` to allow `docker cp` follow symbol link
@runcom runcom merged commit 3ff9bb5 into moby:master Nov 21, 2015
@WeiZhang555
Copy link
Contributor Author

Yeah, Windows build is a naughty boy 😄

Thank you all for helping! 😆

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

docker cp can't follow symbol link