This fix is part of the effort to convert commands to spf13/cobra #23211.
Thif fix coverted command `docker commit` to use spf13/cobra
NOTE: `RequiresMinMaxArgs()` has been renamed to `RequiresRangeArgs()`.
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
| ... | ... |
@@ -3,7 +3,6 @@ package client |
| 3 | 3 |
// Command returns a cli command handler if one exists |
| 4 | 4 |
func (cli *DockerCli) Command(name string) func(...string) error {
|
| 5 | 5 |
return map[string]func(...string) error{
|
| 6 |
- "commit": cli.CmdCommit, |
|
| 7 | 6 |
"cp": cli.CmdCp, |
| 8 | 7 |
"exec": cli.CmdExec, |
| 9 | 8 |
"info": cli.CmdInfo, |
| 10 | 9 |
deleted file mode 100644 |
| ... | ... |
@@ -1,62 +0,0 @@ |
| 1 |
-package client |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "encoding/json" |
|
| 5 |
- "fmt" |
|
| 6 |
- |
|
| 7 |
- "golang.org/x/net/context" |
|
| 8 |
- |
|
| 9 |
- Cli "github.com/docker/docker/cli" |
|
| 10 |
- "github.com/docker/docker/opts" |
|
| 11 |
- flag "github.com/docker/docker/pkg/mflag" |
|
| 12 |
- "github.com/docker/engine-api/types" |
|
| 13 |
- "github.com/docker/engine-api/types/container" |
|
| 14 |
-) |
|
| 15 |
- |
|
| 16 |
-// CmdCommit creates a new image from a container's changes. |
|
| 17 |
-// |
|
| 18 |
-// Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] |
|
| 19 |
-func (cli *DockerCli) CmdCommit(args ...string) error {
|
|
| 20 |
- cmd := Cli.Subcmd("commit", []string{"CONTAINER [REPOSITORY[:TAG]]"}, Cli.DockerCommands["commit"].Description, true)
|
|
| 21 |
- flPause := cmd.Bool([]string{"p", "-pause"}, true, "Pause container during commit")
|
|
| 22 |
- flComment := cmd.String([]string{"m", "-message"}, "", "Commit message")
|
|
| 23 |
- flAuthor := cmd.String([]string{"a", "-author"}, "", "Author (e.g., \"John Hannibal Smith <hannibal@a-team.com>\")")
|
|
| 24 |
- flChanges := opts.NewListOpts(nil) |
|
| 25 |
- cmd.Var(&flChanges, []string{"c", "-change"}, "Apply Dockerfile instruction to the created image")
|
|
| 26 |
- // FIXME: --run is deprecated, it will be replaced with inline Dockerfile commands. |
|
| 27 |
- flConfig := cmd.String([]string{"#-run"}, "", "This option is deprecated and will be removed in a future version in favor of inline Dockerfile-compatible commands")
|
|
| 28 |
- cmd.Require(flag.Max, 2) |
|
| 29 |
- cmd.Require(flag.Min, 1) |
|
| 30 |
- |
|
| 31 |
- cmd.ParseFlags(args, true) |
|
| 32 |
- |
|
| 33 |
- var ( |
|
| 34 |
- name = cmd.Arg(0) |
|
| 35 |
- reference = cmd.Arg(1) |
|
| 36 |
- ) |
|
| 37 |
- |
|
| 38 |
- var config *container.Config |
|
| 39 |
- if *flConfig != "" {
|
|
| 40 |
- config = &container.Config{}
|
|
| 41 |
- if err := json.Unmarshal([]byte(*flConfig), config); err != nil {
|
|
| 42 |
- return err |
|
| 43 |
- } |
|
| 44 |
- } |
|
| 45 |
- |
|
| 46 |
- options := types.ContainerCommitOptions{
|
|
| 47 |
- Reference: reference, |
|
| 48 |
- Comment: *flComment, |
|
| 49 |
- Author: *flAuthor, |
|
| 50 |
- Changes: flChanges.GetAll(), |
|
| 51 |
- Pause: *flPause, |
|
| 52 |
- Config: config, |
|
| 53 |
- } |
|
| 54 |
- |
|
| 55 |
- response, err := cli.client.ContainerCommit(context.Background(), name, options) |
|
| 56 |
- if err != nil {
|
|
| 57 |
- return err |
|
| 58 |
- } |
|
| 59 |
- |
|
| 60 |
- fmt.Fprintln(cli.out, response.ID) |
|
| 61 |
- return nil |
|
| 62 |
-} |
| 63 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,93 @@ |
| 0 |
+package container |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "encoding/json" |
|
| 4 |
+ "fmt" |
|
| 5 |
+ |
|
| 6 |
+ "golang.org/x/net/context" |
|
| 7 |
+ |
|
| 8 |
+ "github.com/docker/docker/api/client" |
|
| 9 |
+ "github.com/docker/docker/cli" |
|
| 10 |
+ dockeropts "github.com/docker/docker/opts" |
|
| 11 |
+ "github.com/docker/engine-api/types" |
|
| 12 |
+ containertypes "github.com/docker/engine-api/types/container" |
|
| 13 |
+ "github.com/spf13/cobra" |
|
| 14 |
+) |
|
| 15 |
+ |
|
| 16 |
+type commitOptions struct {
|
|
| 17 |
+ container string |
|
| 18 |
+ reference string |
|
| 19 |
+ |
|
| 20 |
+ pause bool |
|
| 21 |
+ comment string |
|
| 22 |
+ author string |
|
| 23 |
+ changes dockeropts.ListOpts |
|
| 24 |
+ config string |
|
| 25 |
+} |
|
| 26 |
+ |
|
| 27 |
+// NewCommitCommand creats a new cobra.Command for `docker commit` |
|
| 28 |
+func NewCommitCommand(dockerCli *client.DockerCli) *cobra.Command {
|
|
| 29 |
+ var opts commitOptions |
|
| 30 |
+ |
|
| 31 |
+ cmd := &cobra.Command{
|
|
| 32 |
+ Use: "commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]", |
|
| 33 |
+ Short: "Create a new image from a container's changes", |
|
| 34 |
+ Args: cli.RequiresRangeArgs(1, 2), |
|
| 35 |
+ RunE: func(cmd *cobra.Command, args []string) error {
|
|
| 36 |
+ opts.container = args[0] |
|
| 37 |
+ if len(args) > 1 {
|
|
| 38 |
+ opts.reference = args[1] |
|
| 39 |
+ } |
|
| 40 |
+ return runCommit(dockerCli, &opts) |
|
| 41 |
+ }, |
|
| 42 |
+ } |
|
| 43 |
+ cmd.SetFlagErrorFunc(flagErrorFunc) |
|
| 44 |
+ |
|
| 45 |
+ flags := cmd.Flags() |
|
| 46 |
+ flags.SetInterspersed(false) |
|
| 47 |
+ |
|
| 48 |
+ flags.BoolVarP(&opts.pause, "pause", "p", true, "Pause container during commit") |
|
| 49 |
+ flags.StringVarP(&opts.comment, "message", "m", "", "Commit message") |
|
| 50 |
+ flags.StringVarP(&opts.author, "author", "a", "", "Author (e.g., \"John Hannibal Smith <hannibal@a-team.com>\")") |
|
| 51 |
+ |
|
| 52 |
+ opts.changes = dockeropts.NewListOpts(nil) |
|
| 53 |
+ flags.VarP(&opts.changes, "change", "c", "Apply Dockerfile instruction to the created image") |
|
| 54 |
+ |
|
| 55 |
+ // FIXME: --run is deprecated, it will be replaced with inline Dockerfile commands. |
|
| 56 |
+ flags.StringVar(&opts.config, "run", "", "This option is deprecated and will be removed in a future version in favor of inline Dockerfile-compatible commands") |
|
| 57 |
+ flags.MarkDeprecated("run", "it will be replaced with inline Dockerfile commands.")
|
|
| 58 |
+ |
|
| 59 |
+ return cmd |
|
| 60 |
+} |
|
| 61 |
+ |
|
| 62 |
+func runCommit(dockerCli *client.DockerCli, opts *commitOptions) error {
|
|
| 63 |
+ ctx := context.Background() |
|
| 64 |
+ |
|
| 65 |
+ name := opts.container |
|
| 66 |
+ reference := opts.reference |
|
| 67 |
+ |
|
| 68 |
+ var config *containertypes.Config |
|
| 69 |
+ if opts.config != "" {
|
|
| 70 |
+ config = &containertypes.Config{}
|
|
| 71 |
+ if err := json.Unmarshal([]byte(opts.config), config); err != nil {
|
|
| 72 |
+ return err |
|
| 73 |
+ } |
|
| 74 |
+ } |
|
| 75 |
+ |
|
| 76 |
+ options := types.ContainerCommitOptions{
|
|
| 77 |
+ Reference: reference, |
|
| 78 |
+ Comment: opts.comment, |
|
| 79 |
+ Author: opts.author, |
|
| 80 |
+ Changes: opts.changes.GetAll(), |
|
| 81 |
+ Pause: opts.pause, |
|
| 82 |
+ Config: config, |
|
| 83 |
+ } |
|
| 84 |
+ |
|
| 85 |
+ response, err := dockerCli.Client().ContainerCommit(ctx, name, options) |
|
| 86 |
+ if err != nil {
|
|
| 87 |
+ return err |
|
| 88 |
+ } |
|
| 89 |
+ |
|
| 90 |
+ fmt.Fprintln(dockerCli.Out(), response.ID) |
|
| 91 |
+ return nil |
|
| 92 |
+} |
| ... | ... |
@@ -25,7 +25,7 @@ func NewPortCommand(dockerCli *client.DockerCli) *cobra.Command {
|
| 25 | 25 |
cmd := &cobra.Command{
|
| 26 | 26 |
Use: "port CONTAINER [PRIVATE_PORT[/PROTO]]", |
| 27 | 27 |
Short: "List port mappings or a specific mapping for the container", |
| 28 |
- Args: cli.RequiresMinMaxArgs(1, 2), |
|
| 28 |
+ Args: cli.RequiresRangeArgs(1, 2), |
|
| 29 | 29 |
RunE: func(cmd *cobra.Command, args []string) error {
|
| 30 | 30 |
opts.container = args[0] |
| 31 | 31 |
if len(args) > 1 {
|
| ... | ... |
@@ -36,6 +36,7 @@ func NewCobraAdaptor(clientFlags *cliflags.ClientFlags) CobraAdaptor {
|
| 36 | 36 |
rootCmd.SetOutput(stdout) |
| 37 | 37 |
rootCmd.AddCommand( |
| 38 | 38 |
container.NewAttachCommand(dockerCli), |
| 39 |
+ container.NewCommitCommand(dockerCli), |
|
| 39 | 40 |
container.NewCreateCommand(dockerCli), |
| 40 | 41 |
container.NewDiffCommand(dockerCli), |
| 41 | 42 |
container.NewExportCommand(dockerCli), |
| ... | ... |
@@ -60,8 +60,8 @@ func RequiresMaxArgs(max int) cobra.PositionalArgs {
|
| 60 | 60 |
} |
| 61 | 61 |
} |
| 62 | 62 |
|
| 63 |
-// RequiresMinMaxArgs returns an error if there is not at least min args and at most max args |
|
| 64 |
-func RequiresMinMaxArgs(min int, max int) cobra.PositionalArgs {
|
|
| 63 |
+// RequiresRangeArgs returns an error if there is not at least min args and at most max args |
|
| 64 |
+func RequiresRangeArgs(min int, max int) cobra.PositionalArgs {
|
|
| 65 | 65 |
return func(cmd *cobra.Command, args []string) error {
|
| 66 | 66 |
if len(args) >= min && len(args) <= max {
|
| 67 | 67 |
return nil |
| ... | ... |
@@ -8,7 +8,6 @@ type Command struct {
|
| 8 | 8 |
|
| 9 | 9 |
// DockerCommandUsage lists the top level docker commands and their short usage |
| 10 | 10 |
var DockerCommandUsage = []Command{
|
| 11 |
- {"commit", "Create a new image from a container's changes"},
|
|
| 12 | 11 |
{"cp", "Copy files/folders between a container and the local filesystem"},
|
| 13 | 12 |
{"exec", "Run a command in a running container"},
|
| 14 | 13 |
{"info", "Display system-wide information"},
|