Skip to content

Commit

Permalink
feat: Delete multiple images.
Browse files Browse the repository at this point in the history
Possible close bmuschko#1190
  • Loading branch information
red55 committed Oct 5, 2023
1 parent 4995eaa commit 7042649
Show file tree
Hide file tree
Showing 2 changed files with 258 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import com.bmuschko.gradle.docker.AbstractGroovyDslFunctionalTest
import org.gradle.testkit.runner.BuildResult

class DockerRemoveImageFunctionalTest extends AbstractGroovyDslFunctionalTest {
private static final String TEST_IMAGE2 = "alpine";
private static final String TEST_IMAGE2_TAG = "3.18.3";
public static final String TEST_IMAGE2_WITH_TAG = "${TEST_IMAGE2}:${TEST_IMAGE2_TAG}"

def "can remove image"() {
buildFile << """
Expand All @@ -21,13 +24,13 @@ class DockerRemoveImageFunctionalTest extends AbstractGroovyDslFunctionalTest {
dependsOn dockerfile
inputDir = file("build/docker")
}
task removeImage(type: DockerRemoveImage) {
dependsOn buildImage
force = true
targetImageId buildImage.getImageId()
}
task removeImageAndCheckRemoval(type: DockerListImages) {
dependsOn removeImage
showAll = true
Expand All @@ -39,6 +42,7 @@ class DockerRemoveImageFunctionalTest extends AbstractGroovyDslFunctionalTest {
BuildResult result = build('removeImageAndCheckRemoval')

then:
result.output.contains("[DEPRECATED]")
!result.output.contains("repository")
}

Expand All @@ -59,21 +63,21 @@ class DockerRemoveImageFunctionalTest extends AbstractGroovyDslFunctionalTest {
dependsOn dockerfile
inputDir = file("build/docker")
}
task tagImage(type: DockerTagImage) {
dependsOn buildImage
repository = "repository"
tag = "tag2"
targetImageId buildImage.getImageId()
}
task tagImageSecondTime(type: DockerTagImage) {
dependsOn tagImage
repository = "repository"
tag = "tag2"
targetImageId buildImage.getImageId()
}
task removeImage(type: DockerRemoveImage) {
dependsOn tagImageSecondTime
force = true
Expand All @@ -91,6 +95,120 @@ class DockerRemoveImageFunctionalTest extends AbstractGroovyDslFunctionalTest {
BuildResult result = build('removeImageAndCheckRemoval')

then:
result.output.contains("[DEPRECATED]")
!result.output.contains("repository")
}

def "can remove multiple images (ids from List<Property<T>>)"() {
buildFile << """
import com.bmuschko.gradle.docker.tasks.image.Dockerfile
import com.bmuschko.gradle.docker.tasks.image.DockerBuildImage
import com.bmuschko.gradle.docker.tasks.image.DockerListImages
import com.bmuschko.gradle.docker.tasks.image.DockerRemoveImage
import com.bmuschko.gradle.docker.tasks.image.DockerTagImage

task dockerfile1(type: Dockerfile) {
from '$TEST_IMAGE_WITH_TAG'
label(['maintainer': '[email protected]', 'test':'can remove multiple images (ids from List<Property<T>>)'])
}

task buildImage1(type: DockerBuildImage) {
dependsOn dockerfile1
inputDir = file("build/docker")
}

task dockerfile2(type: Dockerfile) {
from '$TEST_IMAGE2_WITH_TAG'
label(['maintainer': '[email protected]', 'test':'can remove multiple images (ids from List<Property<T>>)'])
}

task buildImage2(type: DockerBuildImage) {
dependsOn dockerfile2
inputDir = file("build/docker")
}

task removeImage(type: DockerRemoveImage) {
dependsOn buildImage1, buildImage2
force = true

targetImageIds = [buildImage1.imageId, buildImage2.imageId]

}

task removeImageAndCheckRemoval(type: DockerListImages) {
dependsOn removeImage
labels = ['test':'can remove multiple images (ids from List<Property<T>>)']
dangling = true
}

"""
when:
BuildResult result = build('removeImageAndCheckRemoval')
then:
!result.output.contains("[DEPRECATED]")
!result.output.contains("Repository Tags :")
}
def "can remove multiple images (ids from List<String>)"() {
buildFile << """
import com.bmuschko.gradle.docker.tasks.image.Dockerfile
import com.bmuschko.gradle.docker.tasks.image.DockerBuildImage
import com.bmuschko.gradle.docker.tasks.image.DockerListImages
import com.bmuschko.gradle.docker.tasks.image.DockerRemoveImage
import com.bmuschko.gradle.docker.tasks.image.DockerTagImage

tasks.register('dockerfile1', Dockerfile) {
from '$TEST_IMAGE_WITH_TAG'
label(['maintainer': '[email protected]', 'test':'can remove multiple images (ids from List<String>)'])
}

tasks.register('buildImage1', DockerBuildImage) {
dependsOn dockerfile1
inputDir = file("build/docker")
}

tasks.register('dockerfile2', Dockerfile) {
from '$TEST_IMAGE2_WITH_TAG'
label(['maintainer': '[email protected]', 'test':'can remove multiple images (ids from List<String>)'])
}

tasks.register('buildImage2', DockerBuildImage) {
dependsOn dockerfile2
inputDir = file("build/docker")
}

def images = []
tasks.register('listImages', DockerListImages) {
dependsOn tasks.named('buildImage1'), tasks.named('buildImage2')
labels = ['test':'can remove multiple images (ids from List<String>)']
dangling = true
onNext {
i -> images.add(i.Id)
}
}

tasks.register('removeImage', DockerRemoveImage) {
dependsOn tasks.named('listImages')
force = true

targetImageIds {
images
}
}

tasks.register('removeImageAndCheckRemoval', DockerListImages) {
dependsOn tasks.named('removeImage')
labels = ['test':'can remove multiple images (ids from List<String>)']
dangling = true
}

"""
when:
BuildResult result = build('removeImageAndCheckRemoval')
then:
!result.output.contains("[DEPRECATED]")
!result.output.contains("Repository Tags :")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,156 @@
*/
package com.bmuschko.gradle.docker.tasks.image;

import com.bmuschko.gradle.docker.tasks.AbstractDockerRemoteApiTask;
import com.fasterxml.jackson.databind.annotation.JsonAppend;
import com.github.dockerjava.api.command.RemoveImageCmd;
import groovy.lang.Closure;
import org.gradle.api.Action;
import org.gradle.api.internal.provider.PropertyFactory;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.provider.Provider;
import org.gradle.api.provider.ProviderFactory;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Optional;
import org.gradle.api.internal.provider.DefaultProperty;
import org.gradle.internal.lazy.Lazy;

public class DockerRemoveImage extends DockerExistingImage {
import java.util.List;
import java.util.concurrent.Callable;

public class DockerRemoveImage extends AbstractDockerRemoteApiTask {
private final ProviderFactory providers = getProject().getProviders();
private final ObjectFactory objects = getProject().getObjects();
private final Property<String> imageId = objects.property(String.class);

private final void issueDeprecationWarning(String propertyName) {
getLogger().warn("[DEPRECATED] DockerRemoveImage.{} is deprecated. Please use DockerRemoveImage.{}s.", propertyName, propertyName);
}

//region Obsolete
@Input
@Optional
@Deprecated
public final Property<String> getImageId() {
return imageId;

}

/**
* [Deprecated] Sets the target image ID or name.
*
* @param imageId Image ID or name
* @see #targetImageId(Callable)
* @see #targetImageId(Provider)
*/
@Deprecated
public void targetImageId(String imageId) {

issueDeprecationWarning("targetImageId");
this.imageId.set(imageId);
}

/**
* [Deprecated] Sets the target image ID or name.
*
* @param imageId Image ID or name as Callable
* @see #targetImageId(String)
* @see #targetImageId(Provider)
*/
@Deprecated
public void targetImageId(Callable<String> imageId) {

issueDeprecationWarning("targetImageId");
targetImageId(providers.provider(imageId));
}
/**
* [Deprecated] Sets the target image ID or name.
*
* @param imageId Image ID or name as Provider
* @see #targetImageId(String)
* @see #targetImageId(Callable)
*/
@Deprecated
public void targetImageId(Provider<String> imageId) {
issueDeprecationWarning("targetImageId");
this.imageId.set(imageId);
}
//endregion

protected ListProperty<String> imageIds = objects.listProperty(java.lang.String.class);
/**
* Gets the target image IDs
*
*/
@Input
@Optional
public ListProperty<String> getTargetImageIds() {
return imageIds;
}


public void setTargetImageIds(List<Property<String>> imageIds) {
this.imageIds = objects.listProperty(java.lang.String.class);

for (var id: imageIds) {
this.imageIds.add(id);
}
}

public void setTargetImageIds(Callable<List<String>> setImageIds) {
setTargetImageIds(providers.provider(setImageIds));
}

public void setTargetImageIds(Provider<List<String>> setImageIds) {
this.imageIds.set(setImageIds);
}

public void targetImageIds(Closure<List<String>> imageIds) {
setTargetImageIds(providers.provider(imageIds));
}

public void targetImageIds(List<String> imageIds) {
Callable<List<String>> task = () -> {
return imageIds;
};
setTargetImageIds(task);
}

@Input
@Optional
public final Property<Boolean> getForce() {
return force;
}

private final Property<Boolean> force = getProject().getObjects().property(Boolean.class);
private final Property<Boolean> force = objects.property(Boolean.class);

@Override
public void runRemoteCommand() {
getLogger().quiet("Removing image with ID \'" + getImageId().get() + "\'.");
RemoveImageCmd removeImageCmd = getDockerClient().removeImageCmd(getImageId().get());

if (Boolean.TRUE.equals(force.getOrNull())) {
removeImageCmd.withForce(force.get());
if (null != this.imageId.getOrNull()) {
getLogger().quiet("Removing image with ID '" + imageId.get() + ".");
try (RemoveImageCmd removeImageCmd = getDockerClient().removeImageCmd(imageId.get())) {
if (Boolean.TRUE.equals(force.getOrNull())) {
removeImageCmd.withForce(force.get());
}
removeImageCmd.exec();
}
} else {
getLogger().warn("DockerRemoveImage: Id for remove image is empty.");
}

removeImageCmd.exec();
if (null != this.imageIds.getOrNull() && !this.imageIds.get().isEmpty()) {
for (var id : this.imageIds.get()) {
getLogger().quiet("Removing image with ID '" + id + ".");
try (RemoveImageCmd removeImageCmd = getDockerClient().removeImageCmd(id)) {
if (Boolean.TRUE.equals(force.getOrNull())) {
removeImageCmd.withForce(force.get());
}
removeImageCmd.exec();
}
}
} else {
getLogger().warn("DockerRemoveImage: no image ids were set.");
}
}
}

0 comments on commit 7042649

Please sign in to comment.