commit.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package daemon
  2. import (
  3. "github.com/docker/docker/image"
  4. "github.com/docker/docker/pkg/archive"
  5. "github.com/docker/docker/pkg/ioutils"
  6. "github.com/docker/docker/runconfig"
  7. )
  8. // ContainerCommitConfig contains build configs for commit operation,
  9. // and is used when making a commit with the current state of the container.
  10. type ContainerCommitConfig struct {
  11. Pause bool
  12. Repo string
  13. Tag string
  14. Author string
  15. Comment string
  16. Config *runconfig.Config
  17. }
  18. // Commit creates a new filesystem image from the current state of a container.
  19. // The image can optionally be tagged into a repository.
  20. func (daemon *Daemon) Commit(container *Container, c *ContainerCommitConfig) (*image.Image, error) {
  21. if c.Pause && !container.isPaused() {
  22. daemon.containerPause(container)
  23. defer daemon.containerUnpause(container)
  24. }
  25. rwTar, err := daemon.exportContainerRw(container)
  26. if err != nil {
  27. return nil, err
  28. }
  29. defer func() {
  30. if rwTar != nil {
  31. rwTar.Close()
  32. }
  33. }()
  34. // Create a new image from the container's base layers + a new layer from container changes
  35. img, err := daemon.graph.Create(rwTar, container.ID, container.ImageID, c.Comment, c.Author, container.Config, c.Config)
  36. if err != nil {
  37. return nil, err
  38. }
  39. // Register the image if needed
  40. if c.Repo != "" {
  41. if err := daemon.repositories.Tag(c.Repo, c.Tag, img.ID, true); err != nil {
  42. return img, err
  43. }
  44. }
  45. daemon.LogContainerEvent(container, "commit")
  46. return img, nil
  47. }
  48. func (daemon *Daemon) exportContainerRw(container *Container) (archive.Archive, error) {
  49. archive, err := daemon.diff(container)
  50. if err != nil {
  51. return nil, err
  52. }
  53. return ioutils.NewReadCloserWrapper(archive, func() error {
  54. err := archive.Close()
  55. return err
  56. }),
  57. nil
  58. }