The imageRefs map was being popualted with containerID, and accessed
with an imageID which would never match.
Remove this broken code because: 1) it hasn't ever worked so isn't
necessary, and 2) because at best it would be racy
ImageDelete() should already handle preventing of removal of used
images.
Signed-off-by: Daniel Nephin <dnephin@docker.com>
| ... | ... |
@@ -10,6 +10,7 @@ import ( |
| 10 | 10 |
"github.com/docker/docker/api/types" |
| 11 | 11 |
"github.com/docker/docker/api/types/filters" |
| 12 | 12 |
timetypes "github.com/docker/docker/api/types/time" |
| 13 |
+ "github.com/docker/docker/errdefs" |
|
| 13 | 14 |
"github.com/docker/docker/image" |
| 14 | 15 |
"github.com/docker/docker/layer" |
| 15 | 16 |
"github.com/docker/docker/pkg/directory" |
| ... | ... |
@@ -193,16 +194,6 @@ func (daemon *Daemon) ImagesPrune(ctx context.Context, pruneFilters filters.Args |
| 193 | 193 |
} else {
|
| 194 | 194 |
allImages = daemon.imageStore.Map() |
| 195 | 195 |
} |
| 196 |
- allContainers := daemon.List() |
|
| 197 |
- imageRefs := map[string]bool{}
|
|
| 198 |
- for _, c := range allContainers {
|
|
| 199 |
- select {
|
|
| 200 |
- case <-ctx.Done(): |
|
| 201 |
- return nil, ctx.Err() |
|
| 202 |
- default: |
|
| 203 |
- imageRefs[c.ID] = true |
|
| 204 |
- } |
|
| 205 |
- } |
|
| 206 | 196 |
|
| 207 | 197 |
// Filter intermediary images and get their unique size |
| 208 | 198 |
allLayers := make(map[layer.ChainID]layer.Layer) |
| ... | ... |
@@ -242,14 +233,8 @@ deleteImagesLoop: |
| 242 | 242 |
default: |
| 243 | 243 |
} |
| 244 | 244 |
|
| 245 |
- dgst := digest.Digest(id) |
|
| 246 |
- hex := dgst.Hex() |
|
| 247 |
- if _, ok := imageRefs[hex]; ok {
|
|
| 248 |
- continue |
|
| 249 |
- } |
|
| 250 |
- |
|
| 251 | 245 |
deletedImages := []types.ImageDeleteResponseItem{}
|
| 252 |
- refs := daemon.referenceStore.References(dgst) |
|
| 246 |
+ refs := daemon.referenceStore.References(id.Digest()) |
|
| 253 | 247 |
if len(refs) > 0 {
|
| 254 | 248 |
shouldDelete := !danglingOnly |
| 255 | 249 |
if !shouldDelete {
|
| ... | ... |
@@ -268,17 +253,16 @@ deleteImagesLoop: |
| 268 | 268 |
if shouldDelete {
|
| 269 | 269 |
for _, ref := range refs {
|
| 270 | 270 |
imgDel, err := daemon.ImageDelete(ref.String(), false, true) |
| 271 |
- if err != nil {
|
|
| 272 |
- logrus.Warnf("could not delete reference %s: %v", ref.String(), err)
|
|
| 271 |
+ if imageDeleteFailed(ref.String(), err) {
|
|
| 273 | 272 |
continue |
| 274 | 273 |
} |
| 275 | 274 |
deletedImages = append(deletedImages, imgDel...) |
| 276 | 275 |
} |
| 277 | 276 |
} |
| 278 | 277 |
} else {
|
| 278 |
+ hex := id.Digest().Hex() |
|
| 279 | 279 |
imgDel, err := daemon.ImageDelete(hex, false, true) |
| 280 |
- if err != nil {
|
|
| 281 |
- logrus.Warnf("could not delete image %s: %v", hex, err)
|
|
| 280 |
+ if imageDeleteFailed(hex, err) {
|
|
| 282 | 281 |
continue |
| 283 | 282 |
} |
| 284 | 283 |
deletedImages = append(deletedImages, imgDel...) |
| ... | ... |
@@ -309,6 +293,18 @@ deleteImagesLoop: |
| 309 | 309 |
return rep, nil |
| 310 | 310 |
} |
| 311 | 311 |
|
| 312 |
+func imageDeleteFailed(ref string, err error) bool {
|
|
| 313 |
+ switch {
|
|
| 314 |
+ case err == nil: |
|
| 315 |
+ return false |
|
| 316 |
+ case errdefs.IsConflict(err): |
|
| 317 |
+ return true |
|
| 318 |
+ default: |
|
| 319 |
+ logrus.Warnf("failed to prune image %s: %v", ref, err)
|
|
| 320 |
+ return true |
|
| 321 |
+ } |
|
| 322 |
+} |
|
| 323 |
+ |
|
| 312 | 324 |
// localNetworksPrune removes unused local networks |
| 313 | 325 |
func (daemon *Daemon) localNetworksPrune(ctx context.Context, pruneFilters filters.Args) *types.NetworksPruneReport {
|
| 314 | 326 |
rep := &types.NetworksPruneReport{}
|