diff --git a/src/main/java/io/fabric8/maven/docker/service/BuildService.java b/src/main/java/io/fabric8/maven/docker/service/BuildService.java index 8b43388ce..c9e53a331 100644 --- a/src/main/java/io/fabric8/maven/docker/service/BuildService.java +++ b/src/main/java/io/fabric8/maven/docker/service/BuildService.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.LinkedList; import io.fabric8.maven.docker.access.BuildOptions; import io.fabric8.maven.docker.access.DockerAccess; @@ -199,14 +200,20 @@ private void autoPullBaseImage(ImageConfiguration imageConfig, ImagePullManager return; } - String fromImage; + List fromImages; if (buildConfig.isDockerFileMode()) { - fromImage = extractBaseFromDockerfile(buildConfig, buildContext); + fromImages = extractBaseFromDockerfile(buildConfig, buildContext); } else { - fromImage = extractBaseFromConfiguration(buildConfig); + fromImages = new LinkedList<>(); + String baseImage = extractBaseFromConfiguration(buildConfig); + if (baseImage!=null) { + fromImages.add(extractBaseFromConfiguration(buildConfig)); + } } - if (fromImage != null && !DockerAssemblyManager.SCRATCH_IMAGE.equals(fromImage)) { - registryService.pullImageWithPolicy(fromImage, imagePullManager, buildContext.getRegistryConfig(), queryService.hasImage(fromImage)); + for (String fromImage : fromImages) { + if (fromImage != null && !DockerAssemblyManager.SCRATCH_IMAGE.equals(fromImage)) { + registryService.pullImageWithPolicy(fromImage, imagePullManager, buildContext.getRegistryConfig(), queryService.hasImage(fromImage)); + } } } @@ -222,17 +229,17 @@ private String extractBaseFromConfiguration(BuildImageConfiguration buildConfig) return fromImage; } - private String extractBaseFromDockerfile(BuildImageConfiguration buildConfig, BuildContext buildContext) { - String fromImage; + private List extractBaseFromDockerfile(BuildImageConfiguration buildConfig, BuildContext buildContext) { + List fromImage; try { File fullDockerFilePath = buildConfig.getAbsoluteDockerFilePath(buildContext.getMojoParameters()); - fromImage = DockerFileUtil.extractBaseImage( + fromImage = DockerFileUtil.extractBaseImages( fullDockerFilePath, DockerFileUtil.createInterpolator(buildContext.getMojoParameters(), buildConfig.getFilter())); } catch (IOException e) { // Cant extract base image, so we wont try an auto pull. An error will occur later anyway when // building the image, so we are passive here. - fromImage = null; + return Collections.emptyList(); } return fromImage; } diff --git a/src/main/java/io/fabric8/maven/docker/util/DockerFileUtil.java b/src/main/java/io/fabric8/maven/docker/util/DockerFileUtil.java index 384abf6a1..1fc5fc099 100644 --- a/src/main/java/io/fabric8/maven/docker/util/DockerFileUtil.java +++ b/src/main/java/io/fabric8/maven/docker/util/DockerFileUtil.java @@ -17,6 +17,7 @@ import java.io.*; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -43,16 +44,31 @@ private DockerFileUtil() {} * * @param dockerFile file from where to extract the base image * @param interpolator interpolator for replacing properties + * @deprecated Use {@link DockerFileUtil#extractBaseImages} extractBaseImages instead */ + @Deprecated public static String extractBaseImage(File dockerFile, FixedStringSearchInterpolator interpolator) throws IOException { + List result = extractBaseImages(dockerFile, interpolator); + return result.isEmpty() ? null : result.iterator().next(); + } + + /** + * Extract the base images from a dockerfile. All lines containing a FROM is + * taken. + * + * @param dockerFile file from where to extract the base image + * @param interpolator interpolator for replacing properties + * @return LinkedList of base images name or empty collection if none is found. + */ + public static List extractBaseImages(File dockerFile, FixedStringSearchInterpolator interpolator) throws IOException { List fromLines = extractLines(dockerFile, "FROM", interpolator); - if (!fromLines.isEmpty()) { - String[] parts = fromLines.get(0); - if (parts.length > 1) { - return parts[1]; + LinkedList result = new LinkedList<>(); + for (String[] fromLine : fromLines) { + if (fromLine.length > 1) { + result.add(fromLine[1]); } } - return null; + return result; } /** diff --git a/src/test/java/io/fabric8/maven/docker/util/DockerFileUtilTest.java b/src/test/java/io/fabric8/maven/docker/util/DockerFileUtilTest.java index ff245c641..26b707140 100644 --- a/src/test/java/io/fabric8/maven/docker/util/DockerFileUtilTest.java +++ b/src/test/java/io/fabric8/maven/docker/util/DockerFileUtilTest.java @@ -17,11 +17,7 @@ import java.io.*; import java.nio.file.Files; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; +import java.util.*; import org.apache.commons.io.FileUtils; import org.apache.maven.artifact.repository.ArtifactRepository; @@ -52,6 +48,17 @@ public void testSimple() throws Exception { toTest, FixedStringSearchInterpolator.create())); } + @Test + public void testMultiStage() throws Exception { + File toTest = copyToTempDir("Dockerfile_multi_stage"); + Iterator fromClauses = DockerFileUtil.extractBaseImages( + toTest, FixedStringSearchInterpolator.create()).iterator(); + + assertEquals("fabric8/s2i-java", fromClauses.next()); + assertEquals("fabric8/s1i-java", fromClauses.next()); + assertEquals(false, fromClauses.hasNext()); + } + private File copyToTempDir(String resource) throws IOException { File dir = Files.createTempDirectory("d-m-p").toFile(); File ret = new File(dir, "Dockerfile"); diff --git a/src/test/resources/io/fabric8/maven/docker/util/Dockerfile_multi_stage b/src/test/resources/io/fabric8/maven/docker/util/Dockerfile_multi_stage new file mode 100644 index 000000000..368439a1f --- /dev/null +++ b/src/test/resources/io/fabric8/maven/docker/util/Dockerfile_multi_stage @@ -0,0 +1,6 @@ +# Dockerfile with a multi FROM clause +# see https://docs.docker.com/develop/develop-images/multistage-build/ + +FROM fabric8/s2i-java + +FROM fabric8/s1i-java \ No newline at end of file