Commit 31ff7f18 authored by Andy Wilkinson's avatar Andy Wilkinson

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".
parent 0270ccaf
...@@ -22,6 +22,7 @@ import java.io.IOException; ...@@ -22,6 +22,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern; import java.util.regex.Pattern;
...@@ -32,7 +33,9 @@ import javax.ws.rs.client.Entity; ...@@ -32,7 +33,9 @@ import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget; import javax.ws.rs.client.WebTarget;
import com.github.dockerjava.api.DockerClient; import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.DockerClientException;
import com.github.dockerjava.api.command.DockerCmd; 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.api.model.Frame;
import com.github.dockerjava.core.CompressArchiveUtil; import com.github.dockerjava.core.CompressArchiveUtil;
import com.github.dockerjava.core.DockerClientBuilder; import com.github.dockerjava.core.DockerClientBuilder;
...@@ -257,10 +260,58 @@ public class SysVinitLaunchScriptIT { ...@@ -257,10 +260,58 @@ public class SysVinitLaunchScriptIT {
} }
private String buildImage(DockerClient docker) { private String buildImage(DockerClient docker) {
BuildImageResultCallback resultCallback = new BuildImageResultCallback();
String dockerfile = "src/test/resources/conf/" + this.os + "/" + this.version String dockerfile = "src/test/resources/conf/" + this.os + "/" + this.version
+ "/Dockerfile"; + "/Dockerfile";
String tag = "spring-boot-it/" + this.os.toLowerCase() + ":" + this.version; String tag = "spring-boot-it/" + this.os.toLowerCase() + ":" + this.version;
BuildImageResultCallback resultCallback = new BuildImageResultCallback() {
private List<BuildResponseItem> items = new ArrayList<BuildResponseItem>();
@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); docker.buildImageCmd(new File(dockerfile)).withTag(tag).exec(resultCallback);
String imageId = resultCallback.awaitImageId(); String imageId = resultCallback.awaitImageId();
return imageId; return imageId;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment