feat(host): add container copy by tar methods (#21903)

This commit is contained in:
Zexi Li
2024-12-27 17:54:01 +08:00
committed by GitHub
parent 56efaed760
commit ce0db061d7
2 changed files with 41 additions and 44 deletions
+36 -4
View File
@@ -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})
}
+5 -40
View File
@@ -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 {