Skip to content

Commit

Permalink
Add support of docker multi stage builds
Browse files Browse the repository at this point in the history
  • Loading branch information
kostia.kolesnichenko committed Jul 23, 2018
1 parent fee0393 commit dc4c1a9
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 19 deletions.
25 changes: 16 additions & 9 deletions src/main/java/io/fabric8/maven/docker/service/BuildService.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -199,14 +200,20 @@ private void autoPullBaseImage(ImageConfiguration imageConfig, ImagePullManager
return;
}

String fromImage;
List<String> 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));
}
}
}

Expand All @@ -222,17 +229,17 @@ private String extractBaseFromConfiguration(BuildImageConfiguration buildConfig)
return fromImage;
}

private String extractBaseFromDockerfile(BuildImageConfiguration buildConfig, BuildContext buildContext) {
String fromImage;
private List<String> extractBaseFromDockerfile(BuildImageConfiguration buildConfig, BuildContext buildContext) {
List<String> 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;
}
Expand Down
25 changes: 20 additions & 5 deletions src/main/java/io/fabric8/maven/docker/util/DockerFileUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -44,15 +45,29 @@ private DockerFileUtil() {}
* @param dockerFile file from where to extract the base image
* @param interpolator interpolator for replacing properties
*/
@Deprecated
public static String extractBaseImage(File dockerFile, FixedStringSearchInterpolator interpolator) throws IOException {
LinkedList<String> result = extractBaseImages(dockerFile, interpolator);
return result.isEmpty() ? null : result.getFirst();
}

/**
* Extract the base images from a dockerfile. All lines containing a <code>FROM</code> 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 LinkedList<String> extractBaseImages(File dockerFile, FixedStringSearchInterpolator interpolator) throws IOException {
List<String[]> fromLines = extractLines(dockerFile, "FROM", interpolator);
if (!fromLines.isEmpty()) {
String[] parts = fromLines.get(0);
if (parts.length > 1) {
return parts[1];
LinkedList<String> result = new LinkedList<>();
for (String[] fromLine : fromLines) {
if (fromLine.length > 1) {
result.add(fromLine[1]);
}
}
return null;
return result;
}

/**
Expand Down
17 changes: 12 additions & 5 deletions src/test/java/io/fabric8/maven/docker/util/DockerFileUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<String> 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");
Expand Down
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit dc4c1a9

Please sign in to comment.