(ctx context.Context, rmMap map[string]*RemoveImageReport, processedIDs []string, referencedBy string, options *RemoveImagesOptions)
| 350 | } |
| 351 | |
| 352 | func (i *Image) removeRecursive(ctx context.Context, rmMap map[string]*RemoveImageReport, processedIDs []string, referencedBy string, options *RemoveImagesOptions) ([]string, error) { |
| 353 | // If referencedBy is empty, the image is considered to be removed via |
| 354 | // `image remove --all` which alters the logic below. |
| 355 | |
| 356 | // The removal logic below is complex. There is a number of rules |
| 357 | // inherited from Podman and Buildah (and Docker). This function |
| 358 | // should be the *only* place to extend the removal logic so we keep it |
| 359 | // sealed in one place. Make sure to add verbose comments to leave |
| 360 | // some breadcrumbs for future readers. |
| 361 | logrus.Debugf("Removing image %s", i.ID()) |
| 362 | |
| 363 | if i.IsReadOnly() { |
| 364 | return processedIDs, errors.Errorf("cannot remove read-only image %q", i.ID()) |
| 365 | } |
| 366 | |
| 367 | if i.runtime.eventChannel != nil { |
| 368 | defer i.runtime.writeEvent(&Event{ID: i.ID(), Name: referencedBy, Time: time.Now(), Type: EventTypeImageRemove}) |
| 369 | } |
| 370 | |
| 371 | // Check if already visisted this image. |
| 372 | report, exists := rmMap[i.ID()] |
| 373 | if exists { |
| 374 | // If the image has already been removed, we're done. |
| 375 | if report.Removed { |
| 376 | return processedIDs, nil |
| 377 | } |
| 378 | } else { |
| 379 | report = &RemoveImageReport{ID: i.ID()} |
| 380 | rmMap[i.ID()] = report |
| 381 | } |
| 382 | |
| 383 | // The image may have already been (partially) removed, so we need to |
| 384 | // have a closer look at the errors. On top, image removal should be |
| 385 | // tolerant toward corrupted images. |
| 386 | handleError := func(err error) error { |
| 387 | switch errors.Cause(err) { |
| 388 | case storage.ErrImageUnknown, storage.ErrNotAnImage, storage.ErrLayerUnknown: |
| 389 | // The image or layers of the image may already |
| 390 | // have been removed in which case we consider |
| 391 | // the image to be removed. |
| 392 | return nil |
| 393 | default: |
| 394 | return err |
| 395 | } |
| 396 | } |
| 397 | |
| 398 | // Calculate the size if requested. `podman-image-prune` likes to |
| 399 | // report the regained size. |
| 400 | if options.WithSize { |
| 401 | size, err := i.Size() |
| 402 | if handleError(err) != nil { |
| 403 | return processedIDs, err |
| 404 | } |
| 405 | report.Size = size |
| 406 | } |
| 407 | |
| 408 | skipRemove := false |
| 409 | numNames := len(i.Names()) |
no test coverage detected