package org.arquillian.cube.docker.impl.client; import java.io.File; import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import org.apache.commons.lang.StringUtils; import org.arquillian.cube.docker.impl.client.config.CubeContainer; import org.arquillian.cube.docker.impl.client.config.DockerCompositions; import org.arquillian.cube.docker.impl.model.DockerMachineDistro; import org.arquillian.cube.docker.impl.util.ConfigUtil; import org.arquillian.cube.docker.impl.util.DockerMachine; import org.arquillian.cube.docker.impl.util.HomeResolverUtil; import org.arquillian.cube.spi.AutoStartParser; import org.jboss.arquillian.core.api.Injector; public class CubeDockerConfiguration { public static final String DOCKER_URI = "serverUri"; public static final String DOCKER_SERVER_IP = "dockerServerIp"; public static final String CERT_PATH = "certPath"; public static final String TLS_VERIFY = "tlsVerify"; public static final String DOCKER_CONTAINERS = "dockerContainers"; public static final String BOOT2DOCKER_PATH = "boot2dockerPath"; public static final String DOCKER_MACHINE_PATH = "dockerMachinePath"; public static final String DOCKER_MACHINE_NAME = "machineName"; public static final String DOCKER_MACHINE_DRIVER = "machineDriver"; public static final String AUTO_START_ORDER = "autoStartOrder"; public static final String DOCKER_MACHINE_CUSTOM_PATH = "dockerMachineCustomPath"; public static final String DOCKER_MACHINE_ARQUILLIAN_PATH = "~/.arquillian/machine"; public static final String CUBE_SPECIFIC_PROPERTIES = "cubeSpecificProperties"; public static final String CLEAN = "clean"; public static final String REMOVE_VOLUMES = "removeVolumes"; public static final String CLEAN_BUILD_IMAGE = "cleanBuildImage"; static final String DIND_RESOLUTION = "dockerInsideDockerResolution"; private static final String DOCKER_VERSION = "serverVersion"; private static final String USERNAME = "username"; private static final String PASSWORD = "password"; private static final String EMAIL = "email"; private static final String DOCKER_CONTAINERS_FILE = "dockerContainersFile"; private static final String DOCKER_CONTAINERS_FILES = "dockerContainersFiles"; private static final String IGNORE_CONTAINERS_DEFINITION = "ignoreContainersDefinition"; private static final String DOCKER_REGISTRY = "dockerRegistry"; private static final String AUTO_START_CONTAINERS = "autoStartContainers"; private static final String DEFINITION_FORMAT = "definitionFormat"; private static final String CUBE_ENVIRONMENT = "cube.environment"; private String dockerServerVersion; private String dockerServerUri; private String dockerRegistry; private String boot2DockerPath; private String dockerMachinePath; private String machineName; private String username; private String password; private String email; private String certPath; private boolean tlsVerify; private String dockerServerIp; private DefinitionFormat definitionFormat = DefinitionFormat.COMPOSE; private boolean dockerInsideDockerResolution = true; private boolean clean = false; private boolean removeVolumes = true; private boolean cleanBuildImage = true; private boolean ignoreContainersDefinition = false; private AutoStartParser autoStartContainers = null; private DockerAutoStartOrder dockerAutoStartOrder = null; private DockerCompositions dockerContainersContent; public static CubeDockerConfiguration fromMap(Map<String, String> map, Injector injector) { CubeDockerConfiguration cubeConfiguration = new CubeDockerConfiguration(); if (map.containsKey(DOCKER_SERVER_IP)) { cubeConfiguration.dockerServerIp = map.get(DOCKER_SERVER_IP); } if (map.containsKey(DOCKER_VERSION)) { cubeConfiguration.dockerServerVersion = map.get(DOCKER_VERSION); } if (map.containsKey(DOCKER_URI)) { cubeConfiguration.dockerServerUri = map.get(DOCKER_URI); } if (map.containsKey(DIND_RESOLUTION)) { cubeConfiguration.dockerInsideDockerResolution = Boolean.parseBoolean(map.get(DIND_RESOLUTION)); } if (map.containsKey(BOOT2DOCKER_PATH)) { cubeConfiguration.boot2DockerPath = map.get(BOOT2DOCKER_PATH); } if (map.containsKey(DOCKER_MACHINE_PATH)) { cubeConfiguration.dockerMachinePath = map.get(DOCKER_MACHINE_PATH); } if (map.containsKey(DOCKER_MACHINE_NAME)) { cubeConfiguration.machineName = map.get(DOCKER_MACHINE_NAME); } if (map.containsKey(USERNAME)) { cubeConfiguration.username = map.get(USERNAME); } if (map.containsKey(PASSWORD)) { cubeConfiguration.password = map.get(PASSWORD); } if (map.containsKey(EMAIL)) { cubeConfiguration.email = map.get(EMAIL); } if (map.containsKey(CERT_PATH)) { cubeConfiguration.certPath = map.get(CERT_PATH); } if (map.containsKey(TLS_VERIFY)) { cubeConfiguration.tlsVerify = Boolean.parseBoolean(map.get(TLS_VERIFY)); } if (map.containsKey(DOCKER_REGISTRY)) { cubeConfiguration.dockerRegistry = map.get(DOCKER_REGISTRY); } if (map.containsKey(IGNORE_CONTAINERS_DEFINITION)) { cubeConfiguration.ignoreContainersDefinition = Boolean.parseBoolean(map.get(IGNORE_CONTAINERS_DEFINITION)); } if (map.containsKey(DEFINITION_FORMAT)) { String definitionContent = map.get(DEFINITION_FORMAT); cubeConfiguration.definitionFormat = DefinitionFormat.valueOf(DefinitionFormat.class, definitionContent); } if (map.containsKey(DOCKER_CONTAINERS) && !cubeConfiguration.ignoreContainersDefinition) { String content = map.get(DOCKER_CONTAINERS); cubeConfiguration.dockerContainersContent = DockerContainerDefinitionParser.convert(content, cubeConfiguration.definitionFormat); } if (map.containsKey(DOCKER_CONTAINERS_FILE) && !cubeConfiguration.ignoreContainersDefinition) { final String location = map.get(DOCKER_CONTAINERS_FILE); final List<URI> resolveUri = new ArrayList<>(); try { final URI uri = URI.create(location); resolveUri.add(uri); if (System.getProperty(CUBE_ENVIRONMENT) != null) { final String resolveFilename = resolveFilename(uri); final String environmentUri = uri.toString() .replace(resolveFilename, resolveFilename + "." + System.getProperty(CUBE_ENVIRONMENT)); resolveUri.add(URI.create(environmentUri)); } cubeConfiguration.dockerContainersContent = DockerContainerDefinitionParser.convert(cubeConfiguration.definitionFormat, resolveUri.toArray(new URI[resolveUri.size()])); } catch (IOException e) { throw new IllegalArgumentException(e); } } if (map.containsKey(DOCKER_CONTAINERS_FILES) && !cubeConfiguration.ignoreContainersDefinition) { String locations = map.get(DOCKER_CONTAINERS_FILES); List<URI> realLocations = getUris(locations); try { cubeConfiguration.dockerContainersContent = DockerContainerDefinitionParser.convert(cubeConfiguration.definitionFormat, realLocations.toArray(new URI[realLocations.size()])); } catch (IOException e) { throw new IllegalArgumentException(e); } } if ( !map.containsKey(DOCKER_CONTAINERS) && !map.containsKey(DOCKER_CONTAINERS_FILE) && !map.containsKey( DOCKER_CONTAINERS_FILES) && !cubeConfiguration.ignoreContainersDefinition) { try { cubeConfiguration.dockerContainersContent = DockerContainerDefinitionParser.convertDefault(cubeConfiguration.definitionFormat); } catch (IOException e) { throw new IllegalArgumentException(e); } } if (map.containsKey(CUBE_SPECIFIC_PROPERTIES)) { String content = map.get(CUBE_SPECIFIC_PROPERTIES); final DockerCompositions overrideInformation = DockerContainerDefinitionParser.convert(content, DefinitionFormat.CUBE); cubeConfiguration.dockerContainersContent.overrideCubeProperties(overrideInformation); } if (map.containsKey(AUTO_START_CONTAINERS)) { String expression = map.get(AUTO_START_CONTAINERS); DockerCompositions containerDefinitions = cubeConfiguration.getDockerContainersContent(); AutoStartParser autoStartParser = AutoStartParserFactory.create(expression, containerDefinitions, injector); cubeConfiguration.autoStartContainers = autoStartParser; } if (map.containsKey(CLEAN)) { cubeConfiguration.clean = Boolean.parseBoolean(map.get(CLEAN)); } if (map.containsKey(AUTO_START_ORDER)) { cubeConfiguration.dockerAutoStartOrder = AutoStartOrderFactory.createDockerAutoStartOrder(map.get(AUTO_START_ORDER)); } else { cubeConfiguration.dockerAutoStartOrder = AutoStartOrderFactory.createDefaultDockerAutoStartOrder(); } if (map.containsKey(REMOVE_VOLUMES)) { cubeConfiguration.removeVolumes = Boolean.parseBoolean(map.get(REMOVE_VOLUMES)); } if (map.containsKey(CLEAN_BUILD_IMAGE)) { cubeConfiguration.cleanBuildImage = Boolean.parseBoolean(map.get(CLEAN_BUILD_IMAGE)); } for (CubeContainer container : cubeConfiguration.dockerContainersContent.getContainers().values()) { if (container.getRemoveVolumes() == null) { container.setRemoveVolumes(cubeConfiguration.isRemoveVolumes()); } } return cubeConfiguration; } private static String resolveFilename(URI uri) { if (uri.getScheme() == null || "file".equals(uri.getScheme())) { //it is a local path final String fullPath = uri.toString(); final int lastSeparatorChar = fullPath.lastIndexOf(File.separatorChar); if (lastSeparatorChar > -1) { return fullPath.substring(lastSeparatorChar + 1, fullPath.lastIndexOf('.')); } else { return fullPath.substring(0, fullPath.lastIndexOf('.')); } } else { //means it is a remote uri (http, ftp, ... final String fullPath = uri.toString(); final int lastSeparatorChar = fullPath.lastIndexOf(File.separatorChar); return fullPath.substring(lastSeparatorChar + 1, fullPath.lastIndexOf('.')); } } private static List<URI> getUris(String locations) { // Transform comma-separated values to an array of URIs List<URI> realLocations = new ArrayList<>(); StringTokenizer tokenizer = new StringTokenizer(locations, ","); while (tokenizer.hasMoreTokens()) { realLocations.add(URI.create(tokenizer.nextToken().trim())); } return realLocations; } public static String resolveUrl(String machineVersion) { return "https://github.com/docker/machine/releases/download/" + machineVersion + "/" + DockerMachineDistro.resolveDistro(); } public static File resolveMachinePath(String machineCustomPath, String machineVersion) { if (StringUtils.isBlank(machineCustomPath)) { machineCustomPath = DOCKER_MACHINE_ARQUILLIAN_PATH; } String dockerMachineFile = HomeResolverUtil.resolveHomeDirectoryChar( machineCustomPath + "/" + machineVersion + "/" + DockerMachine.DOCKER_MACHINE_EXEC); return new File(dockerMachineFile); } public String getDockerServerUri() { return dockerServerUri; } public String getDockerServerVersion() { return dockerServerVersion; } public DockerCompositions getDockerContainersContent() { return dockerContainersContent; } public String getDockerRegistry() { return dockerRegistry; } public String getBoot2DockerPath() { return boot2DockerPath; } public String getDockerMachinePath() { return dockerMachinePath; } public String getMachineName() { return machineName; } public boolean isDockerMachineName() { return this.getMachineName() != null; } public String getUsername() { return username; } public String getPassword() { return password; } public String getEmail() { return email; } public String getCertPath() { return certPath; } public boolean getTlsVerify() { return tlsVerify; } //this property is resolved in DockerCubeConfigurator class. public String getDockerServerIp() { return dockerServerIp; } public AutoStartParser getAutoStartContainers() { return autoStartContainers; } void setAutoStartContainers(AutoStartParser autoStartParser) { this.autoStartContainers = autoStartParser; } public DockerAutoStartOrder getDockerAutoStartOrder() { return dockerAutoStartOrder; } public boolean isClean() { return clean; } public boolean isRemoveVolumes() { return removeVolumes; } public DefinitionFormat getDefinitionFormat() { return definitionFormat; } public boolean isDockerInsideDockerResolution() { return dockerInsideDockerResolution; } public boolean isCleanBuildImage() { return cleanBuildImage; } @Override public String toString() { String SEP = System.getProperty("line.separator"); StringBuilder content = new StringBuilder(); content.append("CubeDockerConfiguration: ").append(SEP); if (dockerServerVersion != null) { content.append(" ").append(DOCKER_VERSION).append(" = ").append(dockerServerVersion).append(SEP); } if (dockerServerUri != null) { content.append(" ").append(DOCKER_URI).append(" = ").append(dockerServerUri).append(SEP); } if (dockerRegistry != null) { content.append(" ").append(DOCKER_REGISTRY).append(" = ").append(dockerRegistry).append(SEP); } if (boot2DockerPath != null) { content.append(" ").append(BOOT2DOCKER_PATH).append(" = ").append(boot2DockerPath).append(SEP); } if (dockerMachinePath != null) { content.append(" ").append(DOCKER_MACHINE_PATH).append(" = ").append(dockerMachinePath).append(SEP); } if (machineName != null) { content.append(" ").append(DOCKER_MACHINE_NAME).append(" = ").append(machineName).append(SEP); } if (username != null) { content.append(" ").append(USERNAME).append(" = ").append(username).append(SEP); } if (password != null) { content.append(" ").append(PASSWORD).append(" = ").append(password).append(SEP); } if (email != null) { content.append(" ").append(EMAIL).append(" = ").append(email).append(SEP); } if (certPath != null) { content.append(" ").append(CERT_PATH).append(" = ").append(certPath).append(SEP); } content.append(" ").append(TLS_VERIFY).append(" = ").append(tlsVerify).append(SEP); if (dockerServerIp != null) { content.append(" ").append(DOCKER_SERVER_IP).append(" = ").append(dockerServerIp).append(SEP); } if (definitionFormat != null) { content.append(" ").append(DEFINITION_FORMAT).append(" = ").append(definitionFormat).append(SEP); } if (autoStartContainers != null) { content.append(" ").append(AUTO_START_CONTAINERS).append(" = ").append(autoStartContainers).append(SEP); } content.append(" ").append(CLEAN).append(" = ").append(clean).append(SEP); content.append(" ").append(REMOVE_VOLUMES).append(" = ").append(removeVolumes).append(SEP); if (dockerContainersContent != null) { String output = ConfigUtil.dump(dockerContainersContent); content.append(" ").append(DOCKER_CONTAINERS).append(" = ").append(output).append(SEP); } return content.toString(); } }