From ce0db061d704f3fb118009419334056736479265 Mon Sep 17 00:00:00 2001 From: Zexi Li Date: Fri, 27 Dec 2024 17:54:01 +0800 Subject: [PATCH] feat(host): add container copy by tar methods (#21903) --- .../modules/compute/mod_containers.go | 40 +++++++++++++++-- pkg/util/pod/stream/cp/cp.go | 45 +++---------------- 2 files changed, 41 insertions(+), 44 deletions(-) diff --git a/pkg/mcclient/modules/compute/mod_containers.go b/pkg/mcclient/modules/compute/mod_containers.go index c9553b8095e..d45d8001bfb 100644 --- a/pkg/mcclient/modules/compute/mod_containers.go +++ b/pkg/mcclient/modules/compute/mod_containers.go @@ -217,7 +217,7 @@ func (man ContainerManager) EnsureDir(s *mcclient.ClientSession, ctrId string, d return man.ExecV2(s, ctrId, opt) } -func (man ContainerManager) CopyTo(s *mcclient.ClientSession, ctrId string, destPath string, in io.Reader) error { +func (man ContainerManager) copyTo(s *mcclient.ClientSession, ctrId string, destPath string, in io.Reader, ctrCmd []string) error { destDir := path.Dir(destPath) if err := man.EnsureDir(s, ctrId, destDir); err != nil { return errors.Wrapf(err, "ensure dir %s", destDir) @@ -232,7 +232,6 @@ func (man ContainerManager) CopyTo(s *mcclient.ClientSession, ctrId string, dest } }() - ctrCmd := []string{"sh", "-c", fmt.Sprintf("cat - > %s", destPath)} opt := &ContainerExecInput{ Command: ctrCmd, Tty: false, @@ -243,10 +242,35 @@ func (man ContainerManager) CopyTo(s *mcclient.ClientSession, ctrId string, dest return man.ExecV2(s, ctrId, opt) } -func (man ContainerManager) CopyFrom(s *mcclient.ClientSession, ctrId string, ctrFile string, out io.Writer) error { +func (man ContainerManager) CopyTo(s *mcclient.ClientSession, ctrId string, destPath string, in io.Reader) error { + ctrCmd := []string{"sh", "-c", fmt.Sprintf("cat - > %s", destPath)} + return man.copyTo(s, ctrId, destPath, in, ctrCmd) +} + +func (man ContainerManager) CopyTarTo(s *mcclient.ClientSession, ctrId string, destDir string, in io.Reader, noSamePermissions bool) error { + ctrCmd := []string{"tar", "-xmf", "-"} + if noSamePermissions { + ctrCmd = []string{"tar", "--no-same-permissions", "--no-same-owner", "-xmf", "-"} + } + ctrCmd = append(ctrCmd, "-C", destDir) + return man.copyTo(s, ctrId, destDir, in, ctrCmd) +} + +func (man ContainerManager) CheckDestinationIsDir(s *mcclient.ClientSession, ctrId string, destPath string) error { + opt := &ContainerExecInput{ + Command: []string{"test", "-d", destPath}, + Tty: false, + Stdin: os.Stdin, + Stdout: os.Stdout, + Stderr: os.Stderr, + } + return man.ExecV2(s, ctrId, opt) +} + +func (man ContainerManager) copyFrom(s *mcclient.ClientSession, ctrId string, out io.Writer, cmd []string) error { reader, outStream := io.Pipe() opts := &ContainerExecInput{ - Command: []string{"cat", ctrFile}, + Command: cmd, Tty: false, Stdin: nil, Stdout: outStream, @@ -264,3 +288,11 @@ func (man ContainerManager) CopyFrom(s *mcclient.ClientSession, ctrId string, ct } return nil } + +func (man ContainerManager) CopyFrom(s *mcclient.ClientSession, ctrId string, ctrFile string, out io.Writer) error { + return man.copyFrom(s, ctrId, out, []string{"cat", ctrFile}) +} + +func (man ContainerManager) CopyTarFrom(s *mcclient.ClientSession, ctrId string, ctrDir string, out io.Writer) error { + return man.copyFrom(s, ctrId, out, []string{"tar", "cf", "-", ctrDir}) +} diff --git a/pkg/util/pod/stream/cp/cp.go b/pkg/util/pod/stream/cp/cp.go index f2bb67bc5fc..f05a1d94aef 100644 --- a/pkg/util/pod/stream/cp/cp.go +++ b/pkg/util/pod/stream/cp/cp.go @@ -58,20 +58,13 @@ func (o *sCopy) CopyFromContainer(s *mcclient.ClientSession, src ContainerFileOp } reader, outStream := io.Pipe() - opts := &compute.ContainerExecInput{ - Command: []string{"tar", "cf", "-", src.File}, - Tty: false, - Stdin: nil, - Stdout: outStream, - Stderr: os.Stderr, - } - go func() { defer outStream.Close() - if err := compute.Containers.ExecV2(s, src.ContainerId, opts); err != nil { - log.Errorf("compute.Containers.ExecV2: %v", err) + if err := compute.Containers.CopyTarFrom(s, src.ContainerId, src.File, outStream); err != nil { + log.Errorf("copy src by tar from container: %v", err) } }() + prefix := getPrefix(src.File) prefix = path.Clean(prefix) // remove extraneous path shortcuts - these could occur if a path contained extra "../ @@ -196,7 +189,7 @@ func (o *sCopy) CopyToContainer(s *mcclient.ClientSession, srcFile string, dest if dest.File != "/" && strings.HasSuffix(string(dest.File[len(dest.File)-1]), "/") { dest.File = dest.File[:len(dest.File)-1] } - if err := o.checkDestinationIsDir(s, dest); err == nil { + if err := compute.Containers.CheckDestinationIsDir(s, dest.ContainerId, dest.File); err == nil { // If no error, dest.File was found to be a directory. // Copy specified src info it dest.File = dest.File + "/" + path.Base(srcFile) @@ -208,37 +201,9 @@ func (o *sCopy) CopyToContainer(s *mcclient.ClientSession, srcFile string, dest log.Errorf("makeTar error: %v", err) } }() - var cmdArr []string - if o.noPreserve { - cmdArr = []string{"tar", "--no-same-permissions", "--no-same-owner", "-xmf", "-"} - } else { - cmdArr = []string{"tar", "-xmf", "-"} - } destDir := path.Dir(dest.File) - if len(destDir) > 0 { - cmdArr = append(cmdArr, "-C", destDir) - } - - opt := &compute.ContainerExecInput{ - Command: cmdArr, - Tty: false, - Stdin: reader, - Stdout: os.Stdout, - Stderr: os.Stderr, - } - return compute.Containers.ExecV2(s, dest.ContainerId, opt) -} - -func (o *sCopy) checkDestinationIsDir(s *mcclient.ClientSession, dest ContainerFileOpt) error { - opt := &compute.ContainerExecInput{ - Command: []string{"test", "-d", dest.File}, - Tty: false, - Stdin: os.Stdin, - Stdout: os.Stdout, - Stderr: os.Stderr, - } - return compute.Containers.ExecV2(s, dest.ContainerId, opt) + return compute.Containers.CopyTarTo(s, dest.ContainerId, destDir, reader, o.noPreserve) } func makeTar(srcPath, destPath string, writer io.Writer) error {