/******************************************************************************* * Copyright (c) 2015, 2017 Red Hat. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Red Hat - Initial Contribution *******************************************************************************/ package org.eclipse.linuxtools.internal.docker.core; import static org.eclipse.linuxtools.docker.core.EnumDockerConnectionSettings.BINDING_MODE; import static org.eclipse.linuxtools.docker.core.EnumDockerConnectionSettings.TCP_CERT_PATH; import static org.eclipse.linuxtools.docker.core.EnumDockerConnectionSettings.TCP_HOST; import static org.eclipse.linuxtools.docker.core.EnumDockerConnectionSettings.TCP_TLS_VERIFY; import static org.eclipse.linuxtools.docker.core.EnumDockerConnectionSettings.UNIX_SOCKET; import static org.eclipse.linuxtools.docker.core.EnumDockerConnectionSettings.UNIX_SOCKET_PATH; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.Platform; import org.eclipse.linuxtools.docker.core.EnumDockerConnectionSettings; import org.eclipse.linuxtools.docker.core.IDockerConnection; import org.eclipse.linuxtools.docker.core.IDockerConnectionSettings; import org.eclipse.linuxtools.docker.core.IDockerConnectionSettingsFinder; import org.eclipse.linuxtools.docker.core.IDockerConnectionSettingsProvider; import com.spotify.docker.client.DockerClient; import com.spotify.docker.client.exceptions.DockerCertificateException; /** * A utility class that looks for candidate {@link IDockerConnection}s on the * host system. */ public class DefaultDockerConnectionSettingsFinder implements IDockerConnectionSettingsFinder { public static final String DOCKER_CERT_PATH = "DOCKER_CERT_PATH"; //$NON-NLS-1$ public static final String DOCKER_TLS_VERIFY = "DOCKER_TLS_VERIFY"; //$NON-NLS-1$ public static final String DOCKER_TLS_VERIFY_TRUE = "1"; //$NON-NLS-1$ public static final String DOCKER_HOST = "DOCKER_HOST"; //$NON-NLS-1$ @Override public IDockerConnectionSettings findDefaultConnectionSettings() { final IDockerConnectionSettings defaultsWithUnixSocket = defaultsWithUnixSocket(); if (defaultsWithUnixSocket != null) { return defaultsWithUnixSocket; } final IDockerConnectionSettings defaultsWithSystemEnv = defaultsWithSystemEnv(); if (defaultsWithSystemEnv != null) { return defaultsWithSystemEnv; } final IDockerConnectionSettings defaultsWithShellEnv = defaultsWithShellEnv(); if (defaultsWithShellEnv != null) { return defaultsWithShellEnv; } return null; } @Override public String resolveConnectionName( final IDockerConnectionSettings connectionSettings) { if (connectionSettings == null) { return null; } try { final DockerClient client = new DockerClientFactory() .getClient(connectionSettings); if (client != null) { return client.info().name(); } } catch (DockerCertificateException | com.spotify.docker.client.exceptions.DockerException | InterruptedException e) { // ignore and return null } return null; } /** * Checks if there is a Unix socket available at the given location * * @return {@code IDockerConnectionSettings} if the Unix socket exists and * is readable and writable, {@code null} otherwise. */ public IDockerConnectionSettings defaultsWithUnixSocket() { final List<IDockerConnectionSettings> res = new DefaultUnixConnectionSettingsProvider() .getConnectionSettings(); if (res != null && !res.isEmpty()) { return res.get(0); } return null; } /** * Checks if there are {@code DOCKER_xxx} environment variables in the * current Eclipse process. * * @return {@code IDockerConnectionSettings} if the {@code DOCKER_xxx} * environment variables exist, {@code null} otherwise. */ public IDockerConnectionSettings defaultsWithSystemEnv() { final List<IDockerConnectionSettings> res = new SystemConnectionSettingsProvider() .getConnectionSettings(); if (res != null && !res.isEmpty()) { return res.get(0); } return null; } /** * Checks if there are {@code DOCKER_xxx} environment variables when running * a script in a shell. * * @return {@code IDockerConnectionSettings} if the {@code DOCKER_xxx} * environment variables exist, {@code null} otherwise. */ public IDockerConnectionSettings defaultsWithShellEnv() { final List<IDockerConnectionSettings> res = new ShellConnectionSettingsProvider() .getConnectionSettings(); if (res != null && !res.isEmpty()) { return res.get(0); } return null; } public static class Defaults { public static final String DEFAULT_UNIX_SOCKET_PATH = "unix:///var/run/docker.sock"; //$NON-NLS-1$ private boolean settingsResolved; private String name = null; private final Map<EnumDockerConnectionSettings, Object> settings = new HashMap<>(); public boolean isSettingsResolved() { return settingsResolved; } public String getName() { return name; } /** * @return the default binding mode that was found, or UNIX_SOCKET if * the property was not was not found. */ public EnumDockerConnectionSettings getBindingMode() { if (settings.containsKey(BINDING_MODE)) { return (EnumDockerConnectionSettings) settings .get(BINDING_MODE); } return UNIX_SOCKET; } /** * @return the path to the Unix socket, or {@code null} if if the * property was not was not found. */ public String getUnixSocketPath() { return (String) settings.get(UNIX_SOCKET_PATH); } /** * @return the TCP host, or {@code null} if none was found. */ public String getTcpHost() { return (String) settings.get(TCP_HOST); } /** * @return the TLS_VERIFY {@link Boolean} flag, or {@code false} if the * property was not was not found. */ public boolean getTcpTlsVerify() { if (settings.containsKey(TCP_TLS_VERIFY)) { return (Boolean) settings.get(TCP_TLS_VERIFY); } return false; } /** * @return the path to the TCP certificates, or {@code null} if the * property was not was found. */ public String getTcpCertPath() { return (String) settings.get(TCP_CERT_PATH); } } @Override public List<IDockerConnectionSettings> getKnownConnectionSettings() { List<IDockerConnectionSettings> result = new ArrayList<>(); IConfigurationElement[] configs = getConfigurationElements(); for (IConfigurationElement config : configs) { try { Object obj = config.createExecutableExtension("provider"); //$NON-NLS-1$ if (obj instanceof IDockerConnectionSettingsProvider) { List<IDockerConnectionSettings> settings = ((IDockerConnectionSettingsProvider) obj) .getConnectionSettings(); if (settings != null && !settings.isEmpty()) { result.addAll(settings); } } } catch (CoreException e) { // continue, perhaps another configuration will succeed } } return result; } /** * Helper method to return the list of extensions that contribute the the * connection registry * * @return All extensions that contribute to the connection registry. */ private static IConfigurationElement[] getConfigurationElements() { IExtensionPoint extPoint = Platform.getExtensionRegistry() .getExtensionPoint("org.eclipse.linuxtools.docker.core.connection"); //$NON-NLS-1$ return extPoint.getConfigurationElements(); } }