commit.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. package daemon
  2. import (
  3. "github.com/docker/docker/engine"
  4. "github.com/docker/docker/image"
  5. "github.com/docker/docker/runconfig"
  6. )
  7. func (daemon *Daemon) ContainerCommit(job *engine.Job) engine.Status {
  8. if len(job.Args) != 1 {
  9. return job.Errorf("Not enough arguments. Usage: %s CONTAINER\n", job.Name)
  10. }
  11. name := job.Args[0]
  12. container := daemon.Get(name)
  13. if container == nil {
  14. return job.Errorf("No such container: %s", name)
  15. }
  16. var (
  17. config = container.Config
  18. newConfig runconfig.Config
  19. )
  20. if err := job.GetenvJson("config", &newConfig); err != nil {
  21. return job.Error(err)
  22. }
  23. if err := runconfig.Merge(&newConfig, config); err != nil {
  24. return job.Error(err)
  25. }
  26. img, err := daemon.Commit(container, job.Getenv("repo"), job.Getenv("tag"), job.Getenv("comment"), job.Getenv("author"), job.GetenvBool("pause"), &newConfig)
  27. if err != nil {
  28. return job.Error(err)
  29. }
  30. job.Printf("%s\n", img.ID)
  31. return engine.StatusOK
  32. }
  33. // Commit creates a new filesystem image from the current state of a container.
  34. // The image can optionally be tagged into a repository
  35. func (daemon *Daemon) Commit(container *Container, repository, tag, comment, author string, pause bool, config *runconfig.Config) (*image.Image, error) {
  36. if pause {
  37. container.Pause()
  38. defer container.Unpause()
  39. }
  40. if err := container.Mount(); err != nil {
  41. return nil, err
  42. }
  43. defer container.Unmount()
  44. rwTar, err := container.ExportRw()
  45. if err != nil {
  46. return nil, err
  47. }
  48. defer rwTar.Close()
  49. // Create a new image from the container's base layers + a new layer from container changes
  50. var (
  51. containerID, parentImageID string
  52. containerConfig *runconfig.Config
  53. )
  54. if container != nil {
  55. containerID = container.ID
  56. parentImageID = container.ImageID
  57. containerConfig = container.Config
  58. }
  59. img, err := daemon.graph.Create(rwTar, containerID, parentImageID, comment, author, containerConfig, config)
  60. if err != nil {
  61. return nil, err
  62. }
  63. // Register the image if needed
  64. if repository != "" {
  65. if err := daemon.repositories.Set(repository, tag, img.ID, true); err != nil {
  66. return img, err
  67. }
  68. }
  69. return img, nil
  70. }