-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
support container to container copy #10728
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -80,11 +80,14 @@ func cp(cmd *cobra.Command, args []string) error { | |
return err | ||
} | ||
|
||
if len(sourceContainerStr) > 0 { | ||
if len(sourceContainerStr) > 0 && len(destContainerStr) > 0 { | ||
return copyContainerToContainer(sourceContainerStr, sourcePath, destContainerStr, destPath) | ||
} else if len(sourceContainerStr) > 0 { | ||
return copyFromContainer(sourceContainerStr, sourcePath, destPath) | ||
} | ||
|
||
return copyToContainer(destContainerStr, destPath, sourcePath) | ||
|
||
} | ||
|
||
// containerMustExist returns an error if the specified container does not | ||
|
@@ -113,6 +116,55 @@ func doCopy(funcA func() error, funcB func() error) error { | |
return errorhandling.JoinErrors(copyErrors) | ||
} | ||
|
||
func copyContainerToContainer(fromContainer string, sourcePath string, toContainer string, destPath string) error { | ||
if err := containerMustExist(fromContainer); err != nil { | ||
return err | ||
} | ||
|
||
if err := containerMustExist(toContainer); err != nil { | ||
return err | ||
} | ||
|
||
fromContainerInfo, err := registry.ContainerEngine().ContainerStat(registry.GetContext(), fromContainer, sourcePath) | ||
if err != nil { | ||
return errors.Wrapf(err, "%q could not be found on container %s", sourcePath, fromContainer) | ||
} | ||
|
||
toContainerInfo, err := registry.ContainerEngine().ContainerStat(registry.GetContext(), toContainer, destPath) | ||
if err != nil { | ||
return errors.Wrapf(err, "%q could not be found on container %s", destPath, toContainer) | ||
} | ||
|
||
fromContainerTarget, toContainerTarget := fromContainerInfo.LinkTarget, toContainerInfo.LinkTarget | ||
reader, writer := io.Pipe() | ||
|
||
fromContainerCopy := func() error { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. potentially could consolidate There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there might be some changes to the functions, so depending on what the final outcome looks like i'll refactor the code |
||
defer writer.Close() | ||
copyFunc, err := registry.ContainerEngine().ContainerCopyToArchive(registry.GetContext(), fromContainer, fromContainerTarget, writer) | ||
if err != nil { | ||
return err | ||
} | ||
if err := copyFunc(); err != nil { | ||
return errors.Wrap(err, "error copying from container") | ||
} | ||
return nil | ||
} | ||
|
||
toContainerCopy := func() error { | ||
defer reader.Close() | ||
copyFunc, err := registry.ContainerEngine().ContainerCopyFromArchive(registry.GetContext(), toContainer, toContainerTarget, reader) | ||
if err != nil { | ||
return err | ||
} | ||
if err := copyFunc(); err != nil { | ||
return errors.Wrap(err, "error copying to container") | ||
} | ||
return nil | ||
} | ||
|
||
return doCopy(fromContainerCopy, toContainerCopy) | ||
} | ||
|
||
// copyFromContainer copies from the containerPath on the container to hostPath. | ||
func copyFromContainer(container string, containerPath string, hostPath string) error { | ||
if err := containerMustExist(container); err != nil { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That should not be an error per-se. If I do
cp 1:/foo.txt 2:/foo.txt
then "foo.txt" should be created at the destination. Have a look at the copy functions above for the wiring.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't understand why we are checking for this condition here: https://github.com/containers/podman/blob/master/cmd/podman/containers/cp.go#L266
If possible, could you please give an example
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we do a
cp 1:/dir 2:/tmp/foo/
foo
must exist. If we do acp 1:/dir 2:/tmp/foo
foo
would be created if it doesn't exist.The condition enforces that rule. The
podman-cp
man pages mention these rules.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding those comments btw, they are very helpful! I will work on the missing cases soon
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy to help! Feel free to ping me here on IRC at any time. I am reachable during regular CEST working hours.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vrothberg a bit confused about git, how do I get the changes you made to the branch on my fork?
would it be like checking out to main and then pulling the changes and checking out to my branch
c2c-copy
and then merging main to my branch?wouldn't that mean losing the changes I made?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I usually do is the following (
upstream
is the remote branch pointing github.com/containers/podman
):Note that while rebasing you may have to resolve merge conflicts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
been on this for hours now, cant seem to figure this. I was able to update the c2c-copy branch to the recent changes on podman but the changes you made yesterday don't reflect? even git log shows your merged PR
And surprisingly, I did not get any merge conflicts?
I think I might have to just re-add those changes and continue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nevermind, I figured it out. Didn't have to do anything manually
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vrothberg so I am not sure how we will go about renaming files for container-container copy in a case like:
podman container cp distracted_tesla:ok.txt pedantic_hertz:ok.txt
In host->container or container->host I can see that the buildah copier package is handling that for us but how do we do this for this case?
I was able to fix the segmentation fault