Merge pull request #23269 from vdemeester/migrate-import-to-cobra

Use spf13/cobra for docker import
This commit is contained in:
Sebastiaan van Stijn 2016-06-07 13:07:30 +02:00
commit f061f556f2
9 changed files with 107 additions and 77 deletions

View file

@ -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,

View file

@ -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)

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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),
)

View file

@ -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"},

View file

@ -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

View file

@ -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")
}

View file

@ -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