github.com/xeptore/docker-cli@v20.10.14+incompatible/cli/command/image/save.go (about) 1 package image 2 3 import ( 4 "context" 5 "io" 6 7 "github.com/docker/cli/cli" 8 "github.com/docker/cli/cli/command" 9 "github.com/pkg/errors" 10 "github.com/spf13/cobra" 11 ) 12 13 type saveOptions struct { 14 images []string 15 output string 16 } 17 18 // NewSaveCommand creates a new `docker save` command 19 func NewSaveCommand(dockerCli command.Cli) *cobra.Command { 20 var opts saveOptions 21 22 cmd := &cobra.Command{ 23 Use: "save [OPTIONS] IMAGE [IMAGE...]", 24 Short: "Save one or more images to a tar archive (streamed to STDOUT by default)", 25 Args: cli.RequiresMinArgs(1), 26 RunE: func(cmd *cobra.Command, args []string) error { 27 opts.images = args 28 return RunSave(dockerCli, opts) 29 }, 30 } 31 32 flags := cmd.Flags() 33 34 flags.StringVarP(&opts.output, "output", "o", "", "Write to a file, instead of STDOUT") 35 36 return cmd 37 } 38 39 // RunSave performs a save against the engine based on the specified options 40 func RunSave(dockerCli command.Cli, opts saveOptions) error { 41 if opts.output == "" && dockerCli.Out().IsTerminal() { 42 return errors.New("cowardly refusing to save to a terminal. Use the -o flag or redirect") 43 } 44 45 if err := command.ValidateOutputPath(opts.output); err != nil { 46 return errors.Wrap(err, "failed to save image") 47 } 48 49 responseBody, err := dockerCli.Client().ImageSave(context.Background(), opts.images) 50 if err != nil { 51 return err 52 } 53 defer responseBody.Close() 54 55 if opts.output == "" { 56 _, err := io.Copy(dockerCli.Out(), responseBody) 57 return err 58 } 59 60 return command.CopyToFile(opts.output, responseBody) 61 }