Skip to content

Commit

Permalink
rewrite podman-cp
Browse files Browse the repository at this point in the history
* Add a new `pkg/copy` to centralize all container-copy related code.

* The new code is based on Buildah's `copier` package.

* The compat `/archive` endpoints use the new `copy` package.

* Update docs and an several new tests.

* Includes many fixes, most notably, the look-up of volumes and mounts.

Breaking changes:

 * Podman is now expecting that container-destination paths exist.
   Before, Podman created the paths if needed.  Docker does not do
   that and I believe Podman should not either as it's a recipe for
   masking errors.  These errors may be user induced (e.g., a path
   typo), or internal typos (e.g., when the destination may be a
   mistakenly unmounted volume).  Let's keep the magic low for such
   a security sensitive feature.

Signed-off-by: Valentin Rothberg <[email protected]>
  • Loading branch information
vrothberg committed Dec 4, 2020
1 parent 8dab410 commit ccbca0b
Show file tree
Hide file tree
Showing 13 changed files with 1,397 additions and 941 deletions.
19 changes: 2 additions & 17 deletions cmd/podman/containers/cp.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ package containers
import (
"github.com/containers/podman/v2/cmd/podman/common"
"github.com/containers/podman/v2/cmd/podman/registry"
"github.com/containers/podman/v2/pkg/cgroups"
"github.com/containers/podman/v2/pkg/domain/entities"
"github.com/containers/podman/v2/pkg/rootless"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -43,7 +40,7 @@ var (
func cpFlags(cmd *cobra.Command) {
flags := cmd.Flags()
flags.BoolVar(&cpOpts.Extract, "extract", false, "Extract the tar file into the destination directory.")
flags.BoolVar(&cpOpts.Pause, "pause", copyPause(), "Pause the container while copying")
flags.BoolVar(&cpOpts.Pause, "pause", true, "Pause the container while copying")
}

func init() {
Expand All @@ -62,17 +59,5 @@ func init() {
}

func cp(cmd *cobra.Command, args []string) error {
_, err := registry.ContainerEngine().ContainerCp(registry.GetContext(), args[0], args[1], cpOpts)
return err
}

func copyPause() bool {
if rootless.IsRootless() {
cgroupv2, _ := cgroups.IsCgroup2UnifiedMode()
if !cgroupv2 {
logrus.Debugf("defaulting to pause==false on rootless cp in cgroupv1 systems")
return false
}
}
return true
return registry.ContainerEngine().ContainerCp(registry.GetContext(), args[0], args[1], cpOpts)
}
30 changes: 15 additions & 15 deletions docs/source/markdown/podman-cp.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ podman\-cp - Copy files/folders between a container and the local filesystem
**podman container cp** [*options*] [*container*:]*src_path* [*container*:]*dest_path*

## DESCRIPTION
Copies the contents of **src_path** to the **dest_path**. You can copy from the container's filesystem to the local machine or the reverse, from the local filesystem to the container.
If - is specified for either the SRC_PATH or DEST_PATH, you can also stream a tar archive from STDIN or to STDOUT.
Copy the contents of **src_path** to the **dest_path**. You can copy from the container's filesystem to the local machine or the reverse, from the local filesystem to the container.
If `-` is specified for either the SRC_PATH or DEST_PATH, you can also stream a tar archive from STDIN or to STDOUT.

The CONTAINER can be a running or stopped container. The **src_path** or **dest_path** can be a file or directory.

The **podman cp** command assumes container paths are relative to the container's / (root) directory.
The **podman cp** command assumes container paths are relative to the container's root directory (i.e., `/`).

This means supplying the initial forward slash is optional;

Expand All @@ -27,24 +27,22 @@ Assuming a path separator of /, a first argument of **src_path** and second argu

**src_path** specifies a file
- **dest_path** does not exist
- the file is saved to a file created at **dest_path**
- **dest_path** does not exist and ends with /
- Error condition: the destination directory must exist.
- the file is saved to a file created at **dest_path** (note that parent directory must exist)
- **dest_path** exists and is a file
- the destination is overwritten with the source file's contents
- the destination is overwritten with the source file's contents
- **dest_path** exists and is a directory
- the file is copied into this directory using the basename from **src_path**
- the file is copied into this directory using the basename from **src_path**

**src_path** specifies a directory
- **dest_path** does not exist
- **dest_path** is created as a directory and the contents of the source directory are copied into this directory
- **dest_path** is created as a directory and the contents of the source directory are copied into this directory
- **dest_path** exists and is a file
- Error condition: cannot copy a directory to a file
- Error condition: cannot copy a directory to a file
- **dest_path** exists and is a directory
- **src_path** ends with /
- the source directory is copied into this directory
- **src_path** ends with /. (that is: slash followed by dot)
- the content of the source directory is copied into this directory
- **src_path** ends with `/`
- the source directory is copied into this directory
- **src_path** ends with `/.` (i.e., slash followed by dot)
- the content of the source directory is copied into this directory

The command requires **src_path** and **dest_path** to exist according to the above rules.

Expand All @@ -57,11 +55,13 @@ You can also use : when specifying paths to a **src_path** or **dest_path** on a
If you use a : in a local machine path, you must be explicit with a relative or absolute path, for example:
`/path/to/file:name.txt` or `./file:name.txt`

Using `-` as the *src_path* streams the contents of STDIN as a tar archive. The command extracts the content of the tar to the *DEST_PATH* in the container. In this case, *dest_path* must specify a directory. Using `-` as the *dest_path* streams the contents of the resource (can be a directory) as a tar archive to STDOUT.

## OPTIONS

#### **--extract**

Extract the tar file into the destination directory. If the destination directory is not provided, extract the tar file into the root directory.
If the source is a tar archive, extract it to the provided destination (must be a directory). If the source is not a tar archive, follow the above rules.

#### **--pause**

Expand Down
5 changes: 5 additions & 0 deletions libpod/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,11 @@ func (c *Container) Config() *ContainerConfig {
return returnConfig
}

// Runtime returns the container's Runtime.
func (c *Container) Runtime() *Runtime {
return c.runtime
}

// Spec returns the container's OCI runtime spec
// The spec returned is the one used to create the container. The running
// spec may differ slightly as mounts are added based on the image
Expand Down
2 changes: 2 additions & 0 deletions libpod/events/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ const (
Cleanup Status = "cleanup"
// Commit ...
Commit Status = "commit"
// Copy ...
Copy Status = "copy"
// Create ...
Create Status = "create"
// Exec ...
Expand Down
Loading

0 comments on commit ccbca0b

Please sign in to comment.