Repository: docker-java/docker-java
Pull request #180 (2015-03-25 13:00:50)

Dockerfiles not called 'dockerfile'
Pass the name of the Dockerfile to docker (required or it doesn't know where to find it).
Adjust the TAR file to build from the correct path
Implement some tests to show it working with a nonstandard name.

Signed-off-by: Nigel Magnay <nigel.magnay@gmail.com>

marcuslinke: @magnayn I'm missing the advertised test case in your PR. Could you provide one please?

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7c659958..f8841d76 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,8 +2,6 @@ Change Log
 ===
 Latest SNAPSHOT
 ---
- 
- * [#179](https://github.com/docker-java/docker-java/pull/170) Add support for cpuset in CreateContainerCmd
  * [#170](https://github.com/docker-java/docker-java/pull/170) Allow to specify alternative files other than 'Dockerfile' for building images
  * [#165](https://github.com/docker-java/docker-java/pull/165) PushImageCmd assumes that you have an auth config setup 
  * [#161](https://github.com/docker-java/docker-java/pull/161) Inspect exec command
diff --git a/src/main/java/com/github/dockerjava/api/DockerClient.java b/src/main/java/com/github/dockerjava/api/DockerClient.java
index c4e4859c..9e275eb3 100644
--- a/src/main/java/com/github/dockerjava/api/DockerClient.java
+++ b/src/main/java/com/github/dockerjava/api/DockerClient.java
@@ -98,7 +98,9 @@ public interface DockerClient extends Closeable {
 
 	public CommitCmd commitCmd(String containerId);
 
-	public BuildImageCmd buildImageCmd(File dockerFolder);
+    public BuildImageCmd buildImageCmd();
+
+	public BuildImageCmd buildImageCmd(File dockerFileOrFolder);
 
 	public BuildImageCmd buildImageCmd(InputStream tarInputStream);
 
diff --git a/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java b/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java
index becaeccc..1f26d37d 100644
--- a/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java
+++ b/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java
@@ -28,8 +28,12 @@ public interface BuildImageCmd extends DockerCmd<BuildImageCmd.Response>{
 
 	public boolean isQuiet();
 
+    public String getPathToDockerfile();
+
 	public AuthConfigurations getBuildAuthConfigs();
-	
+
+    public BuildImageCmd withBaseDirectory(File baseDirectory);
+
     public BuildImageCmd withDockerfile(File dockerfile);
 	
 	public BuildImageCmd withTarInputStream(InputStream tarInputStream);
diff --git a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java
index c6a1234c..88a6caf0 100644
--- a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java
+++ b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java
@@ -62,10 +62,6 @@ public interface CreateContainerCmd extends DockerCmd<CreateContainerResponse>{
 
 	public CreateContainerCmd withCpuShares(int cpuShares);
 
-	public String getCpuset();
-
-	public CreateContainerCmd withCpuset(String cpuset);
-
 	public boolean isAttachStdin();
 
 	public CreateContainerCmd withAttachStdin(boolean attachStdin);
diff --git a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java
index 0dd560af..de3d9e23 100644
--- a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java
+++ b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java
@@ -291,6 +291,12 @@ public class DockerClientImpl implements Closeable, DockerClient {
 				.createCommitCmdExec(), containerId);
 	}
 
+    @Override
+    public BuildImageCmd buildImageCmd() {
+        return new BuildImageCmdImpl(getDockerCmdExecFactory()
+                .createBuildImageCmdExec());
+    }
+
 	@Override
 	public BuildImageCmd buildImageCmd(File dockerFileOrFolder) {
 		return new BuildImageCmdImpl(getDockerCmdExecFactory()
diff --git a/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java
index c793ed6e..180befd0 100644
--- a/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java
+++ b/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java
@@ -9,6 +9,7 @@ import java.io.InputStream;
 import com.github.dockerjava.api.command.BuildImageCmd;
 import com.github.dockerjava.api.model.AuthConfigurations;
 import com.github.dockerjava.core.dockerfile.Dockerfile;
+import com.google.common.base.Optional;
 
 /**
  * 
@@ -24,6 +25,8 @@ public class BuildImageCmdImpl extends AbstrDockerCmd<BuildImageCmd, BuildImageC
 	private boolean remove = true;
 	private boolean quiet;
 	private AuthConfigurations buildAuthConfigs;
+    private File dockerFile;
+    private File baseDirectory;
 
     public BuildImageCmdImpl(BuildImageCmd.Exec exec) {
         super(exec);
@@ -33,10 +36,13 @@ public class BuildImageCmdImpl extends AbstrDockerCmd<BuildImageCmd, BuildImageC
 		super(exec);
 		checkNotNull(dockerFileOrFolder, "dockerFolder is null");
 
-        if( dockerFileOrFolder.isDirectory() )
-            withDockerfile( new File(dockerFileOrFolder, "Dockerfile"));
-        else
-            withDockerfile( dockerFileOrFolder);
+        if( dockerFileOrFolder.isDirectory() ) {
+            withBaseDirectory(dockerFileOrFolder);
+            withDockerfile(new File(dockerFileOrFolder, "Dockerfile"));
+        }
+        else {
+            withDockerfile(dockerFileOrFolder);
+        }
 	}
 
 	public BuildImageCmdImpl(BuildImageCmd.Exec exec, InputStream tarInputStream) {
@@ -55,12 +61,20 @@ public class BuildImageCmdImpl extends AbstrDockerCmd<BuildImageCmd, BuildImageC
         checkNotNull(dockerfile);
         if( !dockerfile.exists() )
             throw new IllegalArgumentException("Dockerfile does not exist");
+        if( !dockerfile.isFile() )
+            throw new IllegalArgumentException("Not a directory");
+
+        if( baseDirectory == null )
+            withBaseDirectory(dockerfile.getParentFile());
+
+
+        this.dockerFile = dockerfile;
 
         try {
             withTarInputStream(
                     new Dockerfile(dockerfile)
                             .parse()
-                            .buildDockerFolderTar() );
+                            .buildDockerFolderTar(baseDirectory) );
         } catch (IOException e) {
             // we just created the file this should never happen.
             throw new RuntimeException(e);
@@ -102,12 +116,24 @@ public class BuildImageCmdImpl extends AbstrDockerCmd<BuildImageCmd, BuildImageC
 		return quiet;
 	}
 
-	@Override
+    @Override
+    public String getPathToDockerfile() {
+        int baseLen = baseDirectory.getAbsolutePath().length();
+        return dockerFile.getAbsolutePath().substring(baseLen+1);
+    }
+
+    @Override
 	public AuthConfigurations getBuildAuthConfigs() {
 		return buildAuthConfigs;
 	}
 
-	@Override
+    @Override
+    public BuildImageCmd withBaseDirectory(File baseDirectory) {
+        this.baseDirectory = baseDirectory;
+        return this;
+    }
+
+    @Override
 	public BuildImageCmdImpl withNoCache() {
 		return withNoCache(true);
 	}
diff --git a/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java
index ac32960a..0948bf16 100644
--- a/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java
+++ b/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java
@@ -32,7 +32,6 @@ public class CreateContainerCmdImpl extends AbstrDockerCmd<CreateContainerCmd, C
     @JsonProperty("Memory")       private long      memoryLimit = 0;
     @JsonProperty("MemorySwap")   private long      memorySwap = 0;
     @JsonProperty("CpuShares")    private int       cpuShares = 0;
-    @JsonProperty("Cpuset")       private String    cpuset;
     @JsonProperty("AttachStdin")  private boolean   attachStdin = false;
     @JsonProperty("AttachStdout") private boolean   attachStdout = false;
     @JsonProperty("AttachStderr") private boolean   attachStderr = false;
@@ -203,17 +202,6 @@ public class CreateContainerCmdImpl extends AbstrDockerCmd<CreateContainerCmd, C
         return this;
     }
 
-    @Override
-	public String getCpuset() {
-        return cpuset;
-    }
-
-    @Override
-	public CreateContainerCmdImpl withCpuset(String cpuset) {
-        this.cpuset = cpuset;
-        return this;
-    }
-
     @Override
 	public boolean isAttachStdin() {
         return attachStdin;
diff --git a/src/main/java/com/github/dockerjava/core/dockerfile/Dockerfile.java b/src/main/java/com/github/dockerjava/core/dockerfile/Dockerfile.java
index 72e85c35..7f6519e2 100644
--- a/src/main/java/com/github/dockerjava/core/dockerfile/Dockerfile.java
+++ b/src/main/java/com/github/dockerjava/core/dockerfile/Dockerfile.java
@@ -166,6 +166,10 @@ public class Dockerfile {
     final List<File> filesToAdd = new ArrayList<File>();
 
     public InputStream buildDockerFolderTar() {
+        return buildDockerFolderTar(getDockerFolder());
+    }
+
+    public InputStream buildDockerFolderTar(File directory) {
 
       // ARCHIVE TAR
       File dockerFolderTar = null;
@@ -173,7 +177,7 @@ public class Dockerfile {
       try {
         String archiveNameWithOutExtension = UUID.randomUUID().toString();
 
-        dockerFolderTar = CompressArchiveUtil.archiveTARFiles(getDockerFolder(),
+        dockerFolderTar = CompressArchiveUtil.archiveTARFiles(directory,
                                                               filesToAdd,
                                                               archiveNameWithOutExtension);
         return FileUtils.openInputStream(dockerFolderTar);
diff --git a/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java
index 405192ad..5c2b87fc 100644
--- a/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java
+++ b/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java
@@ -35,6 +35,7 @@ public class BuildImageCmdExec extends AbstrDockerCmdExec<BuildImageCmd, BuildIm
 	@Override
 	protected ResponseImpl execute(BuildImageCmd command) {
 		WebTarget webResource = getBaseResource().path("/build");
+        String dockerFilePath = command.getPathToDockerfile();
 		
 		if(command.getTag() != null) {
 			webResource = webResource.queryParam("t", command.getTag());
@@ -48,6 +49,9 @@ public class BuildImageCmdExec extends AbstrDockerCmdExec<BuildImageCmd, BuildIm
         if (command.isQuiet()) {
             webResource = webResource.queryParam("q", "true");
         }
+        if( dockerFilePath != null && !"Dockerfile".equals(dockerFilePath)) {
+            webResource = webResource.queryParam("dockerfile", dockerFilePath);
+        }
 		
 
 	  webResource.property(ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.CHUNKED);


Test patch:
diff --git a/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java
index 4c69d86e..c1a70ef2 100644
--- a/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java
+++ b/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java
@@ -76,6 +76,34 @@ public class BuildImageCmdImplTest extends AbstractDockerClientTest {
 				equalTo("Guillaume J. Charmes \"guillaume@dotcloud.com\""));
 	}
 
+    @Test
+    public void testNonstandard1() {
+        File baseDir = new File(Thread.currentThread().getContextClassLoader()
+                .getResource("nonstandard/subdirectory/Dockerfile-nonstandard").getFile());
+
+        InputStream response = dockerClient.buildImageCmd(baseDir).withNoCache().exec();
+
+        String fullLog = asString(response);
+        assertThat(fullLog, containsString("Successfully built"));
+    }
+
+    @Test
+    public void testNonstandard2() {
+        File baseDir = new File(Thread.currentThread().getContextClassLoader()
+                .getResource("nonstandard").getFile());
+        File dockerFile = new File(Thread.currentThread().getContextClassLoader()
+                .getResource("nonstandard/subdirectory/Dockerfile-nonstandard").getFile());
+
+
+            InputStream response = dockerClient.buildImageCmd()
+                    .withBaseDirectory(baseDir)
+                    .withDockerfile(dockerFile)
+                    .withNoCache().exec();
+
+        String fullLog = asString(response);
+        assertThat(fullLog, containsString("Successfully built"));
+    }
+
 	@Test
 	public void testDockerBuilderAddUrl()  {
 		File baseDir = new File(Thread.currentThread().getContextClassLoader()
diff --git a/src/test/resources/nonstandard/subdirectory/Dockerfile-nonstandard b/src/test/resources/nonstandard/subdirectory/Dockerfile-nonstandard
new file mode 100644
index 00000000..2d0fa24c
--- /dev/null
+++ b/src/test/resources/nonstandard/subdirectory/Dockerfile-nonstandard
@@ -0,0 +1,12 @@
+# Nginx
+#
+# VERSION               0.0.1
+
+FROM      ubuntu:latest
+MAINTAINER Guillaume J. Charmes "guillaume@dotcloud.com"
+
+# make sure the package repository is up to date
+RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
+RUN apt-get update
+
+RUN apt-get install -y inotify-tools nginx apache2 openssh-server
\ No newline at end of file