This replaces the visitAll recursive function with a test that verifies that the option is set for all commands and subcommands, so that it doesn't have to be modified at runtime. We currently still have to loop over all functions for the setValidateArgs call, but that can be looked at separately. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
71 lines
1.7 KiB
Go
71 lines
1.7 KiB
Go
package container
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
|
|
"github.com/docker/cli/cli"
|
|
"github.com/docker/cli/cli/command"
|
|
"github.com/docker/cli/cli/command/completion"
|
|
"github.com/moby/sys/atomicwriter"
|
|
"github.com/pkg/errors"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
type exportOptions struct {
|
|
container string
|
|
output string
|
|
}
|
|
|
|
// newExportCommand creates a new "docker container export" command.
|
|
func newExportCommand(dockerCLI command.Cli) *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(cmd.Context(), dockerCLI, opts)
|
|
},
|
|
Annotations: map[string]string{
|
|
"aliases": "docker container export, docker export",
|
|
},
|
|
ValidArgsFunction: completion.ContainerNames(dockerCLI, true),
|
|
DisableFlagsInUseLine: true,
|
|
}
|
|
|
|
flags := cmd.Flags()
|
|
|
|
flags.StringVarP(&opts.output, "output", "o", "", "Write to a file, instead of STDOUT")
|
|
|
|
return cmd
|
|
}
|
|
|
|
func runExport(ctx context.Context, dockerCLI command.Cli, opts exportOptions) error {
|
|
var output io.Writer
|
|
if opts.output == "" {
|
|
if dockerCLI.Out().IsTerminal() {
|
|
return errors.New("cowardly refusing to save to a terminal. Use the -o flag or redirect")
|
|
}
|
|
output = dockerCLI.Out()
|
|
} else {
|
|
writer, err := atomicwriter.New(opts.output, 0o600)
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to export container")
|
|
}
|
|
defer writer.Close()
|
|
output = writer
|
|
}
|
|
|
|
responseBody, err := dockerCLI.Client().ContainerExport(ctx, opts.container)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer responseBody.Close()
|
|
|
|
_, err = io.Copy(output, responseBody)
|
|
return err
|
|
}
|