From e6f13f85943b258d6db1f2d477e8dc57713040f7 Mon Sep 17 00:00:00 2001 From: Yoann Dubreuil Date: Wed, 18 Jun 2014 11:38:07 +0200 Subject: [PATCH] Refactor BuildImgCmd command to accept the docker tar folder as a InputStream, so we can build it on the fly without a temporary folder. --- .../dockerjava/client/DockerClient.java | 6 +- .../client/command/BuildImgCmd.java | 73 ++++++++++++------- 2 files changed, 51 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/github/dockerjava/client/DockerClient.java b/src/main/java/com/github/dockerjava/client/DockerClient.java index 22e78b7c4..b7d0993ed 100644 --- a/src/main/java/com/github/dockerjava/client/DockerClient.java +++ b/src/main/java/com/github/dockerjava/client/DockerClient.java @@ -19,6 +19,7 @@ import org.apache.http.impl.conn.PoolingClientConnectionManager; import com.github.dockerjava.client.command.AbstrDockerCmd; +import com.github.dockerjava.client.command.AttachContainerCmd; import com.github.dockerjava.client.command.AuthCmd; import com.github.dockerjava.client.command.BuildImgCmd; import com.github.dockerjava.client.command.CommitCmd; @@ -32,7 +33,6 @@ import com.github.dockerjava.client.command.KillContainerCmd; import com.github.dockerjava.client.command.ListContainersCmd; import com.github.dockerjava.client.command.ListImagesCmd; -import com.github.dockerjava.client.command.AttachContainerCmd; import com.github.dockerjava.client.command.LogContainerCmd; import com.github.dockerjava.client.command.PullImageCmd; import com.github.dockerjava.client.command.PushImageCmd; @@ -326,6 +326,10 @@ public BuildImgCmd buildImageCmd(File dockerFolder) { return new BuildImgCmd(dockerFolder).withBaseResource(baseResource); } + public BuildImgCmd buildImageCmd(InputStream tarInputStream) { + return new BuildImgCmd(tarInputStream).withBaseResource(baseResource); + } + public TopContainerCmd topContainerCmd(String containerId) { return new TopContainerCmd(containerId).withBaseResource(baseResource); } diff --git a/src/main/java/com/github/dockerjava/client/command/BuildImgCmd.java b/src/main/java/com/github/dockerjava/client/command/BuildImgCmd.java index b50b9eefc..edaa3110c 100644 --- a/src/main/java/com/github/dockerjava/client/command/BuildImgCmd.java +++ b/src/main/java/com/github/dockerjava/client/command/BuildImgCmd.java @@ -2,6 +2,7 @@ import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; @@ -33,7 +34,8 @@ public class BuildImgCmd extends AbstrDockerCmd { private static final Logger LOGGER = LoggerFactory.getLogger(BuildImgCmd.class); - private File dockerFolder; + private File dockerFolder = null; + private InputStream tarInputStream = null; private String tag; private boolean noCache; @@ -43,6 +45,11 @@ public BuildImgCmd(File dockerFolder) { this.dockerFolder = dockerFolder; } + public BuildImgCmd(InputStream tarInputStream) { + Preconditions.checkNotNull(tarInputStream, "tarInputStream is null"); + this.tarInputStream = tarInputStream; + } + public BuildImgCmd withTag(String tag) { Preconditions.checkNotNull(tag, "Tag is null"); this.tag = tag; @@ -55,17 +62,49 @@ public BuildImgCmd withNoCache(boolean noCache) { } protected ClientResponse impl() { - - Preconditions.checkArgument(dockerFolder.exists(), "Path %s doesn't exist", dockerFolder); - Preconditions.checkArgument(dockerFolder.isDirectory(), "Folder %s doesn't exist", dockerFolder); - Preconditions.checkState(new File(dockerFolder, "Dockerfile").exists(), "Dockerfile doesn't exist in " + dockerFolder); - + if (tarInputStream == null) { + File dockerFolderTar = buildDockerFolderTar(); + try { + return callDocker(FileUtils.openInputStream(dockerFolderTar)); + } catch (IOException e) { + throw new DockerException(e); + } finally { + FileUtils.deleteQuietly(dockerFolderTar); + } + } else { + return callDocker(tarInputStream); + } + } + + protected ClientResponse callDocker(final InputStream dockerFolderTarInputStream) { MultivaluedMap params = new MultivaluedMapImpl(); params.add("t", tag); if (noCache) { params.add("nocache", "true"); } + WebResource webResource = baseResource.path("/build").queryParams(params); + + try { + LOGGER.trace("POST: {}", webResource); + return webResource + .type("application/tar") + .accept(MediaType.TEXT_PLAIN) + .post(ClientResponse.class, dockerFolderTarInputStream); + } catch (UniformInterfaceException exception) { + if (exception.getResponse().getStatus() == 500) { + throw new DockerException("Server error", exception); + } else { + throw new DockerException(exception); + } + } + } + + protected File buildDockerFolderTar() { + Preconditions.checkArgument(dockerFolder.exists(), "Path %s doesn't exist", dockerFolder); + Preconditions.checkArgument(dockerFolder.isDirectory(), "Folder %s doesn't exist", dockerFolder); + Preconditions.checkState(new File(dockerFolder, "Dockerfile").exists(), "Dockerfile doesn't exist in " + dockerFolder); + // ARCHIVE TAR String archiveNameWithOutExtension = UUID.randomUUID().toString(); @@ -112,31 +151,11 @@ protected ClientResponse impl() { } dockerFolderTar = CompressArchiveUtil.archiveTARFiles(dockerFolder, filesToAdd, archiveNameWithOutExtension); - + return dockerFolderTar; } catch (IOException ex) { FileUtils.deleteQuietly(dockerFolderTar); throw new DockerException("Error occurred while preparing Docker context folder.", ex); } - - WebResource webResource = baseResource.path("/build").queryParams(params); - - try { - LOGGER.trace("POST: {}", webResource); - return webResource - .type("application/tar") - .accept(MediaType.TEXT_PLAIN) - .post(ClientResponse.class, FileUtils.openInputStream(dockerFolderTar)); - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error", exception); - } else { - throw new DockerException(exception); - } - } catch (IOException e) { - throw new DockerException(e); - } finally { - FileUtils.deleteQuietly(dockerFolderTar); - } } private static boolean isFileResource(String resource) {