Skip to content

Commit

Permalink
Merge pull request moby#11430 from jfrazelle/export_outputflag
Browse files Browse the repository at this point in the history
Modified `docker export` to allow an --output flag
  • Loading branch information
tiborvass committed Mar 18, 2015
2 parents 474f58e + 6a313e8 commit 8ec4e69
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 10 deletions.
32 changes: 29 additions & 3 deletions api/client/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -1899,14 +1899,40 @@ func (cli *DockerCli) CmdEvents(args ...string) error {
}

func (cli *DockerCli) CmdExport(args ...string) error {
cmd := cli.Subcmd("export", "CONTAINER", "Export the contents of a filesystem as a tar archive to STDOUT", true)
cmd := cli.Subcmd("export", "CONTAINER", "Export a filesystem as a tar archive (streamed to STDOUT by default)", true)
outfile := cmd.String([]string{"o", "-output"}, "", "Write to a file, instead of STDOUT")
cmd.Require(flag.Exact, 1)

utils.ParseFlags(cmd, args, true)

if err := cli.stream("GET", "/containers/"+cmd.Arg(0)+"/export", nil, cli.out, nil); err != nil {
return err
var (
output io.Writer = cli.out
err error
)
if *outfile != "" {
output, err = os.Create(*outfile)
if err != nil {
return err
}
} else if cli.isTerminalOut {
return errors.New("Cowardly refusing to save to a terminal. Use the -o flag or redirect.")
}

if len(cmd.Args()) == 1 {
image := cmd.Arg(0)
if err := cli.stream("GET", "/containers/"+image+"/export", nil, output, nil); err != nil {
return err
}
} else {
v := url.Values{}
for _, arg := range cmd.Args() {
v.Add("names", arg)
}
if err := cli.stream("GET", "/containers/get?"+v.Encode(), nil, output, nil); err != nil {
return err
}
}

return nil
}

Expand Down
16 changes: 12 additions & 4 deletions docs/man/docker-export.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,24 @@ Export the contents of a container's filesystem using the full or shortened
container ID or container name. The output is exported to STDOUT and can be
redirected to a tar file.

Stream to a file instead of STDOUT by using **-o**.

# OPTIONS
**--help**
Print usage statement
**-o**, **--output**=""
Write to a file, instead of STDOUT

# EXAMPLES
Export the contents of the container called angry_bell to a tar file
called test.tar:
called angry_bell.tar:

# docker export angry_bell > test.tar
# ls *.tar
test.tar
# docker export angry_bell > angry_bell.tar
# docker export --output=angry_bell-latest.tar angry_bell
# ls -sh angry_bell.tar
321M angry_bell.tar
# ls -sh angry_bell-latest.tar
321M angry_bell-latest.tar

# See also
**docker-import(1)** to create an empty filesystem image
Expand All @@ -34,3 +41,4 @@ and import the contents of the tarball into it, then optionally tag it.
April 2014, Originally compiled by William Henry (whenry at redhat dot com)
based on docker.com source material and internal work.
June 2014, updated by Sven Dowideit <[email protected]>
Janurary 2015, updated by Joseph Kern (josephakern at gmail dot com)
14 changes: 11 additions & 3 deletions docs/sources/reference/commandline/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -1068,14 +1068,22 @@ This will create a new Bash session in the container `ubuntu_bash`.

## export

Usage: docker export CONTAINER
Usage: docker export [OPTIONS] CONTAINER

Export the contents of a filesystem as a tar archive to STDOUT
Export the contents of a filesystem to a tar archive (streamed to STDOUT by default)

For example:
-o, --output="" Write to a file, instead of STDOUT

Produces a tarred repository to the standard output stream.

For example:

$ sudo docker export red_panda > latest.tar

Or

$ sudo docker export --output="latest.tar" red_panda

> **Note:**
> `docker export` does not export the contents of volumes associated with the
> container. If a volume is mounted on top of an existing directory in the
Expand Down
50 changes: 50 additions & 0 deletions integration-cli/docker_cli_export_import_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"os"
"os/exec"
"strings"
"testing"
Expand Down Expand Up @@ -47,3 +48,52 @@ func TestExportContainerAndImportImage(t *testing.T) {
logDone("export - export a container")
logDone("import - import an image")
}

// Used to test output flag in the export command
func TestExportContainerWithOutputAndImportImage(t *testing.T) {
runCmd := exec.Command(dockerBinary, "run", "-d", "busybox", "true")
out, _, err := runCommandWithOutput(runCmd)
if err != nil {
t.Fatal("failed to create a container", out, err)
}

cleanedContainerID := stripTrailingCharacters(out)

inspectCmd := exec.Command(dockerBinary, "inspect", cleanedContainerID)
out, _, err = runCommandWithOutput(inspectCmd)
if err != nil {
t.Fatalf("output should've been a container id: %s %s ", cleanedContainerID, err)
}

exportCmd := exec.Command(dockerBinary, "export", "--output=testexp.tar", cleanedContainerID)
if out, _, err = runCommandWithOutput(exportCmd); err != nil {
t.Fatalf("failed to export container: %s, %v", out, err)
}

out, _, err = runCommandWithOutput(exec.Command("cat", "testexp.tar"))
if err != nil {
t.Fatal(out, err)
}

importCmd := exec.Command(dockerBinary, "import", "-", "repo/testexp:v1")
importCmd.Stdin = strings.NewReader(out)
out, _, err = runCommandWithOutput(importCmd)
if err != nil {
t.Fatalf("failed to import image: %s, %v", out, err)
}

cleanedImageID := stripTrailingCharacters(out)

inspectCmd = exec.Command(dockerBinary, "inspect", cleanedImageID)
if out, _, err = runCommandWithOutput(inspectCmd); err != nil {
t.Fatalf("output should've been an image id: %s, %v", out, err)
}

deleteContainer(cleanedContainerID)
deleteImages("repo/testexp:v1")

os.Remove("/tmp/testexp.tar")

logDone("export - export a container with output flag")
logDone("import - import an image with output flag")
}

0 comments on commit 8ec4e69

Please sign in to comment.