Merge pull request #23309 from yongtang/23211-spf13-cobra-commit
Use spf13/cobra for docker commit
This commit is contained in:
commit
e6c49bf71b
7 changed files with 97 additions and 67 deletions
|
@ -3,7 +3,6 @@ package client
|
|||
// Command returns a cli command handler if one exists
|
||||
func (cli *DockerCli) Command(name string) func(...string) error {
|
||||
return map[string]func(...string) error{
|
||||
"commit": cli.CmdCommit,
|
||||
"cp": cli.CmdCp,
|
||||
"exec": cli.CmdExec,
|
||||
"info": cli.CmdInfo,
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
Cli "github.com/docker/docker/cli"
|
||||
"github.com/docker/docker/opts"
|
||||
flag "github.com/docker/docker/pkg/mflag"
|
||||
"github.com/docker/engine-api/types"
|
||||
"github.com/docker/engine-api/types/container"
|
||||
)
|
||||
|
||||
// CmdCommit creates a new image from a container's changes.
|
||||
//
|
||||
// Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
|
||||
func (cli *DockerCli) CmdCommit(args ...string) error {
|
||||
cmd := Cli.Subcmd("commit", []string{"CONTAINER [REPOSITORY[:TAG]]"}, Cli.DockerCommands["commit"].Description, true)
|
||||
flPause := cmd.Bool([]string{"p", "-pause"}, true, "Pause container during commit")
|
||||
flComment := cmd.String([]string{"m", "-message"}, "", "Commit message")
|
||||
flAuthor := cmd.String([]string{"a", "-author"}, "", "Author (e.g., \"John Hannibal Smith <hannibal@a-team.com>\")")
|
||||
flChanges := opts.NewListOpts(nil)
|
||||
cmd.Var(&flChanges, []string{"c", "-change"}, "Apply Dockerfile instruction to the created image")
|
||||
// FIXME: --run is deprecated, it will be replaced with inline Dockerfile commands.
|
||||
flConfig := cmd.String([]string{"#-run"}, "", "This option is deprecated and will be removed in a future version in favor of inline Dockerfile-compatible commands")
|
||||
cmd.Require(flag.Max, 2)
|
||||
cmd.Require(flag.Min, 1)
|
||||
|
||||
cmd.ParseFlags(args, true)
|
||||
|
||||
var (
|
||||
name = cmd.Arg(0)
|
||||
reference = cmd.Arg(1)
|
||||
)
|
||||
|
||||
var config *container.Config
|
||||
if *flConfig != "" {
|
||||
config = &container.Config{}
|
||||
if err := json.Unmarshal([]byte(*flConfig), config); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
options := types.ContainerCommitOptions{
|
||||
Reference: reference,
|
||||
Comment: *flComment,
|
||||
Author: *flAuthor,
|
||||
Changes: flChanges.GetAll(),
|
||||
Pause: *flPause,
|
||||
Config: config,
|
||||
}
|
||||
|
||||
response, err := cli.client.ContainerCommit(context.Background(), name, options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Fprintln(cli.out, response.ID)
|
||||
return nil
|
||||
}
|
93
api/client/container/commit.go
Normal file
93
api/client/container/commit.go
Normal file
|
@ -0,0 +1,93 @@
|
|||
package container
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/docker/docker/api/client"
|
||||
"github.com/docker/docker/cli"
|
||||
dockeropts "github.com/docker/docker/opts"
|
||||
"github.com/docker/engine-api/types"
|
||||
containertypes "github.com/docker/engine-api/types/container"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type commitOptions struct {
|
||||
container string
|
||||
reference string
|
||||
|
||||
pause bool
|
||||
comment string
|
||||
author string
|
||||
changes dockeropts.ListOpts
|
||||
config string
|
||||
}
|
||||
|
||||
// NewCommitCommand creats a new cobra.Command for `docker commit`
|
||||
func NewCommitCommand(dockerCli *client.DockerCli) *cobra.Command {
|
||||
var opts commitOptions
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]",
|
||||
Short: "Create a new image from a container's changes",
|
||||
Args: cli.RequiresRangeArgs(1, 2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
opts.container = args[0]
|
||||
if len(args) > 1 {
|
||||
opts.reference = args[1]
|
||||
}
|
||||
return runCommit(dockerCli, &opts)
|
||||
},
|
||||
}
|
||||
cmd.SetFlagErrorFunc(flagErrorFunc)
|
||||
|
||||
flags := cmd.Flags()
|
||||
flags.SetInterspersed(false)
|
||||
|
||||
flags.BoolVarP(&opts.pause, "pause", "p", true, "Pause container during commit")
|
||||
flags.StringVarP(&opts.comment, "message", "m", "", "Commit message")
|
||||
flags.StringVarP(&opts.author, "author", "a", "", "Author (e.g., \"John Hannibal Smith <hannibal@a-team.com>\")")
|
||||
|
||||
opts.changes = dockeropts.NewListOpts(nil)
|
||||
flags.VarP(&opts.changes, "change", "c", "Apply Dockerfile instruction to the created image")
|
||||
|
||||
// FIXME: --run is deprecated, it will be replaced with inline Dockerfile commands.
|
||||
flags.StringVar(&opts.config, "run", "", "This option is deprecated and will be removed in a future version in favor of inline Dockerfile-compatible commands")
|
||||
flags.MarkDeprecated("run", "it will be replaced with inline Dockerfile commands.")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func runCommit(dockerCli *client.DockerCli, opts *commitOptions) error {
|
||||
ctx := context.Background()
|
||||
|
||||
name := opts.container
|
||||
reference := opts.reference
|
||||
|
||||
var config *containertypes.Config
|
||||
if opts.config != "" {
|
||||
config = &containertypes.Config{}
|
||||
if err := json.Unmarshal([]byte(opts.config), config); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
options := types.ContainerCommitOptions{
|
||||
Reference: reference,
|
||||
Comment: opts.comment,
|
||||
Author: opts.author,
|
||||
Changes: opts.changes.GetAll(),
|
||||
Pause: opts.pause,
|
||||
Config: config,
|
||||
}
|
||||
|
||||
response, err := dockerCli.Client().ContainerCommit(ctx, name, options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Fprintln(dockerCli.Out(), response.ID)
|
||||
return nil
|
||||
}
|
|
@ -25,7 +25,7 @@ func NewPortCommand(dockerCli *client.DockerCli) *cobra.Command {
|
|||
cmd := &cobra.Command{
|
||||
Use: "port CONTAINER [PRIVATE_PORT[/PROTO]]",
|
||||
Short: "List port mappings or a specific mapping for the container",
|
||||
Args: cli.RequiresMinMaxArgs(1, 2),
|
||||
Args: cli.RequiresRangeArgs(1, 2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
opts.container = args[0]
|
||||
if len(args) > 1 {
|
||||
|
|
|
@ -36,6 +36,7 @@ func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor {
|
|||
rootCmd.SetOutput(stdout)
|
||||
rootCmd.AddCommand(
|
||||
container.NewAttachCommand(dockerCli),
|
||||
container.NewCommitCommand(dockerCli),
|
||||
container.NewCreateCommand(dockerCli),
|
||||
container.NewDiffCommand(dockerCli),
|
||||
container.NewExportCommand(dockerCli),
|
||||
|
|
|
@ -60,8 +60,8 @@ func RequiresMaxArgs(max int) cobra.PositionalArgs {
|
|||
}
|
||||
}
|
||||
|
||||
// RequiresMinMaxArgs returns an error if there is not at least min args and at most max args
|
||||
func RequiresMinMaxArgs(min int, max int) cobra.PositionalArgs {
|
||||
// RequiresRangeArgs returns an error if there is not at least min args and at most max args
|
||||
func RequiresRangeArgs(min int, max int) cobra.PositionalArgs {
|
||||
return func(cmd *cobra.Command, args []string) error {
|
||||
if len(args) >= min && len(args) <= max {
|
||||
return nil
|
||||
|
|
|
@ -8,7 +8,6 @@ type Command struct {
|
|||
|
||||
// DockerCommandUsage lists the top level docker commands and their short usage
|
||||
var DockerCommandUsage = []Command{
|
||||
{"commit", "Create a new image from a container's changes"},
|
||||
{"cp", "Copy files/folders between a container and the local filesystem"},
|
||||
{"exec", "Run a command in a running container"},
|
||||
{"info", "Display system-wide information"},
|
||||
|
|
Loading…
Reference in a new issue