Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support for additional container configuration options #60

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -114,20 +114,26 @@
<version>1.51</version>
</dependency>

<dependency>
<groupId>org.jmockit</groupId>
<artifactId>jmockit</artifactId>
<version>${jmockit.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.jmockit</groupId>
<artifactId>jmockit</artifactId>
<version>${jmockit.version}</version>
<groupId>org.skyscreamer</groupId>
<artifactId>jsonassert</artifactId>
<version>1.2.3</version>
<scope>test</scope>
</dependency>

</dependencies>

<build>
Expand Down
56 changes: 40 additions & 16 deletions src/main/java/org/jolokia/docker/maven/StartMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,15 @@ public void executeInternal(DockerAccess docker) throws DockerAccessException, M
checkImage(docker,imageName);

RunImageConfiguration runConfig = imageConfig.getRunConfiguration();
if (runConfig == null) {
// It's a data image which needs not to have a runtime configuration
runConfig = RunImageConfiguration.DEFAULT;
}
PortMapping mappedPorts = getPortMapping(runConfig);
String container = docker.createContainer(imageName,
runConfig.getCommand(), mappedPorts.getContainerPorts(),
runConfig.getEnv());
docker.startContainer(container,
mappedPorts,
findContainersForImages(runConfig.getVolumesFrom()), findLinksWithContainerNames(docker,runConfig.getLinks()));
PortMapping mappedPorts = getPortMapping(runConfig, project.getProperties());

ContainerConfig containerConfig = createContainerConfig(imageName, runConfig, mappedPorts.getContainerPorts());
String container = docker.createContainer(containerConfig);

ContainerHostConfig hostConfig = createHostConfig(docker, runConfig, mappedPorts);
docker.startContainer(container, hostConfig);
registerContainer(container, imageConfig);

info("Created and started container " +
getContainerAndImageDescription(container, imageConfig.getDescription()));

Expand All @@ -90,10 +87,36 @@ public void executeInternal(DockerAccess docker) throws DockerAccessException, M
}
}
}

// visible for testing
ContainerConfig createContainerConfig(String imageName, RunImageConfiguration runConfig, Set<Integer> ports)
throws MojoExecutionException {
try {
return new ContainerConfig(imageName).hostname(runConfig.getHostname()).domainname(runConfig.getDomainname())
.user(runConfig.getUser()).workingDir(runConfig.getWorkingDir()).memory(runConfig.getMemory())
.memorySwap(runConfig.getMemorySwap()).entrypoint(runConfig.getEntrypoint()).exposedPorts(ports)
.environment(runConfig.getEnv()).command(runConfig.getCommand()).bind(runConfig.getBind());
}
catch (IllegalArgumentException e) {
throw new MojoExecutionException(String.format("Failed to create contained configuration for [%s]", imageName), e);
}
}

private PortMapping getPortMapping(RunImageConfiguration runConfig) throws MojoExecutionException {
// visible for testing
ContainerHostConfig createHostConfig(DockerAccess docker, RunImageConfiguration runConfig, PortMapping mappedPorts)
throws DockerAccessException, MojoExecutionException {
RunImageConfiguration.RestartPolicy restartPolicy = runConfig.getRestartPolicy();
return new ContainerHostConfig().bind(runConfig.getBind()).links(findLinksWithContainerNames(docker, runConfig.getLinks()))
.portBindings(mappedPorts).privileged(runConfig.getPrivileged()).dns(runConfig.getDns())
.dnsSearch(runConfig.getDnsSearch()).volumesFrom(findContainersForImages(runConfig.getVolumesFrom()))
.capAdd(runConfig.getCapAdd()).capDrop(runConfig.getCapDrop())
.restartPolicy(restartPolicy.getName(), restartPolicy.getRetry());
}

// visible for testing
PortMapping getPortMapping(RunImageConfiguration runConfig, Properties properties) throws MojoExecutionException {
try {
return new PortMapping(runConfig.getPorts(), project.getProperties());
return new PortMapping(runConfig.getPorts(), properties);
} catch (IllegalArgumentException exp) {
throw new MojoExecutionException("Cannot parse portmapping",exp);
}
Expand All @@ -108,7 +131,8 @@ private List<StartOrderResolver.Resolvable> getImagesConfigsInOrder() throws Moj
}
}

private List<String> findLinksWithContainerNames(DockerAccess docker, List<String> links) throws DockerAccessException {
// visible for testing
List<String> findLinksWithContainerNames(DockerAccess docker, List<String> links) throws DockerAccessException {
List<String> ret = new ArrayList<>();
for (String[] link : EnvUtil.splitLinks(links)) {
String container = lookupContainer(link[0]);
Expand All @@ -120,7 +144,8 @@ private List<String> findLinksWithContainerNames(DockerAccess docker, List<Strin
return ret;
}

private List<String> findContainersForImages(List<String> images) throws MojoExecutionException {
// visible for testing
List<String> findContainersForImages(List<String> images) throws MojoExecutionException {
List<String> containers = new ArrayList<>();
if (images != null) {
for (String image : images) {
Expand Down Expand Up @@ -177,7 +202,6 @@ public void checkImage(DockerAccess docker,String image) throws DockerAccessExce
private void waitIfRequested(RunImageConfiguration runConfig, PortMapping mappedPorts, DockerAccess docker, String containerId) {
WaitConfiguration wait = runConfig.getWaitConfiguration();
if (wait != null) {
int maxTime = wait.getTime();
ArrayList<WaitUtil.WaitChecker> checkers = new ArrayList<>();
ArrayList<String> logOut = new ArrayList<>();
if (wait.getUrl() != null) {
Expand Down
132 changes: 132 additions & 0 deletions src/main/java/org/jolokia/docker/maven/access/ContainerConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package org.jolokia.docker.maven.access;

import java.util.List;
import java.util.Map;
import java.util.Set;

import org.jolokia.docker.maven.util.EnvUtil;
import org.json.JSONArray;
import org.json.JSONObject;


/**
* Represents a configuration used to create a container
*/
public class ContainerConfig {

private final String imageName;

private final JSONObject object = new JSONObject();

public ContainerConfig(String imageName) {
this.imageName = imageName;
object.put("Image", imageName);
}

public ContainerConfig bind(List<String> bind) {
if (bind != null && !bind.isEmpty()) {
JSONObject volumes = new JSONObject();
for (String volume : bind) {
if (volume.contains(":")) {
volume = volume.split(":")[0];
}
volumes.put(volume, new JSONObject());
}
object.put("Volumes", volumes);
}
return this;
}

public ContainerConfig command(String command) {
if (command != null) {
JSONArray a = new JSONArray();
for (String s : EnvUtil.splitWOnSpaceWithEscape(command)) {
a.put(s);
}
object.put("Cmd", a);
}
return this;
}

public ContainerConfig domainname(String domainname) {
add("Domainname", domainname);
return this;
}

public ContainerConfig entrypoint(String entrypoint) {
if (entrypoint != null) {
add("Entrypoint", entrypoint);
}
return this;
}

public ContainerConfig environment(Map<String, String> env) throws IllegalArgumentException {
if (env != null && env.size() > 0) {
JSONArray a = new JSONArray();
for (Map.Entry<String, String> entry : env.entrySet()) {
String value = entry.getValue();
if (value == null || value.length() == 0) {
throw new IllegalArgumentException(String.format("Env variable '%s' must not be null or empty when running %s",
entry.getKey(), imageName));
}
a.put(entry.getKey() + "=" + entry.getValue());
}
object.put("Env", a);
}
return this;
}

public ContainerConfig exposedPorts(Set<Integer> ports) {
if (ports != null && ports.size() > 0) {
JSONObject exposedPorts = new JSONObject();
for (Integer port : ports) {
exposedPorts.put(port.toString() + "/tcp", new JSONObject());
}
object.put("ExposedPorts", exposedPorts);
}
return this;
}

public String getImageName() {
return imageName;
}

public ContainerConfig hostname(String hostname) {
add("Hostname", hostname);
return this;
}

public ContainerConfig memory(long memory) {
if (memory != 0) {
object.put("Memory", memory);
}
return this;
}

public ContainerConfig memorySwap(long memorySwap) {
if (memorySwap != 0) {
object.put("MemorySwap", memorySwap);
}
return this;
}

public String toJson() {
return object.toString();
}

public ContainerConfig user(String user) {
add("User", user);
return this;
}

public ContainerConfig workingDir(String workingDir) {
add("WorkingDir", workingDir);
return this;
}

private void add(String name, String value) {
if (value != null) {
object.put(name, value);
}
}
}
125 changes: 125 additions & 0 deletions src/main/java/org/jolokia/docker/maven/access/ContainerHostConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package org.jolokia.docker.maven.access;

import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONObject;


/**
* Represents a configuration used to start a container
*/
public class ContainerHostConfig {

private final JSONObject object = new JSONObject();

public ContainerHostConfig bind(List<String> bind) {
if (bind != null && !bind.isEmpty()) {
JSONArray host = new JSONArray();
for (String volume : bind) {
if (volume.contains(":")) {
host.put(volume);
}
}
object.put("Binds", host);
}
return this;
}

public ContainerHostConfig capAdd(List<String> capAdd)
{
if (capAdd != null) {
object.put("CapAdd", new JSONArray(capAdd));
}
return this;
}

public ContainerHostConfig capDrop(List<String> capDrop)
{
if (capDrop != null) {
object.put("CapDrop", new JSONArray(capDrop));
}
return this;
}

public ContainerHostConfig dns(List<String> dns)
{
if (dns != null) {
object.put("Dns", new JSONArray(dns));
}
return this;
}

public ContainerHostConfig dnsSearch(List<String> dnsSearch)
{
if (dnsSearch != null) {
object.put("DnsSearch", new JSONArray(dnsSearch));
}
return this;
}

public ContainerHostConfig links(List<String> links) {
if (links != null) {
object.put("Links", new JSONArray(links));
}
return this;
}

public ContainerHostConfig portBindings(PortMapping portMapping) {
Map<Integer, Integer> portMap = portMapping.getPortsMap();
if (!portMap.isEmpty()) {
JSONObject portBindings = new JSONObject();
Map<Integer, String> bindToMap = portMapping.getBindToMap();

for (Map.Entry<Integer, Integer> entry : portMap.entrySet()) {
Integer port = entry.getKey();
Integer hostPort = entry.getValue();

JSONObject o = new JSONObject();
o.put("HostPort", hostPort != null ? hostPort.toString() : "");

if (bindToMap.containsKey(port)) {
o.put("HostIp", bindToMap.get(port));
}

JSONArray array = new JSONArray();
array.put(o);

portBindings.put(port + "/tcp", array);
}

object.put("PortBindings", portBindings);
}
return this;
}

public ContainerHostConfig privileged(boolean privileged)
{
object.put("Privileged", privileged);
return this;
}

public ContainerHostConfig restartPolicy(String name, int retry)
{
if (name != null) {
JSONObject policy = new JSONObject();
policy.put("Name", name);
policy.put("MaximumRetryCount", retry);

object.put("RestartPolicy", policy);
}
return this;
}

public String toJson() {
return object.toString();
}

public ContainerHostConfig volumesFrom(List<String> volumesFrom) {
if (volumesFrom != null) {
object.put("VolumesFrom", new JSONArray(volumesFrom));
}
return this;
}
}
Loading