Skip to content

Commit

Permalink
Added 'contextDir' configuration option. Used to specify Docker build…
Browse files Browse the repository at this point in the history
… context (#1189)

* Added 'contextDir' configuration option. Used to specify Docker build context (if Dockerfile located externally to build context)

Signed-off-by: Andrey Osipov <blaketsk@gmail.com>

* Refactor BuildImageConfiguration in order to handle contextDir
  • Loading branch information
rohanKanojia authored and rhuss committed Apr 7, 2019
1 parent dc82c82 commit 2ff5bd4
Show file tree
Hide file tree
Showing 10 changed files with 130 additions and 12 deletions.
5 changes: 5 additions & 0 deletions doc/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@
- Support docker SHELL setting for runCmds (#1157)
- Added 'autoRemove' option for running containers (#1179)
- Added support for AWS EC2 instance roles when pushing to AWS ECR (#1186)
- Introduce `contextDir` configuration option which would be used to specify docker build context (#1189)
- Add support for auto-pulling multiple base image for multi stage builds (#1057)
- Fix usage of credential helper that do not support 'version' command (#1159)

Please note that `dockerFileDir` is now deprecated in favor of `contextDir` which also allows absolute paths to Dockerfile with
`dockerFile` and it will be removed in 1.0.0. It's still supported in this release but users are suggested to migrate to
`contextDir` instead.

* **0.28.0** (2018-12-13)
- Update to JMockit 1.43
Expand Down
2 changes: 1 addition & 1 deletion samples/dockerfile/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
<alias>dockerfile</alias>
<build>
<!-- filter>@</filter-->
<dockerFileDir>${project.basedir}/src/main/docker</dockerFileDir>
<contextDir>${project.basedir}/src/main/docker</contextDir>
<assembly>
<descriptorRef>rootWar</descriptorRef>
</assembly>
Expand Down
5 changes: 3 additions & 2 deletions src/main/asciidoc/inc/build/_overview.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ When using this mode, the Dockerfile is created on the fly with all instructions
.External Dockerfile or Docker archive
Alternatively an external Dockerfile template or Docker archive can be used. This mode is switched on by using one of these three configuration options within

* *dockerFileDir* specifies a directory containing a Dockerfile that will be used to create the image. The name of the Dockerfile is `Dockerfile` by default but can be also set with the option `dockerFile` (see below).
* *dockerFile* specifies a specific Dockerfile path. The Docker build context directory is set to `dockerFileDir` if given. If not the directory by default is the directory in which the Dockerfile is stored.
* *contextDir* specifies docker build context if an external dockerfile is located outside of Docker build context. If not specified, Dockerfile's parent directory is used as build context.
* *dockerFile* specifies a specific Dockerfile path.
* *dockerArchive* specifies a previously saved image archive to load directly. Such a tar archive can be created with `docker save`. If a `dockerArchive` is provided, no `dockerFile` or `dockerFileDir` must be given.
* *dockerFileDir* (*deprecated*, use *contextDir*) specifies a directory containing a Dockerfile that will be used to create the image. The name of the Dockerfile is `Dockerfile` by default but can be also set with the option `dockerFile` (see below).
All paths can be either absolute or relative paths (except when both `dockerFileDir` and `dockerFile` are provided in which case `dockerFile` must not be absolute). A relative path is looked up in `${project.basedir}/src/main/docker` by default. You can make it easily an absolute path by using `${project.basedir}` in your configuration.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public File createDockerTarArchive(String imageName, final MojoParameters params
archiveCustomizers.add(new ArchiverCustomizer() {
@Override
public TarArchiver customize(TarArchiver archiver) throws IOException {
DefaultFileSet fileSet = DefaultFileSet.fileSet(dockerFile.getParentFile());
DefaultFileSet fileSet = DefaultFileSet.fileSet(buildConfig.getAbsoluteContextDirPath(params));
addDockerIncludesExcludesIfPresent(fileSet, params);
// Exclude non-interpolated dockerfile from source tree
// Interpolated Dockerfile is already added as it was created into the output directory when
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package io.fabric8.maven.docker.config;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;

import io.fabric8.maven.docker.util.*;
Expand All @@ -18,15 +21,23 @@ public class BuildImageConfiguration implements Serializable {
public static final String DEFAULT_FILTER = "${*}";
public static final String DEFAULT_CLEANUP = "try";

/**
* Directory is used as build context.
* If not specified, dockerfile's parent directory is used as build context.
*/
@Parameter
private String contextDir;

/**
* Directory holding an external Dockerfile which is used to build the
* image. This Dockerfile will be enriched by the addition build configuration
*/
@Parameter
@Deprecated
private String dockerFileDir;

/**
* Path to a dockerfile to use. Its parent directory is used as build context (i.e. as <code>dockerFileDir</code>).
* Path to a dockerfile to use.
* Multiple different Dockerfiles can be specified that way. If set overwrites a possibly givem
* <code>dockerFileDir</code>
*/
Expand Down Expand Up @@ -150,6 +161,14 @@ public boolean isDockerFileMode() {
return dockerFileFile != null;
}

public File getContextDir() {
return contextDir != null ? new File(contextDir) : getDockerFile().getParentFile();
}

public String getContextDirRaw() {
return contextDir;
}

public File getDockerFile() {
return dockerFileFile;
}
Expand Down Expand Up @@ -306,6 +325,10 @@ public Map<String, String> getArgs() {
return args;
}

public File getAbsoluteContextDirPath(MojoParameters mojoParams) {
return EnvUtil.prepareAbsoluteSourceDirPath(mojoParams, getContextDir().getPath());
}

public File getAbsoluteDockerFilePath(MojoParameters mojoParams) {
return EnvUtil.prepareAbsoluteSourceDirPath(mojoParams, getDockerFile().getPath());
}
Expand All @@ -329,6 +352,11 @@ public Builder(BuildImageConfiguration that) {
}
}

public Builder contextDir(String dir) {
config.contextDir = dir;
return this;
}

public Builder dockerFileDir(String dir) {
config.dockerFileDir = dir;
return this;
Expand Down Expand Up @@ -547,21 +575,41 @@ private void initDockerFileFile(Logger log) {
}

private File findDockerFileFile(Logger log) {
if(dockerFileDir != null && contextDir != null) {
log.warn("Both contextDir (%s) and deprecated dockerFileDir (%s) are configured. Using contextDir.", contextDir, dockerFileDir);
}

if (dockerFile != null) {
if (EnvUtil.isWindows() && !EnvUtil.isValidWindowsFileName(dockerFile)) {
throw new IllegalArgumentException(String.format("Invalid Windows file name %s for <dockerFile>", dockerFile));
}

File dFile = new File(dockerFile);
if (dockerFileDir == null) {
if (dockerFileDir == null && contextDir == null) {
return dFile;
} else {
if (dFile.isAbsolute()) {
throw new IllegalArgumentException("<dockerFile> can not be absolute path if <dockerFileDir> also set.");
if(contextDir != null) {
if (dFile.isAbsolute()) {
return dFile;
}
return new File(contextDir, dockerFile);
}
if (EnvUtil.isWindows() && !EnvUtil.isValidWindowsFileName(dockerFile)) {
throw new IllegalArgumentException(String.format("Invalid Windows file name %s for <dockerFile>", dockerFile));

if (dockerFileDir != null) {
if (dFile.isAbsolute()) {
throw new IllegalArgumentException("<dockerFile> can not be absolute path if <dockerFileDir> also set.");
}
log.warn("dockerFileDir parameter is deprecated, please migrate to contextDir");
return new File(dockerFileDir, dockerFile);
}
return new File(dockerFileDir, dockerFile);
}
}


if (contextDir != null) {
return new File(contextDir, "Dockerfile");
}

if (dockerFileDir != null) {
return new File(dockerFileDir, "Dockerfile");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public static String getExternalConfigActivationProperty(MavenProject project) {
*
* @param images the images to check
* @param apiVersion the original API version intended to use
* @param nameFormatter formmatter for image names
* @param nameFormatter formatter for image names
* @param log a logger for printing out diagnostic messages
* @return the minimal API Docker API required to be used for the given configuration.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public enum ConfigKey {
NOCACHE,
OPTIMISE,
CMD,
CONTEXT_DIR,
DEPENDS_ON,
DOMAINNAME,
DNS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ private boolean buildConfigured(BuildImageConfiguration config, ValueProvider va
return true;
}

if (isStringValueNull(valueProvider, config, CONTEXT_DIR, () -> config.getContextDirRaw())) {
return true;
}

if (isStringValueNull(valueProvider, config, DOCKER_FILE_DIR, () -> config.getDockerFileDirRaw())) {
return true;
}
Expand Down Expand Up @@ -150,6 +154,7 @@ private BuildImageConfiguration extractBuildConfiguration(ImageConfiguration fro
.workdir(valueProvider.getString(WORKDIR, config == null ? null : config.getWorkdir()))
.skip(valueProvider.getBoolean(SKIP_BUILD, config == null ? null : config.getSkip()))
.imagePullPolicy(valueProvider.getString(IMAGE_PULL_POLICY_BUILD, config == null ? null : config.getImagePullPolicy()))
.contextDir(valueProvider.getString(CONTEXT_DIR, config == null ? null : config.getContextDirRaw()))
.dockerArchive(valueProvider.getString(DOCKER_ARCHIVE, config == null ? null : config.getDockerArchiveRaw()))
.dockerFile(valueProvider.getString(DOCKER_FILE, config == null ? null : config.getDockerFileRaw()))
.dockerFileDir(valueProvider.getString(DOCKER_FILE_DIR, config == null ? null : config.getDockerFileDirRaw()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/

import java.io.File;
import java.io.IOException;

import io.fabric8.maven.docker.util.Logger;
import mockit.Expectations;
Expand Down Expand Up @@ -55,6 +56,7 @@ public void simpleDockerfile() {
config.initAndValidate(logger);
assertTrue(config.isDockerFileMode());
assertEquals(config.getDockerFile(),new File("src/docker/Dockerfile"));
assertEquals(config.getContextDir(),new File("src/docker"));
}

@Test
Expand All @@ -65,6 +67,7 @@ public void simpleDockerfileDir() {
config.initAndValidate(logger);
assertTrue(config.isDockerFileMode());
assertEquals(config.getDockerFile(),new File("src/docker/Dockerfile"));
assertEquals(config.getContextDir(),new File("src/docker"));
}

@Test
Expand All @@ -87,6 +90,53 @@ public void DockerfileDirAndDockerfileAlsoSetButDockerfileIsAbsoluteExceptionThr
config.initAndValidate(logger);
}

@Test
public void contextDir() {
BuildImageConfiguration config =
new BuildImageConfiguration.Builder().
contextDir("target").build();
config.initAndValidate(logger);
assertEquals(new File("target"), config.getContextDir());
}

@Test
public void contextDirAndDockerfile() {
BuildImageConfiguration config =
new BuildImageConfiguration.Builder().
dockerFile("src/docker/Dockerfile").
contextDir("target").build();
config.initAndValidate(logger);
assertEquals(new File("target/src/docker/Dockerfile"), config.getDockerFile());
assertEquals(new File("target"), config.getContextDir());
}

@Test
public void contextDirAndDockerfileDir() {
BuildImageConfiguration config =
new BuildImageConfiguration.Builder().
dockerFileDir("src/docker").
contextDir("target").build();
config.initAndValidate(logger);
assertEquals(new File("target/Dockerfile"), config.getDockerFile());
assertEquals(new File("target"), config.getContextDir());
}

@Test
public void contextDirAndAbsoluteDockerfile() throws IOException {
File tempDockerFile = File.createTempFile("Dockerfile", "");
tempDockerFile.deleteOnExit();
BuildImageConfiguration config = new BuildImageConfiguration.Builder()
.dockerFile(tempDockerFile.getAbsolutePath())
.contextDir("target")
.build();

// If contextDir is given and the dockerFile is an absolute path.
// The Dockerfile should then be copied over.
config.initAndValidate(logger);
assertEquals(new File(tempDockerFile.getAbsolutePath()), config.getDockerFile());
assertEquals(new File("target"), config.getContextDir());
}

@Test
public void deprecatedDockerfileDir() {
AssemblyConfiguration assemblyConfig = new AssemblyConfiguration.Builder().dockerFileDir("src/docker").build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,14 @@ public void testDockerFileDir() {
assertNotNull(config.getBuildConfiguration());
}

@Test
public void testContextDir() {
String[] testData = new String[] {k(ConfigKey.NAME), "image", k(ConfigKey.CONTEXT_DIR), "dir" };

ImageConfiguration config = resolveExternalImageConfig(testData);
assertNotNull(config.getBuildConfiguration());
}

@Test
public void testFilterDefault() {
String[] testData = new String[] {k(ConfigKey.NAME), "image", k(ConfigKey.FROM), "base" };
Expand Down

0 comments on commit 2ff5bd4

Please sign in to comment.