Skip to content

Commit

Permalink
Merge pull request #948 from stromnet/property-merging
Browse files Browse the repository at this point in the history
Merging Properties and POM based configuration
  • Loading branch information
rhuss authored Mar 18, 2018
2 parents 689b7e0 + ac1db28 commit 33f11d8
Show file tree
Hide file tree
Showing 28 changed files with 1,406 additions and 316 deletions.
5 changes: 3 additions & 2 deletions samples/properties/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@
<postgres.docker.name>postgres:9.5.2</postgres.docker.name>
<postgres.docker.log.prefix>postgres</postgres.docker.log.prefix>
<postgres.docker.ports.1>${itest.postgres.port}:5432</postgres.docker.ports.1>
<postgres.docker.env.POSTGRES_USER>superuser</postgres.docker.env.POSTGRES_USER>
<postgres.docker.env.POSTGRES_PASSWORD>superuser-password</postgres.docker.env.POSTGRES_PASSWORD>
<postgres.docker.env.POSTGRES_DB>localhost</postgres.docker.env.POSTGRES_DB>
<postgres.docker.envRun.POSTGRES_USER>superuser</postgres.docker.envRun.POSTGRES_USER>
<postgres.docker.envRun.POSTGRES_PASSWORD>superuser-password</postgres.docker.envRun.POSTGRES_PASSWORD>
<postgres.docker.wait.time>10000</postgres.docker.wait.time>
<postgres.docker.wait.log>PostgreSQL init process complete</postgres.docker.wait.log>
</properties>
Expand Down
2 changes: 1 addition & 1 deletion src/main/asciidoc/inc/build/_buildargs.adoc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

[[property-buildargs]]
As described in section <<build-configuration,Configuration>> for external Dockerfiles https://docs.docker.com/engine/reference/commandline/build/#set-build-time-variables-build-arg[Docker build arg] can be used. In addition to the
configuration within the plugin configuration you can also use properties to specify them:

Expand Down
134 changes: 129 additions & 5 deletions src/main/asciidoc/inc/external/_property_configuration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,25 @@ configuration. Such a property based configuration can be selected
with an `<type>` of `properties`. As extra configuration a prefix for the
properties can be defined which by default is `docker`.

For single-image configurations it is also possible to active property
based configuration via an externally set property.

By default, property based configuration uses only properties, ignoring
any `<build>` and `<run>` sections. To combine values from both sources,
use the <<combining-property-config,property mode configuration>>.

Properties are read from the Maven project (defined in `<properties>` or global
Maven configuration from `settings.xml`) and, since 0.25.0, from any `-D`
flags given to Maven (takes priority over project properties).

.Example
[source,xml]
----
<image>
<external>
<type>properties</type>
<prefix>docker</prefix> <!-- this is the default -->
<mode>only</mode> <!-- this is the default -->
</external>
</image>
----
Expand All @@ -21,6 +33,7 @@ up from the following properties, which correspond to the corresponding
values in the `<build>` and `<run>` sections. A build configuration is only created
when a `docker.from` or a `docker.fromExt` is set.


.External properties
[cols="1,5"]
|===
Expand Down Expand Up @@ -57,6 +70,9 @@ when a `docker.from` or a `docker.fromExt` is set.
| *docker.bind.idx*
| Sets a list of paths to bind/expose in the container

| *docker.buildArg.VARIABLE*
| Set a ARG to be available during build of image. *Note*: this is handled separately from external configuration, and is always available. See <<property-buildargs,Build Args>> for more details.

| *docker.capAdd.idx*
| List of kernel capabilities to add to the container

Expand Down Expand Up @@ -94,10 +110,16 @@ when a `docker.from` or a `docker.fromExt` is set.
| Property part for the exposed container properties like internal IP addresses as described in <<start-overview, docker:start>>.

| *docker.env.VARIABLE*
| Sets an environment variable. E.g. `<docker.env.JAVA_OPTS>-Xmx512m</docker.env.JAVA_OPTS>` sets the environment variable `JAVA_OPTS`. Multiple such entries can be provided. This environment is used both for building images and running containers. The value cannot be empty but can contain Maven property names which are resolved before the Dockerfile is created.
| Sets an environment variable used in build and run. E.g. `<docker.env.JAVA_OPTS>-Xmx512m</docker.env.JAVA_OPTS>` sets the environment variable `JAVA_OPTS`. Multiple such entries can be provided. This environment is used both for building images and running containers. The value cannot be empty but can contain Maven property names which are resolved before the Dockerfile is created.

| *docker.envBuild.VARIABLE*
| Sets an environment variable used in build only. E.g. `<docker.envBuild.JAVA_OPTS>-Xmx512m</docker.envBuild.JAVA_OPTS>` sets the environment variable `JAVA_OPTS`. Multiple such entries can be provided. This environment is building images only. The value cannot be empty but can contain Maven property names which are resolved before the Dockerfile is created.

| *docker.envRun.VARIABLE*
| Sets an environment variable used in run only. E.g. `<docker.envRun.JAVA_OPTS>-Xmx512m</docker.envRun.JAVA_OPTS>` sets the environment variable `JAVA_OPTS`. Multiple such entries can be provided. This environment is used both for running containers only. The value cannot be empty but can contain Maven property names which are resolved before the Dockerfile is created.

| *docker.envPropertyFile*
| specifies the path to a property file whose properties are used as environment variables. The environment variables takes precedence over any other environment variables specified.
| specifies the path to a property file whose properties are used as environment variables in run. The environment variables takes precedence over any other environment variables specified.

| *docker.extraHosts.idx*
| List of `host:ip` to add to `/etc/hosts`
Expand Down Expand Up @@ -129,6 +151,9 @@ when a `docker.from` or a `docker.fromExt` is set.
| *docker.hostname*
| Container hostname

| *docker.imagePropertyConfiguration*
| Special property to activate property configuration without altering XML file (see <<combining-property-config,Combining property and XML config>>).

| *docker.imagePullPolicy.build*
| Specific pull policy used when building images. See <<image-pull-policy,imagePullPolicy>> for the possible values.

Expand Down Expand Up @@ -274,14 +299,65 @@ when a `docker.from` or a `docker.fromExt` is set.
| Current Working dir for commands to run in when running containers
|===

Any other `<run>` or `<build>` sections are ignored when this handler
is used. Multiple property configuration handlers can be used if they
Multiple property configuration handlers can be used if they
use different prefixes. As stated above the environment and ports
configuration are both used for running container and building
images. If you need a separate configuration you should use explicit
run and build configuration sections.

.Example
[[combining-property-config]]
.Combining property and XML configuration
By default the property handler will only consider properties and ignore any other image
configuration in the XML/POM file. This can be changed by adding the `<mode>`
configuration (since version 0.25.0), which can have one of the following values:

.Property mode
[cols="1,5"]
|===
|`only`
| Only look at properties, ignore any `<run>` or `<build>` sections for this image. This is the default, and also the behavior in versions before 0.25.0.

|`override`
| Use property if set, else fall back to value found in `<run>` or `<build>` sections for this image.

|`fallback`
| Use value found in `<run>` or `<build>` sections for this image, else fall back to to property value.

|`skip`
| Effectively disable properties, same as not specifying the `<external>` section at all.
|===

For single-image configurations it is also possible to active property
configuration by setting the property `docker.imagePropertyConfiguration` to a
valid `property mode`, without adding a `<external>` section.
This will use properties with default prefix.
This can be useful if most of configuration is specified in XML/POM file, but there
is need to override certain configuration values without altering the POM file.

.Merging POM and property values
For some fields it may be desired to merge values from both POM and properties. For example, in a certain run environment
we might want to inject a `http_proxy` environment variable, but we do not want to add this to the POM file.

This is solved using a *Combine policy* which can be either `replace` or `merge`. Merge is only available for
configuration of Map or List type. For scalar values such as strings and integers, it is not supported.
For Maps, both sources are merged, with the priority source taking precedence. For Lists, they are concatenated, with values
from the priority source being added first.

Combine policy is specified per configuration key/property, and the default in most cases is currently `replace`. The following
keys have `merge` as default policy:

* docker.args
* docker.envBuild
* docker.envRun
* docker.labels
* docker.ports
* docker.tags
This can be overridden individually for all configuration keys (of map/list type) by setting an additional property suffixed `._combine`.
For example, to not merge ports, set `docker.ports._combine=replace`, and to enable merging of dns, set `docker.dns._combine=merge`.


.Example, properties only
[source,xml]
----
<properties>
Expand Down Expand Up @@ -314,3 +390,51 @@ run and build configuration sections.
</plugins>
</build>
----

.Example, combining properties and XML/POM configuration
[source,xml]
----
<properties>
<docker.assembly.descriptor>src/main/docker-assembly.xml</docker.assembly.descriptor>
<docker.env.CATALINA_OPTS>-Xmx32m</docker.env.CATALINA_OPTS>
<docker.label.version>${project.version}</docker.label.version>
<docker.ports.jolokia.port>8080</docker.ports.jolokia.port>
<docker.wait.url>http://localhost:${jolokia.port}/jolokia</docker.wait.url>
</properties>
<build>
<plugins>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<images>
<image>
<external>
<type>properties</type>
<prefix>docker</prefix>
<mode>override</mode>
</external>
<name>jolokia/demo</name>
<alias>service</alias>
<build>
<from>consol/tomcat:7.0</from>
<labels>
<software>tomcat</software>
</labels>
</build>
</image>
</images>
</configuration>
</plugin>
</plugins>
</build>
----

This would build the same image as the previous example.
If instead built with `mvn docker:build -Pdocker.from=console/tomcat:8.0 -Ddocker.tags.0=tc8-test` it would build from that image instead, and also add that tag to the image.

If `-Ddocker.labels.status=beta` is added, the image would be given two labels: `status=beta` and `software=tomcat`.
If `-Ddocker.labels._combine=replace` is added, the image would be given one label only: `status=beta`.
6 changes: 3 additions & 3 deletions src/main/java/io/fabric8/maven/docker/AbstractDockerMojo.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package io.fabric8.maven.docker;

import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.*;

import io.fabric8.maven.docker.access.DockerAccess;
import io.fabric8.maven.docker.access.DockerAccessException;
Expand Down Expand Up @@ -212,6 +210,8 @@ public void execute() throws MojoExecutionException, MojoFailureException {

LogOutputSpecFactory logSpecFactory = new LogOutputSpecFactory(useColor, logStdout, logDate);

ConfigHelper.validateExternalPropertyActivation(project, images);

// The 'real' images configuration to use (configured images + externally resolved images)
this.minimalApiVersion = initImageConfiguration(getBuildTimestamp());
DockerAccess access = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ public class AssemblyConfiguration implements Serializable {
@Parameter
private Boolean ignorePermissions;

@Deprecated
public Boolean getIgnorePermissions() {
return ignorePermissions;
}

@Parameter
private AssemblyMode mode;

Expand All @@ -71,6 +76,10 @@ public class AssemblyConfiguration implements Serializable {
@Parameter
private String tarLongFileMode;

public Boolean getExportTargetDir() {
return exportTargetDir;
}

public Boolean exportTargetDir() {
if (exportTargetDir != null) {
return exportTargetDir;
Expand Down Expand Up @@ -120,6 +129,10 @@ public AssemblyMode getMode() {
return mode != null ? mode : AssemblyMode.dir;
}

public String getModeRaw() {
return mode != null ? mode.name() : null;
}

public String getTarLongFileMode() {
return tarLongFileMode;
}
Expand All @@ -136,6 +149,10 @@ public PermissionMode getPermissions() {
return permissions != null ? permissions : PermissionMode.keep;
}

public String getPermissionsRaw() {
return permissions != null ? permissions.name() : null;
}

public String getName() {
return name;
}
Expand Down
Loading

0 comments on commit 33f11d8

Please sign in to comment.