Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Coulon2015-09-21 08:05:03 +0000
committerXavier Coulon2015-11-03 20:39:21 +0000
commita9a65b73f50d13db8147199b8f663de24fbf3e86 (patch)
treeb3867db95843f6ed6a0fe8dbb9ed7ec69a7ce428 /containers/org.eclipse.linuxtools.docker.core/src/org/eclipse
parent91cfeea5a294d419d94a300f540bcee1ff2f0c95 (diff)
downloadorg.eclipse.linuxtools-a9a65b73f50d13db8147199b8f663de24fbf3e86.tar.gz
org.eclipse.linuxtools-a9a65b73f50d13db8147199b8f663de24fbf3e86.tar.xz
org.eclipse.linuxtools-a9a65b73f50d13db8147199b8f663de24fbf3e86.zip
Bug 477912 - Mock the Docker daemon in unit tests
- Refactoring the code to move the logic of discovering connection settings into a new interface/implementation. - Added a hierarchy of connection settings classes for Unix sockets vs TCP - New pluggable utility class to discover connection settings - Refactored the ConnectionManager by moving the storage logic (load/save connections) in an external class that implements the new IDockerConnectionStorageManager interface - In unit tests, the interfaces mentionned above are mocked to return anything needed (no connection, valid socket, etc.) - Added a bundle to wrap the org.hamcrest dependencies and expose a single exported package for Mockito. (See https://bugs.eclipse.org/bugs/show_bug.cgi?id=403676#c10) Change-Id: I3dcfcd674ab8c17eff63d037a7a1d6f2250e1677 Signed-off-by: Xavier Coulon <xcoulon@redhat.com> Reviewed-on: https://git.eclipse.org/r/56859 Tested-by: Hudson CI
Diffstat (limited to 'containers/org.eclipse.linuxtools.docker.core/src/org/eclipse')
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/DockerConnectionManager.java183
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnectionSettings.java40
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnectionSettingsFinder.java23
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnectionStorageManager.java36
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/Messages.properties2
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/BaseConnectionSettings.java42
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DefaultDockerConnectionSettingsFinder.java377
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DefaultDockerConnectionStorageManager.java142
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java4
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/TCPConnectionSettings.java78
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/UnixSocketConnectionSettings.java45
11 files changed, 827 insertions, 145 deletions
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/DockerConnectionManager.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/DockerConnectionManager.java
index 4d5c420701..9c7a6309f3 100644
--- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/DockerConnectionManager.java
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/DockerConnectionManager.java
@@ -10,168 +10,60 @@
*******************************************************************************/
package org.eclipse.linuxtools.docker.core;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.eclipse.core.runtime.IPath;
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
-import org.eclipse.equinox.security.storage.ISecurePreferences;
-import org.eclipse.equinox.security.storage.SecurePreferencesFactory;
-import org.eclipse.equinox.security.storage.StorageException;
-import org.eclipse.linuxtools.internal.docker.core.DockerConnection;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.linuxtools.internal.docker.core.DefaultDockerConnectionSettingsFinder;
+import org.eclipse.linuxtools.internal.docker.core.DefaultDockerConnectionStorageManager;
public class DockerConnectionManager {
- public final static String CONNECTIONS_FILE_NAME = "dockerconnections.xml"; //$NON-NLS-1$
-
private static DockerConnectionManager instance;
- private ArrayList<IDockerConnection> connections;
+ private List<IDockerConnection> connections;
private ListenerList connectionManagerListeners;
- private DockerConnectionManager() {
- connections = new ArrayList<>();
- loadConnections();
- }
+ private IDockerConnectionSettingsFinder connectionSettingsFinder = new DefaultDockerConnectionSettingsFinder();
+ private IDockerConnectionStorageManager connectionStorageManager = new DefaultDockerConnectionStorageManager();
- static public DockerConnectionManager getInstance() {
- if (instance == null)
+ public static DockerConnectionManager getInstance() {
+ if (instance == null) {
instance = new DockerConnectionManager();
-
+ }
return instance;
}
- private void loadConnections() {
- IPath stateLocation = Activator.getDefault().getStateLocation();
- File connectionFile = stateLocation.append(CONNECTIONS_FILE_NAME)
- .toFile();
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- try {
- DocumentBuilder db = dbf.newDocumentBuilder();
- if (connectionFile.exists()) {
- Document d = db.parse(connectionFile);
- Element e = d.getDocumentElement();
- // Get the stored configuration data
- NodeList connectionNodes = e.getElementsByTagName("connection"); // $NON-NLS-1$
- for (int x = 0; x < connectionNodes.getLength(); ++x) {
- Node n = connectionNodes.item(x);
- NamedNodeMap attrs = n.getAttributes();
- Node nameNode = attrs.getNamedItem("name"); //$NON-NLS-1$
- Node uriNode = attrs.getNamedItem("uri"); //$NON-NLS-1$
- Node usernameNode = attrs.getNamedItem("username"); //$NON-NLS-1$
- Node certNode = attrs.getNamedItem("cert"); //$NON-NLS-1$
- if (uriNode != null) {
- String uri = uriNode.getNodeValue();
- String name = nameNode.getNodeValue();
-
- if (usernameNode != null) {
- String username = usernameNode.getNodeValue();
- String key = DockerConnection.getPreferencesKey(
- uri, username);
- ISecurePreferences root = SecurePreferencesFactory
- .getDefault();
- ISecurePreferences node = root.node(key);
- @SuppressWarnings("unused")
- String password;
- try {
- password = node.get("password", null); //$NON-NLS-1$
- } catch (StorageException e1) {
- e1.printStackTrace();
- }
- }
-
- DockerConnection.Builder builder = new DockerConnection.Builder()
- .name(name);
- if (uri.startsWith("unix:")) { //$NON-NLS-1$
- builder = builder.unixSocket(uri);
- } else {
- builder = builder.tcpHost(uri);
- if (certNode != null) {
- String cert = certNode.getNodeValue();
- builder = builder.tcpCertPath(cert);
- }
- }
- try {
- DockerConnection connection = builder.build();
- addConnection(connection);
- } catch (DockerException e1) {
- Activator.log(e1);
- }
- }
- }
+ private DockerConnectionManager() {
+ reloadConnections();
+ }
+
+ public void reloadConnections() {
+ this.connections = connectionStorageManager.loadConnections();
+ for (IDockerConnection connection : connections) {
+ try {
+ connection.open(true);
+ } catch (DockerException e) {
+ Activator.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ e.getMessage()));
}
- } catch (ParserConfigurationException e) {
- Activator.log(e);
- } catch (SAXException e) {
- Activator.log(e);
- } catch (IOException e) {
- Activator.log(e);
}
+ notifyListeners(IDockerConnectionManagerListener.ADD_EVENT);
+ }
- /*if (connections.size() == 0) {
- // create a new connection from the UI preferences
- final IEclipsePreferences preferences = InstanceScope.INSTANCE
- .getNode("org.eclipse.linuxtools.docker.ui"); //$NON-NLS-1$
- final int bindingMode = preferences.getInt(BINDING_MODE, UNIX_SOCKET);
- try {
- if(bindingMode == UNIX_SOCKET) {
- final String unixSocketPath = preferences.get(UNIX_SOCKET_PATH, DEFAULT_UNIX_SOCKET_PATH);
- connections.add(new DockerConnection.Builder().unixSocket(unixSocketPath).build());
- } else {
- final String tcpHost = preferences.get(TCP_HOST, null);
- final String tcpCertPath = preferences.get(TCP_CERT_PATH, null);
- connections.add(new DockerConnection.Builder().tcpHost(tcpHost).tcpCertPath(tcpCertPath).build()); //$NON-NLS-1$
- }
- } catch (DockerCertificateException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } //$NON-NLS-1$
- }*/
+ public void setConnectionSettingsFinder(
+ final IDockerConnectionSettingsFinder connectionSettingsFinder) {
+ this.connectionSettingsFinder = connectionSettingsFinder;
+ }
+
+ public void setConnectionStorageManager(
+ final IDockerConnectionStorageManager connectionStorageManager) {
+ this.connectionStorageManager = connectionStorageManager;
}
public void saveConnections() {
- try {
- IPath stateLocation = Activator.getDefault().getStateLocation();
- File ConnectionFile = stateLocation.append(CONNECTIONS_FILE_NAME)
- .toFile();
- if (!ConnectionFile.exists())
- ConnectionFile.createNewFile();
- if (ConnectionFile.exists()) {
- PrintWriter p = new PrintWriter(new BufferedWriter(
- new FileWriter(ConnectionFile)));
- p.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); //$NON-NLS-1$
- p.println("<connections>"); // $NON-NLS-1$
- for (IDockerConnection d : connections) {
- p.print("<connection name=\"" + d.getName() + //$NON-NLS-1$
- "\" uri=\"" + d.getUri()); //$NON-NLS-1$
- if (d.getUsername() != null) {
- p.print("\" username=\"" + d.getUsername()); //$NON-NLS-1$
- }
- if (d.getTcpCertPath() != null) {
- p.print("\" cert=\"" + d.getTcpCertPath()); //$NON-NLS-1$
- }
- p.println("\"/>");
- }
- p.println("</connections>"); //$NON-NLS-1$
- p.close();
- }
- } catch (Exception e) {
- Activator.log(e);
- }
+ this.connectionStorageManager.saveConnections(this.connections);
}
public IDockerConnection[] getConnections() {
@@ -231,4 +123,9 @@ public class DockerConnectionManager {
}
}
+ public List<IDockerConnectionSettings> findConnectionSettings() {
+ // delegate the call to a utility class.
+ return connectionSettingsFinder.findConnectionSettings();
+ }
+
}
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnectionSettings.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnectionSettings.java
new file mode 100644
index 0000000000..962c4ed1bb
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnectionSettings.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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.docker.core;
+
+/**
+ * Settings for an {@link IDockerConnection}
+ */
+public interface IDockerConnectionSettings {
+
+ public enum BindingType {
+ UNIX_SOCKET_CONNECTION, TCP_CONNECTION;
+ }
+
+ /**
+ * @return the type of binding
+ */
+ public abstract BindingType getType();
+
+ /**
+ * @return the name of the Docker daemon
+ */
+ public abstract String getName();
+
+ /**
+ * @return <code>true</code> if the connection could be established and
+ * Docker daemon responded to a 'ping' request, <code>false</code>
+ * otherwise.
+ */
+ public abstract boolean isSettingsResolved();
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnectionSettingsFinder.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnectionSettingsFinder.java
new file mode 100644
index 0000000000..e5c6416028
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnectionSettingsFinder.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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.docker.core;
+
+import java.util.List;
+
+/**
+ * Interface for Docker Connection Settings finder utilities. This bundle
+ * provides a default implementation, which can be replaced if needed (hint: for
+ * testing purposes)
+ */
+public interface IDockerConnectionSettingsFinder {
+
+ public List<IDockerConnectionSettings> findConnectionSettings();
+}
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnectionStorageManager.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnectionStorageManager.java
new file mode 100644
index 0000000000..3af0e8d70a
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnectionStorageManager.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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.docker.core;
+
+import java.util.List;
+
+/**
+ * Manager that takes care of loading and saving connections settings in a file.
+ */
+public interface IDockerConnectionStorageManager {
+
+ /**
+ * Loads connections from the underlying file
+ *
+ * @return {@link List} of {@link IDockerConnection}
+ */
+ public List<IDockerConnection> loadConnections();
+
+ /**
+ * Saves the given {@link List} of {@link IDockerConnection} into a file
+ *
+ * @param connections
+ * the connections to save
+ */
+ public void saveConnections(List<IDockerConnection> connections);
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/Messages.properties b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/Messages.properties
index 38168d3171..8ff695386b 100644
--- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/Messages.properties
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/Messages.properties
@@ -21,7 +21,7 @@ Removal_In_Progress_specifier=Removal In Progress
Missing_Default_Settings=Could not find default settings to connect to a local Docker daemon
Missing_Settings=Unable to open a new client to the Docker daemon: missing configuration
Retrieve_Default_Settings_Failure=Failed to retrieve default connection settings
-Open_Connection_Failure=Failed to open a connection
+Open_Connection_Failure=Failed to open connection '''{0}'''
Docker_Daemon_Ping_Failure=Failed to ping the Docker daemon
Retrieve_Docker_Certificates_Failure=Unable to retrieve certificates to connect to the Docker daemon
List_Docker_Containers_Failure=Failed to load list of Docker containers from {0}
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/BaseConnectionSettings.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/BaseConnectionSettings.java
new file mode 100644
index 0000000000..49c181265e
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/BaseConnectionSettings.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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 org.eclipse.linuxtools.docker.core.IDockerConnectionSettings;
+
+public abstract class BaseConnectionSettings
+ implements IDockerConnectionSettings {
+
+ /** the connection name. */
+ private String name = null;
+
+ /** flag indicating if the Docker responded to a ping request. */
+ private boolean settingsResolved = false;
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ public void setSettingsResolved(boolean settingsResolved) {
+ this.settingsResolved = settingsResolved;
+ }
+
+ @Override
+ public boolean isSettingsResolved() {
+ return this.settingsResolved;
+ }
+
+} \ No newline at end of file
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DefaultDockerConnectionSettingsFinder.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DefaultDockerConnectionSettingsFinder.java
new file mode 100644
index 0000000000..571fcddb09
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DefaultDockerConnectionSettingsFinder.java
@@ -0,0 +1,377 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.linuxtools.docker.core.Activator;
+import org.eclipse.linuxtools.docker.core.DockerException;
+import org.eclipse.linuxtools.docker.core.EnumDockerConnectionSettings;
+import org.eclipse.linuxtools.docker.core.IDockerConnection;
+import org.eclipse.linuxtools.docker.core.IDockerConnectionInfo;
+import org.eclipse.linuxtools.docker.core.IDockerConnectionSettings;
+import org.eclipse.linuxtools.docker.core.IDockerConnectionSettingsFinder;
+import org.eclipse.linuxtools.docker.core.Messages;
+
+import jnr.unixsocket.UnixSocketAddress;
+import jnr.unixsocket.UnixSocketChannel;
+
+/**
+ * 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 List<IDockerConnectionSettings> findConnectionSettings() {
+ final List<IDockerConnectionSettings> availableConnectionSettings = new ArrayList<>();
+ final IDockerConnectionSettings defaultsWithUnixSocket = defaultsWithUnixSocket();
+ if (defaultsWithUnixSocket != null) {
+ availableConnectionSettings.add(defaultsWithUnixSocket);
+ }
+ final IDockerConnectionSettings defaultsWithSystemEnv = defaultsWithSystemEnv();
+ if (defaultsWithSystemEnv != null) {
+ availableConnectionSettings.add(defaultsWithSystemEnv);
+ }
+ final IDockerConnectionSettings defaultsWithShellEnv = defaultsWithShellEnv();
+ if (defaultsWithShellEnv != null) {
+ availableConnectionSettings.add(defaultsWithShellEnv);
+ }
+ // now that we have connection settings, let's ping them and retrieve the connection info.
+ for (IDockerConnectionSettings connectionSettings : availableConnectionSettings) {
+ switch(connectionSettings.getType()) {
+ case UNIX_SOCKET_CONNECTION:
+ final UnixSocketConnectionSettings unixSocketConnectionSettings = (UnixSocketConnectionSettings) connectionSettings;
+ final DockerConnection unixSocketConnection = new DockerConnection.Builder()
+ .unixSocket(unixSocketConnectionSettings.getPath())
+ .build();
+ resolveDockerName(unixSocketConnectionSettings,
+ unixSocketConnection);
+ break;
+ case TCP_CONNECTION:
+ final TCPConnectionSettings tcpConnectionSettings = (TCPConnectionSettings) connectionSettings;
+ final DockerConnection tcpConnection = new DockerConnection.Builder()
+ .tcpHost(tcpConnectionSettings.getHost())
+ .tcpCertPath(
+ tcpConnectionSettings.getPathToCertificates())
+ .build();
+ resolveDockerName(tcpConnectionSettings, tcpConnection);
+ break;
+ }
+ }
+ return availableConnectionSettings;
+ }
+
+ private void resolveDockerName(
+ final BaseConnectionSettings connectionSettings,
+ final DockerConnection connection) {
+ try {
+ connection.open(false);
+ final IDockerConnectionInfo info = connection.getInfo();
+ if (info != null) {
+ connectionSettings.setName(info.getName());
+ connectionSettings.setSettingsResolved(true);
+ }
+ } catch (DockerException e) {
+ // ignore and keep 'settingsResolved' to false
+ connectionSettings.setSettingsResolved(false);
+ } finally {
+ connection.close();
+ }
+ }
+
+ /**
+ * 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.
+ */
+ private IDockerConnectionSettings defaultsWithUnixSocket() {
+ final File unixSocketFile = new File("/var/run/docker.sock"); //$NON-NLS-1$
+ if (unixSocketFile.exists() && unixSocketFile.canRead()
+ && unixSocketFile.canWrite()) {
+ final UnixSocketAddress address = new UnixSocketAddress(
+ unixSocketFile);
+ try (final UnixSocketChannel channel = UnixSocketChannel
+ .open(address)) {
+ // assume socket works
+ return new UnixSocketConnectionSettings(
+ unixSocketFile.getAbsolutePath());
+ } catch (IOException e) {
+ // do nothing, just assume socket did not work.
+ }
+ }
+ 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.
+ */
+ private IDockerConnectionSettings defaultsWithSystemEnv() {
+ final String dockerHostEnv = System.getenv(DOCKER_HOST);
+ if (dockerHostEnv != null) {
+ final String tlsVerifyEnv = System.getenv(DOCKER_TLS_VERIFY);
+ final boolean useTls = tlsVerifyEnv != null
+ && tlsVerifyEnv.equals(DOCKER_TLS_VERIFY_TRUE); // $NON-NLS-1$
+ final String pathToCertificates = System.getenv(DOCKER_CERT_PATH);
+ return new TCPConnectionSettings(dockerHostEnv, useTls,
+ pathToCertificates);
+ }
+ 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.
+ * @throws DockerException
+ */
+ private IDockerConnectionSettings defaultsWithShellEnv() {
+ try {
+ final String connectionSettingsDetectionScriptName = getConnectionSettingsDetectionScriptName();
+ if (connectionSettingsDetectionScriptName == null) {
+ Activator.log(new Status(IStatus.WARNING, Activator.PLUGIN_ID,
+ Messages.Docker_No_Settings_Description_Script));
+ return null;
+ }
+ final File connectionSettingsDetectionScript = getConnectionSettingsDetectionScript(
+ connectionSettingsDetectionScriptName);
+ final String[] cmdArray = getConnectionSettingsDetectionCommandArray(
+ connectionSettingsDetectionScript);
+ final Process process = Runtime.getRuntime().exec(cmdArray);
+ process.waitFor();
+ final int exitValue = process.exitValue();
+ if (exitValue == 0) {
+ final InputStream processInputStream = process.getInputStream();
+ // read content from process input stream
+ final Properties dockerSettings = new Properties();
+ dockerSettings.load(processInputStream);
+ final Object dockerHostEnvVariable = dockerSettings.get(DOCKER_HOST);
+ final Object dockerTlsVerifyEnvVariable = dockerSettings
+ .get(DOCKER_TLS_VERIFY);
+ final Object dockerCertPathEnvVariable = dockerSettings
+ .get(DOCKER_CERT_PATH);
+ return new TCPConnectionSettings(
+ dockerHostEnvVariable != null
+ ? dockerHostEnvVariable.toString() : null,
+ dockerTlsVerifyEnvVariable != null
+ ? dockerTlsVerifyEnvVariable
+ .equals(DOCKER_TLS_VERIFY_TRUE)
+ : null,
+ dockerCertPathEnvVariable != null
+ ? dockerCertPathEnvVariable.toString() : null);
+ } else {
+ // log what happened if the process did not end as expected
+ // an exit value of 1 should indicate no connection found
+ if (exitValue != 1) {
+ final InputStream processErrorStream = process
+ .getErrorStream();
+ final String errorMessage = streamToString(
+ processErrorStream);
+ Activator.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ errorMessage));
+ }
+ }
+ } catch (IOException | IllegalArgumentException
+ | InterruptedException e) {
+ Activator.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+ Messages.Retrieve_Default_Settings_Failure, e));
+ }
+ return null;
+ }
+
+ /**
+ * @param script
+ * the script to execute
+ * @return the OS-specific command to run the connection settings
+ * detection script.
+ */
+ private String[] getConnectionSettingsDetectionCommandArray(
+ final File script) {
+ final String osName = System.getProperty("os.name"); //$NON-NLS-1$
+ if (osName.toLowerCase().startsWith("win")) { //$NON-NLS-1$
+ return new String[] { "cmd.exe", "/C", //$NON-NLS-1$ //$NON-NLS-2$
+ script.getAbsolutePath() };
+ } else if (osName.toLowerCase().startsWith("mac") //$NON-NLS-1$
+ || osName.toLowerCase().contains("linux") //$NON-NLS-1$
+ || osName.toLowerCase().contains("nix")) { //$NON-NLS-1$
+ return new String[] { script.getAbsolutePath() };
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Finds the script file in the data directory of the bundle given its
+ * name, or creates it from the 'resources' dir in the bundle if it was
+ * not found in the data dir.
+ *
+ * @param scriptName
+ * the name of the script to load in the data dir or in the
+ * 'resources' dir in the bundle
+ * @return the script {@link File}
+ */
+ private File getConnectionSettingsDetectionScript(
+ final String scriptName) {
+ final File script = Activator.getDefault().getBundle()
+ .getDataFile(scriptName);
+ // if the script file does not exist or is outdated.
+ if (script != null
+ && (!script.exists() || script.lastModified() < Activator
+ .getDefault().getBundle().getLastModified())) {
+ try (final FileOutputStream output = new FileOutputStream(
+ script);
+ final InputStream is = DockerConnection.class
+ .getResourceAsStream(
+ "/resources/" + scriptName)) { //$NON-NLS-1$
+ byte[] buff = new byte[1024];
+ int n;
+ while ((n = is.read(buff)) > 0) {
+ output.write(buff, 0, n);
+ }
+ script.setExecutable(true);
+ } catch (IOException e) {
+ Activator.logErrorMessage(e.getMessage());
+ }
+ }
+ return script;
+ }
+
+ /**
+ * @return the name of the script to run, depending on the OS (Windows,
+ * MAc, *Nix)
+ */
+ private String getConnectionSettingsDetectionScriptName() {
+ final String osName = System.getProperty("os.name"); //$NON-NLS-1$
+ if (osName.toLowerCase().startsWith("win")) { //$NON-NLS-1$
+ return "script.bat"; //$NON-NLS-1$
+ } else if (osName.toLowerCase().startsWith("mac") //$NON-NLS-1$
+ || osName.toLowerCase().contains("linux") //$NON-NLS-1$
+ || osName.toLowerCase().contains("nix")) { //$NON-NLS-1$
+ return "script.sh";//$NON-NLS-1$
+ } else {
+ return null;
+ }
+ }
+
+ private String streamToString(InputStream stream) {
+ BufferedReader buff = new BufferedReader(
+ new InputStreamReader(stream));
+ StringBuffer res = new StringBuffer();
+ String line = "";
+ try {
+ while ((line = buff.readLine()) != null) {
+ res.append(System.getProperty("line.separator")); //$NON-NLS-1$
+ res.append(line);
+ }
+ buff.close();
+ } catch (IOException e) {
+ }
+ return res.length() > 0 ? res.substring(1) : "";
+ }
+
+ 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);
+ }
+
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DefaultDockerConnectionStorageManager.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DefaultDockerConnectionStorageManager.java
new file mode 100644
index 0000000000..65792a2d50
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DefaultDockerConnectionStorageManager.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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 java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.equinox.security.storage.ISecurePreferences;
+import org.eclipse.equinox.security.storage.SecurePreferencesFactory;
+import org.eclipse.equinox.security.storage.StorageException;
+import org.eclipse.linuxtools.docker.core.Activator;
+import org.eclipse.linuxtools.docker.core.IDockerConnection;
+import org.eclipse.linuxtools.docker.core.IDockerConnectionStorageManager;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+/**
+ * Default implementation of the {@link IDockerConnectionStorageManager}.
+ */
+public class DefaultDockerConnectionStorageManager
+ implements IDockerConnectionStorageManager {
+
+ public final static String CONNECTIONS_FILE_NAME = "dockerconnections.xml"; //$NON-NLS-1$
+
+ @Override
+ public List<IDockerConnection> loadConnections() {
+ final List<IDockerConnection> connections = new ArrayList<>();
+ final IPath stateLocation = Activator.getDefault().getStateLocation();
+ final File connectionFile = stateLocation.append(CONNECTIONS_FILE_NAME)
+ .toFile();
+ final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ try {
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ if (connectionFile.exists()) {
+ Document d = db.parse(connectionFile);
+ Element e = d.getDocumentElement();
+ // Get the stored configuration data
+ NodeList connectionNodes = e.getElementsByTagName("connection"); // $NON-NLS-1$
+ for (int x = 0; x < connectionNodes.getLength(); ++x) {
+ Node n = connectionNodes.item(x);
+ NamedNodeMap attrs = n.getAttributes();
+ Node nameNode = attrs.getNamedItem("name"); //$NON-NLS-1$
+ Node uriNode = attrs.getNamedItem("uri"); //$NON-NLS-1$
+ Node usernameNode = attrs.getNamedItem("username"); //$NON-NLS-1$
+ Node certNode = attrs.getNamedItem("cert"); //$NON-NLS-1$
+ if (uriNode != null) {
+ String uri = uriNode.getNodeValue();
+ String name = nameNode.getNodeValue();
+
+ if (usernameNode != null) {
+ String username = usernameNode.getNodeValue();
+ String key = DockerConnection.getPreferencesKey(uri,
+ username);
+ ISecurePreferences root = SecurePreferencesFactory
+ .getDefault();
+ ISecurePreferences node = root.node(key);
+ @SuppressWarnings("unused")
+ String password;
+ try {
+ password = node.get("password", null); //$NON-NLS-1$
+ } catch (StorageException e1) {
+ e1.printStackTrace();
+ }
+ }
+
+ DockerConnection.Builder builder = new DockerConnection.Builder()
+ .name(name);
+ if (uri.startsWith("unix:")) { //$NON-NLS-1$
+ builder = builder.unixSocket(uri);
+ } else {
+ builder = builder.tcpHost(uri);
+ if (certNode != null) {
+ builder = builder
+ .tcpCertPath(certNode.getNodeValue());
+ }
+ }
+ DockerConnection connection = builder.build();
+ connections.add(connection);
+ }
+ }
+ }
+ } catch (ParserConfigurationException | SAXException | IOException e) {
+ Activator.log(e);
+ }
+ return connections;
+ }
+
+ @Override
+ public void saveConnections(List<IDockerConnection> connections) {
+ final IPath stateLocation = Activator.getDefault().getStateLocation();
+ final File connectionFile = stateLocation.append(CONNECTIONS_FILE_NAME)
+ .toFile();
+ try {
+ if (!connectionFile.exists()) {
+ connectionFile.createNewFile();
+ }
+ try (final PrintWriter p = new PrintWriter(
+ new BufferedWriter(new FileWriter(connectionFile)))) {
+ p.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); //$NON-NLS-1$
+ p.println("<connections>"); // $NON-NLS-1$
+ for (IDockerConnection d : connections) {
+ p.print("<connection name=\"" + d.getName() + //$NON-NLS-1$
+ "\" uri=\"" + d.getUri()); //$NON-NLS-1$
+ if (d.getUsername() != null) {
+ p.print("\" username=\"" + d.getUsername()); //$NON-NLS-1$
+ }
+ if (d.getTcpCertPath() != null) {
+ p.print("\" cert=\"" + d.getTcpCertPath()); //$NON-NLS-1$
+ }
+ p.println("\"/>"); //$NON-NLS-1$
+ }
+ p.println("</connections>"); //$NON-NLS-1$
+ }
+ } catch (Exception e) {
+ Activator.log(e);
+ }
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java
index e1ddc56765..6eecdef4ab 100644
--- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java
@@ -111,6 +111,7 @@ import jnr.unixsocket.UnixSocketChannel;
*/
public class DockerConnection implements IDockerConnection, Closeable {
+ @Deprecated
public static class Defaults {
public static final String DEFAULT_UNIX_SOCKET_PATH = "unix:///var/run/docker.sock"; //$NON-NLS-1$
@@ -585,7 +586,8 @@ public class DockerConnection implements IDockerConnection, Closeable {
}
}
} catch (DockerCertificateException e) {
- throw new DockerException(Messages.Open_Connection_Failure, e);
+ throw new DockerException(
+ NLS.bind(Messages.Open_Connection_Failure, this.name));
}
}
}
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/TCPConnectionSettings.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/TCPConnectionSettings.java
new file mode 100644
index 0000000000..f0f0889c85
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/TCPConnectionSettings.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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;
+
+/**
+ * TCP Connection settings
+ */
+public class TCPConnectionSettings extends BaseConnectionSettings {
+
+ /**
+ * the host to connect to (a URI representation, including 'tcp' scheme and
+ * port number).
+ */
+ private final String host;
+
+ /** flag to indicate if TLS is used. */
+ private final boolean tlsVerify;
+
+ /**
+ * absolute path to folder containing the certificates (ca.pem, key.pem and
+ * cert.pem).
+ */
+ private final String pathToCertificates;
+
+ /**
+ * Constructor
+ *
+ * @param host
+ * host to connect to
+ * @param tlsVerify
+ * flag to indicate if TLS is used
+ * @param pathToCertificates
+ * absolute path to folder containing the certificates
+ */
+ public TCPConnectionSettings(final String host, final boolean tlsVerify,
+ final String pathToCertificates) {
+ super();
+ this.host = host;
+ this.tlsVerify = tlsVerify;
+ this.pathToCertificates = pathToCertificates;
+ }
+
+ @Override
+ public BindingType getType() {
+ return BindingType.TCP_CONNECTION;
+ }
+
+ /**
+ * @return the host
+ */
+ public String getHost() {
+ return host;
+ }
+
+ /**
+ * @return the tlsVerify
+ */
+ public boolean isTlsVerify() {
+ return tlsVerify;
+ }
+
+ /**
+ * @return the pathToCertificates
+ */
+ public String getPathToCertificates() {
+ return pathToCertificates;
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/UnixSocketConnectionSettings.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/UnixSocketConnectionSettings.java
new file mode 100644
index 0000000000..7ba03bd671
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/UnixSocketConnectionSettings.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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;
+
+/**
+ * Unix Socket Connection Settings
+ */
+public class UnixSocketConnectionSettings extends BaseConnectionSettings {
+
+ /** The path to the Unix Socket, including scheme (unix://). */
+ private final String path;
+
+ /**
+ * Constructor
+ *
+ * @param path
+ * the path to the Unix Socket
+ */
+ public UnixSocketConnectionSettings(String path) {
+ super();
+ this.path = path;
+ }
+
+ @Override
+ public BindingType getType() {
+ return BindingType.UNIX_SOCKET_CONNECTION;
+ }
+
+ /**
+ * @return the path to the Unix Socket
+ */
+ public String getPath() {
+ return path;
+ }
+
+}

Back to the top