removeContainers removes all containers using the image.
(options *RemoveImagesOptions)
| 270 | |
| 271 | // removeContainers removes all containers using the image. |
| 272 | func (i *Image) removeContainers(options *RemoveImagesOptions) error { |
| 273 | if !options.Force && !options.ExternalContainers { |
| 274 | // Nothing to do. |
| 275 | return nil |
| 276 | } |
| 277 | |
| 278 | if options.Force && options.RemoveContainerFunc != nil { |
| 279 | logrus.Debugf("Removing containers of image %s with custom removal function", i.ID()) |
| 280 | if err := options.RemoveContainerFunc(i.ID()); err != nil { |
| 281 | return err |
| 282 | } |
| 283 | } |
| 284 | |
| 285 | containers, err := i.Containers() |
| 286 | if err != nil { |
| 287 | return err |
| 288 | } |
| 289 | |
| 290 | if !options.Force && options.ExternalContainers { |
| 291 | // All containers must be external ones. |
| 292 | for _, cID := range containers { |
| 293 | isExternal, err := options.IsExternalContainerFunc(cID) |
| 294 | if err != nil { |
| 295 | return fmt.Errorf("checking if %s is an external container: %w", cID, err) |
| 296 | } |
| 297 | if !isExternal { |
| 298 | return fmt.Errorf("cannot remove container %s: not an external container", cID) |
| 299 | } |
| 300 | } |
| 301 | } |
| 302 | |
| 303 | logrus.Debugf("Removing containers of image %s from the local containers storage", i.ID()) |
| 304 | var multiE error |
| 305 | for _, cID := range containers { |
| 306 | if err := i.runtime.store.DeleteContainer(cID); err != nil { |
| 307 | // If the container does not exist anymore, we're good. |
| 308 | if errors.Cause(err) != storage.ErrContainerUnknown { |
| 309 | multiE = multierror.Append(multiE, err) |
| 310 | } |
| 311 | } |
| 312 | } |
| 313 | |
| 314 | return multiE |
| 315 | } |
| 316 | |
| 317 | // RemoveContainerFunc allows for customizing the removal of containers using |
| 318 | // an image specified by imageID. |