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

Allow docker cp to copy host->container, container->host, container->container #6580

Closed
wants to merge 17 commits into from

Conversation

vieux
Copy link
Contributor

@vieux vieux commented Jun 20, 2014

Closes #5846

This allows:

docker cp <container_id>:/path path
docker cp path <container_id>:/path
docker cp <container_id>:/path <container2_id>:/path

With container to container, to keep the code simple (for now?) the content goes through the client's fs.

Needs API bump & doc

This one needs a lot of testing @crosbymichael @tiborvass @unclejack @LK4D4

return fmt.Errorf("Missing parameter")
}

resource := r.Header.Get("Resource")
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it ok to use the header for this ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure, do you have another idea ?

Copy link
Contributor

Choose a reason for hiding this comment

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

in the url?

@cyphar
Copy link
Contributor

cyphar commented Jun 21, 2014

Wouldn't it be neater (and cleaner) to do this with interfaces? You take the two arguments and convert them to types which fulfill interfaces that allow you to copy to and from them.

@LK4D4
Copy link
Contributor

LK4D4 commented Jun 23, 2014

I'm not very sure how it must working :) But for now it is very strange behavior as for me:

$docker run --name cp_test -d ubuntu ping google.com
02e3e9395b802e241ecf17163aa13c0b08036d47b9b5fca564772fc022a890ba

$docker cp kernel_config cp_test:/.config

$file /var/lib/docker/btrfs/subvolumes/02e3e9395b802e241ecf17163aa13c0b08036d47b9b5fca564772fc022a890ba/.config
/var/lib/docker/btrfs/subvolumes/02e3e9395b802e241ecf17163aa13c0b08036d47b9b5fca564772fc022a890ba/.config: directory

$ls /var/lib/docker/btrfs/subvolumes/02e3e9395b802e241ecf17163aa13c0b08036d47b9b5fca564772fc022a890ba/.config

$docker cp cp_test:/etc/passwd ./pswd

$file ./pswd
./pswd: directory

$ls ./pswd  
passwd

Also

docker cp kernel_config cp_test:/

does nothing for me :(

pathSrc = cmd.Arg(0)
pathDst = cmd.Arg(1)
)
if len(infoSrc) != 2 && len(infoDst) != 2 {
return fmt.Errorf("Error: Path not specified")
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it should be sort of "Wrong path format" and usage print.

@LK4D4
Copy link
Contributor

LK4D4 commented Jun 23, 2014

Also for from cont to cont works better:

$ docker cp cp_test:/etc/passwd cp_test2:/passwd
$ docker diff cp_test2
A /passwd
A /passwd/passwd

And there is no check about files existence on host.

}
defer data.Close()
switch method {
case "OUT":
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we should have two separate jobs for this cases?

@LK4D4
Copy link
Contributor

LK4D4 commented Jun 23, 2014

Also word copy in method names was pretty confusing for me when I read code. Maybe we should use sort of Read/WriteResource and same for jobs. Don't know if anyone have same feeling, and maybe someone could propose better naming.

@vieux
Copy link
Contributor Author

vieux commented Jun 23, 2014

@LK4D4 "And there is no check about files existence on host." ?

@LK4D4
Copy link
Contributor

LK4D4 commented Jun 23, 2014

@vieux

$ls asd
ls: cannot access asd: No such file or directory

$docker cp asd cp_test2:/asd

@vieux
Copy link
Contributor Author

vieux commented Jun 23, 2014

@LK4D4 addressed most of the comments, regarding the failures I think we have an issue with files in the Archive package: https://github.com/vieux/docker/compare/dotcloud:master...vieux:tar_untar_file?expand=1

@SvenDowideit
Copy link
Contributor

neat! a pony, and in my favourite colour too!!

@tiborvass
Copy link
Contributor

@vieux remove "file" from the path.Join in both the Tar and Untar function calls.

@LK4D4
Copy link
Contributor

LK4D4 commented Jun 24, 2014

Also, we should check autocomplete. Doesn't work in zsh for me at least.

@vieux
Copy link
Contributor Author

vieux commented Jun 24, 2014

@LK4D4 feel free to submit a PR to my branch to update all the completion scripts..:)

@tianon
Copy link
Member

tianon commented Jun 25, 2014

Autocomplete here is already kind of annoying since we don't have something
like "docker ls".

@LK4D4
Copy link
Contributor

LK4D4 commented Jun 25, 2014

@tianon ah, also there was two PRs with ls IIRC, but @crosbymichael rejected them and maybe he was right :)
I want at least host-side completion.

@vieux
Copy link
Contributor Author

vieux commented Jun 25, 2014

Isn't completion handled by the bash/zsh/fish scripts ?

@tianon
Copy link
Member

tianon commented Jun 25, 2014

Yeah, I can PR an update to bash, but I'm not zsh or fish fluent so can't help much there.

@tianon
Copy link
Member

tianon commented Jun 25, 2014

vieux#6

errorOut(err, t, fmt.Sprintf("failed to cp to the container: %v", err))
}

/* TODO: allow overriding files
Copy link
Contributor Author

Choose a reason for hiding this comment

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

ping @tiborvass

Copy link
Contributor

Choose a reason for hiding this comment

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

@vieux
Copy link
Contributor Author

vieux commented Jun 26, 2014

I updated. 2 things for @tiborvass .

  • I think we should be able to override a file
  • docker cp file <container_id>:/ doesn't work as you tweaked this earlier this week, can you please take a look ?

Docker-DCO-1.1-Signed-off-by: Victor Vieux <victor.vieux@docker.com> (github: vieux)
Docker-DCO-1.1-Signed-off-by: Victor Vieux <victor.vieux@docker.com> (github: vieux)
Docker-DCO-1.1-Signed-off-by: Victor Vieux <victor.vieux@docker.com> (github: vieux)
vieux and others added 9 commits June 27, 2014 23:44
Docker-DCO-1.1-Signed-off-by: Victor Vieux <vieux@docker.com> (github: vieux)
Docker-DCO-1.1-Signed-off-by: Victor Vieux <vieux@docker.com> (github: vieux)
Docker-DCO-1.1-Signed-off-by: Victor Vieux <vieux@docker.com> (github: vieux)
Docker-DCO-1.1-Signed-off-by: Victor Vieux <vieux@docker.com> (github: vieux)
Docker-DCO-1.1-Signed-off-by: Victor Vieux <vieux@docker.com> (github: vieux)
Docker-DCO-1.1-Signed-off-by: Victor Vieux <vieux@docker.com> (github: vieux)
Docker-DCO-1.1-Signed-off-by: Victor Vieux <vieux@docker.com> (github: vieux)
Docker-DCO-1.1-Signed-off-by: Tibor Vass <teabee89@gmail.com> (github: tiborvass)
@vieux
Copy link
Contributor Author

vieux commented Jun 28, 2014

@LK4D4 can you retry now ?

@LK4D4
Copy link
Contributor

LK4D4 commented Jun 28, 2014

@vieux yup, I'll try on weekend

@LK4D4
Copy link
Contributor

LK4D4 commented Jun 29, 2014

moroz@minigrind ~ % docker cp copier1:/urlview copier2:/shuview                                                                         
moroz@minigrind ~ % docker cp copier1:/urlview copier2:/shuview
2014/06/29 11:17:11 Error: Trying to untar an archive with multiple entries to an inexistant target `/var/lib/docker/btrfs/subvolumes/81dd7864831d4945ba99bbd58d07f5e6c36cc8c87e5c7b503104cb9ce8642c31/shuview`: did you mean `/var/lib/docker/btrfs/subvolumes/81dd7864831d4945ba99bbd58d07f5e6c36cc8c87e5c7b503104cb9ce8642c31` instead?

After first command shuview is a file, after second - directory with file urlview, all following cp leave it as a directory.

tianon and others added 2 commits June 30, 2014 18:32
Docker-DCO-1.1-Signed-off-by: Andrew Page <admwiggin@gmail.com> (github: tianon)
Update bash-completion for bidirectional "docker cp"
@@ -994,6 +994,28 @@ func postContainersCopy(eng *engine.Engine, version version.Version, w http.Resp
return nil
}

func putContainersCopy(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
if vars == nil {
return fmt.Errorf("Missing parameter")
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe be more explicit in the error message about which parameter you're expecting.

@cpuguy83
Copy link
Member

cpuguy83 commented Jul 3, 2014

This is sweet.

@vieux vieux added this to the 1.1.1 milestone Jul 3, 2014
tiborvass referenced this pull request in tiborvass/docker Jul 8, 2014
… multiple entries in the archive stream

Docker-DCO-1.1-Signed-off-by: Tibor Vass <teabee89@gmail.com> (github: tiborvass)
@vieux
Copy link
Contributor Author

vieux commented Jul 8, 2014

Closing for now, will reopen when we figure out the tar stuff

@duglin
Copy link
Contributor

duglin commented Aug 12, 2014

Just curious, if windows is ever supported would things like:
docker cp container_id:/path container2_id:/path
cause an ambiguity problems? Granted container_id is usually more than just one character, but its not a requirement.

@duglin
Copy link
Contributor

duglin commented Aug 13, 2014

Ignoring the client command line syntax for a moment, and just focusing on the REST API, I was wondering what people thought about cleaning it up a bit? As I mentioned in https://groups.google.com/forum/#!topic/docker-dev/TmaCiWIEyVk using POST to retrieve a file feels a bit odd and having the path to the file be in the http body is a bit limiting.

I was wondering what people thought about adding new APIs that were a bit more natural/RESTy, in particular:
GET /containers/{id}/resources/{path} to copy a file from a container to the host
HEAD /containers/{id}/resources/{path} to check for existence of a file in a container (or get just metadata)
PUT /containers/{id}/resources/{path} to copy a file from the host to the container - where the contents of the file are either:
a) in the http body, or
b) referenced by an http header (e.g. DOCKER_SRC: {container-id}:{path} ) in the case of container-to-container copy
This could use POST instead I guess, but I'm more used to POST being used in cases where the target URL of the resource is generated by the server and PUT being used when the target URL is already known by the client.
DELETE /containers/{id}/resources/{path} to delete a file from the container - which seems only natural once you have the idea of creating a file at all.

I'd be interested in working on a PR on this but only if there's interest - aside from the container->container copy, I think most of the code is already there and its just minor edits to expose it slightly differently. The old APIs can stick around and be deprecated. Thoughts?

@duglin
Copy link
Contributor

duglin commented Aug 15, 2014

@vieux - was wondering if you had any feedback on this? I'm most interested in the support for checking to see if a file is present in a container - the other stuff around it, while interesting, isn't as critical to my needs right now. I'd really like to submit a PR for this "does a file exist" feature but don't want to code it up until I get a sense for the direction people would like to see it go. .

@tobegit3hub
Copy link

@duglin is right! But we also like the feature to copy the file from host to container. Maybe we don't need to copy from container to container because we can do it by the existing methods.

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

Successfully merging this pull request may close these issues.

Moving a file from the host system to a container via docker cp