commit.go 2.5 KB

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