commit.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package container
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "golang.org/x/net/context"
  6. "github.com/docker/docker/api/client"
  7. "github.com/docker/docker/cli"
  8. dockeropts "github.com/docker/docker/opts"
  9. "github.com/docker/engine-api/types"
  10. containertypes "github.com/docker/engine-api/types/container"
  11. "github.com/spf13/cobra"
  12. )
  13. type commitOptions struct {
  14. container string
  15. reference string
  16. pause bool
  17. comment string
  18. author string
  19. changes dockeropts.ListOpts
  20. config string
  21. }
  22. // NewCommitCommand creats a new cobra.Command for `docker commit`
  23. func NewCommitCommand(dockerCli *client.DockerCli) *cobra.Command {
  24. var opts commitOptions
  25. cmd := &cobra.Command{
  26. Use: "commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]",
  27. Short: "Create a new image from a container's changes",
  28. Args: cli.RequiresRangeArgs(1, 2),
  29. RunE: func(cmd *cobra.Command, args []string) error {
  30. opts.container = args[0]
  31. if len(args) > 1 {
  32. opts.reference = args[1]
  33. }
  34. return runCommit(dockerCli, &opts)
  35. },
  36. }
  37. cmd.SetFlagErrorFunc(flagErrorFunc)
  38. flags := cmd.Flags()
  39. flags.SetInterspersed(false)
  40. flags.BoolVarP(&opts.pause, "pause", "p", true, "Pause container during commit")
  41. flags.StringVarP(&opts.comment, "message", "m", "", "Commit message")
  42. flags.StringVarP(&opts.author, "author", "a", "", "Author (e.g., \"John Hannibal Smith <hannibal@a-team.com>\")")
  43. opts.changes = dockeropts.NewListOpts(nil)
  44. flags.VarP(&opts.changes, "change", "c", "Apply Dockerfile instruction to the created image")
  45. // FIXME: --run is deprecated, it will be replaced with inline Dockerfile commands.
  46. flags.StringVar(&opts.config, "run", "", "This option is deprecated and will be removed in a future version in favor of inline Dockerfile-compatible commands")
  47. flags.MarkDeprecated("run", "it will be replaced with inline Dockerfile commands.")
  48. return cmd
  49. }
  50. func runCommit(dockerCli *client.DockerCli, opts *commitOptions) error {
  51. ctx := context.Background()
  52. name := opts.container
  53. reference := opts.reference
  54. var config *containertypes.Config
  55. if opts.config != "" {
  56. config = &containertypes.Config{}
  57. if err := json.Unmarshal([]byte(opts.config), config); err != nil {
  58. return err
  59. }
  60. }
  61. options := types.ContainerCommitOptions{
  62. Reference: reference,
  63. Comment: opts.comment,
  64. Author: opts.author,
  65. Changes: opts.changes.GetAll(),
  66. Pause: opts.pause,
  67. Config: config,
  68. }
  69. response, err := dockerCli.Client().ContainerCommit(ctx, name, options)
  70. if err != nil {
  71. return err
  72. }
  73. fmt.Fprintln(dockerCli.Out(), response.ID)
  74. return nil
  75. }