Skip to content

Commit

Permalink
Modified docker export to allow an --output flag
Browse files Browse the repository at this point in the history
Copied code from CmdSave into CmdExport. This should work, not an expert in the API calls being made. But it does make more sense to have a consistent export/save flag.

Signed-off-by: Joseph Kern <[email protected]>

checkpoint before edits on the export functions

Signed-off-by: Joseph Kern <[email protected]>

Added an --output flag to docker export and created tests.

Signed-off-by: Joseph Kern <[email protected]>

White space cleanup.

Signed-off-by: Joseph Kern <[email protected]>

Docker-DCO-1.1-Signed-off-by: Joseph Kern <[email protected]> (github: jfrazelle)

checkpoint before edits on the export functions

Signed-off-by: Joseph Kern <[email protected]>

White space cleanup.

Signed-off-by: Joseph Kern <[email protected]>

Added text to reflect a new output option for the export command.

Signed-off-by: Joseph Kern <[email protected]>

Whitespace clean up

Signed-off-by: Joseph Kern <[email protected]>

Added man page documentation for the new --output flag in export

Signed-off-by: Joseph Kern <[email protected]>
  • Loading branch information
josephkern authored and jessfraz committed Mar 17, 2015
1 parent f4f10cf commit 5ff122f
Show file tree
Hide file tree
Showing 4 changed files with 100 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 @@ -1872,14 +1872,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 @@ -1066,14 +1066,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
48 changes: 48 additions & 0 deletions integration-cli/docker_cli_export_import_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package main

import (
"fmt"
"os"
"os/exec"
"strings"
"testing"
Expand Down Expand Up @@ -47,3 +49,49 @@ 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)
}

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

importCmdFinal := `cat /tmp/testexp.tar | docker import - repo/testexp:v1`
importCmd := exec.Command(importCmdFinal)
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 5ff122f

Please sign in to comment.