Bug 497100: Add extension point for Docker Connection settings.

The following methods that provide default settings for docker
connection settings are converted to classes that implement
IConnectionSettingsProvider, and that contribute to the
o.e.l.docker.core.connection extension point :

defaultsWithUnixSocket() -> DefaultUnixConnectionSettingsProvider
defaultswithSystemEnv() -> SystemConnectionSettingsProvider
defaultsWithShellEnv() -> ShellConnectionSettingsProvider

DefaultTCPConnectionSettingsProvider is also created which checks the
default TCP location (127.0.0.1:2375) if it exists.

Change-Id: I23d3238282035e1bc5c0294694f60c4473b87fb8
Reviewed-on: https://git.eclipse.org/r/77551
Tested-by: Hudson CI
Reviewed-by: Roland Grunberg <rgrunber@redhat.com>
diff --git a/containers/org.eclipse.linuxtools.docker.core/META-INF/MANIFEST.MF b/containers/org.eclipse.linuxtools.docker.core/META-INF/MANIFEST.MF
index a2fcbd9..c811e69 100644
--- a/containers/org.eclipse.linuxtools.docker.core/META-INF/MANIFEST.MF
+++ b/containers/org.eclipse.linuxtools.docker.core/META-INF/MANIFEST.MF
@@ -1,8 +1,8 @@
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: Docker Core Plugin
-Bundle-SymbolicName: org.eclipse.linuxtools.docker.core
-Bundle-Version: 2.0.0.qualifier
+Bundle-SymbolicName: org.eclipse.linuxtools.docker.core;singleton:=true
+Bundle-Version: 2.1.0.qualifier
 Bundle-Activator: org.eclipse.linuxtools.docker.core.Activator
 Bundle-Vendor: Eclipse Linux Tools
 Require-Bundle: org.eclipse.core.runtime;bundle-version="3.12.0",
diff --git a/containers/org.eclipse.linuxtools.docker.core/build.properties b/containers/org.eclipse.linuxtools.docker.core/build.properties
index dff841f..55925ca 100644
--- a/containers/org.eclipse.linuxtools.docker.core/build.properties
+++ b/containers/org.eclipse.linuxtools.docker.core/build.properties
@@ -3,4 +3,6 @@
 bin.includes = META-INF/,\
                .,\
                resources/,\
-               about.html
+               about.html,\
+               plugin.xml,\
+               schema/
diff --git a/containers/org.eclipse.linuxtools.docker.core/plugin.xml b/containers/org.eclipse.linuxtools.docker.core/plugin.xml
new file mode 100644
index 0000000..10c5f19
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.core/plugin.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+   <extension-point id="org.eclipse.linuxtools.docker.core.connection" name="connections" schema="schema/org.eclipse.linuxtools.docker.core.connection.exsd"/>
+   <extension
+         point="org.eclipse.linuxtools.docker.core.connection">
+      <connection
+            provider="org.eclipse.linuxtools.internal.docker.core.DefaultUnixConnectionSettingsProvider"
+            type="default.unix">
+      </connection>
+      <connection
+            provider="org.eclipse.linuxtools.internal.docker.core.DefaultTCPConnectionSettingsProvider"
+            type="default.tcp">
+      </connection>
+      <connection
+            provider="org.eclipse.linuxtools.internal.docker.core.SystemConnectionSettingsProvider"
+            type="system">
+      </connection>
+      <connection
+            provider="org.eclipse.linuxtools.internal.docker.core.ShellConnectionSettingsProvider"
+            type="shell">
+      </connection>
+   </extension>
+
+</plugin>
diff --git a/containers/org.eclipse.linuxtools.docker.core/pom.xml b/containers/org.eclipse.linuxtools.docker.core/pom.xml
index 20f4586..7758d6f 100644
--- a/containers/org.eclipse.linuxtools.docker.core/pom.xml
+++ b/containers/org.eclipse.linuxtools.docker.core/pom.xml
@@ -7,7 +7,7 @@
 		<version>2.1.0-SNAPSHOT</version>
 	</parent>
 	<artifactId>org.eclipse.linuxtools.docker.core</artifactId>
-	<version>2.0.0-SNAPSHOT</version>
+	<version>2.1.0-SNAPSHOT</version>
 	<packaging>eclipse-plugin</packaging>
 
 </project>
diff --git a/containers/org.eclipse.linuxtools.docker.core/schema/org.eclipse.linuxtools.docker.core.connection.exsd b/containers/org.eclipse.linuxtools.docker.core/schema/org.eclipse.linuxtools.docker.core.connection.exsd
new file mode 100644
index 0000000..bb63fb0
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.core/schema/org.eclipse.linuxtools.docker.core.connection.exsd
@@ -0,0 +1,128 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.linuxtools.docker.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+      <appinfo>
+         <meta.schema plugin="org.eclipse.linuxtools.docker.core" id="org.eclipse.linuxtools.docker.core.connection" name="Docker Daemon Connections"/>
+      </appinfo>
+      <documentation>
+         This extension point allows the contribution of connection settings for Docker Daemons. The consumer supplies a unique name for the type of connections, and an implementation of an interface that returns connection settings for Docker Daemons of a particular type.
+      </documentation>
+   </annotation>
+
+   <element name="extension">
+      <annotation>
+         <appinfo>
+            <meta.element />
+         </appinfo>
+      </annotation>
+      <complexType>
+         <choice minOccurs="1" maxOccurs="unbounded">
+            <element ref="connection"/>
+         </choice>
+         <attribute name="point" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="id" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute translatable="true"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="connection">
+      <complexType>
+         <attribute name="type" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The type of the connection being provided (eg. unix, tcp, docker-machine, projectatomic)
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="identifier"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+         <attribute name="provider" type="string" use="required">
+            <annotation>
+               <documentation>
+                  A class that provides connections of the specified type.
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn=":org.eclipse.linuxtools.docker.core.IDockerConnectionSettingsProvider"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="since"/>
+      </appinfo>
+      <documentation>
+         2.1.0
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="examples"/>
+      </appinfo>
+      <documentation>
+         &lt;extension point=&quot;org.eclipse.linuxtools.docker.core.connection&quot;&gt;
+  &lt;connection provider=&quot;org.eclipse.myproject.docker.core.MyUnixSocketProvider&quot; type=&quot;unix&quot;/&gt;
+  &lt;connection provider=&quot;org.eclipse.myproject.docker.core.DockerMachineProvider&quot; type=&quot;docker-machine&quot;/&gt;
+  &lt;connection provider=&quot;org.eclipse.myproject.docker.core.CustomDaemonProvider&quot; type=&quot;custom&quot;/&gt;
+&lt;/extension&gt;
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="apiinfo"/>
+      </appinfo>
+      <documentation>
+         [Enter API information here.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="implementation"/>
+      </appinfo>
+      <documentation>
+         [Enter information about supplied implementation of this extension point.]
+      </documentation>
+   </annotation>
+
+   <annotation>
+      <appinfo>
+         <meta.section type="copyright"/>
+      </appinfo>
+      <documentation>
+         Copyright (c) 2016 Red Hat.&lt;br/&gt;
+All rights reserved. This program and the accompanying materials&lt;br/&gt;
+are made available under the terms of the Eclipse Public License v1.0&lt;br/&gt;
+which accompanies this distribution, and is available at&lt;br/&gt;
+http://www.eclipse.org/legal/epl-v10.html&lt;br/&gt;
+      </documentation>
+   </annotation>
+
+</schema>
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
index 5b584e5..fdcd7ac 100644
--- 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
@@ -25,5 +25,10 @@
 	IDockerConnectionSettings findDefaultConnectionSettings();
 
 	String resolveConnectionName(IDockerConnectionSettings settings);
+
+	/**
+	 * @since 2.1
+	 */
+	List<IDockerConnectionSettings> getKnownConnectionSettings();
 }
 
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnectionSettingsProvider.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnectionSettingsProvider.java
new file mode 100644
index 0000000..2bab536
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnectionSettingsProvider.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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;
+
+/**
+ * @since 2.1
+ */
+public interface IDockerConnectionSettingsProvider {
+
+	List<IDockerConnectionSettings> getConnectionSettings();
+
+}
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
index 1b33213..cd9df28 100644
--- 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
@@ -18,36 +18,26 @@
 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.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionPoint;
 import org.eclipse.core.runtime.Platform;
-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 org.eclipse.linuxtools.docker.core.IDockerConnectionSettingsProvider;
 
 import com.spotify.docker.client.DockerCertificateException;
 import com.spotify.docker.client.DockerClient;
 
-import jnr.unixsocket.UnixSocketAddress;
-import jnr.unixsocket.UnixSocketChannel;
-
 /**
  * A utility class that looks for candidate {@link IDockerConnection}s on the
  * host system.
@@ -159,19 +149,10 @@
 	 *         is readable and writable, {@code null} otherwise.
 	 */
 	public 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.
-			}
+		List<IDockerConnectionSettings> res = new DefaultUnixConnectionSettingsProvider()
+				.getConnectionSettings();
+		if (res != null) {
+			return res.get(0);
 		}
 		return null;
 	}
@@ -184,11 +165,10 @@
 	 *         environment variables exist, {@code null} otherwise.
 	 */
 	public IDockerConnectionSettings defaultsWithSystemEnv() {
-		final String dockerHostEnv = System.getenv(DOCKER_HOST);
-		if (dockerHostEnv != null) {
-			final String pathToCertificates = System.getenv(DOCKER_CERT_PATH);
-			return new TCPConnectionSettings(dockerHostEnv,
-					pathToCertificates);
+		List<IDockerConnectionSettings> res = new SystemConnectionSettingsProvider()
+				.getConnectionSettings();
+		if (res != null) {
+			return res.get(0);
 		}
 		return null;
 	}
@@ -201,154 +181,14 @@
 	 *         environment variables exist, {@code null} otherwise.
 	 */
 	public IDockerConnectionSettings defaultsWithShellEnv() {
-		try {
-			final String connectionSettingsDetectionScriptName = getConnectionSettingsDetectionScriptName();
-			if (connectionSettingsDetectionScriptName == null) {
-				Activator.log(new Status(IStatus.ERROR, 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);
-				return createDockerConnectionSettings(dockerSettings);
-			} 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));
+		List<IDockerConnectionSettings> res = new ShellConnectionSettingsProvider()
+				.getConnectionSettings();
+		if (res != null) {
+			return res.get(0);
 		}
 		return null;
 	}
 
-	/**
-	 * Creates connection settings from the given {@code docerSettings}, or
-	 * <code>null</code> if the settings did not contain a property with the
-	 * {@code DOCKER_HOST} key.
-	 * 
-	 * @param dockerSettings
-	 *            the connection settings
-	 * @return the {@link IDockerConnectionSettings} or <code>null</code> if the
-	 *         settings are invalid.
-	 */
-	public IDockerConnectionSettings createDockerConnectionSettings(
-			final Properties dockerSettings) {
-		final Object dockerHostEnvVariable = dockerSettings.get(DOCKER_HOST);
-		final Object dockerCertPathEnvVariable = dockerSettings
-				.get(DOCKER_CERT_PATH);
-		// at least 'dockerHostEnvVariable' should be not null
-		if (dockerHostEnvVariable == null) {
-			return null;
-		}
-		return new TCPConnectionSettings(
-				dockerHostEnvVariable.toString(),
-				dockerCertPathEnvVariable != null
-						? dockerCertPathEnvVariable.toString() : null);
-	}
-
-	/**
-	 * @param script
-	 *            the script to execute
-	 * @return the OS-specific command to run the connection settings detection
-	 *         script or <code>null</code> if the current OS is not supported.
-	 */
-	private String[] getConnectionSettingsDetectionCommandArray(
-			final File script) {
-		if (Platform.getOS().equals(Platform.OS_WIN32)) {
-			return new String[] { "cmd.exe", "/C", //$NON-NLS-1$ //$NON-NLS-2$
-					script.getAbsolutePath() };
-		} else {
-			return new String[] { script.getAbsolutePath() };
-		}
-	}
-
-	/**
-	 * 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) or <code>null</code> if the current OS is not supported.
-	 */
-	private String getConnectionSettingsDetectionScriptName() {
-		if (SystemUtils.isLinux()) {
-			return "script.sh";//$NON-NLS-1$
-		} else if (SystemUtils.isMac()) {
-			return "script-macosx.sh";//$NON-NLS-1$
-		} else if (SystemUtils.isWindows()) {
-			return "script.bat"; //$NON-NLS-1$
-		}
-		return null;
-	}
-
-	private String streamToString(InputStream stream) {
-		BufferedReader buff = new BufferedReader(
-				new InputStreamReader(stream));
-		StringBuffer res = new StringBuffer();
-		String line = ""; //$NON-NLS-1$
-		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$
@@ -413,4 +253,37 @@
 
 	}
 
+	@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) {
+						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();
+    }
+
 }
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DefaultTCPConnectionSettingsProvider.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DefaultTCPConnectionSettingsProvider.java
new file mode 100644
index 0000000..71670bf
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DefaultTCPConnectionSettingsProvider.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.util.Arrays;
+import java.util.List;
+
+import org.eclipse.linuxtools.docker.core.DockerException;
+import org.eclipse.linuxtools.docker.core.IDockerConnectionSettings;
+import org.eclipse.linuxtools.docker.core.IDockerConnectionSettingsProvider;
+
+public class DefaultTCPConnectionSettingsProvider implements IDockerConnectionSettingsProvider {
+
+	@Override
+	public List<IDockerConnectionSettings> getConnectionSettings() {
+		final TCPConnectionSettings tcp = new TCPConnectionSettings(
+				"127.0.0.1:2375", null); //$NON-NLS-1$
+		tcp.setName(tcp.getHost());
+		DockerConnection conn = new DockerConnection.Builder().tcpConnection(tcp);
+		try {
+			conn.open(false);
+			conn.close();
+		} catch (DockerException e) {
+			return null;
+		}
+		return Arrays.asList(new IDockerConnectionSettings[] { tcp });
+	}
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DefaultUnixConnectionSettingsProvider.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DefaultUnixConnectionSettingsProvider.java
new file mode 100644
index 0000000..f13efdc
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DefaultUnixConnectionSettingsProvider.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.linuxtools.docker.core.IDockerConnectionSettings;
+import org.eclipse.linuxtools.docker.core.IDockerConnectionSettingsProvider;
+
+import jnr.unixsocket.UnixSocketAddress;
+import jnr.unixsocket.UnixSocketChannel;
+
+public class DefaultUnixConnectionSettingsProvider implements IDockerConnectionSettingsProvider {
+
+	@Override
+	public List<IDockerConnectionSettings> getConnectionSettings() {
+		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
+				final UnixSocketConnectionSettings socket = new UnixSocketConnectionSettings(
+						DefaultDockerConnectionSettingsFinder.Defaults.DEFAULT_UNIX_SOCKET_PATH);
+				socket.setName(socket.getPath());
+				return Arrays.asList(new IDockerConnectionSettings[] { socket });
+			} catch (IOException e) {
+				// do nothing, just assume socket did not work.
+			}
+		}
+		return null;
+	}
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/ShellConnectionSettingsProvider.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/ShellConnectionSettingsProvider.java
new file mode 100644
index 0000000..4135c3f
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/ShellConnectionSettingsProvider.java
@@ -0,0 +1,180 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.linuxtools.docker.core.Activator;
+import org.eclipse.linuxtools.docker.core.IDockerConnectionSettings;
+import org.eclipse.linuxtools.docker.core.IDockerConnectionSettingsProvider;
+import org.eclipse.linuxtools.docker.core.Messages;
+
+public class ShellConnectionSettingsProvider implements IDockerConnectionSettingsProvider {
+
+	@Override
+	public List<IDockerConnectionSettings> getConnectionSettings() {
+		try {
+			final String connectionSettingsDetectionScriptName = getConnectionSettingsDetectionScriptName();
+			if (connectionSettingsDetectionScriptName == null) {
+				Activator.log(new Status(IStatus.ERROR, 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);
+				IDockerConnectionSettings setting = createDockerConnectionSettings(dockerSettings);
+				return Arrays.asList(new IDockerConnectionSettings [] { setting });
+			} 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 or <code>null</code> if the current OS is not supported.
+	 */
+	private String[] getConnectionSettingsDetectionCommandArray(
+			final File script) {
+		if (Platform.getOS().equals(Platform.OS_WIN32)) {
+			return new String[] { "cmd.exe", "/C", //$NON-NLS-1$ //$NON-NLS-2$
+					script.getAbsolutePath() };
+		} else {
+			return new String[] { script.getAbsolutePath() };
+		}
+	}
+
+	/**
+	 * 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) or <code>null</code> if the current OS is not supported.
+	 */
+	private String getConnectionSettingsDetectionScriptName() {
+		if (SystemUtils.isLinux()) {
+			return "script.sh";//$NON-NLS-1$
+		} else if (SystemUtils.isMac()) {
+			return "script-macosx.sh";//$NON-NLS-1$
+		} else if (SystemUtils.isWindows()) {
+			return "script.bat"; //$NON-NLS-1$
+		}
+		return null;
+	}
+
+	private String streamToString(InputStream stream) {
+		BufferedReader buff = new BufferedReader(new InputStreamReader(stream));
+		StringBuffer res = new StringBuffer();
+		String line = ""; //$NON-NLS-1$
+		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) : "";
+	}
+
+	/**
+	 * Creates connection settings from the given {@code docerSettings}, or
+	 * <code>null</code> if the settings did not contain a property with the
+	 * {@code DOCKER_HOST} key.
+	 * 
+	 * @param dockerSettings
+	 *            the connection settings
+	 * @return the {@link IDockerConnectionSettings} or <code>null</code> if the
+	 *         settings are invalid.
+	 */
+	public static IDockerConnectionSettings createDockerConnectionSettings(
+			final Properties dockerSettings) {
+		final Object dockerHostEnvVariable = dockerSettings
+				.get(DefaultDockerConnectionSettingsFinder.DOCKER_HOST);
+		final Object dockerCertPathEnvVariable = dockerSettings
+				.get(DefaultDockerConnectionSettingsFinder.DOCKER_CERT_PATH);
+		// at least 'dockerHostEnvVariable' should be not null
+		if (dockerHostEnvVariable == null) {
+			return null;
+		}
+		return new TCPConnectionSettings(dockerHostEnvVariable.toString(),
+				dockerCertPathEnvVariable != null
+						? dockerCertPathEnvVariable.toString() : null);
+	}
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/SystemConnectionSettingsProvider.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/SystemConnectionSettingsProvider.java
new file mode 100644
index 0000000..95fb8f7
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/SystemConnectionSettingsProvider.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.util.Arrays;
+import java.util.List;
+
+import org.eclipse.linuxtools.docker.core.IDockerConnectionSettings;
+import org.eclipse.linuxtools.docker.core.IDockerConnectionSettingsProvider;
+
+public class SystemConnectionSettingsProvider implements IDockerConnectionSettingsProvider {
+
+	@Override
+	public List<IDockerConnectionSettings> getConnectionSettings() {
+		final String dockerHostEnv = System.getenv(DefaultDockerConnectionSettingsFinder.DOCKER_HOST);
+		if (dockerHostEnv != null) {
+			String pathToCertificates = System.getenv(DefaultDockerConnectionSettingsFinder.DOCKER_CERT_PATH);
+			TCPConnectionSettings tcp = new TCPConnectionSettings(dockerHostEnv, pathToCertificates);
+			return Arrays.asList(new IDockerConnectionSettings[] { tcp });
+		}
+		return null;
+	}
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui.tests/plugin.xml b/containers/org.eclipse.linuxtools.docker.ui.tests/plugin.xml
index 2774b58..d72505f 100644
--- a/containers/org.eclipse.linuxtools.docker.ui.tests/plugin.xml
+++ b/containers/org.eclipse.linuxtools.docker.ui.tests/plugin.xml
@@ -8,6 +8,17 @@
 	     <adapter type="org.eclipse.debug.ui.actions.ILaunchable"/>
 	  </factory>
 	</extension>
+ <extension
+       point="org.eclipse.linuxtools.docker.core.connection">
+    <connection
+          provider="org.eclipse.linuxtools.docker.core.DockerConnectionManagerTest$TCPTestConnectionProvider"
+          type="tcp-test">
+    </connection>
+    <connection
+          provider="org.eclipse.linuxtools.docker.core.DockerConnectionManagerTest$UnixTestConnectionProvider"
+          type="unix-test">
+    </connection>
+ </extension>
 
 
 </plugin>
diff --git a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/docker/core/DockerConnectionManagerTest.java b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/docker/core/DockerConnectionManagerTest.java
index ba3478e..1032d98 100644
--- a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/docker/core/DockerConnectionManagerTest.java
+++ b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/docker/core/DockerConnectionManagerTest.java
@@ -11,12 +11,21 @@
 
 package org.eclipse.linuxtools.docker.core;
 
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Arrays;
+import java.util.List;
 import java.util.concurrent.TimeUnit;
 
 import org.assertj.core.api.Assertions;
+import org.eclipse.linuxtools.docker.core.IDockerConnectionSettings.BindingType;
+import org.eclipse.linuxtools.internal.docker.core.DefaultDockerConnectionSettingsFinder;
 import org.eclipse.linuxtools.internal.docker.core.DefaultDockerConnectionStorageManager;
 import org.eclipse.linuxtools.internal.docker.core.DockerConnection;
 import org.eclipse.linuxtools.internal.docker.core.DockerContainerRefreshManager;
+import org.eclipse.linuxtools.internal.docker.core.TCPConnectionSettings;
+import org.eclipse.linuxtools.internal.docker.core.UnixSocketConnectionSettings;
 import org.eclipse.linuxtools.internal.docker.ui.testutils.MockDockerClientFactory;
 import org.eclipse.linuxtools.internal.docker.ui.testutils.MockDockerConnectionFactory;
 import org.eclipse.linuxtools.internal.docker.ui.testutils.MockDockerConnectionStorageManagerFactory;
@@ -29,7 +38,7 @@
 import com.spotify.docker.client.DockerClient;
 
 /**
- * 
+ *
  */
 public class DockerConnectionManagerTest {
 
@@ -47,7 +56,7 @@
 	public void reset() {
 		dockerContainersRefreshManager.reset();
 	}
-	
+
 	@Test
 	public void shouldRegisterConnectionOnRefreshContainersManager() {
 		// given
@@ -57,11 +66,10 @@
 		dockerConnectionManager
 				.setConnectionStorageManager(MockDockerConnectionStorageManagerFactory.providing(dockerConnection));
 		SWTUtils.syncExec(() -> dockerConnectionManager.reloadConnections());
-		Assertions.assertThat(dockerContainersRefreshManager.getConnections()).isEmpty();
 		// when
 		dockerConnection.getContainers();
 		// then
-		Assertions.assertThat(dockerContainersRefreshManager.getConnections()).containsExactly(dockerConnection);
+		Assertions.assertThat(dockerContainersRefreshManager.getConnections()).contains(dockerConnection);
 	}
 
 	@Test
@@ -74,11 +82,55 @@
 				.setConnectionStorageManager(MockDockerConnectionStorageManagerFactory.providing(dockerConnection));
 		SWTUtils.syncExec(() -> dockerConnectionManager.reloadConnections());
 		dockerConnection.getContainers();
-		Assertions.assertThat(dockerContainersRefreshManager.getConnections()).containsExactly(dockerConnection);
+		Assertions.assertThat(dockerContainersRefreshManager.getConnections()).contains(dockerConnection);
 		// when
 		SWTUtils.syncExec(() -> dockerConnectionManager.removeConnection(dockerConnection));
 		SWTUtils.wait(1, TimeUnit.SECONDS);
 		// then
-		Assertions.assertThat(dockerContainersRefreshManager.getConnections()).isEmpty();
+		Assertions.assertThat(!dockerContainersRefreshManager.getConnections().contains(dockerConnection));
+	}
+
+	@Test
+	public void testExtensionPointProvidedConnections() {
+		DefaultDockerConnectionSettingsFinder finder = new DefaultDockerConnectionSettingsFinder();
+		List<IDockerConnectionSettings> settings = finder.getKnownConnectionSettings();
+		assertTrue(settings.size() > 0);
+		for (IDockerConnectionSettings s : settings) {
+			if (s instanceof TCPConnectionSettings) {
+				TCPConnectionSettings t = (TCPConnectionSettings) s;
+				assertTrue(t.getType() == BindingType.TCP_CONNECTION);
+				assertTrue(t.getHost().equals("https://1.2.3.4:5678"));
+				assertTrue(t.getPathToCertificates().equals("/foo/bar/baz/certs"));
+				assertTrue(t.getName().equals("https://1.2.3.4:5678"));
+			} else if (s instanceof UnixSocketConnectionSettings) {
+				UnixSocketConnectionSettings t = (UnixSocketConnectionSettings) s;
+				assertTrue(t.getType() == BindingType.UNIX_SOCKET_CONNECTION);
+				assertTrue(t.getPath().equals("unix:///foo/bar/baz/docker.sock"));
+				assertTrue(t.getName().equals("unix:///foo/bar/baz/docker.sock"));
+			} else {
+				fail("Docker Connection Settings does not match a known type");
+			}
+		}
+	}
+
+	public static class UnixTestConnectionProvider implements IDockerConnectionSettingsProvider {
+		@Override
+		public List<IDockerConnectionSettings> getConnectionSettings() {
+			final String socketPath = "unix:///foo/bar/baz/docker.sock";
+			UnixSocketConnectionSettings unix = new UnixSocketConnectionSettings(socketPath);
+			unix.setName(socketPath);
+			return Arrays.asList(new IDockerConnectionSettings[] { unix });
+		}
+	}
+
+	public static class TCPTestConnectionProvider implements IDockerConnectionSettingsProvider {
+		@Override
+		public List<IDockerConnectionSettings> getConnectionSettings() {
+			final String tcpHost = "https://1.2.3.4:5678";
+			final String tcpCertPath = "/foo/bar/baz/certs";
+			TCPConnectionSettings tcp = new TCPConnectionSettings(tcpHost, tcpCertPath);
+			tcp.setName(tcpHost);
+			return Arrays.asList(new IDockerConnectionSettings[] { tcp });
+		}
 	}
 }
diff --git a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/core/DefaultDockerConnectionSettingsFinderSWTBotTest.java b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/core/DefaultDockerConnectionSettingsFinderSWTBotTest.java
index 8aea4ae..1c3c1d8 100644
--- a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/core/DefaultDockerConnectionSettingsFinderSWTBotTest.java
+++ b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/core/DefaultDockerConnectionSettingsFinderSWTBotTest.java
@@ -33,7 +33,7 @@
 		// actually, the DOCKER_TLS_VERIFY is not used. If DOCKER_CERT_PATH is set, the we assume that DOCKER_TLS_VERIFY is '1'
 		//properties.setProperty(DefaultDockerConnectionSettingsFinder.DOCKER_TLS_VERIFY, "1");
 		// when
-		final IDockerConnectionSettings connectionSettings = new DefaultDockerConnectionSettingsFinder().createDockerConnectionSettings(properties);
+		final IDockerConnectionSettings connectionSettings = ShellConnectionSettingsProvider.createDockerConnectionSettings(properties);
 		// then
 		assertThat(connectionSettings.isSettingsResolved()).isFalse();
 		assertThat(connectionSettings.getType()).isEqualTo(BindingType.TCP_CONNECTION);
@@ -50,7 +50,7 @@
 		// actually, the DOCKER_TLS_VERIFY is not used. If DOCKER_CERT_PATH is set, the we assume that DOCKER_TLS_VERIFY is '1'
 		//properties.setProperty(DefaultDockerConnectionSettingsFinder.DOCKER_TLS_VERIFY, "1");
 		// when
-		final IDockerConnectionSettings connectionSettings = new DefaultDockerConnectionSettingsFinder().createDockerConnectionSettings(properties);
+		final IDockerConnectionSettings connectionSettings = ShellConnectionSettingsProvider.createDockerConnectionSettings(properties);
 		// then
 		assertThat(connectionSettings).isNull();
 	}