diff --git a/CHANGELOG.md b/CHANGELOG.md index 53bb9d213a..9637a84453 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ Usage: * Fix 440: Added quickstart for MicroProfile running on OpenLiberty * Fix: Valid content type for REST docker API requests with body * Fix #448: Service.spec.type added from config if existing Service fragment doesn't specify it +* Fix: Docker push works with Podman REST API ### 1.0.1 (2020-10-05) * Fix #381: Remove root as default user in AssemblyConfigurationUtils#getAssemblyConfigurationOrCreateDefault diff --git a/jkube-kit/build/service/docker/src/main/java/org/eclipse/jkube/kit/build/service/docker/access/hc/DockerAccessWithHcClient.java b/jkube-kit/build/service/docker/src/main/java/org/eclipse/jkube/kit/build/service/docker/access/hc/DockerAccessWithHcClient.java index e6dc41b21d..1d23e40f97 100644 --- a/jkube-kit/build/service/docker/src/main/java/org/eclipse/jkube/kit/build/service/docker/access/hc/DockerAccessWithHcClient.java +++ b/jkube-kit/build/service/docker/src/main/java/org/eclipse/jkube/kit/build/service/docker/access/hc/DockerAccessWithHcClient.java @@ -46,7 +46,6 @@ import org.eclipse.jkube.kit.build.service.docker.access.DockerAccessException; import org.eclipse.jkube.kit.build.service.docker.access.UrlBuilder; import org.eclipse.jkube.kit.build.service.docker.access.chunked.BuildJsonResponseHandler; -import org.eclipse.jkube.kit.build.service.docker.access.chunked.EntityStreamReaderUtil; import org.eclipse.jkube.kit.build.service.docker.access.chunked.PullOrPushResponseJsonHandler; import org.eclipse.jkube.kit.build.service.docker.access.hc.http.HttpClientBuilder; import org.eclipse.jkube.kit.build.service.docker.access.hc.unix.UnixSocketClientBuilder; @@ -174,7 +173,7 @@ public void startExecContainer(String containerId, LogOutputSpec outputSpec) thr } } - private ResponseHandler createExecResponseHandler(LogOutputSpec outputSpec) throws FileNotFoundException { + private ResponseHandler createExecResponseHandler(LogOutputSpec outputSpec) { final LogCallback callback = new DefaultLogCallback(outputSpec); return new ResponseHandler() { @Override @@ -707,25 +706,6 @@ private static boolean isSSL(String url) { return url != null && url.toLowerCase().startsWith("https"); } - // Preparation for performing requests - private static class HcChunkedResponseHandlerWrapper implements ResponseHandler { - - private EntityStreamReaderUtil.JsonEntityResponseHandler handler; - - HcChunkedResponseHandlerWrapper(EntityStreamReaderUtil.JsonEntityResponseHandler handler) { - this.handler = handler; - } - - @Override - public Object handleResponse(HttpResponse response) throws IOException { - try (InputStream stream = response.getEntity().getContent()) { - // Parse text as json - EntityStreamReaderUtil.processJsonStream(handler, stream); - } - return null; - } - } - public String fetchApiVersionFromServer(String baseUrl, ApacheHttpClientDelegate delegate) throws IOException { HttpGet get = new HttpGet(baseUrl + (baseUrl.endsWith("/") ? "" : "/") + "version"); get.addHeader(HttpHeaders.ACCEPT, "*/*"); diff --git a/jkube-kit/build/service/docker/src/main/java/org/eclipse/jkube/kit/build/service/docker/access/hc/HcChunkedResponseHandlerWrapper.java b/jkube-kit/build/service/docker/src/main/java/org/eclipse/jkube/kit/build/service/docker/access/hc/HcChunkedResponseHandlerWrapper.java new file mode 100644 index 0000000000..879c7a07bf --- /dev/null +++ b/jkube-kit/build/service/docker/src/main/java/org/eclipse/jkube/kit/build/service/docker/access/hc/HcChunkedResponseHandlerWrapper.java @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2019 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at: + * + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.jkube.kit.build.service.docker.access.hc; + +import org.apache.http.HttpResponse; +import org.apache.http.client.ResponseHandler; +import org.eclipse.jkube.kit.build.service.docker.access.chunked.EntityStreamReaderUtil; + +import java.io.IOException; +import java.io.InputStream; +import java.util.stream.Stream; + +class HcChunkedResponseHandlerWrapper implements ResponseHandler { + + private final EntityStreamReaderUtil.JsonEntityResponseHandler handler; + + HcChunkedResponseHandlerWrapper(EntityStreamReaderUtil.JsonEntityResponseHandler handler) { + this.handler = handler; + } + + @Override + public Object handleResponse(HttpResponse response) throws IOException { + try (InputStream stream = response.getEntity().getContent()) { + // Parse text as json + if (isJson(response)) { + EntityStreamReaderUtil.processJsonStream(handler, stream); + } + } + return null; + } + + private static boolean isJson(HttpResponse response) { + return Stream.of(response.getAllHeaders()) + .filter(h -> h.getName().equalsIgnoreCase("Content-Type")) + .anyMatch(h -> h.getValue().toLowerCase().startsWith("application/json")); + } +} diff --git a/jkube-kit/build/service/docker/src/test/java/org/eclipse/jkube/kit/build/service/docker/access/hc/HcChunkedResponseHandlerWrapperTest.java b/jkube-kit/build/service/docker/src/test/java/org/eclipse/jkube/kit/build/service/docker/access/hc/HcChunkedResponseHandlerWrapperTest.java new file mode 100644 index 0000000000..fb34455ce2 --- /dev/null +++ b/jkube-kit/build/service/docker/src/test/java/org/eclipse/jkube/kit/build/service/docker/access/hc/HcChunkedResponseHandlerWrapperTest.java @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2019 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at: + * + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ +package org.eclipse.jkube.kit.build.service.docker.access.hc; + +import java.io.IOException; + +import org.eclipse.jkube.kit.build.service.docker.access.chunked.EntityStreamReaderUtil; + +import mockit.Expectations; +import mockit.Mocked; +import mockit.Verifications; +import org.apache.http.Header; +import org.apache.http.HttpResponse; +import org.apache.http.message.BasicHeader; +import org.junit.Before; +import org.junit.Test; + +@SuppressWarnings("unused") +public class HcChunkedResponseHandlerWrapperTest { + + @Mocked + private EntityStreamReaderUtil.JsonEntityResponseHandler handler; + @Mocked + private HttpResponse response; + @Mocked + private EntityStreamReaderUtil entityStreamReaderUtil; + + private Header[] headers; + private HcChunkedResponseHandlerWrapper hcChunkedResponseHandlerWrapper; + + @Before + public void setUp() { + hcChunkedResponseHandlerWrapper = new HcChunkedResponseHandlerWrapper(handler); + + } + + @Test + public void handleResponseWithJsonResponse() throws IOException { + givenResponseHeaders(new BasicHeader("ConTenT-Type", "application/json; charset=UTF-8")); + hcChunkedResponseHandlerWrapper.handleResponse(response); + verifyProcessJsonStream(1); + } + + @Test + public void handleResponseWithTextPlainResponse() throws IOException { + givenResponseHeaders(new BasicHeader("Content-Type", "text/plain")); + hcChunkedResponseHandlerWrapper.handleResponse(response); + verifyProcessJsonStream(0); + } + + @Test + public void handleResponseWithNoContentType() throws IOException { + givenResponseHeaders(); + hcChunkedResponseHandlerWrapper.handleResponse(response); + verifyProcessJsonStream(0); + } + + private void givenResponseHeaders(Header... headers) { + // @formatter:off + new Expectations() {{ + response.getAllHeaders(); result = headers; + }}; + // @formatter:on + } + + @SuppressWarnings("AccessStaticViaInstance") + private void verifyProcessJsonStream(int timesCalled) throws IOException { + // @formatter:off + new Verifications() {{ + entityStreamReaderUtil.processJsonStream(handler, response.getEntity().getContent()); times = timesCalled; + }}; + // @formatter:on + } +} \ No newline at end of file diff --git a/jkube-kit/config/service/src/main/java/org/eclipse/jkube/kit/config/service/kubernetes/DockerBuildService.java b/jkube-kit/config/service/src/main/java/org/eclipse/jkube/kit/config/service/kubernetes/DockerBuildService.java index 38c244f21d..f5946644bb 100644 --- a/jkube-kit/config/service/src/main/java/org/eclipse/jkube/kit/config/service/kubernetes/DockerBuildService.java +++ b/jkube-kit/config/service/src/main/java/org/eclipse/jkube/kit/config/service/kubernetes/DockerBuildService.java @@ -49,7 +49,7 @@ public void build(ImageConfiguration imageConfig) throws JKubeServiceException { // Assume we always want to tag jKubeServiceHub.getDockerServiceHub().getBuildService().tagImage(imageConfig.getName(), imageConfig); } catch (IOException ex) { - throw new JKubeServiceException("Error while trying to build the image", ex); + throw new JKubeServiceException("Error while trying to build the image: " + ex.getMessage(), ex); } } @@ -59,7 +59,7 @@ public void push(Collection imageConfigs, int retries, Regis jKubeServiceHub.getDockerServiceHub().getRegistryService() .pushImages(imageConfigs, retries, registryConfig, skipTag); } catch (IOException ex) { - throw new JKubeServiceException("Error while trying to push the image", ex); + throw new JKubeServiceException("Error while trying to push the image: " + ex.getMessage(), ex); } }