diff --git a/core/src/main/java/org/testcontainers/images/builder/ImageFromDockerfile.java b/core/src/main/java/org/testcontainers/images/builder/ImageFromDockerfile.java index 2daed45b3fb..b35ef830c11 100644 --- a/core/src/main/java/org/testcontainers/images/builder/ImageFromDockerfile.java +++ b/core/src/main/java/org/testcontainers/images/builder/ImageFromDockerfile.java @@ -32,9 +32,11 @@ import java.nio.file.Path; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedHashSet; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.function.Consumer; import java.util.zip.GZIPOutputStream; @Slf4j @@ -62,6 +64,8 @@ public class ImageFromDockerfile private Optional target = Optional.empty(); + private final Set> buildImageCmdModifiers = new LinkedHashSet<>(); + private Set dependencyImageNames = Collections.emptySet(); public ImageFromDockerfile() { @@ -180,6 +184,7 @@ protected void configure(BuildImageCmd buildImageCmd) { this.buildArgs.forEach(buildImageCmd::withBuildArg); this.target.ifPresent(buildImageCmd::withTarget); + this.buildImageCmdModifiers.forEach(hook -> hook.accept(buildImageCmd)); } private void prePullDependencyImages(Set imagesToPull) { @@ -248,4 +253,16 @@ public ImageFromDockerfile withDockerfile(Path dockerfile) { this.dockerfile = Optional.of(dockerfile); return this; } + + /** + * Allow low level modifications of {@link BuildImageCmd}. + * Warning: this does expose the underlying docker-java API so might change outside of our control. + * + * @param modifier {@link Consumer} of {@link BuildImageCmd}. + * @return this + */ + public ImageFromDockerfile withBuildImageCmdModifier(Consumer modifier) { + this.buildImageCmdModifiers.add(modifier); + return this; + } } diff --git a/core/src/test/java/org/testcontainers/containers/MultiStageBuildTest.java b/core/src/test/java/org/testcontainers/containers/MultiStageBuildTest.java index 80ae37a0a07..f5bed1020c0 100644 --- a/core/src/test/java/org/testcontainers/containers/MultiStageBuildTest.java +++ b/core/src/test/java/org/testcontainers/containers/MultiStageBuildTest.java @@ -25,4 +25,20 @@ public void testDockerMultistageBuild() throws IOException, InterruptedException assertThat(container.execInContainer("ls").getStdout()).contains("hello.txt"); } } + + @Test + public void shouldBuildMultistageBuildWithBuildImageCmdModifier() throws IOException, InterruptedException { + try ( + GenericContainer container = new GenericContainer<>( + new ImageFromDockerfile() + .withDockerfile(Paths.get("src/test/resources/Dockerfile-multistage")) + .withBuildImageCmdModifier(cmd -> cmd.withTarget("builder")) + ) + .withCommand("/bin/sh", "-c", "sleep 10") + ) { + container.start(); + assertThat(container.execInContainer("pwd").getStdout()).contains("/my-files"); + assertThat(container.execInContainer("ls").getStdout()).contains("hello.txt"); + } + } }