package com.sequenceiq.cloudbreak.orchestrator.swarm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.github.dockerjava.api.DockerClient; import com.github.dockerjava.api.NotFoundException; import com.github.dockerjava.api.NotModifiedException; import com.github.dockerjava.api.command.CreateContainerCmd; import com.github.dockerjava.api.command.InspectContainerResponse; import com.sequenceiq.cloudbreak.orchestrator.exception.CloudbreakOrchestratorFailedException; public class DockerClientUtil { private static final Logger LOGGER = LoggerFactory.getLogger(DockerClientUtil.class); private DockerClientUtil() { } public static void createContainer(DockerClient client, CreateContainerCmd cmd, String node) { String name = cmd.getName(); try { InspectContainerResponse inspectResponse = inspect(client, name); if (inspectResponse != null && inspectResponse.getId() != null && !isContainerRunning(inspectResponse)) { remove(client, inspectResponse, name, node); } } catch (NotFoundException ex) { create(cmd, node, name); } } public static void startContainer(DockerClient client, String name) throws Exception { try { start(client, name); InspectContainerResponse inspectResponse = inspect(client, name); if (inspectResponse == null || !isContainerRunning(inspectResponse)) { LOGGER.warn("Container {} failed to start! details: {}.", name, inspectResponse); throw new CloudbreakOrchestratorFailedException(String.format("Container %s failed to start! ", name)); } } catch (NotModifiedException e) { LOGGER.info("Container {} is already running.", name); } } public static void remove(DockerClient client, String name, String node) throws CloudbreakOrchestratorFailedException { try { InspectContainerResponse inspectResponse = inspect(client, name); if (inspectResponse != null && inspectResponse.getId() != null && isContainerRunning(inspectResponse)) { LOGGER.warn("Container {} is still running on node: {}! Trying to remove it again.", name, node); remove(client, inspectResponse, name, node); } throw new CloudbreakOrchestratorFailedException(String.format("Container %s is still running on node: %s!", name, node)); } catch (NotFoundException ex) { LOGGER.info("Container '{}' has already been deleted from node '{}'.", name, node); } } private static void start(DockerClient client, String name) { long start = System.currentTimeMillis(); client.startContainerCmd(name).exec(); LOGGER.info("Container {} start command took {} ms", name, System.currentTimeMillis() - start); } private static InspectContainerResponse inspect(DockerClient client, String name) { long start = System.currentTimeMillis(); InspectContainerResponse inspectResponse = client.inspectContainerCmd(name).exec(); LOGGER.info("Container {} inspect command took {} ms", name, System.currentTimeMillis() - start); return inspectResponse; } private static void remove(DockerClient client, InspectContainerResponse inspectResponse, String name, String node) { LOGGER.warn("Container {} already exists, it will be removed! node: {}", name, node); long start = System.currentTimeMillis(); client.removeContainerCmd(inspectResponse.getId()).withForce(true).exec(); LOGGER.info("Container {} remove command took {} ms", name, System.currentTimeMillis() - start); } private static void create(CreateContainerCmd cmd, String node, String name) { LOGGER.info("Creating container {} on node {}", name, node); long start = System.currentTimeMillis(); cmd.exec(); LOGGER.info("Container {} create command took {} ms", name, System.currentTimeMillis() - start); } private static boolean isContainerRunning(InspectContainerResponse inspect) { return inspect.getState().isRunning(); } }