Skip to content

Commit 26ed1b5

Browse files
committed
Ref #33873: check health of docker swarm container
1 parent bf2d6ee commit 26ed1b5

3 files changed

Lines changed: 49 additions & 7 deletions

File tree

src/main/java/eu/openanalytics/containerproxy/backend/docker/AbstractDockerBackend.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
*/
2121
package eu.openanalytics.containerproxy.backend.docker;
2222

23+
import com.fasterxml.jackson.core.JsonProcessingException;
24+
import com.fasterxml.jackson.databind.ObjectMapper;
2325
import eu.openanalytics.containerproxy.ContainerProxyException;
2426
import eu.openanalytics.containerproxy.backend.AbstractContainerBackend;
2527
import eu.openanalytics.containerproxy.model.runtime.Container;
@@ -31,9 +33,12 @@
3133
import org.mandas.docker.client.DockerCertificates;
3234
import org.mandas.docker.client.DockerClient;
3335
import org.mandas.docker.client.LogStream;
36+
import org.mandas.docker.client.ObjectMapperProvider;
3437
import org.mandas.docker.client.builder.jersey.JerseyDockerClientBuilder;
3538
import org.mandas.docker.client.exceptions.DockerCertificateException;
3639
import org.mandas.docker.client.exceptions.DockerException;
40+
import org.slf4j.Logger;
41+
import org.slf4j.LoggerFactory;
3742

3843
import javax.inject.Inject;
3944
import java.io.IOException;
@@ -64,6 +69,8 @@ public abstract class AbstractDockerBackend extends AbstractContainerBackend {
6469
protected Integer portRangeTo;
6570

6671
private final ScheduledExecutorService releasePortExecutor = Executors.newSingleThreadScheduledExecutor();
72+
private final ObjectMapper objectMapper = new ObjectMapper();
73+
private final Logger logger = LoggerFactory.getLogger(getClass());
6774

6875
@Override
6976
public void initialize() throws ContainerProxyException {
@@ -144,4 +151,13 @@ protected void releasePort(String ownerId) {
144151
releasePortExecutor.schedule(() -> portAllocator.release(ownerId), 10, TimeUnit.SECONDS);
145152
}
146153

154+
protected String toJson(Object object) {
155+
try {
156+
return objectMapper.writeValueAsString(object);
157+
} catch (JsonProcessingException e) {
158+
logger.warn("Error while generating json", e);
159+
return null;
160+
}
161+
}
162+
147163
}

src/main/java/eu/openanalytics/containerproxy/backend/docker/DockerEngineBackend.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
*/
2121
package eu.openanalytics.containerproxy.backend.docker;
2222

23-
import com.fasterxml.jackson.core.JsonProcessingException;
24-
import com.fasterxml.jackson.databind.ObjectMapper;
2523
import eu.openanalytics.containerproxy.ContainerFailedToStartException;
2624
import eu.openanalytics.containerproxy.event.NewProxyEvent;
2725
import eu.openanalytics.containerproxy.model.runtime.Container;
@@ -315,15 +313,14 @@ public boolean isProxyHealthy(Proxy proxy) {
315313
ContainerInfo info = dockerClient.inspectContainer(container.getId());
316314
ContainerState state = info.state();
317315
if (!state.running() || !state.status().equals("running")) {
318-
ObjectMapper objectMapper = new ObjectMapper();
319-
slog.warn(proxy, "Docker container failed: container not running, state reported by docker: " + objectMapper.writeValueAsString(state));
316+
slog.warn(proxy, "Docker container failed: container not running, state reported by docker: " + toJson(state));
320317
return false;
321318
}
322319
return true;
323320
} catch (ContainerNotFoundException e) {
324321
slog.warn(proxy, "Docker container failed: container does not exist");
325322
return false;
326-
} catch (DockerException | InterruptedException | JsonProcessingException e) {
323+
} catch (DockerException | InterruptedException e) {
327324
throw new RuntimeException(e);
328325
}
329326
}

src/main/java/eu/openanalytics/containerproxy/backend/docker/DockerSwarmBackend.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import org.mandas.docker.client.LogStream;
4545
import org.mandas.docker.client.exceptions.DockerException;
4646
import org.mandas.docker.client.exceptions.ServiceNotFoundException;
47+
import org.mandas.docker.client.exceptions.TaskNotFoundException;
4748
import org.mandas.docker.client.messages.RegistryAuth;
4849
import org.mandas.docker.client.messages.mount.Mount;
4950
import org.mandas.docker.client.messages.swarm.DnsConfig;
@@ -53,6 +54,7 @@
5354
import org.mandas.docker.client.messages.swarm.Reservations;
5455
import org.mandas.docker.client.messages.swarm.ResourceRequirements;
5556
import org.mandas.docker.client.messages.swarm.Resources;
57+
import org.mandas.docker.client.messages.swarm.RestartPolicy;
5658
import org.mandas.docker.client.messages.swarm.SecretBind;
5759
import org.mandas.docker.client.messages.swarm.SecretFile;
5860
import org.mandas.docker.client.messages.swarm.Service;
@@ -314,7 +316,7 @@ public List<ExistingContainerInfo> scanExistingContainers() throws Exception {
314316
ArrayList<ExistingContainerInfo> containers = new ArrayList<>();
315317

316318
for (Service service : dockerClient.listServices()) {
317-
org.mandas.docker.client.messages.swarm.ContainerSpec containerSpec = service.spec().taskTemplate().containerSpec();
319+
org.mandas.docker.client.messages.swarm.ContainerSpec containerSpec = service.spec().taskTemplate().containerSpec();
318320

319321
if (containerSpec == null) {
320322
continue;
@@ -359,7 +361,34 @@ public List<ExistingContainerInfo> scanExistingContainers() throws Exception {
359361

360362
@Override
361363
public boolean isProxyHealthy(Proxy proxy) {
362-
return true; // TODO
364+
for (Container container : proxy.getContainers()) {
365+
try {
366+
BackendContainerName serviceId = container.getRuntimeObjectOrNull(BackendContainerNameKey.inst);
367+
if (serviceId == null) {
368+
slog.warn(proxy, "Docker Swarm container failed: no service id found");
369+
return false;
370+
}
371+
dockerClient.inspectService(serviceId.getName()); // check service exists
372+
List<Task> serviceTask = dockerClient.listTasks(Task.Criteria.builder().serviceName(serviceId.getName()).build());
373+
if (serviceTask.isEmpty()) {
374+
slog.warn(proxy, "Docker Swarm container failed: service does not exist");
375+
return false;
376+
}
377+
Task task = serviceTask.get(0);
378+
if (!task.status().state().equals("running")) {
379+
slog.warn(proxy, "Docker Swarm container failed: container not running, state reported by docker: " + toJson(task.status()));
380+
return false;
381+
}
382+
return true;
383+
} catch (ServiceNotFoundException e) {
384+
slog.warn(proxy, "Docker Swarm container failed: service does not exist");
385+
return false;
386+
} catch (DockerException | InterruptedException e) {
387+
slog.warn(proxy, e, "Failed to check Docker Swarm container health");
388+
return false;
389+
}
390+
}
391+
return true;
363392
}
364393

365394
@Override

0 commit comments

Comments
 (0)