Handle delete of multiple images with same dockerImageId

A docker-compose.yml with the following structure

```
version: '2.1'
services:
  app_1:
    build: ./noisy-1
    image: noisy1
  app_2:
    build: ./noisy-1
    image: noisy1
  app_3:
    build: ./noisy-1
    image: noisy1
```

Will lead to the supervisor creating multiple image database entries
with the same dockerId (this is because of how the engine handles this
particular case). This case is not handled by the removal process
leading to image pile up and increased disk usage.

Change-type: patch
Signed-off-by: Felipe Lalanne <felipe@balena.io>
Connects-to: #1434
This commit is contained in:
Felipe Lalanne 2020-09-17 12:58:38 -03:00 committed by Miguel Casqueira
parent c3ff277bb0
commit 4795c336d0

View File

@ -534,6 +534,33 @@ async function removeImageIfNotNeeded(image: Image): Promise<void> {
);
logger.logSystemEvent(LogTypes.deleteImage, { image });
docker.getImage(img.dockerImageId).remove({ force: true });
removed = true;
} else if (imagesFromDb.length > 1 && hasDigest(img.name)) {
const [dockerRepo] = img.name.split('@');
const dockerImage = await docker.getImage(img.dockerImageId).inspect();
const matchingTags = dockerImage.RepoTags.filter((tag) => {
const [tagRepo] = tag.split(':');
return tagRepo === dockerRepo;
});
reportChange(
image.imageId,
_.merge(_.clone(image), { status: 'Deleting' }),
);
logger.logSystemEvent(LogTypes.deleteImage, { image });
// Remove tags that match the repo part of the image.name
await Promise.all(
matchingTags.map((tag) =>
docker.getImage(tag).remove({ noprune: true }),
),
);
// Since there are multiple images with same id we need to
// remove by name
await Bluebird.delay(Math.random() * 100); // try to prevent race conditions
await docker.getImage(img.name).remove();
removed = true;
} else if (!hasDigest(img.name)) {
// Image has a regular tag, so we might have to remove unnecessary tags