Skip to content

Commit

Permalink
Only force delete image (and container) for images that are built by …
Browse files Browse the repository at this point in the history
…this plugin.

When not force deleting, verify that image is indeed dangling (that it has no tags) prior to deleting or do not delete it at all.
  • Loading branch information
Roman Khmelichek authored and rohanKanojia committed Jan 22, 2022
1 parent 998dae1 commit 7b36470
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ public interface DockerAccess {
*/
String getImageId(String name) throws DockerAccessException;

/**
* Get the list of tags of a given image name or <code>null</code> if no such image exists
*
* @param name name to lookup
* @return the list of image tags or <code>null</code>
*/
List<String> getImageTags(String name) throws DockerAccessException;

/**
* List all containers from the Docker server.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,22 @@ public String getImageId(String name) throws DockerAccessException {
return imageDetails.get("Id").getAsString().substring(0, 12);
}

@Override
public List<String> getImageTags(String name) throws DockerAccessException {
HttpBodyAndStatus response = inspectImage(name);
if (response.getStatusCode() == HTTP_NOT_FOUND) {
return null;
}
JsonObject imageDetails = JsonFactory.newJsonObject(response.getBody());
JsonArray tagsArr = imageDetails.get("RepoTags").getAsJsonArray();
if (tagsArr.size() == 0) {
return Collections.emptyList();
}
List<String> tags = new ArrayList<>();
tagsArr.forEach(tag-> tags.add(tag.getAsString()));
return tags;
}

private HttpBodyAndStatus inspectImage(String name) throws DockerAccessException {
String url = urlBuilder.inspectImage(name);
try {
Expand Down
44 changes: 30 additions & 14 deletions src/main/java/io/fabric8/maven/docker/service/BuildService.java
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ protected void buildImage(ImageConfiguration imageConfig, MojoParameters params,
String newImageId = doBuildImage(imageName, dockerArchive, opts);
log.info("%s: Built image %s", imageConfig.getDescription(), newImageId);

removeDanglingImage(imageName, oldImageId, newImageId, cleanupMode);
removeDanglingImage(imageName, oldImageId, newImageId, cleanupMode, true);
}

public void tagImage(String imageName, String tag, String repo, CleanupMode cleanupMode) throws DockerAccessException {
Expand All @@ -200,7 +200,7 @@ public void tagImage(String imageName, String tag, String repo, CleanupMode clea

String newImageId = queryService.getImageId(fullImageName);

removeDanglingImage(fullImageName, oldImageId, newImageId, cleanupMode);
removeDanglingImage(fullImageName, oldImageId, newImageId, cleanupMode, false);
}
}

Expand Down Expand Up @@ -392,7 +392,7 @@ private void autoPullBaseImage(ImageConfiguration imageConfig, ImagePullManager

String newImageId = queryService.getImageId(fromImage);

removeDanglingImage(fromImage, oldImageId, newImageId, cleanupMode);
removeDanglingImage(fromImage, oldImageId, newImageId, cleanupMode, false);
}
}
}
Expand All @@ -419,7 +419,7 @@ private void autoPullCacheFromImage(ImageConfiguration imageConfig, ImagePullMan

String newImageId = queryService.getImageId(cacheFromImage);

removeDanglingImage(cacheFromImage, oldImageId, newImageId, cleanupMode);
removeDanglingImage(cacheFromImage, oldImageId, newImageId, cleanupMode, false);
}
}

Expand Down Expand Up @@ -451,22 +451,38 @@ private List<String> extractBaseFromDockerfile(BuildImageConfiguration buildConf
return fromImage;
}

private void removeDanglingImage(String oldImageName, String oldImageId, String newImageId, CleanupMode cleanupMode) throws DockerAccessException {
private void removeDanglingImage(String oldImageName, String oldImageId, String newImageId, CleanupMode cleanupMode, boolean force) throws DockerAccessException {
if (oldImageId != null && !oldImageId.equals(newImageId)) {
try {
docker.removeImage(oldImageId, true);
log.info("%s: Removed dangling image %s", oldImageName, oldImageId);
} catch (DockerAccessException exp) {
if (cleanupMode == CleanupMode.TRY_TO_REMOVE) {
log.warn("%s: %s (dangling image)%s", oldImageName, exp.getMessage(),
(exp.getCause() != null ? " [" + exp.getCause().getMessage() + "]" : ""));
} else {
throw exp;
if (force) {
removeImage(oldImageName, oldImageId, cleanupMode, true);
} else {
// Verify that the image is indeed dangling and remove it (or skip removal altogether).
List<String> oldImageTags = docker.getImageTags(oldImageId);
if (oldImageTags != null) {
if (!oldImageTags.isEmpty()) {
removeImage(oldImageName, oldImageId, cleanupMode, false);
} else {
log.warn("%s: Skipped removing image %s; still tagged with: ", oldImageName, oldImageId, String.join(",", oldImageTags));
}
}
}
}
}

private void removeImage(String oldImageName, String oldImageId, CleanupMode cleanupMode, boolean force) throws DockerAccessException {
try {
docker.removeImage(oldImageId, force);
log.info("%s: Removed dangling image %s", oldImageName, oldImageId);
} catch (DockerAccessException exp) {
if (cleanupMode == CleanupMode.TRY_TO_REMOVE) {
log.warn("%s: %s (dangling image)%s", oldImageName, exp.getMessage(),
(exp.getCause() != null ? " [" + exp.getCause().getMessage() + "]" : ""));
} else {
throw exp;
}
}
}

private boolean checkForNocache(ImageConfiguration imageConfig) {
String noCache = System.getProperty("docker.noCache");
if (noCache == null) {
Expand Down

0 comments on commit 7b36470

Please sign in to comment.