github.com/torfuzx/docker@v1.8.1/daemon/delete.go (about) 1 package daemon 2 3 import ( 4 "fmt" 5 "os" 6 "path" 7 "runtime" 8 9 "github.com/Sirupsen/logrus" 10 ) 11 12 type ContainerRmConfig struct { 13 ForceRemove, RemoveVolume, RemoveLink bool 14 } 15 16 func (daemon *Daemon) ContainerRm(name string, config *ContainerRmConfig) error { 17 container, err := daemon.Get(name) 18 if err != nil { 19 return err 20 } 21 22 if config.RemoveLink { 23 name, err := GetFullContainerName(name) 24 if err != nil { 25 return err 26 } 27 parent, n := path.Split(name) 28 if parent == "/" { 29 return fmt.Errorf("Conflict, cannot remove the default name of the container") 30 } 31 pe := daemon.ContainerGraph().Get(parent) 32 if pe == nil { 33 return fmt.Errorf("Cannot get parent %s for name %s", parent, name) 34 } 35 parentContainer, _ := daemon.Get(pe.ID()) 36 37 if err := daemon.ContainerGraph().Delete(name); err != nil { 38 return err 39 } 40 41 if parentContainer != nil { 42 parentContainer.DisableLink(n) 43 } 44 45 return nil 46 } 47 48 if err := daemon.rm(container, config.ForceRemove); err != nil { 49 return fmt.Errorf("Cannot destroy container %s: %v", name, err) 50 } 51 52 if config.RemoveVolume { 53 container.removeMountPoints() 54 } 55 return nil 56 } 57 58 // Destroy unregisters a container from the daemon and cleanly removes its contents from the filesystem. 59 func (daemon *Daemon) rm(container *Container, forceRemove bool) (err error) { 60 if container.IsRunning() { 61 if !forceRemove { 62 return fmt.Errorf("Conflict, You cannot remove a running container. Stop the container before attempting removal or use -f") 63 } 64 if err := container.Kill(); err != nil { 65 return fmt.Errorf("Could not kill running container, cannot remove - %v", err) 66 } 67 } 68 69 // stop collection of stats for the container regardless 70 // if stats are currently getting collected. 71 daemon.statsCollector.stopCollection(container) 72 73 element := daemon.containers.Get(container.ID) 74 if element == nil { 75 return fmt.Errorf("Container %v not found - maybe it was already destroyed?", container.ID) 76 } 77 78 // Container state RemovalInProgress should be used to avoid races. 79 if err = container.SetRemovalInProgress(); err != nil { 80 return fmt.Errorf("Failed to set container state to RemovalInProgress: %s", err) 81 } 82 83 defer container.ResetRemovalInProgress() 84 85 if err = container.Stop(3); err != nil { 86 return err 87 } 88 89 // Mark container dead. We don't want anybody to be restarting it. 90 container.SetDead() 91 92 // Save container state to disk. So that if error happens before 93 // container meta file got removed from disk, then a restart of 94 // docker should not make a dead container alive. 95 if err := container.ToDisk(); err != nil { 96 logrus.Errorf("Error saving dying container to disk: %v", err) 97 } 98 99 // If force removal is required, delete container from various 100 // indexes even if removal failed. 101 defer func() { 102 if err != nil && forceRemove { 103 daemon.idIndex.Delete(container.ID) 104 daemon.containers.Delete(container.ID) 105 os.RemoveAll(container.root) 106 container.LogEvent("destroy") 107 } 108 }() 109 110 if _, err := daemon.containerGraph.Purge(container.ID); err != nil { 111 logrus.Debugf("Unable to remove container from link graph: %s", err) 112 } 113 114 if err = daemon.driver.Remove(container.ID); err != nil { 115 return fmt.Errorf("Driver %s failed to remove root filesystem %s: %s", daemon.driver, container.ID, err) 116 } 117 118 // There will not be an -init on Windows, so don't fail by not attempting to delete it 119 if runtime.GOOS != "windows" { 120 initID := fmt.Sprintf("%s-init", container.ID) 121 if err := daemon.driver.Remove(initID); err != nil { 122 return fmt.Errorf("Driver %s failed to remove init filesystem %s: %s", daemon.driver, initID, err) 123 } 124 } 125 126 if err = os.RemoveAll(container.root); err != nil { 127 return fmt.Errorf("Unable to remove filesystem for %v: %v", container.ID, err) 128 } 129 130 if err = daemon.execDriver.Clean(container.ID); err != nil { 131 return fmt.Errorf("Unable to remove execdriver data for %s: %s", container.ID, err) 132 } 133 134 selinuxFreeLxcContexts(container.ProcessLabel) 135 daemon.idIndex.Delete(container.ID) 136 daemon.containers.Delete(container.ID) 137 138 container.LogEvent("destroy") 139 return nil 140 } 141 142 func (daemon *Daemon) DeleteVolumes(c *Container) error { 143 return c.removeMountPoints() 144 }