commit.go 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package client
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. Cli "github.com/docker/docker/cli"
  7. "github.com/docker/docker/opts"
  8. flag "github.com/docker/docker/pkg/mflag"
  9. "github.com/docker/docker/reference"
  10. "github.com/docker/engine-api/types"
  11. "github.com/docker/engine-api/types/container"
  12. )
  13. // CmdCommit creates a new image from a container's changes.
  14. //
  15. // Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
  16. func (cli *DockerCli) CmdCommit(args ...string) error {
  17. cmd := Cli.Subcmd("commit", []string{"CONTAINER [REPOSITORY[:TAG]]"}, Cli.DockerCommands["commit"].Description, true)
  18. flPause := cmd.Bool([]string{"p", "-pause"}, true, "Pause container during commit")
  19. flComment := cmd.String([]string{"m", "-message"}, "", "Commit message")
  20. flAuthor := cmd.String([]string{"a", "-author"}, "", "Author (e.g., \"John Hannibal Smith <hannibal@a-team.com>\")")
  21. flChanges := opts.NewListOpts(nil)
  22. cmd.Var(&flChanges, []string{"c", "-change"}, "Apply Dockerfile instruction to the created image")
  23. // FIXME: --run is deprecated, it will be replaced with inline Dockerfile commands.
  24. flConfig := cmd.String([]string{"#-run"}, "", "This option is deprecated and will be removed in a future version in favor of inline Dockerfile-compatible commands")
  25. cmd.Require(flag.Max, 2)
  26. cmd.Require(flag.Min, 1)
  27. cmd.ParseFlags(args, true)
  28. var (
  29. name = cmd.Arg(0)
  30. repositoryAndTag = cmd.Arg(1)
  31. repositoryName string
  32. tag string
  33. )
  34. //Check if the given image name can be resolved
  35. if repositoryAndTag != "" {
  36. ref, err := reference.ParseNamed(repositoryAndTag)
  37. if err != nil {
  38. return err
  39. }
  40. repositoryName = ref.Name()
  41. switch x := ref.(type) {
  42. case reference.Canonical:
  43. return errors.New("cannot commit to digest reference")
  44. case reference.NamedTagged:
  45. tag = x.Tag()
  46. }
  47. }
  48. var config *container.Config
  49. if *flConfig != "" {
  50. config = &container.Config{}
  51. if err := json.Unmarshal([]byte(*flConfig), config); err != nil {
  52. return err
  53. }
  54. }
  55. options := types.ContainerCommitOptions{
  56. ContainerID: name,
  57. RepositoryName: repositoryName,
  58. Tag: tag,
  59. Comment: *flComment,
  60. Author: *flAuthor,
  61. Changes: flChanges.GetAll(),
  62. Pause: *flPause,
  63. Config: config,
  64. }
  65. response, err := cli.client.ContainerCommit(options)
  66. if err != nil {
  67. return err
  68. }
  69. fmt.Fprintln(cli.out, response.ID)
  70. return nil
  71. }