save.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. package image
  2. import (
  3. "errors"
  4. "io"
  5. "golang.org/x/net/context"
  6. "github.com/docker/docker/api/client"
  7. "github.com/docker/docker/cli"
  8. "github.com/spf13/cobra"
  9. )
  10. type saveOptions struct {
  11. images []string
  12. output string
  13. }
  14. // NewSaveCommand creates a new `docker save` command
  15. func NewSaveCommand(dockerCli *client.DockerCli) *cobra.Command {
  16. var opts saveOptions
  17. cmd := &cobra.Command{
  18. Use: "save [OPTIONS] IMAGE [IMAGE...]",
  19. Short: "Save one or more images to a tar archive (streamed to STDOUT by default)",
  20. Args: cli.RequiresMinArgs(1),
  21. RunE: func(cmd *cobra.Command, args []string) error {
  22. opts.images = args
  23. return runSave(dockerCli, opts)
  24. },
  25. }
  26. flags := cmd.Flags()
  27. flags.StringVarP(&opts.output, "output", "o", "", "Write to a file, instead of STDOUT")
  28. return cmd
  29. }
  30. func runSave(dockerCli *client.DockerCli, opts saveOptions) error {
  31. if opts.output == "" && dockerCli.IsTerminalOut() {
  32. return errors.New("Cowardly refusing to save to a terminal. Use the -o flag or redirect.")
  33. }
  34. responseBody, err := dockerCli.Client().ImageSave(context.Background(), opts.images)
  35. if err != nil {
  36. return err
  37. }
  38. defer responseBody.Close()
  39. if opts.output == "" {
  40. _, err := io.Copy(dockerCli.Out(), responseBody)
  41. return err
  42. }
  43. return client.CopyToFile(opts.output, responseBody)
  44. }