delete.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. package daemon
  2. import (
  3. "fmt"
  4. "os"
  5. "path"
  6. log "github.com/Sirupsen/logrus"
  7. "github.com/docker/docker/engine"
  8. )
  9. func (daemon *Daemon) ContainerRm(job *engine.Job) engine.Status {
  10. if len(job.Args) != 1 {
  11. return job.Errorf("Not enough arguments. Usage: %s CONTAINER\n", job.Name)
  12. }
  13. name := job.Args[0]
  14. removeVolume := job.GetenvBool("removeVolume")
  15. removeLink := job.GetenvBool("removeLink")
  16. forceRemove := job.GetenvBool("forceRemove")
  17. container := daemon.Get(name)
  18. if container == nil {
  19. return job.Errorf("No such container: %s", name)
  20. }
  21. if removeLink {
  22. name, err := GetFullContainerName(name)
  23. if err != nil {
  24. job.Error(err)
  25. }
  26. parent, n := path.Split(name)
  27. if parent == "/" {
  28. return job.Errorf("Conflict, cannot remove the default name of the container")
  29. }
  30. pe := daemon.ContainerGraph().Get(parent)
  31. if pe == nil {
  32. return job.Errorf("Cannot get parent %s for name %s", parent, name)
  33. }
  34. parentContainer := daemon.Get(pe.ID())
  35. if parentContainer != nil {
  36. parentContainer.DisableLink(n)
  37. }
  38. if err := daemon.ContainerGraph().Delete(name); err != nil {
  39. return job.Error(err)
  40. }
  41. return engine.StatusOK
  42. }
  43. if container != nil {
  44. if container.IsRunning() {
  45. if forceRemove {
  46. if err := container.Kill(); err != nil {
  47. return job.Errorf("Could not kill running container, cannot remove - %v", err)
  48. }
  49. } else {
  50. return job.Errorf("Conflict, You cannot remove a running container. Stop the container before attempting removal or use -f")
  51. }
  52. }
  53. if err := daemon.Destroy(container); err != nil {
  54. return job.Errorf("Cannot destroy container %s: %s", name, err)
  55. }
  56. container.LogEvent("destroy")
  57. if removeVolume {
  58. daemon.DeleteVolumes(container.VolumePaths())
  59. }
  60. }
  61. return engine.StatusOK
  62. }
  63. func (daemon *Daemon) DeleteVolumes(volumeIDs map[string]struct{}) {
  64. for id := range volumeIDs {
  65. if err := daemon.volumes.Delete(id); err != nil {
  66. log.Infof("%s", err)
  67. continue
  68. }
  69. }
  70. }
  71. // Destroy unregisters a container from the daemon and cleanly removes its contents from the filesystem.
  72. // FIXME: rename to Rm for consistency with the CLI command
  73. func (daemon *Daemon) Destroy(container *Container) error {
  74. if container == nil {
  75. return fmt.Errorf("The given container is <nil>")
  76. }
  77. element := daemon.containers.Get(container.ID)
  78. if element == nil {
  79. return fmt.Errorf("Container %v not found - maybe it was already destroyed?", container.ID)
  80. }
  81. if err := container.Stop(3); err != nil {
  82. return err
  83. }
  84. // Deregister the container before removing its directory, to avoid race conditions
  85. daemon.idIndex.Delete(container.ID)
  86. daemon.containers.Delete(container.ID)
  87. container.derefVolumes()
  88. if _, err := daemon.containerGraph.Purge(container.ID); err != nil {
  89. log.Debugf("Unable to remove container from link graph: %s", err)
  90. }
  91. if err := daemon.driver.Remove(container.ID); err != nil {
  92. return fmt.Errorf("Driver %s failed to remove root filesystem %s: %s", daemon.driver, container.ID, err)
  93. }
  94. initID := fmt.Sprintf("%s-init", container.ID)
  95. if err := daemon.driver.Remove(initID); err != nil {
  96. return fmt.Errorf("Driver %s failed to remove init filesystem %s: %s", daemon.driver, initID, err)
  97. }
  98. if err := os.RemoveAll(container.root); err != nil {
  99. return fmt.Errorf("Unable to remove filesystem for %v: %v", container.ID, err)
  100. }
  101. if err := daemon.execDriver.Clean(container.ID); err != nil {
  102. return fmt.Errorf("Unable to remove execdriver data for %s: %s", container.ID, err)
  103. }
  104. selinuxFreeLxcContexts(container.ProcessLabel)
  105. return nil
  106. }