1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Fix comparing binds and volume ids from other containers

Currently comparing volume ids for binds and other containers are broken
Fixes #3749
Fixes #3885
Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
This commit is contained in:
Michael Crosby 2014-02-03 13:18:10 -08:00
parent 88d66600b3
commit 720c5774e9

View file

@ -1726,38 +1726,53 @@ func (srv *Server) ContainerDestroy(job *engine.Job) engine.Status {
if container.State.IsRunning() {
return job.Errorf("Impossible to remove a running container, please stop it first")
}
volumes := make(map[string]struct{})
binds := make(map[string]struct{})
for _, bind := range container.hostConfig.Binds {
splitBind := strings.Split(bind, ":")
source := splitBind[0]
binds[source] = struct{}{}
}
// Store all the deleted containers volumes
for _, volumeId := range container.Volumes {
// Skip the volumes mounted from external
if _, exists := binds[volumeId]; exists {
continue
}
volumeId = strings.TrimSuffix(volumeId, "/layer")
volumeId = filepath.Base(volumeId)
volumes[volumeId] = struct{}{}
}
if err := srv.runtime.Destroy(container); err != nil {
return job.Errorf("Cannot destroy container %s: %s", name, err)
}
srv.LogEvent("destroy", container.ID, srv.runtime.repositories.ImageName(container.Image))
if removeVolume {
var (
volumes = make(map[string]struct{})
binds = make(map[string]struct{})
usedVolumes = make(map[string]*Container)
)
// the volume id is always the base of the path
getVolumeId := func(p string) string {
return filepath.Base(strings.TrimSuffix(p, "/layer"))
}
// populate bind map so that they can be skipped and not removed
for _, bind := range container.hostConfig.Binds {
source := strings.Split(bind, ":")[0]
// TODO: refactor all volume stuff, all of it
// this is very important that we eval the link
// or comparing the keys to container.Volumes will not work
p, err := filepath.EvalSymlinks(source)
if err != nil {
return job.Error(err)
}
source = p
binds[source] = struct{}{}
}
// Store all the deleted containers volumes
for _, volumeId := range container.Volumes {
// Skip the volumes mounted from external
// bind mounts here will will be evaluated for a symlink
if _, exists := binds[volumeId]; exists {
continue
}
volumeId = getVolumeId(volumeId)
volumes[volumeId] = struct{}{}
}
// Retrieve all volumes from all remaining containers
usedVolumes := make(map[string]*Container)
for _, container := range srv.runtime.List() {
for _, containerVolumeId := range container.Volumes {
containerVolumeId = getVolumeId(containerVolumeId)
usedVolumes[containerVolumeId] = container
}
}