diff --git a/api/client/commands.go b/api/client/commands.go index a3e0f06d07..26ebf2db21 100644 --- a/api/client/commands.go +++ b/api/client/commands.go @@ -9,7 +9,6 @@ func (cli *DockerCli) Command(name string) func(...string) error { "events": cli.CmdEvents, "exec": cli.CmdExec, "images": cli.CmdImages, - "import": cli.CmdImport, "info": cli.CmdInfo, "inspect": cli.CmdInspect, "kill": cli.CmdKill, diff --git a/api/client/container/diff.go b/api/client/container/diff.go index 053b9e1647..2eb860b390 100644 --- a/api/client/container/diff.go +++ b/api/client/container/diff.go @@ -34,6 +34,9 @@ func NewDiffCommand(dockerCli *client.DockerCli) *cobra.Command { } func runDiff(dockerCli *client.DockerCli, opts *diffOptions) error { + if opts.container == "" { + return fmt.Errorf("Container name cannot be empty") + } ctx := context.Background() changes, err := dockerCli.Client().ContainerDiff(ctx, opts.container) diff --git a/api/client/image/import.go b/api/client/image/import.go new file mode 100644 index 0000000000..2a7c37b905 --- /dev/null +++ b/api/client/image/import.go @@ -0,0 +1,86 @@ +package image + +import ( + "io" + "os" + + "golang.org/x/net/context" + + "github.com/docker/docker/api/client" + "github.com/docker/docker/cli" + "github.com/docker/docker/pkg/jsonmessage" + "github.com/docker/docker/pkg/urlutil" + "github.com/docker/engine-api/types" + "github.com/spf13/cobra" +) + +type importOptions struct { + source string + reference string + changes []string + message string +} + +// NewImportCommand creates a new `docker import` command +func NewImportCommand(dockerCli *client.DockerCli) *cobra.Command { + var opts importOptions + + cmd := &cobra.Command{ + Use: "import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]", + Short: "Import the contents from a tarball to create a filesystem image", + Args: cli.RequiresMinArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + opts.source = args[0] + if len(args) > 1 { + opts.reference = args[1] + } + return runImport(dockerCli, opts) + }, + } + + flags := cmd.Flags() + + flags.StringSliceVarP(&opts.changes, "change", "c", []string{}, "Apply Dockerfile instruction to the created image") + flags.StringVarP(&opts.message, "message", "m", "", "Set commit message for imported image") + + return cmd +} + +func runImport(dockerCli *client.DockerCli, opts importOptions) error { + var ( + in io.Reader + srcName = opts.source + ) + + if opts.source == "-" { + in = dockerCli.In() + } else if !urlutil.IsURL(opts.source) { + srcName = "-" + file, err := os.Open(opts.source) + if err != nil { + return err + } + defer file.Close() + in = file + } + + source := types.ImageImportSource{ + Source: in, + SourceName: srcName, + } + + options := types.ImageImportOptions{ + Message: opts.message, + Changes: opts.changes, + } + + clnt := dockerCli.Client() + + responseBody, err := clnt.ImageImport(context.Background(), source, opts.reference, options) + if err != nil { + return err + } + defer responseBody.Close() + + return jsonmessage.DisplayJSONMessagesStream(responseBody, dockerCli.Out(), dockerCli.OutFd(), dockerCli.IsTerminalOut(), nil) +} diff --git a/api/client/import.go b/api/client/import.go deleted file mode 100644 index 4948191049..0000000000 --- a/api/client/import.go +++ /dev/null @@ -1,68 +0,0 @@ -package client - -import ( - "io" - "os" - - "golang.org/x/net/context" - - Cli "github.com/docker/docker/cli" - "github.com/docker/docker/opts" - "github.com/docker/docker/pkg/jsonmessage" - flag "github.com/docker/docker/pkg/mflag" - "github.com/docker/docker/pkg/urlutil" - "github.com/docker/engine-api/types" -) - -// CmdImport creates an empty filesystem image, imports the contents of the tarball into the image, and optionally tags the image. -// -// The URL argument is the address of a tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz) file or a path to local file relative to docker client. If the URL is '-', then the tar file is read from STDIN. -// -// Usage: docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]] -func (cli *DockerCli) CmdImport(args ...string) error { - cmd := Cli.Subcmd("import", []string{"file|URL|- [REPOSITORY[:TAG]]"}, Cli.DockerCommands["import"].Description, true) - flChanges := opts.NewListOpts(nil) - cmd.Var(&flChanges, []string{"c", "-change"}, "Apply Dockerfile instruction to the created image") - message := cmd.String([]string{"m", "-message"}, "", "Set commit message for imported image") - cmd.Require(flag.Min, 1) - - cmd.ParseFlags(args, true) - - var ( - in io.Reader - src = cmd.Arg(0) - srcName = src - ref = cmd.Arg(1) - changes = flChanges.GetAll() - ) - - if src == "-" { - in = cli.in - } else if !urlutil.IsURL(src) { - srcName = "-" - file, err := os.Open(src) - if err != nil { - return err - } - defer file.Close() - in = file - } - - source := types.ImageImportSource{ - Source: in, - SourceName: srcName, - } - - options := types.ImageImportOptions{ - Message: *message, - Changes: changes, - } - - responseBody, err := cli.client.ImageImport(context.Background(), source, ref, options) - if err != nil { - return err - } - defer responseBody.Close() - - return jsonmessage.DisplayJSONMessagesStream(responseBody, cli.out, cli.outFd, cli.isTerminalOut, nil) -} diff --git a/cli/cobraadaptor/adaptor.go b/cli/cobraadaptor/adaptor.go index f371ce4ed7..f80ae9a0f1 100644 --- a/cli/cobraadaptor/adaptor.go +++ b/cli/cobraadaptor/adaptor.go @@ -51,6 +51,7 @@ func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor { image.NewHistoryCommand(dockerCli), image.NewRemoveCommand(dockerCli), image.NewSearchCommand(dockerCli), + image.NewImportCommand(dockerCli), network.NewNetworkCommand(dockerCli), volume.NewVolumeCommand(dockerCli), ) diff --git a/cli/usage.go b/cli/usage.go index 787a87aaee..987bbdc787 100644 --- a/cli/usage.go +++ b/cli/usage.go @@ -14,7 +14,6 @@ var DockerCommandUsage = []Command{ {"events", "Get real time events from the server"}, {"exec", "Run a command in a running container"}, {"images", "List images"}, - {"import", "Import the contents from a tarball to create a filesystem image"}, {"info", "Display system-wide information"}, {"inspect", "Return low-level information on a container or image"}, {"kill", "Kill a running container"}, diff --git a/hack/vendor.sh b/hack/vendor.sh index f581904cef..570d187110 100755 --- a/hack/vendor.sh +++ b/hack/vendor.sh @@ -139,7 +139,7 @@ clone git github.com/docker/docker-credential-helpers v0.3.0 clone git github.com/docker/containerd 57b7c3da915ebe943bd304c00890959b191e5264 # cli -clone git github.com/spf13/cobra acf60156558542e78c6f3695f74b0f871614ff55 https://github.com/dnephin/cobra.git +clone git github.com/spf13/cobra 75205f23b3ea70dc7ae5e900d074e010c23c37e9 https://github.com/dnephin/cobra.git clone git github.com/spf13/pflag cb88ea77998c3f024757528e3305022ab50b43be clone git github.com/inconshreveable/mousetrap 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 diff --git a/integration-cli/docker_cli_diff_test.go b/integration-cli/docker_cli_diff_test.go index e046740783..957617c97d 100644 --- a/integration-cli/docker_cli_diff_test.go +++ b/integration-cli/docker_cli_diff_test.go @@ -83,5 +83,5 @@ func (s *DockerSuite) TestDiffEnsureDefaultDevs(c *check.C) { func (s *DockerSuite) TestDiffEmptyArgClientError(c *check.C) { out, _, err := dockerCmdWithError("diff", "") c.Assert(err, checker.NotNil) - c.Assert(strings.TrimSpace(out), checker.Contains, "\"docker diff\" requires exactly 1 argument(s).") + c.Assert(strings.TrimSpace(out), checker.Contains, "Container name cannot be empty") } diff --git a/vendor/src/github.com/spf13/cobra/command.go b/vendor/src/github.com/spf13/cobra/command.go index f516af9b0e..d9f85c14ef 100644 --- a/vendor/src/github.com/spf13/cobra/command.go +++ b/vendor/src/github.com/spf13/cobra/command.go @@ -123,6 +123,9 @@ type Command struct { DisableSuggestions bool // If displaying suggestions, allows to set the minimum levenshtein distance to display, must be > 0 SuggestionsMinimumDistance int + + // Disable the flag parsing. If this is true all flags will be passed to the command as arguments. + DisableFlagParsing bool } // os.Args[1:] by default, if desired, can be overridden @@ -556,12 +559,16 @@ func (c *Command) execute(a []string) (err error) { return flag.ErrHelp } - if err := c.ValidateArgs(a); err != nil { - return err + c.preRun() + + argWoFlags := c.Flags().Args() + if c.DisableFlagParsing { + argWoFlags = a } - c.preRun() - argWoFlags := c.Flags().Args() + if err := c.ValidateArgs(argWoFlags); err != nil { + return err + } for p := c; p != nil; p = p.Parent() { if p.PersistentPreRunE != nil { @@ -702,7 +709,7 @@ func (c *Command) ValidateArgs(args []string) error { if c.Args == nil { return nil } - return c.Args(c, stripFlags(args, c)) + return c.Args(c, args) } func (c *Command) initHelpFlag() { @@ -1200,6 +1207,9 @@ func (c *Command) persistentFlag(name string) (flag *flag.Flag) { // ParseFlags parses persistent flag tree & local flags func (c *Command) ParseFlags(args []string) (err error) { + if c.DisableFlagParsing { + return nil + } c.mergePersistentFlags() err = c.Flags().Parse(args) return