diff --git a/api/client/commands.go b/api/client/commands.go index 3e72da50a6..d55ccc7311 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -10,7 +10,6 @@ func (cli *DockerCli) Command(name string) func(...string) error { "diff": cli.CmdDiff, "events": cli.CmdEvents, "exec": cli.CmdExec, - "export": cli.CmdExport, "history": cli.CmdHistory, "images": cli.CmdImages, "import": cli.CmdImport, diff --git a/api/client/container/export.go b/api/client/container/export.go new file mode 100644 index 0000000000..8dbea9f7b0 --- /dev/null +++ b/api/client/container/export.go @@ -0,0 +1,59 @@ +package container + +import ( + "errors" + "io" + + "golang.org/x/net/context" + + "github.com/docker/docker/api/client" + "github.com/docker/docker/cli" + "github.com/spf13/cobra" +) + +type exportOptions struct { + container string + output string +} + +// NewExportCommand creates a new `docker export` command +func NewExportCommand(dockerCli *client.DockerCli) *cobra.Command { + var opts exportOptions + + cmd := &cobra.Command{ + Use: "export [OPTIONS] CONTAINER", + Short: "Export a container's filesystem as a tar archive", + Args: cli.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + opts.container = args[0] + return runExport(dockerCli, opts) + }, + } + + flags := cmd.Flags() + + flags.StringVarP(&opts.output, "output", "o", "", "Write to a file, instead of STDOUT") + + return cmd +} + +func runExport(dockerCli *client.DockerCli, opts exportOptions) error { + if opts.output == "" && dockerCli.IsTerminalOut() { + return errors.New("Cowardly refusing to save to a terminal. Use the -o flag or redirect.") + } + + clnt := dockerCli.Client() + + responseBody, err := clnt.ContainerExport(context.Background(), opts.container) + if err != nil { + return err + } + defer responseBody.Close() + + if opts.output == "" { + _, err := io.Copy(dockerCli.Out(), responseBody) + return err + } + + return client.CopyToFile(opts.output, responseBody) +} diff --git a/api/client/export.go b/api/client/export.go deleted file mode 100644 index 7b7bb3f2c7..0000000000 --- a/api/client/export.go +++ /dev/null @@ -1,41 +0,0 @@ -package client - -import ( - "errors" - "io" - - "golang.org/x/net/context" - - Cli "github.com/docker/docker/cli" - flag "github.com/docker/docker/pkg/mflag" -) - -// CmdExport exports a filesystem as a tar archive. -// -// The tar archive is streamed to STDOUT by default or written to a file. -// -// Usage: docker export [OPTIONS] CONTAINER -func (cli *DockerCli) CmdExport(args ...string) error { - cmd := Cli.Subcmd("export", []string{"CONTAINER"}, Cli.DockerCommands["export"].Description, true) - outfile := cmd.String([]string{"o", "-output"}, "", "Write to a file, instead of STDOUT") - cmd.Require(flag.Exact, 1) - - cmd.ParseFlags(args, true) - - if *outfile == "" && cli.isTerminalOut { - return errors.New("Cowardly refusing to save to a terminal. Use the -o flag or redirect.") - } - - responseBody, err := cli.client.ContainerExport(context.Background(), cmd.Arg(0)) - if err != nil { - return err - } - defer responseBody.Close() - - if *outfile == "" { - _, err := io.Copy(cli.out, responseBody) - return err - } - - return copyToFile(*outfile, responseBody) -} diff --git a/api/client/save.go b/api/client/save.go index 4aabf1bd5d..dfbce203be 100644 --- a/api/client/save.go +++ b/api/client/save.go @@ -37,6 +37,6 @@ func (cli *DockerCli) CmdSave(args ...string) error { return err } - return copyToFile(*outfile, responseBody) + return CopyToFile(*outfile, responseBody) } diff --git a/api/client/utils.go b/api/client/utils.go index 5927499dd7..deaf846b1c 100644 --- a/api/client/utils.go +++ b/api/client/utils.go @@ -162,7 +162,8 @@ func (cli *DockerCli) GetTtySize() (int, int) { return int(ws.Height), int(ws.Width) } -func copyToFile(outfile string, r io.Reader) error { +// CopyToFile writes the content of the reader to the specifed file +func CopyToFile(outfile string, r io.Reader) error { tmpFile, err := ioutil.TempFile(filepath.Dir(outfile), ".docker_temp_") if err != nil { return err diff --git a/cli/cobraadaptor/adaptor.go b/cli/cobraadaptor/adaptor.go index 719eaf4e1d..a838f28170 100644 --- a/cli/cobraadaptor/adaptor.go +++ b/cli/cobraadaptor/adaptor.go @@ -34,6 +34,7 @@ func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor { rootCmd.SetOutput(stdout) rootCmd.AddCommand( container.NewCreateCommand(dockerCli), + container.NewExportCommand(dockerCli), container.NewRunCommand(dockerCli), image.NewSearchCommand(dockerCli), volume.NewVolumeCommand(dockerCli), diff --git a/cli/usage.go b/cli/usage.go index d6c97c32f5..4a22afaad1 100644 --- a/cli/usage.go +++ b/cli/usage.go @@ -15,7 +15,6 @@ var DockerCommandUsage = []Command{ {"diff", "Inspect changes on a container's filesystem"}, {"events", "Get real time events from the server"}, {"exec", "Run a command in a running container"}, - {"export", "Export a container's filesystem as a tar archive"}, {"history", "Show the history of an image"}, {"images", "List images"}, {"import", "Import the contents from a tarball to create a filesystem image"},