commit.go 2.3 KB

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