Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to define a custom ImagePullPolicy via configuration #7520

Merged
merged 9 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 41 additions & 1 deletion core/src/main/java/org/testcontainers/images/PullPolicy.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,62 @@
package org.testcontainers.images;

import com.google.common.annotations.VisibleForTesting;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.testcontainers.utility.TestcontainersConfiguration;

import java.time.Duration;

/**
* Convenience class with logic for building common {@link ImagePullPolicy} instances.
*
*/
@Slf4j
@UtilityClass
public class PullPolicy {

@VisibleForTesting
static ImagePullPolicy instance;

@VisibleForTesting
static ImagePullPolicy defaultImplementation = new DefaultPullPolicy();

/**
* Convenience method for returning the {@link DefaultPullPolicy} default image pull policy
* @return {@link ImagePullPolicy}
*/
public static ImagePullPolicy defaultPolicy() {
return new DefaultPullPolicy();
if (instance == null) {
eddumelendez marked this conversation as resolved.
Show resolved Hide resolved
String imagePullPolicyClassName = TestcontainersConfiguration.getInstance().getImagePullPolicy();
if (imagePullPolicyClassName != null) {
log.debug("Attempting to instantiate an ImagePullPolicy with class: {}", imagePullPolicyClassName);
ImagePullPolicy configuredInstance;
try {
configuredInstance =
(ImagePullPolicy) Thread
.currentThread()
.getContextClassLoader()
.loadClass(imagePullPolicyClassName)
.getConstructor()
.newInstance();
} catch (Exception e) {
throw new IllegalArgumentException(
kiview marked this conversation as resolved.
Show resolved Hide resolved
"Configured ImagePullPolicy could not be loaded: " + imagePullPolicyClassName,
e
);
}

log.info("Found configured Image Pull Policy: {}", configuredInstance.getClass());

instance = configuredInstance;
} else {
instance = defaultImplementation;
}

log.info("Image pull policy will be performed by: {}", instance);
}

return instance;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class RemoteDockerImage extends LazyFuture<String> {
private Future<DockerImageName> imageNameFuture;

@With
private ImagePullPolicy imagePullPolicy = PullPolicy.defaultPolicy();
ImagePullPolicy imagePullPolicy = PullPolicy.defaultPolicy();

@With
private ImageNameSubstitutor imageNameSubstitutor = ImageNameSubstitutor.instance();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ public String getImageSubstitutorClassName() {
return getEnvVarOrProperty("image.substitutor", null);
}

public String getImagePullPolicy() {
return getEnvVarOrProperty("pull.policy", null);
}

public Integer getClientPingTimeout() {
return Integer.parseInt(getEnvVarOrProperty("client.ping.timeout", "10"));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.testcontainers.images;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mockito;
import org.testcontainers.DockerRegistryContainer;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.utility.FakeImagePullPolicy;
import org.testcontainers.utility.MockTestcontainersConfigurationRule;
import org.testcontainers.utility.TestcontainersConfiguration;

import static org.assertj.core.api.Assertions.assertThat;

public class OverrideImagePullPolicyTest {

@Rule
public MockTestcontainersConfigurationRule config = new MockTestcontainersConfigurationRule();

private ImagePullPolicy originalInstance;

private ImagePullPolicy originalDefaultImplementation;

@Before
public void setUp() {
this.originalInstance = PullPolicy.instance;
this.originalDefaultImplementation = PullPolicy.defaultImplementation;
PullPolicy.instance = null;
PullPolicy.defaultImplementation = Mockito.mock(ImagePullPolicy.class);
}

@After
public void tearDown() {
PullPolicy.instance = originalInstance;
PullPolicy.defaultImplementation = originalDefaultImplementation;
}

@Test
public void simpleConfigurationTest() {
Mockito
.doReturn(FakeImagePullPolicy.class.getCanonicalName())
.when(TestcontainersConfiguration.getInstance())
.getImagePullPolicy();

try (DockerRegistryContainer registry = new DockerRegistryContainer()) {
registry.start();
GenericContainer<?> container = new GenericContainer<>(registry.createImage()).withExposedPorts(8080);
container.start();
assertThat(container.getImage().imagePullPolicy).isInstanceOf(FakeImagePullPolicy.class);
container.stop();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.testcontainers.utility;

import org.testcontainers.images.AbstractImagePullPolicy;
import org.testcontainers.images.ImageData;

public class FakeImagePullPolicy extends AbstractImagePullPolicy {

@Override
protected boolean shouldPullCached(DockerImageName imageName, ImageData localImageData) {
return false;
}
}