From 31ff7f1846d9df30205de869bf5c3155ea46617f Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Sat, 3 Jun 2017 13:00:15 +0100 Subject: [PATCH] Tolerate Successfully built being found in response other than last Different versions of Docker produce different responses when building and tagging an image. On CI, a response with a stream like "Successfully built 185991ffe24a" followed by a response with a stream like "Successfully tagged spring-boot-it/centos:6.9-a23bced6" is received. By default, for the building of an image to be considered successful, the Docker Java client requires the stream for the last response item to contain "Successfully built". This means that, on the CI server, it incorrectly believes that the building of the tagged image has failed. This commit uses a custom BuildImageResultCallback that doesn't require the last response to be the one that has a stream containing "Successfully built". Instead, it looks back through the error-free responses (newest to oldest) looking for one with a stream containing "Successfully built". --- .../launchscript/SysVinitLaunchScriptIT.java | 53 ++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/java/org/springframework/boot/launchscript/SysVinitLaunchScriptIT.java b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/java/org/springframework/boot/launchscript/SysVinitLaunchScriptIT.java index 2ad08cac5b..4d4156f75c 100644 --- a/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/java/org/springframework/boot/launchscript/SysVinitLaunchScriptIT.java +++ b/spring-boot-integration-tests/spring-boot-launch-script-tests/src/test/java/org/springframework/boot/launchscript/SysVinitLaunchScriptIT.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; @@ -32,7 +33,9 @@ import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.api.DockerClientException; import com.github.dockerjava.api.command.DockerCmd; +import com.github.dockerjava.api.model.BuildResponseItem; import com.github.dockerjava.api.model.Frame; import com.github.dockerjava.core.CompressArchiveUtil; import com.github.dockerjava.core.DockerClientBuilder; @@ -257,10 +260,58 @@ public class SysVinitLaunchScriptIT { } private String buildImage(DockerClient docker) { - BuildImageResultCallback resultCallback = new BuildImageResultCallback(); String dockerfile = "src/test/resources/conf/" + this.os + "/" + this.version + "/Dockerfile"; String tag = "spring-boot-it/" + this.os.toLowerCase() + ":" + this.version; + BuildImageResultCallback resultCallback = new BuildImageResultCallback() { + + private List items = new ArrayList(); + + @Override + public void onNext(BuildResponseItem item) { + super.onNext(item); + this.items.add(item); + } + + @Override + public String awaitImageId() { + try { + awaitCompletion(); + } + catch (InterruptedException ex) { + throw new DockerClientException( + "Interrupted while waiting for image id", ex); + } + return getImageId(); + } + + @SuppressWarnings("deprecation") + private String getImageId() { + if (this.items.isEmpty()) { + throw new DockerClientException("Could not build image"); + } + String imageId = extractImageId(); + if (imageId == null) { + throw new DockerClientException("Could not build image: " + + this.items.get(this.items.size() - 1).getError()); + } + return imageId; + } + + private String extractImageId() { + Collections.reverse(this.items); + for (BuildResponseItem item : this.items) { + if (item.isErrorIndicated() || item.getStream() == null) { + return null; + } + if (item.getStream().contains("Successfully built")) { + return item.getStream().replace("Successfully built", "").trim(); + } + } + return null; + } + + }; docker.buildImageCmd(new File(dockerfile)).withTag(tag).exec(resultCallback); String imageId = resultCallback.awaitImageId(); return imageId;