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