use of org.eclipse.che.plugin.docker.client.json.ProgressStatus in project che by eclipse.
the class JsonMessageReaderTest method shouldReturnNullIfJsonIsIncorrect.
@Test
public void shouldReturnNullIfJsonIsIncorrect() throws IOException {
final String src = "not json";
final JsonMessageReader<ProgressStatus> reader = new JsonMessageReader<>(new ByteArrayInputStream(src.getBytes()), ProgressStatus.class);
assertNull(reader.next());
}
use of org.eclipse.che.plugin.docker.client.json.ProgressStatus in project che by eclipse.
the class JsonMessageReaderTest method shouldParseSequenceOfProcessStatusObjects.
@Test
public void shouldParseSequenceOfProcessStatusObjects() throws IOException {
final String src = "{\"stream\":\"Step 0 : FROM busybox\\n\"}\n" + "{\"status\":\"The image you are pulling has been verified\",\"id\":\"busybox:latest\"}\n";
final JsonMessageReader<ProgressStatus> reader = new JsonMessageReader<>(new ByteArrayInputStream(src.getBytes()), ProgressStatus.class);
final ProgressStatus status1 = reader.next();
final ProgressStatus status2 = reader.next();
assertEquals(status1.getStream(), "Step 0 : FROM busybox\n");
assertEquals(status2.getStatus(), "The image you are pulling has been verified");
assertEquals(status2.getId(), "busybox:latest");
assertNull(reader.next());
}
use of org.eclipse.che.plugin.docker.client.json.ProgressStatus in project che by eclipse.
the class DockerConnector method pull.
/**
* Pull an image from registry.
* To pull from private registry use registry.address:port/image as image.
*
* @param progressMonitor
* ProgressMonitor for images creation process
* @param dockerDaemonUri
* docker service URI
* @throws IOException
* when a problem occurs with docker api calls
*/
protected void pull(final PullParams params, final ProgressMonitor progressMonitor, final URI dockerDaemonUri) throws IOException {
try (DockerConnection connection = connectionFactory.openConnection(dockerDaemonUri).method("POST").path(apiVersionPathPrefix + "/images/create").query("fromImage", params.getFullRepo()).header("X-Registry-Auth", authResolver.getXRegistryAuthHeaderValue(params.getRegistry(), params.getAuthConfigs()))) {
addQueryParamIfNotNull(connection, "tag", params.getTag());
final DockerResponse response = connection.request();
if (OK.getStatusCode() != response.getStatus()) {
throw getDockerException(response);
}
try (InputStream responseStream = response.getInputStream()) {
JsonMessageReader<ProgressStatus> progressReader = new JsonMessageReader<>(responseStream, ProgressStatus.class);
// Here do some trick to be able interrupt output streaming process.
// Current unix socket implementation of DockerConnection doesn't react to interruption.
// So to be able to close unix socket connection and free resources we use main thread.
// In case of any exception main thread cancels future and close connection.
// If Docker connection implementation supports interrupting it will stop streaming on interruption,
// if not it will be stopped by closure of unix socket
Future<Object> pullFuture = executor.submit(() -> {
ProgressStatus progressStatus;
while ((progressStatus = progressReader.next()) != null) {
progressMonitor.updateProgress(progressStatus);
}
return null;
});
// perform get to be able to get execution exception
pullFuture.get();
} catch (ExecutionException e) {
// unwrap exception thrown by task with .getCause()
throw new DockerException(e.getCause().getLocalizedMessage(), 500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new DockerException("Docker image pulling was interrupted", 500);
}
}
}
use of org.eclipse.che.plugin.docker.client.json.ProgressStatus in project che by eclipse.
the class DockerConnector method buildImage.
private String buildImage(final DockerConnection dockerConnection, final BuildImageParams params, final ProgressMonitor progressMonitor) throws IOException {
final String repository = params.getRepository();
try (DockerConnection connection = dockerConnection.method("POST").path(apiVersionPathPrefix + "/build").header("X-Registry-Config", authResolver.getXRegistryConfigHeaderValue(params.getAuthConfigs()))) {
addQueryParamIfNotNull(connection, "rm", params.isRemoveIntermediateContainer());
addQueryParamIfNotNull(connection, "forcerm", params.isForceRemoveIntermediateContainers());
addQueryParamIfNotNull(connection, "memory", params.getMemoryLimit());
addQueryParamIfNotNull(connection, "memswap", params.getMemorySwapLimit());
addQueryParamIfNotNull(connection, "pull", params.isDoForcePull());
addQueryParamIfNotNull(connection, "dockerfile", params.getDockerfile());
addQueryParamIfNotNull(connection, "nocache", params.isNoCache());
addQueryParamIfNotNull(connection, "q", params.isQuiet());
addQueryParamIfNotNull(connection, "cpusetcpus", params.getCpusetCpus());
addQueryParamIfNotNull(connection, "cpuperiod", params.getCpuPeriod());
addQueryParamIfNotNull(connection, "cpuquota", params.getCpuQuota());
if (params.getTag() == null) {
addQueryParamIfNotNull(connection, "t", repository);
} else {
addQueryParamIfNotNull(connection, "t", repository == null ? null : repository + ':' + params.getTag());
}
if (params.getBuildArgs() != null) {
addQueryParamIfNotNull(connection, "buildargs", URLEncoder.encode(GSON.toJson(params.getBuildArgs()), "UTF-8"));
}
final DockerResponse response = connection.request();
if (OK.getStatusCode() != response.getStatus()) {
throw getDockerException(response);
}
try (InputStream responseStream = response.getInputStream()) {
JsonMessageReader<ProgressStatus> progressReader = new JsonMessageReader<>(responseStream, ProgressStatus.class);
// Here do some trick to be able interrupt output streaming process.
// Current unix socket implementation of DockerConnection doesn't react to interruption.
// So to be able to close unix socket connection and free resources we use main thread.
// In case of any exception main thread cancels future and close connection.
// If Docker connection implementation supports interrupting it will stop streaming on interruption,
// if not it will be stopped by closure of unix socket
Future<String> imageIdFuture = executor.submit(() -> {
ProgressStatus progressStatus;
while ((progressStatus = progressReader.next()) != null) {
if (progressStatus.getError() != null) {
String errorMessage = progressStatus.getError();
if (errorMessage.matches("Error: image .+ not found")) {
throw new ImageNotFoundException(errorMessage);
}
}
final String buildImageId = getBuildImageId(progressStatus);
if (buildImageId != null) {
return buildImageId;
}
progressMonitor.updateProgress(progressStatus);
}
throw new DockerException("Docker image build failed. Image id not found in build output.", 500);
});
return imageIdFuture.get();
} catch (ExecutionException e) {
// unwrap exception thrown by task with .getCause()
if (e.getCause() instanceof ImageNotFoundException) {
throw new ImageNotFoundException(e.getCause().getLocalizedMessage());
} else {
throw new DockerException(e.getCause().getLocalizedMessage(), 500);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new DockerException("Docker image build was interrupted", 500);
}
}
}
use of org.eclipse.che.plugin.docker.client.json.ProgressStatus in project che by eclipse.
the class DockerConnector method push.
/**
* Push docker image to the registry.
*
* @param progressMonitor
* ProgressMonitor for images pushing process
* @return digest of just pushed image
* @throws IOException
* when a problem occurs with docker api calls
*/
public String push(final PushParams params, final ProgressMonitor progressMonitor) throws IOException {
final String fullRepo = params.getFullRepo();
try (DockerConnection connection = connectionFactory.openConnection(dockerDaemonUri).method("POST").path(apiVersionPathPrefix + "/images/" + fullRepo + "/push").header("X-Registry-Auth", authResolver.getXRegistryAuthHeaderValue(params.getRegistry(), params.getAuthConfigs()))) {
addQueryParamIfNotNull(connection, "tag", params.getTag());
final DockerResponse response = connection.request();
if (OK.getStatusCode() != response.getStatus()) {
throw getDockerException(response);
}
try (InputStream responseStream = response.getInputStream()) {
JsonMessageReader<ProgressStatus> progressReader = new JsonMessageReader<>(responseStream, ProgressStatus.class);
// Here do some trick to be able interrupt output streaming process.
// Current unix socket implementation of DockerConnection doesn't react to interruption.
// So to be able to close unix socket connection and free resources we use main thread.
// In case of any exception main thread cancels future and close connection.
// If Docker connection implementation supports interrupting it will stop streaming on interruption,
// if not it will be stopped by closure of unix socket
Future<String> digestFuture = executor.submit(() -> {
String digestPrefix = firstNonNull(params.getTag(), "latest") + ": digest: ";
ProgressStatus progressStatus;
while ((progressStatus = progressReader.next()) != null) {
progressMonitor.updateProgress(progressStatus);
if (progressStatus.getError() != null) {
throw new DockerException(progressStatus.getError(), 500);
}
String status = progressStatus.getStatus();
// latest: digest: sha256:9a70e6222ded459fde37c56af23887467c512628eb8e78c901f3390e49a800a0 size: 62189
if (status != null && status.startsWith(digestPrefix)) {
return status.substring(digestPrefix.length(), status.indexOf(" ", digestPrefix.length()));
}
}
LOG.error("Docker image {}:{} was successfully pushed, but its digest wasn't obtained", fullRepo, firstNonNull(params.getTag(), "latest"));
throw new DockerException("Docker push response doesn't contain image digest", 500);
});
return digestFuture.get();
} catch (ExecutionException e) {
// unwrap exception thrown by task with .getCause()
throw new DockerException("Docker image pushing failed. Cause: " + e.getCause().getLocalizedMessage(), 500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new DockerException("Docker image pushing was interrupted", 500);
}
}
}
Aggregations