diff --git a/environment/container/container.go b/environment/container/container.go index 102c0bd43..7b15d5c99 100644 --- a/environment/container/container.go +++ b/environment/container/container.go @@ -44,8 +44,8 @@ type ContainerEngine interface { InspectImage(image string) (dockertypes.ImageInspect, error) // TODO: Change paths from map to array CopyDirsIntoImage(image, newImageName string, paths map[string]string) (err error) - CopyDirsIntoContainer(containerID string, paths map[string]string) (err error) - CopyDirsFromContainer(containerID string, paths map[string]string) (err error) + CopyDataIntoContainer(containerID string, paths map[string]string) (err error) + CopyDataFromContainer(containerID string, paths map[string]string) (err error) BuildImage(image, context, dockerfile string) (err error) RemoveImage(image string) (err error) CreateContainer(container environmenttypes.Container) (containerid string, err error) diff --git a/environment/container/dockerengine.go b/environment/container/dockerengine.go index 7010f4250..ea4766c6d 100644 --- a/environment/container/dockerengine.go +++ b/environment/container/dockerengine.go @@ -21,8 +21,10 @@ import ( "bytes" "context" "fmt" + "os" "io" "io/fs" + "path/filepath" "strings" "github.com/docker/docker/api/types" @@ -231,14 +233,26 @@ func (e *dockerEngine) CopyDirsIntoImage(image, newImageName string, paths map[s return nil } -// CopyDirsIntoContainer copies some directories into a container -func (e *dockerEngine) CopyDirsIntoContainer(containerID string, paths map[string]string) (err error) { +// CopyDataIntoContainer copies files or directories into a container +func (e *dockerEngine) CopyDataIntoContainer(containerID string, paths map[string]string) (err error) { for sp, dp := range paths { - err = copyDirToContainer(e.ctx, e.cli, containerID, sp, dp) + fi, err := os.Stat(sp) if err != nil { - return fmt.Errorf("container data copy failed for image '%s' with volume %s:%s . Error: %w", containerID, sp, dp, err) + return fmt.Errorf("failed to stat the source path '%s' . Error: %w", sp, err) } - } + if fi.Mode().IsDir() { + err = copyDirToContainer(e.ctx, e.cli, containerID, sp, dp) + if err != nil { + return fmt.Errorf("container data copy failed for image '%s' with volume %s:%s . Error: %w", containerID, sp, dp, err) + } + } else { + newDestPath := filepath.Join(dp, fi.Name()) + err = copyDirToContainer(e.ctx, e.cli, containerID, sp, newDestPath) + if err != nil { + return fmt.Errorf("container data copy failed for image '%s' with volume %s:%s . Error: %w", containerID, sp, newDestPath, err) + } + } + } return nil } @@ -253,12 +267,23 @@ func (e *dockerEngine) Stat(containerID string, name string) (fs.FileInfo, error }, err } -// CopyDirsFromContainer copies a directory from inside the container -func (e *dockerEngine) CopyDirsFromContainer(containerID string, paths map[string]string) (err error) { - for sp, dp := range paths { - if err := copyFromContainer(e.ctx, e.cli, containerID, sp, dp); err != nil { - return fmt.Errorf("failed to copy data from the container with ID '%s' from source path '%s' to destination path '%s' . Error: %w", containerID, sp, dp, err) +// CopyDataFromContainer copies files or directories from inside the container +func (e *dockerEngine) CopyDataFromContainer(containerID string, paths map[string]string) (err error) { + for sp, dp := range paths { + fi, err := os.Stat(sp) + if err != nil { + return fmt.Errorf("failed to stat the source path '%s' . Error: %w", sp, err) } + if fi.Mode().IsDir() { + if err := copyFromContainer(e.ctx, e.cli, containerID, sp, dp); err != nil { + return fmt.Errorf("failed to copy data from the container with ID '%s' from source path '%s' to destination path '%s' . Error: %w", containerID, sp, dp, err) + } + } else { + newDestPath := filepath.Join(dp, fi.Name()) + if err := copyFromContainer(e.ctx, e.cli, containerID, sp, newDestPath); err != nil { + return fmt.Errorf("failed to copy data from the container with ID '%s' from source path '%s' to destination path '%s' . Error: %w", containerID, sp, newDestPath, err) + } + } } return nil } diff --git a/environment/container/dockerengine_test.go b/environment/container/dockerengine_test.go index 8a03d45f5..7a2916f01 100644 --- a/environment/container/dockerengine_test.go +++ b/environment/container/dockerengine_test.go @@ -296,7 +296,7 @@ func TestIsBuilderAvailable(t *testing.T) { paths[absDir1] = "/dir1" paths[absDir2] = "/dir2" - err = provider.CopyDirsIntoContainer(containerID, paths) + err = provider.CopyDataIntoContainer(containerID, paths) if err != nil { t.Fatalf("failed to copy dirs into iamge '%s' . Error: %q", image, err) } @@ -365,7 +365,7 @@ func TestIsBuilderAvailable(t *testing.T) { paths[absDir1] = "/dir1" paths[absDir2] = "/dir2" - err = provider.CopyDirsIntoContainer(containerID, paths) + err = provider.CopyDataIntoContainer(containerID, paths) if err != nil { t.Fatalf("failed to copy dirs into iamge '%s' . Error: %q", image, err) } @@ -383,7 +383,7 @@ func TestIsBuilderAvailable(t *testing.T) { paths["/dir1"] = tempDir paths["/dir2"] = tempDir - err = provider.CopyDirsFromContainer(containerID, paths) + err = provider.CopyDataFromContainer(containerID, paths) if err != nil { t.Fatal("failed to copy Directories from Container ", err) } diff --git a/environment/peercontainer.go b/environment/peercontainer.go index 5b38f7edc..6c77f1480 100644 --- a/environment/peercontainer.go +++ b/environment/peercontainer.go @@ -186,13 +186,6 @@ func (e *PeerContainer) Destroy() error { // Download downloads the path to outside the environment func (e *PeerContainer) Download(path string) (string, error) { - fileInfo, err := e.Stat(path) - if err != nil { - return path, fmt.Errorf("failed to stat the given path : %s. Error: %v", path, err) - } - if !fileInfo.IsDir() { - return path, fmt.Errorf("download only supports directory paths. The path provided is %s. Error: %v", path, err) - } output, err := os.MkdirTemp(e.TempPath, "*") if err != nil { return path, fmt.Errorf("failed to create temp dir. Error: %w", err) @@ -201,7 +194,7 @@ func (e *PeerContainer) Download(path string) (string, error) { if err != nil { return "", fmt.Errorf("failed to get the container engine. Error: %w", err) } - if err := cengine.CopyDirsFromContainer(e.ContainerInfo.ID, map[string]string{path: output}); err != nil { + if err := cengine.CopyDataFromContainer(e.ContainerInfo.ID, map[string]string{path: output}); err != nil { return path, fmt.Errorf("failed to copy data from the container with ID '%s' . Error: %w", e.ContainerInfo.ID, err) } return output, nil @@ -221,7 +214,7 @@ func (e *PeerContainer) Upload(outpath string) (string, error) { if err != nil { return envpath, fmt.Errorf("failed to get the container engine. Error: %w", err) } - if err := cengine.CopyDirsIntoContainer(e.ContainerInfo.ID, map[string]string{outpath: envpath}); err != nil { + if err := cengine.CopyDataIntoContainer(e.ContainerInfo.ID, map[string]string{outpath: envpath}); err != nil { return envpath, fmt.Errorf("failed to copy data into the container with ID '%s' . Error: %w", e.ContainerInfo.ID, err) } return envpath, nil diff --git a/go.mod b/go.mod index a58265781..8427581e7 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/docker/cli v23.0.3+incompatible github.com/docker/docker v23.0.3+incompatible github.com/docker/libcompose v0.4.1-0.20171025083809-57bd716502dc - github.com/go-git/go-billy/v5 v5.3.1 + github.com/go-git/go-billy/v5 v5.4.1 github.com/go-git/go-git/v5 v5.7.0 github.com/gobwas/glob v0.2.3 github.com/google/go-cmp v0.5.9 @@ -116,7 +116,6 @@ require ( github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.4.1 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/logr v1.2.4 // indirect