Support for discovery of containers launched previously
diff --git a/containers-docker-local/pom.xml b/containers-docker-local/pom.xml
index ae7cada..4c67b7c 100644
--- a/containers-docker-local/pom.xml
+++ b/containers-docker-local/pom.xml
@@ -39,6 +39,12 @@
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
+
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.utils</artifactId>
+ <version>1.10.1-SNAPSHOT</version>
+ </dependency>
</dependencies>
</project>
diff --git a/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerContainerFactory.java b/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerContainerFactory.java
index a7c68d1..93b9464 100644
--- a/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerContainerFactory.java
+++ b/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerContainerFactory.java
@@ -25,9 +25,11 @@
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -37,12 +39,13 @@
import org.apache.aries.containers.ContainerFactory;
import org.apache.aries.containers.Service;
import org.apache.aries.containers.ServiceConfig;
+import org.apache.felix.utils.json.JSONParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LocalDockerContainerFactory implements ContainerFactory {
static final Logger LOG = LoggerFactory.getLogger(LocalDockerContainerFactory.class);
- private static final String SERVICE_NAME = "service.name";
+ private static final String SERVICE_NAME = "org.apache.aries.containers.service.name";
private static final String DOCKER_MACHINE_VM_NAME = System.getenv("DOCKER_MACHINE_NAME");
private static final boolean CHECK_DOCKER_MACHINE = Stream
@@ -67,8 +70,6 @@
if (docker == null)
docker = new LocalDockerController();
-
- // TODO discover any running docker containers.
}
@Override
@@ -79,9 +80,10 @@
if (existingService != null)
return existingService;
- // TODO return discovered containers if it contains the requested one.
+ List<ContainerImpl> containers = discoverContainers(config);
+ if (containers.size() == 0)
+ containers = createContainers(config);
- List<ContainerImpl> containers = createContainers(config);
ServiceImpl svc = new ServiceImpl(config, this, containers);
for (ContainerImpl c : containers) {
c.setService(svc);
@@ -150,6 +152,54 @@
}
}
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ private List<ContainerImpl> discoverContainers(ServiceConfig config) {
+ List<ContainerImpl> res = new ArrayList<>();
+ List<String> ids = docker.ps(SERVICE_NAME + "=" + config.getServiceName());
+ if (ids.size() == 0)
+ return Collections.emptyList();
+
+ String infoJSON = docker.inspect(ids.toArray(new String [] {}));
+ List<Object> data = new JSONParser(infoJSON).getParsedList();
+ for (Object d : data) {
+ if (!(d instanceof Map))
+ continue;
+
+ Map m = (Map) d;
+ Object ns = m.get("NetworkSettings");
+ Map<Integer, Integer> ports = new HashMap<>();
+ if (ns instanceof Map) {
+ Object pd = ((Map) ns).get("Ports");
+ if (pd instanceof Map) {
+ Map pm = (Map) pd;
+ for(Map.Entry entry : (Set<Map.Entry>) pm.entrySet()) {
+ try {
+ String key = entry.getKey().toString();
+ int idx = key.indexOf('/');
+ if (idx > 0)
+ key = key.substring(0, idx);
+ int containerPort = Integer.parseInt(key);
+ int hostPort = -1;
+ for (Object val : (List) entry.getValue()) {
+ if (val instanceof Map) {
+ hostPort = Integer.parseInt(((Map) val).get("HostPort").toString());
+ }
+ }
+
+ if (hostPort != -1) {
+ ports.put(containerPort, hostPort);
+ }
+ } catch (Exception nfe) {
+ // ignore parsing exceptions, try next one
+ }
+ }
+ }
+ }
+ res.add(new ContainerImpl(m.get("Id").toString(), LocalDockerContainerFactory.getContainerHost(), ports));
+ }
+ return res;
+ }
+
private int getFreePort() throws IOException {
try (ServerSocket ss = new ServerSocket(0)) {
return ss.getLocalPort();
diff --git a/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerController.java b/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerController.java
index 2fecfa7..bb36d07 100644
--- a/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerController.java
+++ b/containers-docker-local/src/main/java/org/apache/aries/containers/docker/local/impl/LocalDockerController.java
@@ -18,7 +18,7 @@
*/
package org.apache.aries.containers.docker.local.impl;
-import java.io.LineNumberReader;
+import java.io.BufferedReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
@@ -48,18 +48,39 @@
return new DockerContainerInfo(id, LocalDockerContainerFactory.getContainerHost());
}
+ public List<String> ps(String labelFilter) {
+ String res = runCommand("docker", "ps", "-q", "-f", "label=" + labelFilter);
+
+ String[] sa = res.trim().split("\\s+");
+ List<String> sl = new ArrayList<>(sa.length);
+ for (String s : sa) {
+ s = s.trim();
+ if (s.length() > 0)
+ sl.add(s);
+ }
+ return sl;
+ }
+
+ public String inspect(String... ids) {
+ String[] command = new String[ids.length+2];
+ command[0] = "docker";
+ command[1] = "inspect";
+ System.arraycopy(ids, 0, command, 2, ids.length);
+ return runCommand(command);
+ }
+
String runCommandExpectSingleID(String ... command) throws Exception {
- String res = ProcessRunner.waitFor(ProcessRunner.run(command));
+ String res = runCommand(command);
if (res != null) {
res = res.trim();
String lastLine = res;
- try ( final LineNumberReader lnr = new LineNumberReader(new StringReader(res)) ) {
+ try (BufferedReader lnr = new BufferedReader(new StringReader(res))) {
String line;
- while ( ( line = lnr.readLine()) != null ) {
+ while ((line = lnr.readLine()) != null) {
lastLine = line;
}
}
- if ( lastLine.indexOf(' ') != -1 ) {
+ if (lastLine.indexOf(' ') != -1 ) {
throw new Exception("Unable to execute docker command: " + res);
}
res = lastLine;
@@ -67,4 +88,8 @@
return res;
}
+
+ private String runCommand(String... command) {
+ return ProcessRunner.waitFor(ProcessRunner.run(command));
+ }
}