Skip to content

Commit

Permalink
Feat: Add configuration allowing PortMappingPropertyWriteHelper to cr…
Browse files Browse the repository at this point in the history
…eate parent directories

Signed-off-by: Guillaume Villena <[email protected]>
  • Loading branch information
Willena committed Feb 27, 2024
1 parent 110a8f8 commit 8a91d91
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/main/asciidoc/inc/_global-configuration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ By default a progress meter is printed out on the console, which is omitted when
| Global property file into which the mapped properties should be written to. The format of this file and its purpose are also described in <<start-port-mapping,Port Mapping>>.
|

| *portPropertyFileCreatePaths*
| Enable parent folder creation for paths specified in `portPropertyFile`. If set to false (default) the `portPropertyFile` parent folders must exist prior the file creation. See <<start-port-mapping,Port Mapping>>.
| `docker.portPropertyFileCreatePaths`

| *registry*
| Specify globally a registry to use for pulling and pushing images. See <<registry,Registry handling>> for details.
| `docker.registry`
Expand Down
3 changes: 3 additions & 0 deletions src/main/asciidoc/inc/external/_property_configuration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,9 @@ See <<list-properties>>.
| *docker.portPropertyFile*
| specifies a path to a port mapping used when starting a container.

| *docker.portPropertyFileCreatePaths*
| Specify if parent folder of `docker.portPropertyFile` should be automatically created (default: false).

| *docker.ports.idx*
| Sets a port mapping. For example `<docker.ports.1>jolokia.ports:8080<docker.ports.1>` maps the container port 8080 dynamically to a host port and assigns this host port to the Maven property `${jolokia.port}`. See <<_port-mapping,Port mapping>> for possible mapping options. When creating images images only the right most port is used for exposing the port. For providing multiple port mappings, the index should be count up.
See <<list-properties>> for more information about list properties.
Expand Down
3 changes: 3 additions & 0 deletions src/main/asciidoc/inc/start/_configuration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ a| *This option is deprecated, please use a `containerNamePattern` instead* Nami
| <<start-port-mapping, *portPropertyFile*>>
| File path into which the mapped port properties are written. The format of this file and its purpose are also described in <<start-port-mapping,Port mapping>>

| <<start-port-mapping,*portPropertyFileCreatePaths*>>
| Enable parent folder creation for paths specified in `portPropertyFile`. If set to false (default) the `portPropertyFile` parent folders must exist prior the file creation. See <<start-port-mapping,Port Mapping>>.

| <<start-port-mapping, *ports*>>
| <<start-port-mapping,Port mappings>> for exposing container ports to host ports.

Expand Down
2 changes: 2 additions & 0 deletions src/main/asciidoc/inc/start/_port-mapping.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ Another useful configuration option is `portPropertyFile` which can be used to w

This property file might be useful with tests or with other maven plugins that will be unable to use the resolved properties because they can only be updated after the container has started and plugins resolve their properties in an earlier lifecycle phase.

The `portPropertyFileCreatePaths` option can be used to allow parent folder creation for paths specified in `portPropertyFile`. If set to false (default) the `portPropertyFile` parent folders must exist prior the file creation.

If you don't need to write out such a property file and thus don't need to preserve the property names, you can use normal maven properties as well. E.g. `${host.var}:${port.var}:8080` instead of
`+host.var:port.var:8080`.

6 changes: 5 additions & 1 deletion src/main/java/io/fabric8/maven/docker/StartMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ public class StartMojo extends AbstractDockerMojo {
@Parameter
protected String portPropertyFile;

// allow creation of all subdirectories if absent
@Parameter(property = "docker.portPropertyFileCreatePaths", defaultValue = "false")
protected boolean portPropertyFileCreatePaths;

private static final class StartedContainer {
public final ImageConfiguration imageConfig;
public final String containerId;
Expand Down Expand Up @@ -129,7 +133,7 @@ public synchronized void executeInternal(final ServiceHub hub) throws DockerAcce
QueryService queryService = hub.getQueryService();
final RunService runService = hub.getRunService();

PortMapping.PropertyWriteHelper portMappingPropertyWriteHelper = new PortMapping.PropertyWriteHelper(portPropertyFile);
PortMapping.PropertyWriteHelper portMappingPropertyWriteHelper = new PortMapping.PropertyWriteHelper(portPropertyFile, portPropertyFileCreatePaths);

Check warning on line 136 in src/main/java/io/fabric8/maven/docker/StartMojo.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/io/fabric8/maven/docker/StartMojo.java#L136

Added line #L136 was not covered by tests

boolean success = false;

Expand Down
12 changes: 11 additions & 1 deletion src/main/java/io/fabric8/maven/docker/access/PortMapping.java
Original file line number Diff line number Diff line change
Expand Up @@ -371,14 +371,16 @@ public static class PropertyWriteHelper {

private final Properties globalExport;

private final boolean createPaths;
private final String globalFile;
private final Map<String, Properties> toExport;

public PropertyWriteHelper(String globalFile) {
public PropertyWriteHelper(String globalFile, boolean createPaths) {
this.globalFile = globalFile;

this.toExport = new HashMap<>();
this.globalExport = new Properties();
this.createPaths = createPaths;
}

public void add(PortMapping portMapping, String portPropertyFile) {
Expand All @@ -403,6 +405,14 @@ public void write() throws IOException {

private void writeProperties(Properties props, String file) throws IOException {
File propFile = new File(file);

if (createPaths) {
File parent = propFile.getParentFile();
if (!parent.exists()) {
parent.mkdirs();
}
}

try (OutputStream os = new FileOutputStream(propFile)) {
props.store(os, "Docker ports");
} catch (IOException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ public class RunImageConfiguration implements Serializable {
@Parameter
private String portPropertyFile;

@Parameter
private Boolean portPropertyFileCreatePaths;

// For simple network setups. For complex stuff use "network"
@Parameter
private String net;
Expand Down Expand Up @@ -309,6 +312,10 @@ public String getPortPropertyFile() {
return portPropertyFile;
}

public Boolean getPortPropertyFileCreatePaths() {
return portPropertyFileCreatePaths;
}

public String getWorkingDir() {
return workingDir;
}
Expand Down Expand Up @@ -522,6 +529,11 @@ public Builder portPropertyFile(String portPropertyFile) {
return this;
}

public Builder portPropertyFileCreatePaths(Boolean createPath){
config.portPropertyFileCreatePaths = createPath;
return this;
}

public Builder workingDir(String workingDir) {
config.workingDir = workingDir;
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ public enum ConfigKey {
OPTIMISE,
PLATFORM,
PORT_PROPERTY_FILE,
PORT_PROPERTY_FILE_CREATE_PATHS,
PORTS(ValueCombinePolicy.Merge),
PRIVILEGED,
READ_ONLY,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ private RunImageConfiguration extractRunConfiguration(ImageConfiguration fromCon
.namingStrategy(valueProvider.getString(NAMING_STRATEGY, config.getNamingStrategy() == null ? null : config.getNamingStrategy().name()))
.exposedPropertyKey(valueProvider.getString(EXPOSED_PROPERTY_KEY, config.getExposedPropertyKey()))
.portPropertyFile(valueProvider.getString(PORT_PROPERTY_FILE, config.getPortPropertyFile()))
.portPropertyFileCreatePaths(valueProvider.getBoolean(PORT_PROPERTY_FILE_CREATE_PATHS, config.getPortPropertyFileCreatePaths()))
.ports(valueProvider.getList(PORTS, config.getPorts()))
.shmSize(valueProvider.getLong(SHMSIZE, config.getShmSize()))
.privileged(valueProvider.getBoolean(PRIVILEGED, config.getPrivileged()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
Expand Down Expand Up @@ -84,6 +85,37 @@ void testWriteImageAndGlobal() throws IOException {
thenPropsContains("other.ip1", "1.2.3.4");
}

@Test
void testWriteCreatePaths() throws IOException {
File dir = Files.createTempDirectory("dmp-").toFile();
Assertions.assertTrue(dir.delete());
String globalFile = Paths.get(dir.getAbsolutePath(), "dmp-tmp.properties").toFile().getAbsolutePath();
PortMapping mapping = createPortMapping("jolokia.port:8080", "18181:8181", "127.0.0.1:9090:9090", "127.0.0.1:other.port:5678");

// check that we can write on non-existant path with create set to "true"
givenAPortMappingWriterThatCreatesPaths(globalFile);
whenUpdateDynamicMapping(mapping, "0.0.0.0", 8080, 49900);
whenUpdateDynamicMapping(mapping, "127.0.0.1", 5678, 49901);
whenWritePortMappings(null, mapping);
thenPropsFileExists(globalFile);
thenPropsSizeIs(2);
thenPropsContains("jolokia.port", 49900);
thenPropsContains("other.port", 49901);

// Check that we can still write in an existing path
String globalFile2 = Paths.get(dir.getAbsolutePath(), "dmp-tmp2.properties").toFile().getAbsolutePath();
givenAPortMappingWriterThatCreatesPaths(globalFile2);
whenUpdateDynamicMapping(mapping, "0.0.0.0", 8080, 49900);
whenUpdateDynamicMapping(mapping, "127.0.0.1", 5678, 49901);
whenWritePortMappings(null, mapping);
thenPropsFileExists(globalFile2);
thenPropsSizeIs(2);
thenPropsContains("jolokia.port", 49900);
thenPropsContains("other.port", 49901);


}

private void givenADockerHostAddress(String host) {
projProperties.setProperty("docker.host.address", host);
}
Expand Down Expand Up @@ -124,7 +156,10 @@ private void givenAHostIpProperty(String property, String hostIp) {
}

private void givenAPortMappingWriter(String globalFile) {
propertyWriteHelper = new PortMapping.PropertyWriteHelper(globalFile);
propertyWriteHelper = new PortMapping.PropertyWriteHelper(globalFile, false);
}
private void givenAPortMappingWriterThatCreatesPaths(String globalFile) {
propertyWriteHelper = new PortMapping.PropertyWriteHelper(globalFile, true);
}

private void thenPropsContains(String variable, Object port) {
Expand Down

0 comments on commit 8a91d91

Please sign in to comment.