github.1git.de/docker/cli@v26.1.3+incompatible/cli/command/context/export.go (about) 1 package context 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 "os" 8 9 "github.com/docker/cli/cli" 10 "github.com/docker/cli/cli/command" 11 "github.com/docker/cli/cli/context/store" 12 "github.com/spf13/cobra" 13 ) 14 15 // ExportOptions are the options used for exporting a context 16 type ExportOptions struct { 17 ContextName string 18 Dest string 19 } 20 21 func newExportCommand(dockerCli command.Cli) *cobra.Command { 22 return &cobra.Command{ 23 Use: "export [OPTIONS] CONTEXT [FILE|-]", 24 Short: "Export a context to a tar archive FILE or a tar stream on STDOUT.", 25 Args: cli.RequiresRangeArgs(1, 2), 26 RunE: func(cmd *cobra.Command, args []string) error { 27 opts := &ExportOptions{ 28 ContextName: args[0], 29 } 30 if len(args) == 2 { 31 opts.Dest = args[1] 32 } else { 33 opts.Dest = opts.ContextName + ".dockercontext" 34 } 35 return RunExport(dockerCli, opts) 36 }, 37 } 38 } 39 40 func writeTo(dockerCli command.Cli, reader io.Reader, dest string) error { 41 var writer io.Writer 42 var printDest bool 43 if dest == "-" { 44 if dockerCli.Out().IsTerminal() { 45 return errors.New("cowardly refusing to export to a terminal, please specify a file path") 46 } 47 writer = dockerCli.Out() 48 } else { 49 f, err := os.OpenFile(dest, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0o600) 50 if err != nil { 51 return err 52 } 53 defer f.Close() 54 writer = f 55 printDest = true 56 } 57 if _, err := io.Copy(writer, reader); err != nil { 58 return err 59 } 60 if printDest { 61 fmt.Fprintf(dockerCli.Err(), "Written file %q\n", dest) 62 } 63 return nil 64 } 65 66 // RunExport exports a Docker context 67 func RunExport(dockerCli command.Cli, opts *ExportOptions) error { 68 if err := store.ValidateContextName(opts.ContextName); err != nil && opts.ContextName != command.DefaultContextName { 69 return err 70 } 71 reader := store.Export(opts.ContextName, dockerCli.ContextStore()) 72 defer reader.Close() 73 return writeTo(dockerCli, reader, opts.Dest) 74 }