Skip to content

Commit

Permalink
Merge pull request #347 from codepitbull/add-copyfromcontainer
Browse files Browse the repository at this point in the history
Added CopyFileFromContainer to DockerContainer
  • Loading branch information
gianarb committed Sep 13, 2021
2 parents 31fb76b + 28d20ca commit 19e857f
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 0 deletions.
1 change: 1 addition & 0 deletions container.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ type Container interface {
Exec(ctx context.Context, cmd []string) (int, error)
ContainerIP(context.Context) (string, error) // get container ip
CopyFileToContainer(ctx context.Context, hostFilePath string, containerFilePath string, fileMode int64) error
CopyFileFromContainer(ctx context.Context, filePath string) (io.ReadCloser, error)
}

// ImageBuildInfo defines what is needed to build an image
Expand Down
35 changes: 35 additions & 0 deletions docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,41 @@ func (c *DockerContainer) Exec(ctx context.Context, cmd []string) (int, error) {
return exitCode, nil
}

type FileFromContainer struct {
underlying *io.ReadCloser
tarreader *tar.Reader
}

func (fc *FileFromContainer) Read(b []byte) (int, error) {
return (*fc.tarreader).Read(b)
}

func (fc *FileFromContainer) Close() error {
return (*fc.underlying).Close()
}

func (c *DockerContainer) CopyFileFromContainer(ctx context.Context, filePath string) (io.ReadCloser, error) {
r, _, err := c.provider.client.CopyFromContainer(ctx, c.ID, filePath)
if err != nil {
return nil, err
}
tarReader := tar.NewReader(r)

//if we got here we have exactly one file in the TAR-stream
//so we advance the index by one so the next call to Read will start reading it
_, err = tarReader.Next()
if err != nil {
return nil, err
}

ret := &FileFromContainer{
underlying: &r,
tarreader: tarReader,
}

return ret, nil
}

func (c *DockerContainer) CopyFileToContainer(ctx context.Context, hostFilePath string, containerFilePath string, fileMode int64) error {
fileContent, err := ioutil.ReadFile(hostFilePath)
if err != nil {
Expand Down
74 changes: 74 additions & 0 deletions docker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1455,6 +1455,80 @@ func TestDockerContainerCopyFileToContainer(t *testing.T) {
}
}

func TestDockerContainerCopyFileFromContainer(t *testing.T) {
fileContent, err := ioutil.ReadFile("./testresources/hello.sh")
if err != nil {
t.Fatal(err)
}
ctx := context.Background()

nginxC, err := GenericContainer(ctx, GenericContainerRequest{
ContainerRequest: ContainerRequest{
Image: "nginx:1.17.6",
ExposedPorts: []string{"80/tcp"},
WaitingFor: wait.ForListeningPort("80/tcp"),
},
Started: true,
})
defer nginxC.Terminate(ctx)

copiedFileName := "hello_copy.sh"
nginxC.CopyFileToContainer(ctx, "./testresources/hello.sh", "/"+copiedFileName, 700)
c, err := nginxC.Exec(ctx, []string{"bash", copiedFileName})
if err != nil {
t.Fatal(err)
}
if c != 0 {
t.Fatalf("File %s should exist, expected return code 0, got %v", copiedFileName, c)
}

reader, err := nginxC.CopyFileFromContainer(ctx, "/"+copiedFileName)
if err != nil {
t.Fatal(err)
}

fileContentFromContainer, err := ioutil.ReadAll(reader)
if err != nil {
t.Fatal(err)
}
assert.Equal(t, fileContent, fileContentFromContainer)
}

func TestDockerContainerCopyEmptyFileFromContainer(t *testing.T) {
ctx := context.Background()

nginxC, err := GenericContainer(ctx, GenericContainerRequest{
ContainerRequest: ContainerRequest{
Image: "nginx:1.17.6",
ExposedPorts: []string{"80/tcp"},
WaitingFor: wait.ForListeningPort("80/tcp"),
},
Started: true,
})
defer nginxC.Terminate(ctx)

copiedFileName := "hello_copy.sh"
nginxC.CopyFileToContainer(ctx, "./testresources/empty.sh", "/"+copiedFileName, 700)
c, err := nginxC.Exec(ctx, []string{"bash", copiedFileName})
if err != nil {
t.Fatal(err)
}
if c != 0 {
t.Fatalf("File %s should exist, expected return code 0, got %v", copiedFileName, c)
}

reader, err := nginxC.CopyFileFromContainer(ctx, "/"+copiedFileName)
if err != nil {
t.Fatal(err)
}

fileContentFromContainer, err := ioutil.ReadAll(reader)
if err != nil {
t.Fatal(err)
}
assert.Empty(t, fileContentFromContainer)
}

func TestContainerWithReaperNetwork(t *testing.T) {
ctx := context.Background()
networks := []string{
Expand Down
Empty file added testresources/empty.sh
Empty file.

0 comments on commit 19e857f

Please sign in to comment.