Skip to content
This repository has been archived by the owner on Oct 30, 2018. It is now read-only.

Commit

Permalink
Stream docker export directly to consumer
Browse files Browse the repository at this point in the history
Rather than queueing up into a `bytes.Buffer`.

In my test case (building kube master image) this reduces Maximum RSS (as
measured by time(1)) compared with the previous patch from 2.8G to 110M. The
tar output case goes from 2.1G to 110M also. Overall allocations are ~715M in
both cases.

Signed-off-by: Ian Campbell <ijc@docker.com>
  • Loading branch information
Ian Campbell committed Dec 6, 2017
1 parent 9f44acf commit 3045a80
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 14 deletions.
16 changes: 4 additions & 12 deletions src/moby/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package moby
// and also using the Docker API not shelling out

import (
"bytes"
"errors"
"fmt"
"io"
Expand Down Expand Up @@ -81,25 +80,18 @@ func dockerCreate(image string) (string, error) {
return respBody.ID, nil
}

func dockerExport(container string) ([]byte, error) {
func dockerExport(container string) (io.ReadCloser, error) {
log.Debugf("docker export: %s", container)
cli, err := dockerClient()
if err != nil {
return []byte{}, errors.New("could not initialize Docker API client")
return nil, errors.New("could not initialize Docker API client")
}
responseBody, err := cli.ContainerExport(context.Background(), container)
if err != nil {
return []byte{}, err
}
defer responseBody.Close()

output := bytes.NewBuffer(nil)
_, err = io.Copy(output, responseBody)
if err != nil {
return []byte{}, err
return nil, err
}

return output.Bytes(), nil
return responseBody, err
}

func dockerRm(container string) error {
Expand Down
5 changes: 3 additions & 2 deletions src/moby/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,16 @@ func ImageTar(ref *reference.Spec, prefix string, tw tarWriter, trust bool, pull
if err != nil {
return fmt.Errorf("Failed to docker export container from container %s: %v", container, err)
}
defer contents.Close()

err = dockerRm(container)
if err != nil {
return fmt.Errorf("Failed to docker rm container %s: %v", container, err)
}

// now we need to filter out some files from the resulting tar archive

r := bytes.NewReader(contents)
tr := tar.NewReader(r)
tr := tar.NewReader(contents)

for {
hdr, err := tr.Next()
Expand Down

0 comments on commit 3045a80

Please sign in to comment.