Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public boolean isPullSuccessIndicated() {
}

return (getStatus().contains("Download complete") || getStatus().contains("Image is up to date") || getStatus()
.contains("Downloaded newer image"));
.contains("Downloaded newer image") || getStatus().contains(": downloaded"));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
*/
package com.github.dockerjava.core.command;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.dockerjava.api.DockerClientException;
import com.github.dockerjava.api.model.PullResponseItem;
import com.github.dockerjava.core.async.ResultCallbackTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;

/**
*
Expand All @@ -19,14 +21,71 @@ public class PullImageResultCallback extends ResultCallbackTemplate<PullImageRes

private final static Logger LOGGER = LoggerFactory.getLogger(PullImageResultCallback.class);

private boolean isSwarm = false;
private Map<String, PullResponseItem> results = null;
private PullResponseItem latestItem = null;

@Override
public void onNext(PullResponseItem item) {
this.latestItem = item;
// only do it once
if (results == null && latestItem == null) {
checkForDockerSwarmResponse(item);
}

if (isSwarm) {
handleDockerSwarmResponse(item);
} else {
handleDockerClientResponse(item);
}
LOGGER.debug(item.toString());
}

private void checkForDockerSwarmResponse(PullResponseItem item) {
if (item.getStatus().matches("Pulling\\s.+\\.{3}$")) {
isSwarm = true;
LOGGER.debug("Communicating with Docker Swarm.");
}
}

private void handleDockerSwarmResponse(PullResponseItem item) {
if (results == null) {
results = new HashMap<String, PullResponseItem>();
}
results.put(item.getId(), item);
}

private void checkDockerSwarmPullSuccessful() {
if (results.isEmpty()) {
throw new DockerClientException("Could not pull image");
} else {
boolean pullFailed = false;
StringBuilder sb = new StringBuilder();

for (PullResponseItem pullResponseItem : results.values()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How this should work. The first item that doesn't indicate a succesfull pull will lead to pull error.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Swarm works like so. When you issue a pull cmd, it returns following responses as PullResponseItem for each node in the swarm:
21:38:57.269 DEBUG c.g.d.c.c.PullImageResultCallback - PullResponseItem[stream=<null>,status=Pulling ci1.camunda.loc:5000/camunda-ci-postgresql:9.4...,progressDetail=ResponseItem.ProgressDetail[current=0,total=0,start=0],progress=<null>,id=ci7.camunda.loc,from=<null>,time=0,errorDetail=<null>,error=<null>]
When a pull is successfully for a swarm node following PullResponseItem is returned:
21:39:04.513 DEBUG c.g.d.c.c.PullImageResultCallback - PullResponseItem[stream=<null>,status=Pulling ci1.camunda.loc:5000/camunda-ci-postgresql:9.4... : downloaded,progressDetail=ResponseItem.ProgressDetail[current=0,total=0,start=0],progress=<null>,id=ci3.camunda.loc,from=<null>,time=0,errorDetail=<null>,error=<null>]
There are only these two responses for each swarm node when a pull request is successfull.

My code will first collect all PullResponseItems ordered by node id as key. So only the latest PullResponseItem of each node will be stored, previous ones overwritten.
When the PullImageCmd is finished and awaitSuccess method continues to evaluate the success of the pull, it will check the last result of each node. When one of those results indicates a failed pull, it will throw an exception with all nodes where the pull failed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Now i got it. Thanks!

if (!pullResponseItem.isPullSuccessIndicated()) {
pullFailed = true;
sb.append("[" + pullResponseItem.getId() + ";" + pullResponseItem.getError() + "]");
}
}

if (pullFailed) {
throw new DockerClientException("Could not pull image: " + sb.toString());
}
}
}

private void handleDockerClientResponse(PullResponseItem item) {
latestItem = item;
}

private void checkDockerClientPullSuccessful() {
if (latestItem == null) {
throw new DockerClientException("Could not pull image");
} else if (!latestItem.isPullSuccessIndicated()) {
throw new DockerClientException("Could not pull image: " + latestItem.getError());
}
}

/**
* Awaits the image to be pulled successful.
*
Expand All @@ -40,10 +99,10 @@ public void awaitSuccess() {
throw new DockerClientException("", e);
}

if (latestItem == null) {
throw new DockerClientException("Could not pull image");
} else if (!latestItem.isPullSuccessIndicated()) {
throw new DockerClientException("Could not pull image: " + latestItem.getError());
if (isSwarm) {
checkDockerSwarmPullSuccessful();
} else {
checkDockerClientPullSuccessful();
}
}
}