commit.go 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. package client
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "golang.org/x/net/context"
  7. Cli "github.com/docker/docker/cli"
  8. "github.com/docker/docker/opts"
  9. flag "github.com/docker/docker/pkg/mflag"
  10. "github.com/docker/docker/reference"
  11. "github.com/docker/engine-api/types"
  12. "github.com/docker/engine-api/types/container"
  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. repositoryName = ref.Name()
  42. switch x := ref.(type) {
  43. case reference.Canonical:
  44. return errors.New("cannot commit to digest reference")
  45. case reference.NamedTagged:
  46. tag = x.Tag()
  47. }
  48. }
  49. var config *container.Config
  50. if *flConfig != "" {
  51. config = &container.Config{}
  52. if err := json.Unmarshal([]byte(*flConfig), config); err != nil {
  53. return err
  54. }
  55. }
  56. options := types.ContainerCommitOptions{
  57. ContainerID: name,
  58. RepositoryName: repositoryName,
  59. Tag: tag,
  60. Comment: *flComment,
  61. Author: *flAuthor,
  62. Changes: flChanges.GetAll(),
  63. Pause: *flPause,
  64. Config: config,
  65. }
  66. response, err := cli.client.ContainerCommit(context.Background(), options)
  67. if err != nil {
  68. return err
  69. }
  70. fmt.Fprintln(cli.out, response.ID)
  71. return nil
  72. }