这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 64 additions & 9 deletions plugins/common/docker.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package common

import (
"archive/tar"
"bytes"
"fmt"
"io"
"os"
"strconv"
"strings"
Expand Down Expand Up @@ -104,14 +107,6 @@ func CopyFromImage(appName string, image string, source string, destination stri
}
}

tmpFile, err := os.CreateTemp(os.TempDir(), fmt.Sprintf("dokku-%s-%s", MustGetEnv("DOKKU_PID"), "CopyFromImage"))
if err != nil {
return fmt.Errorf("Cannot create temporary file: %v", err)
}

defer tmpFile.Close()
defer os.Remove(tmpFile.Name())

globalRunArgs := MustGetEnv("DOKKU_GLOBAL_RUN_ARGS")
createLabelArgs := []string{"--label", fmt.Sprintf("com.dokku.app-name=%s", appName), globalRunArgs}
containerID, err := DockerContainerCreate(image, createLabelArgs)
Expand All @@ -125,7 +120,7 @@ func CopyFromImage(appName string, image string, source string, destination stri
// ref: https://github.com/dotcloud/docker/issues/3986
result, err := CallExecCommand(ExecCommandInput{
Command: DockerBin(),
Args: []string{"container", "cp", fmt.Sprintf("%s:%s", containerID, source), tmpFile.Name()},
Args: []string{"container", "cp", "--quiet", fmt.Sprintf("%s:%s", containerID, source), "-"},
})
if err != nil {
return fmt.Errorf("Unable to copy file %s from image: %w", source, err)
Expand All @@ -134,6 +129,36 @@ func CopyFromImage(appName string, image string, source string, destination stri
return fmt.Errorf("Unable to copy file %s from image: %v", source, result.StderrContents())
}

tarContents := result.StdoutContents()
if tarContents == "" {
return fmt.Errorf("Unable to copy file %s from image", source)
}

// extract the contents via tar
content, err := extractTarToString(tarContents)
if err != nil {
return fmt.Errorf("Unable to extract contents from tar: %v", err)
}

tmpFile, err := os.CreateTemp(os.TempDir(), fmt.Sprintf("dokku-%s-%s", MustGetEnv("DOKKU_PID"), "CopyFromImage"))
if err != nil {
return fmt.Errorf("Cannot create temporary file: %v", err)
}

defer func() {
if err := tmpFile.Close(); err != nil {
LogWarn(fmt.Sprintf("Unable to close temporary file: %v", err))
}
if err := os.Remove(tmpFile.Name()); err != nil {
LogWarn(fmt.Sprintf("Unable to remove temporary file: %v", err))
}
}()

// write contents to tmpFile
if _, err := tmpFile.Write([]byte(content)); err != nil {
return fmt.Errorf("Unable to write to temporary file: %v", err)
}

fi, err := os.Stat(tmpFile.Name())
if err != nil {
return err
Expand Down Expand Up @@ -172,6 +197,36 @@ func CopyFromImage(appName string, image string, source string, destination stri
return nil
}

// Function to extract tar contents and return them as a string
func extractTarToString(in string) (string, error) {
// Initialize a buffer to accumulate the extracted content
var extractedContent bytes.Buffer

// Create a tar reader from standard input
tarReader := tar.NewReader(strings.NewReader(in))

// Iterate through the files in the tar archive
for {
// Read the next header (file entry)
_, err := tarReader.Next()
if err == io.EOF {
break // End of archive
}
if err != nil {
return "", fmt.Errorf("error reading tar header: %v", err)
}

// Write the content of the current file into the buffer
_, err = io.Copy(&extractedContent, tarReader)
if err != nil {
return "", fmt.Errorf("error copying file content: %v", err)
}
}

// Return the accumulated content as a string
return strings.TrimSpace(extractedContent.String()), nil
}

// DockerBin returns a string which contains a path to the current docker binary
func DockerBin() string {
dockerBin := os.Getenv("DOCKER_BIN")
Expand Down
Loading