diff options
Diffstat (limited to 'cmd/podman/cp.go')
-rw-r--r-- | cmd/podman/cp.go | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/cmd/podman/cp.go b/cmd/podman/cp.go index 5958370b6..6223676ac 100644 --- a/cmd/podman/cp.go +++ b/cmd/podman/cp.go @@ -27,8 +27,11 @@ import ( var ( cpCommand cliconfig.CpValues - cpDescription = "Copy files/folders between a container and the local filesystem" - _cpCommand = &cobra.Command{ + cpDescription = `Command 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 "-" 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. +` + _cpCommand = &cobra.Command{ Use: "cp [flags] SRC_PATH DEST_PATH", Short: "Copy files/folders between a container and the local filesystem", Long: cpDescription, @@ -43,6 +46,10 @@ var ( func init() { cpCommand.Command = _cpCommand + flags := cpCommand.Flags() + flags.BoolVar(&cpCommand.Extract, "extract", false, "Extract the tar file into the destination directory.") + cpCommand.SetHelpTemplate(HelpTemplate()) + cpCommand.SetUsageTemplate(UsageTemplate()) rootCmd.AddCommand(cpCommand.Command) } @@ -61,10 +68,11 @@ func cpCmd(c *cliconfig.CpValues) error { } defer runtime.Shutdown(false) - return copyBetweenHostAndContainer(runtime, args[0], args[1]) + extract := c.Flag("extract").Changed + return copyBetweenHostAndContainer(runtime, args[0], args[1], extract) } -func copyBetweenHostAndContainer(runtime *libpod.Runtime, src string, dest string) error { +func copyBetweenHostAndContainer(runtime *libpod.Runtime, src string, dest string, extract bool) error { srcCtr, srcPath := parsePath(runtime, src) destCtr, destPath := parsePath(runtime, dest) @@ -166,7 +174,7 @@ func copyBetweenHostAndContainer(runtime *libpod.Runtime, src string, dest strin var lastError error for _, src := range glob { - err := copy(src, destPath, dest, idMappingOpts, &containerOwner) + err := copy(src, destPath, dest, idMappingOpts, &containerOwner, extract) if lastError != nil { logrus.Error(lastError) } @@ -219,7 +227,7 @@ func getPathInfo(path string) (string, os.FileInfo, error) { return path, srcfi, nil } -func copy(src, destPath, dest string, idMappingOpts storage.IDMappingOptions, chownOpts *idtools.IDPair) error { +func copy(src, destPath, dest string, idMappingOpts storage.IDMappingOptions, chownOpts *idtools.IDPair, extract bool) error { srcPath, err := filepath.EvalSymlinks(src) if err != nil { return errors.Wrapf(err, "error evaluating symlinks %q", srcPath) @@ -240,6 +248,7 @@ func copy(src, destPath, dest string, idMappingOpts storage.IDMappingOptions, ch // return functions for copying items copyFileWithTar := chrootarchive.CopyFileWithTarAndChown(chownOpts, digest.Canonical.Digester().Hash(), idMappingOpts.UIDMap, idMappingOpts.GIDMap) copyWithTar := chrootarchive.CopyWithTarAndChown(chownOpts, digest.Canonical.Digester().Hash(), idMappingOpts.UIDMap, idMappingOpts.GIDMap) + untarPath := chrootarchive.UntarPathAndChown(chownOpts, digest.Canonical.Digester().Hash(), idMappingOpts.UIDMap, idMappingOpts.GIDMap) if srcfi.IsDir() { @@ -263,6 +272,15 @@ func copy(src, destPath, dest string, idMappingOpts storage.IDMappingOptions, ch destPath = filepath.Join(destPath, filepath.Base(srcPath)) } } + + if extract { + // We're extracting an archive into the destination directory. + logrus.Debugf("extracting contents of %q into %q", srcPath, destPath) + if err = untarPath(srcPath, destPath); err != nil { + return errors.Wrapf(err, "error extracting %q into %q", srcPath, destPath) + } + return nil + } // Copy the file, preserving attributes. logrus.Debugf("copying %q to %q", srcPath, destPath) if err = copyFileWithTar(srcPath, destPath); err != nil { |