Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Coulon2015-05-26 13:03:51 -0400
committerRoland Grunberg2015-06-02 18:14:44 -0400
commit6641512e5cf08a3deaf82f2db216b5d31fbb034a (patch)
treebdcbc63f97b29dab281e82ef53b41d09cafcc301
parent94734f51f17c6245ce73cfef71fe3ea26708fbfb (diff)
downloadorg.eclipse.linuxtools-6641512e5cf08a3deaf82f2db216b5d31fbb034a.tar.gz
org.eclipse.linuxtools-6641512e5cf08a3deaf82f2db216b5d31fbb034a.tar.xz
org.eclipse.linuxtools-6641512e5cf08a3deaf82f2db216b5d31fbb034a.zip
Bug 468607 - Refactor the wizard to run a container
Change-Id: Ie41be59b3326e9521833f25c3fe91ac565adf6d5 Signed-off-by: Xavier Coulon <xcoulon@redhat.com> Reviewed-on: https://git.eclipse.org/r/48939 Tested-by: Hudson CI Reviewed-by: Roland Grunberg <rgrunber@redhat.com> Tested-by: Roland Grunberg <rgrunber@redhat.com> Reviewed-on: https://git.eclipse.org/r/49258
-rw-r--r--containers/org.eclipse.linuxtools.docker-feature/.project6
-rw-r--r--containers/org.eclipse.linuxtools.docker-feature/.settings/org.eclipse.core.resources.prefs2
-rw-r--r--containers/org.eclipse.linuxtools.docker-feature/.settings/org.eclipse.m2e.core.prefs4
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/.classpath4
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/.settings/org.eclipse.core.resources.prefs2
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnection.java41
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerContainer.java7
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerContainerConfig.java14
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerHostConfig.java4
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerImageSearchResult.java30
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java122
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerContainer.java47
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerContainerConfig.java114
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerHostConfig.java20
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImage.java33
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImageSearchResult.java139
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/.settings/org.eclipse.core.resources.prefs2
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/META-INF/MANIFEST.MF10
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/icons/checked.gifbin0 -> 1627 bytes
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/icons/error_obj.gifbin0 -> 339 bytes
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/icons/file_obj.gifbin0 -> 349 bytes
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/icons/folder_closed.gifbin0 -> 219 bytes
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/icons/unchecked.gifbin0 -> 1628 bytes
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/icons/warning_obj.gifbin0 -> 337 bytes
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/plugin.properties12
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/plugin.xml104
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/Activator.java14
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/launch/ContainerLauncher.java4
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/RunConsole.java47
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/SWTImagesFactory.java40
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/AddConnectionCommandHandler.java13
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/BaseContainersCommandHandler.java16
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/BaseImagesCommandHandler.java3
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandUtils.java31
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CreateContainerCommandHandler.java138
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/DisplayContainerLogCommandHandler.java3
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/RemoveContainerLogCommandHandler.java6
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/RunImageCommandHandler.java188
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/databinding/BaseDatabindingModel.java46
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/databinding/RequiredControlDecorationUpdater.java67
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/databinding/TextCellEditingSupport.java45
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/propertytesters/ContainerPropertyTester.java11
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/utils/IRunnableWithResult.java26
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/ConnectionInfoContentProvider.java6
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DVMessages.properties1
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerContainersView.java2
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerLabelProvider.java25
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerView.java17
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerImagesView.java2
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/LabelUtils.java2
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerCreate.java133
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerCreatePage.java939
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerDataVolumeDialog.java398
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerEnvironmentVariableDialog.java145
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerLinkDialog.java337
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerPortDialog.java225
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/DataVolumeModel.java188
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/EnvironmentVariableModel.java96
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRun.java230
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunResourceVolumesVariablesModel.java204
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunResourceVolumesVariablesPage.java643
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionModel.java516
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionPage.java900
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearch.java60
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearchModel.java81
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearchPage.java395
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/NewDockerConnection.java3
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/NewDockerConnectionPage.java8
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/WizardUtils.java65
-rw-r--r--releng/org.eclipse.linuxtools.target/.project6
-rw-r--r--releng/org.eclipse.linuxtools.target/.settings/org.eclipse.core.resources.prefs2
-rw-r--r--releng/org.eclipse.linuxtools.target/.settings/org.eclipse.m2e.core.prefs4
72 files changed, 5562 insertions, 1486 deletions
diff --git a/containers/org.eclipse.linuxtools.docker-feature/.project b/containers/org.eclipse.linuxtools.docker-feature/.project
index e85a8ddfbe..d176de8c3a 100644
--- a/containers/org.eclipse.linuxtools.docker-feature/.project
+++ b/containers/org.eclipse.linuxtools.docker-feature/.project
@@ -10,8 +10,14 @@
<arguments>
</arguments>
</buildCommand>
+ <buildCommand>
+ <name>org.eclipse.m2e.core.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
+ <nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.pde.FeatureNature</nature>
</natures>
</projectDescription>
diff --git a/containers/org.eclipse.linuxtools.docker-feature/.settings/org.eclipse.core.resources.prefs b/containers/org.eclipse.linuxtools.docker-feature/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000000..99f26c0203
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker-feature/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/containers/org.eclipse.linuxtools.docker-feature/.settings/org.eclipse.m2e.core.prefs b/containers/org.eclipse.linuxtools.docker-feature/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000000..f897a7f1cb
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker-feature/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/containers/org.eclipse.linuxtools.docker.core/.classpath b/containers/org.eclipse.linuxtools.docker.core/.classpath
index 5390b4ca76..46cec6ed2a 100644
--- a/containers/org.eclipse.linuxtools.docker.core/.classpath
+++ b/containers/org.eclipse.linuxtools.docker.core/.classpath
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src/"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
diff --git a/containers/org.eclipse.linuxtools.docker.core/.settings/org.eclipse.core.resources.prefs b/containers/org.eclipse.linuxtools.docker.core/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000000..99f26c0203
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.core/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnection.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnection.java
index 1ec98f1c3e..bf49dc092a 100644
--- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnection.java
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnection.java
@@ -150,8 +150,20 @@ public interface IDockerConnection {
*/
public IDockerConnectionInfo getInfo() throws DockerException;
+ /**
+ * Retrieves/refreshes the {@link IDockerImage} on the Docker daemon and
+ * applies 'dangling' and 'intermediate' flags on each of them. Also
+ * notifies {@link IDockerConnection} listeners with the list of Images.
+ *
+ * @return the {@link List} of existing {@link IDockerImage}
+ * @throws DockerException
+ */
+ public List<IDockerImage> listImages() throws DockerException;
+
void pullImage(String id, IDockerProgressHandler handler) throws DockerException, InterruptedException;
+ public List<IDockerImageSearchResult> searchImages(final String term) throws DockerException;
+
void pushImage(String name, IDockerProgressHandler handler) throws DockerException, InterruptedException;
void tagImage(String name, String newTag) throws DockerException, InterruptedException;
@@ -159,7 +171,12 @@ public interface IDockerConnection {
String buildImage(IPath path, String name, IDockerProgressHandler handler)
throws DockerException, InterruptedException;
- String createContainer(IDockerContainerConfig c) throws DockerException, InterruptedException;
+ String createContainer(IDockerContainerConfig c)
+ throws DockerException, InterruptedException;
+
+ public String createContainer(final IDockerContainerConfig config,
+ final String containerName)
+ throws DockerException, InterruptedException;
void stopContainer(String id) throws DockerException, InterruptedException;
@@ -167,26 +184,34 @@ public interface IDockerConnection {
void pauseContainer(String id) throws DockerException, InterruptedException;
- void unpauseContainer(String id, OutputStream stream) throws DockerException, InterruptedException;
+ void unpauseContainer(String id, OutputStream stream)
+ throws DockerException, InterruptedException;
- void removeContainer(String id) throws DockerException, InterruptedException;
+ void removeContainer(String id)
+ throws DockerException, InterruptedException;
- void startContainer(String id, OutputStream stream) throws DockerException, InterruptedException;
+ void startContainer(String id, OutputStream stream)
+ throws DockerException, InterruptedException;
- void startContainer(String id, IDockerHostConfig config, OutputStream stream)
+ void startContainer(String id, IDockerHostConfig config,
+ OutputStream stream)
throws DockerException, InterruptedException;
- void startContainer(String id, String loggingId, IDockerHostConfig config, OutputStream stream)
+ void startContainer(String id, String loggingId, IDockerHostConfig config,
+ OutputStream stream)
throws DockerException, InterruptedException;
- void commitContainer(String id, String repo, String tag, String comment, String author) throws DockerException;
+ void commitContainer(String id, String repo, String tag, String comment,
+ String author) throws DockerException;
void stopLoggingThread(String id);
- void logContainer(String id, OutputStream stream) throws DockerException, InterruptedException;
+ void logContainer(String id, OutputStream stream)
+ throws DockerException, InterruptedException;
void removeImage(String name) throws DockerException, InterruptedException;
void removeTag(String tag) throws DockerException, InterruptedException;
+
}
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerContainer.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerContainer.java
index fd5cb04009..89573f3836 100644
--- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerContainer.java
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerContainer.java
@@ -48,5 +48,12 @@ public interface IDockerContainer {
*/
public IDockerConnection getConnection();
+ /**
+ * @return the {@link IDockerContainerInfo} by calling the Docker daemon
+ * using the {@link IDockerConnection} associated with this
+ * {@link IDockerContainer}.
+ */
+ public IDockerContainerInfo info();
+
}
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerContainerConfig.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerContainerConfig.java
index e72a074e82..f4791e1a45 100644
--- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerContainerConfig.java
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerContainerConfig.java
@@ -29,21 +29,21 @@ public interface IDockerContainerConfig {
public String cpuset();
- public Boolean attachStdin();
+ public boolean attachStdin();
- public Boolean attachStdout();
+ public boolean attachStdout();
- public Boolean attachStderr();
+ public boolean attachStderr();
public List<String> portSpecs();
public Set<String> exposedPorts();
- public Boolean tty();
+ public boolean tty();
- public Boolean openStdin();
+ public boolean openStdin();
- public Boolean stdinOnce();
+ public boolean stdinOnce();
public List<String> env();
@@ -57,7 +57,7 @@ public interface IDockerContainerConfig {
public List<String> entrypoint();
- public Boolean networkDisabled();
+ public boolean networkDisabled();
public List<String> onBuild();
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerHostConfig.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerHostConfig.java
index 5a976b95b8..9652787229 100644
--- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerHostConfig.java
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerHostConfig.java
@@ -21,13 +21,13 @@ public interface IDockerHostConfig {
public List<IDockerConfParameter> lxcConf();
- public Boolean privileged();
+ public boolean privileged();
public Map<String, List<IDockerPortBinding>> portBindings();
public List<String> links();
- public Boolean publishAllPorts();
+ public boolean publishAllPorts();
public List<String> dns();
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerImageSearchResult.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerImageSearchResult.java
new file mode 100644
index 0000000000..bfd44454ae
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerImageSearchResult.java
@@ -0,0 +1,30 @@
+package org.eclipse.linuxtools.docker.core;
+
+public interface IDockerImageSearchResult {
+
+ /**
+ * @return the image description
+ */
+ String getDescription();
+
+ /**
+ * @return the official image flag
+ */
+ boolean isOfficial();
+
+ /**
+ * @return the automated build flag
+ */
+ boolean isAutomated();
+
+ /**
+ * @return the image name
+ */
+ String getName();
+
+ /**
+ * @return the star count
+ */
+ int getStarCount();
+
+} \ No newline at end of file
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 bb54ba1597..e6b090d954 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
@@ -68,8 +68,8 @@ import org.eclipse.linuxtools.docker.core.IDockerHostConfig;
import org.eclipse.linuxtools.docker.core.IDockerImage;
import org.eclipse.linuxtools.docker.core.IDockerImageInfo;
import org.eclipse.linuxtools.docker.core.IDockerImageListener;
+import org.eclipse.linuxtools.docker.core.IDockerImageSearchResult;
import org.eclipse.linuxtools.docker.core.IDockerPortBinding;
-import org.eclipse.linuxtools.docker.core.IDockerPortMapping;
import org.eclipse.linuxtools.docker.core.IDockerProgressHandler;
import org.eclipse.linuxtools.docker.core.ILogger;
import org.eclipse.linuxtools.docker.core.Messages;
@@ -93,6 +93,7 @@ import com.spotify.docker.client.messages.HostConfig;
import com.spotify.docker.client.messages.HostConfig.LxcConfParameter;
import com.spotify.docker.client.messages.Image;
import com.spotify.docker.client.messages.ImageInfo;
+import com.spotify.docker.client.messages.ImageSearchResult;
import com.spotify.docker.client.messages.Info;
import com.spotify.docker.client.messages.PortBinding;
import com.spotify.docker.client.messages.Version;
@@ -241,7 +242,8 @@ public class DockerConnection implements IDockerConnection {
// log what happened if the process did not end as expected
final InputStream processErrorStream = process
.getErrorStream();
- final String errorMessage = streamToString(processErrorStream);
+ final String errorMessage = streamToString(
+ processErrorStream);
Activator.log(new Status(IStatus.ERROR,
Activator.PLUGIN_ID, errorMessage));
}
@@ -324,8 +326,8 @@ public class DockerConnection implements IDockerConnection {
}
private String streamToString(InputStream stream) {
- BufferedReader buff = new BufferedReader(new InputStreamReader(
- stream));
+ BufferedReader buff = new BufferedReader(
+ new InputStreamReader(stream));
StringBuffer res = new StringBuffer();
String line = "";
try {
@@ -425,7 +427,7 @@ public class DockerConnection implements IDockerConnection {
public Builder tcpCertPath(final String tcpCertPath) {
this.tcpCertPath = tcpCertPath;
- if (tcpCertPath != null) {
+ if (this.tcpHost != null) {
this.tcpHost = tcpHost.replace("http://", "https://");
}
return this;
@@ -555,7 +557,7 @@ public class DockerConnection implements IDockerConnection {
addContainerListener(dcrm);
}
}
- } catch (Exception e) {
+ } catch (DockerCertificateException e) {
throw new DockerException(Messages.Open_Connection_Failure, e);
}
}
@@ -656,8 +658,7 @@ public class DockerConnection implements IDockerConnection {
}
- public void notifyContainerListeners(DockerConnection manager,
- List<IDockerContainer> list) {
+ public void notifyContainerListeners(List<IDockerContainer> list) {
if (containerListeners != null) {
Object[] listeners = containerListeners.getListeners();
for (int i = 0; i < listeners.length; ++i) {
@@ -822,12 +823,6 @@ public class DockerConnection implements IDockerConnection {
// core format in case we decide to change the underlying engine
// in the future.
for (Container c : list) {
- final List<Container.PortMapping> ports = c.ports();
- final List<IDockerPortMapping> portMappings = new ArrayList<>();
- for (Container.PortMapping port : ports) {
- final DockerPortMapping portMapping = new DockerPortMapping(port.getPrivatePort(), port.getPublicPort(), port.getType(), port.getIp());
- portMappings.add(portMapping);
- }
// For containers that have exited, make sure we aren't tracking
// them with a logging thread.
if (c.status().startsWith(Messages.Exited_specifier)) {
@@ -836,15 +831,13 @@ public class DockerConnection implements IDockerConnection {
loggingThreads.remove(c.id());
}
}
- dclist.add(new DockerContainer(this, c.id(), c.image(), c
- .command(), c.created(), c.status(), c.sizeRw(), c
- .sizeRootFs(), portMappings, c.names()));
+ dclist.add(new DockerContainer(this, c));
}
containers = dclist;
}
// perform notification outside of containerLock so we don't have a View
// causing a deadlock
- notifyContainerListeners(this, dclist);
+ notifyContainerListeners(dclist);
return dclist;
}
@@ -903,8 +896,7 @@ public class DockerConnection implements IDockerConnection {
imageListeners.remove(listener);
}
- public void notifyImageListeners(DockerConnection manager,
- List<IDockerImage> list) {
+ public void notifyImageListeners(List<IDockerImage> list) {
if (imageListeners != null) {
Object[] listeners = imageListeners.getListeners();
for (int i = 0; i < listeners.length; ++i) {
@@ -944,7 +936,8 @@ public class DockerConnection implements IDockerConnection {
return imagesLoaded;
}
- private List<IDockerImage> listImages() throws DockerException {
+ @Override
+ public List<IDockerImage> listImages() throws DockerException {
final List<IDockerImage> dilist = new ArrayList<>();
synchronized (imageLock) {
List<Image> rawImages = null;
@@ -972,17 +965,24 @@ public class DockerConnection implements IDockerConnection {
&& imageParentIds.contains(rawImage.id());
final boolean danglingImage = !taggedImage
&& !intermediateImage;
- dilist.add(new DockerImage(this, rawImage
- .repoTags(), rawImage.id(), rawImage.parentId(),
- rawImage.created(), rawImage.size(), rawImage
- .virtualSize(), intermediateImage,
- danglingImage));
+ // FIXME: if an image with a unique ID belongs to multiple repos, we should
+ // probably have multiple instances of IDockerImage
+ final Map<String, List<String>> repoTags = DockerImage.extractTagsByRepo(rawImage.repoTags());
+ for(Entry<String, List<String>> entry : repoTags.entrySet()) {
+ final String repo = entry.getKey();
+ final List<String> tags = entry.getValue();
+ dilist.add(new DockerImage(this, rawImage
+ .repoTags(), repo, tags, rawImage.id(), rawImage.parentId(),
+ rawImage.created(), rawImage.size(), rawImage
+ .virtualSize(), intermediateImage,
+ danglingImage));
+ }
}
images = dilist;
}
// Perform notification outside of lock so that listener doesn't cause a
// deadlock to occur
- notifyImageListeners(this, dilist);
+ notifyImageListeners(dilist);
return dilist;
}
@@ -999,6 +999,22 @@ public class DockerConnection implements IDockerConnection {
throw f;
}
}
+
+ @Override
+ public List<IDockerImageSearchResult> searchImages(final String term) throws DockerException {
+ try {
+ final List<ImageSearchResult> searchResults = client.searchImages(term);
+ final List<IDockerImageSearchResult> results = new ArrayList<>();
+ for(ImageSearchResult r : searchResults) {
+ results.add(new DockerImageSearchResult(r.getDescription(), r.isOfficial(), r.isAutomated(), r.getName(), r.getStarCount()));
+ }
+ return results;
+ } catch (com.spotify.docker.client.DockerException | InterruptedException e) {
+ throw new DockerException(e);
+ }
+ }
+
+
@Override
public void pushImage(final String name, final IDockerProgressHandler handler)
@@ -1075,41 +1091,59 @@ public class DockerConnection implements IDockerConnection {
DockerConnectionManager.getInstance().saveConnections();
}
+
@Override
public String createContainer(final IDockerContainerConfig c)
throws DockerException, InterruptedException {
+ return createContainer(c, null);
+ }
+
+ @Override
+ public String createContainer(final IDockerContainerConfig c,
+ final String containerName)
+ throws DockerException, InterruptedException {
ContainerConfig.Builder builder = ContainerConfig.builder()
.hostname(c.hostname()).domainname(c.domainname())
- .user(c.user()).memory(c.memory()).memorySwap(c.memorySwap())
- .cpuShares(c.cpuShares()).cpuset(c.cpuset())
- .attachStdin(c.attachStdin()).attachStdout(c.attachStdout())
+ .user(c.user()).memory(c.memory())
+ .memorySwap(c.memorySwap()).cpuShares(c.cpuShares())
+ .cpuset(c.cpuset()).attachStdin(c.attachStdin())
+ .attachStdout(c.attachStdout())
.attachStderr(c.attachStderr()).tty(c.tty())
- .openStdin(c.openStdin()).stdinOnce(c.stdinOnce()).cmd(c.cmd())
- .image(c.image()).workingDir(c.workingDir())
+ .openStdin(c.openStdin()).stdinOnce(c.stdinOnce())
+ .cmd(c.cmd()).image(c.image())
+ .workingDir(c.workingDir())
.networkDisabled(c.networkDisabled());
// For those fields that are Collections and not set, they will be null.
// We can't use their values to set the builder's fields as they are
// expecting non-null Collections to copy over. In those cases, we just
// don't set those fields in the builder.
- if (c.portSpecs() != null)
+ if (c.portSpecs() != null) {
builder = builder.portSpecs(c.portSpecs());
- if (c.exposedPorts() != null)
+ }
+ if (c.exposedPorts() != null) {
builder = builder.exposedPorts(c.exposedPorts());
- if (c.env() != null)
+ }
+ if (c.env() != null) {
builder = builder.env(c.env());
- if (c.volumes() != null)
+ }
+ if (c.volumes() != null) {
builder = builder.volumes(c.volumes());
- if (c.entrypoint() != null)
+ }
+ if (c.entrypoint() != null) {
builder = builder.entrypoint(c.entrypoint());
- if (c.onBuild() != null)
+ }
+ if (c.onBuild() != null) {
builder = builder.onBuild(c.onBuild());
-
- final ContainerConfig config = builder.build();
+ }
try {
// create container with default random name
- final ContainerCreation creation = client.createContainer(config);
+ final ContainerCreation creation = client
+ .createContainer(builder.build(),
+ containerName);
final String id = creation.id();
+ // force a refresh of the current containers to include the new one
+ listContainers();
return id;
} catch (com.spotify.docker.client.DockerRequestException e) {
throw new DockerException(e.message());
@@ -1132,7 +1166,7 @@ public class DockerConnection implements IDockerConnection {
}
}
// list of containers needs to be updated once the given container is stopped, to reflect it new state.
- listContainers();
+ listContainers();
} catch (ContainerNotFoundException e) {
throw new DockerContainerNotFoundException(e);
} catch (com.spotify.docker.client.DockerRequestException e) {
@@ -1316,13 +1350,14 @@ public class DockerConnection implements IDockerConnection {
// start container with host config
client.startContainer(id, builder.build());
// Log the started container based on user preference
+ // Log the started container based on user preference
+ // Log the started container based on user preference
IEclipsePreferences preferences = InstanceScope.INSTANCE
.getNode("org.eclipse.linuxtools.docker.ui"); //$NON-NLS-1$
boolean autoLog = preferences.getBoolean("autoLogOnStart", true); //$NON-NLS-1$
if (autoLog && !getContainerInfo(id).config().tty()) {
- // display logs for container
synchronized (loggingThreads) {
LogThread t = loggingThreads.get(loggingId);
if (t == null || !t.isAlive()) {
@@ -1353,6 +1388,7 @@ public class DockerConnection implements IDockerConnection {
client.commitContainer(id, repo, tag, info.config(), comment,
author);
// update images list
+ listImages();
getImages(true);
} catch (com.spotify.docker.client.DockerRequestException e) {
throw new DockerException(e.message());
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerContainer.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerContainer.java
index 9a4d0cf814..ef5c42f871 100644
--- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerContainer.java
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerContainer.java
@@ -13,12 +13,16 @@ package org.eclipse.linuxtools.internal.docker.core;
import java.util.ArrayList;
import java.util.List;
+import org.eclipse.linuxtools.docker.core.IDockerConnection;
import org.eclipse.linuxtools.docker.core.IDockerContainer;
+import org.eclipse.linuxtools.docker.core.IDockerContainerInfo;
import org.eclipse.linuxtools.docker.core.IDockerPortMapping;
+import com.spotify.docker.client.messages.Container;
+
public class DockerContainer implements IDockerContainer {
- private DockerConnection parent;
+ private IDockerConnection parent;
private String id;
private List<String> names;
private String image;
@@ -29,30 +33,36 @@ public class DockerContainer implements IDockerContainer {
private Long sizeRw;
private Long sizeRootFs;
- public DockerContainer(DockerConnection parent, String id, String image,
- String command, Long created, String status, Long sizeRw,
- Long sizeRootFs, List<IDockerPortMapping> ports, List<String> names) {
- this.parent = parent;
- this.id = id;
- this.image = image;
- this.command = command;
- this.created = created;
- this.status = status;
+ public DockerContainer(final IDockerConnection connection,
+ Container container) {
+ this.parent = connection;
+ this.id = container.id();
+ this.image = container.image();
+ this.command = container.command();
+ this.created = container.created();
+ this.status = container.status();
this.names = new ArrayList<>();
- for(String name : names) {
- if(name.startsWith("/")) {
+ for (String name : container.names()) {
+ if (name.startsWith("/")) {
this.names.add(name.substring(1));
} else {
this.names.add(name);
}
}
- this.sizeRw = sizeRw;
- this.sizeRootFs = sizeRootFs;
- this.ports = ports;
+ this.sizeRw = container.sizeRw();
+ this.sizeRootFs = container.sizeRootFs();
+ this.ports = new ArrayList<>();
+ for (Container.PortMapping port : container.ports()) {
+ final DockerPortMapping portMapping = new DockerPortMapping(
+ port.getPrivatePort(), port.getPublicPort(), port.getType(),
+ port.getIp());
+ ports.add(portMapping);
+ }
+ // TODO: include volumes
}
@Override
- public DockerConnection getConnection() {
+ public IDockerConnection getConnection() {
return parent;
}
@@ -107,6 +117,11 @@ public class DockerContainer implements IDockerContainer {
}
@Override
+ public IDockerContainerInfo info() {
+ return this.parent.getContainerInfo(id);
+ }
+
+ @Override
public String toString() {
return "Container: id=" + id() + "\n" + " image=" + image() + "\n"
+ " created=" + created() + "\n" + " command=" + command()
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerContainerConfig.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerContainerConfig.java
index 0cbfb6fe7d..9e40a431b1 100644
--- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerContainerConfig.java
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerContainerConfig.java
@@ -12,6 +12,7 @@ package org.eclipse.linuxtools.internal.docker.core;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
@@ -29,21 +30,21 @@ public class DockerContainerConfig implements IDockerContainerConfig {
private final Long memorySwap;
private final Long cpuShares;
private final String cpuset;
- private final Boolean attachStdin;
- private final Boolean attachStdout;
- private final Boolean attachStderr;
+ private final boolean attachStdin;
+ private final boolean attachStdout;
+ private final boolean attachStderr;
private final List<String> portSpecs;
private final Set<String> exposedPorts;
- private final Boolean tty;
- private final Boolean openStdin;
- private final Boolean stdinOnce;
+ private final boolean tty;
+ private final boolean openStdin;
+ private final boolean stdinOnce;
private final List<String> env;
private final List<String> cmd;
private final String image;
private final Set<String> volumes;
private final String workingDir;
private final List<String> entrypoint;
- private final Boolean networkDisabled;
+ private final boolean networkDisabled;
private final List<String> onBuild;
public DockerContainerConfig(final ContainerConfig containerConfig) {
@@ -54,21 +55,28 @@ public class DockerContainerConfig implements IDockerContainerConfig {
this.memorySwap = containerConfig.memorySwap();
this.cpuShares = containerConfig.cpuShares();
this.cpuset = containerConfig.cpuset();
- this.attachStdin = containerConfig.attachStdin();
- this.attachStdout = containerConfig.attachStdout();
- this.attachStderr = containerConfig.attachStderr();
+ this.attachStdin = containerConfig.attachStdin() != null
+ ? containerConfig.attachStdin() : false;
+ this.attachStdout = containerConfig.attachStdout() != null
+ ? containerConfig.attachStdout() : false;
+ this.attachStderr = containerConfig.attachStderr() != null
+ ? containerConfig.attachStderr() : false;
this.portSpecs = containerConfig.portSpecs();
this.exposedPorts = containerConfig.exposedPorts();
- this.tty = containerConfig.tty();
- this.openStdin = containerConfig.openStdin();
- this.stdinOnce = containerConfig.stdinOnce();
+ this.tty = containerConfig.tty() != null ? containerConfig.tty()
+ : false;
+ this.openStdin = containerConfig.openStdin() != null
+ ? containerConfig.openStdin() : false;
+ this.stdinOnce = containerConfig.stdinOnce() != null
+ ? containerConfig.stdinOnce() : false;
this.env = containerConfig.env();
this.cmd = containerConfig.cmd();
this.image = containerConfig.image();
this.volumes = containerConfig.volumes();
this.workingDir = containerConfig.workingDir();
this.entrypoint = containerConfig.entrypoint();
- this.networkDisabled = containerConfig.networkDisabled();
+ this.networkDisabled = containerConfig.networkDisabled() != null
+ ? containerConfig.networkDisabled() : false;
this.onBuild = containerConfig.onBuild();
}
@@ -80,21 +88,25 @@ public class DockerContainerConfig implements IDockerContainerConfig {
this.memorySwap = builder.memorySwap;
this.cpuShares = builder.cpuShares;
this.cpuset = builder.cpuset;
- this.attachStdin = builder.attachStdin;
- this.attachStdout = builder.attachStdout;
- this.attachStderr = builder.attachStderr;
+ this.attachStdin = builder.attachStdin != null ? builder.attachStdin
+ : false;
+ this.attachStdout = builder.attachStdout != null ? builder.attachStdout
+ : false;
+ this.attachStderr = builder.attachStderr != null ? builder.attachStderr
+ : false;
this.portSpecs = builder.portSpecs;
this.exposedPorts = builder.exposedPorts;
- this.tty = builder.tty;
- this.openStdin = builder.openStdin;
- this.stdinOnce = builder.stdinOnce;
+ this.tty = builder.tty != null ? builder.tty : false;
+ this.openStdin = builder.openStdin != null ? builder.openStdin : false;
+ this.stdinOnce = builder.stdinOnce != null ? builder.stdinOnce : false;
this.env = builder.env;
this.cmd = builder.cmd;
this.image = builder.image;
this.volumes = builder.volumes;
this.workingDir = builder.workingDir;
this.entrypoint = builder.entrypoint;
- this.networkDisabled = builder.networkDisabled;
+ this.networkDisabled = builder.networkDisabled != null
+ ? builder.networkDisabled : false;
this.onBuild = builder.onBuild;
}
@@ -134,52 +146,64 @@ public class DockerContainerConfig implements IDockerContainerConfig {
}
@Override
- public Boolean attachStdin() {
+ public boolean attachStdin() {
return attachStdin;
}
@Override
- public Boolean attachStdout() {
+ public boolean attachStdout() {
return attachStdout;
}
@Override
- public Boolean attachStderr() {
+ public boolean attachStderr() {
return attachStderr;
}
@Override
public List<String> portSpecs() {
+ if (portSpecs == null) {
+ return Collections.emptyList();
+ }
return portSpecs;
}
@Override
public Set<String> exposedPorts() {
+ if (exposedPorts == null) {
+ return Collections.emptySet();
+ }
return exposedPorts;
}
@Override
- public Boolean tty() {
+ public boolean tty() {
return tty;
}
@Override
- public Boolean openStdin() {
+ public boolean openStdin() {
return openStdin;
}
@Override
- public Boolean stdinOnce() {
+ public boolean stdinOnce() {
return stdinOnce;
}
@Override
public List<String> env() {
+ if (env == null) {
+ return Collections.emptyList();
+ }
return env;
}
@Override
public List<String> cmd() {
+ if (cmd == null) {
+ return Collections.emptyList();
+ }
return cmd;
}
@@ -190,6 +214,9 @@ public class DockerContainerConfig implements IDockerContainerConfig {
@Override
public Set<String> volumes() {
+ if (volumes == null) {
+ return Collections.emptySet();
+ }
return volumes;
}
@@ -200,16 +227,22 @@ public class DockerContainerConfig implements IDockerContainerConfig {
@Override
public List<String> entrypoint() {
+ if (entrypoint == null) {
+ return Collections.emptyList();
+ }
return entrypoint;
}
@Override
- public Boolean networkDisabled() {
+ public boolean networkDisabled() {
return networkDisabled;
}
@Override
public List<String> onBuild() {
+ if (onBuild == null) {
+ return Collections.emptyList();
+ }
return onBuild;
}
@@ -330,7 +363,6 @@ public class DockerContainerConfig implements IDockerContainerConfig {
}
public Builder portSpecs(final List<String> portSpecs) {
-
this.portSpecs = new ArrayList<>(portSpecs);
return this;
}
@@ -400,12 +432,18 @@ public class DockerContainerConfig implements IDockerContainerConfig {
}
public Builder cmd(final List<String> cmd) {
- this.cmd = new ArrayList<>(cmd);
+ this.cmd = cmd;
return this;
}
public Builder cmd(final String... cmd) {
- this.cmd = Arrays.asList(cmd);
+ return cmd(Arrays.asList(cmd));
+ }
+
+ public Builder cmd(final String cmd) {
+ if (cmd != null && !cmd.isEmpty()) {
+ return cmd(cmd.split(" "));
+ }
return this;
}
@@ -446,12 +484,22 @@ public class DockerContainerConfig implements IDockerContainerConfig {
}
public Builder entryPoint(final List<String> entrypoint) {
- this.entrypoint = new ArrayList<>(entrypoint);
+ if (entrypoint != null && !entrypoint.isEmpty()) {
+ this.entrypoint = new ArrayList<>(entrypoint);
+ }
return this;
}
public Builder entryPoint(final String... entrypoint) {
- this.entrypoint = Arrays.asList(entrypoint);
+ return entryPoint(Arrays.asList(entrypoint));
+ }
+
+ public Builder entryPoint(final String entrypoint) {
+ if (entrypoint != null && !entrypoint.isEmpty()) {
+ return entryPoint(entrypoint.split(" "));
+ } else {
+ this.entrypoint = null;
+ }
return this;
}
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerHostConfig.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerHostConfig.java
index a4649ee2ec..28696080f7 100644
--- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerHostConfig.java
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerHostConfig.java
@@ -30,10 +30,10 @@ public class DockerHostConfig implements IDockerHostConfig {
private final List<String> binds;
private final String containerIDFile;
private final List<IDockerConfParameter> lxcConf;
- private final Boolean privileged;
+ private final boolean privileged;
private final Map<String, List<IDockerPortBinding>> portBindings;
private final List<String> links;
- private final Boolean publishAllPorts;
+ private final boolean publishAllPorts;
private final List<String> dns;
private final List<String> dnsSearch;
private final List<String> volumesFrom;
@@ -48,7 +48,8 @@ public class DockerHostConfig implements IDockerHostConfig {
this.lxcConf.add(new DockerConfParameter(lxcConfParameter));
}
}
- this.privileged = hostConfig.privileged();
+ this.privileged = hostConfig.privileged() != null
+ ? hostConfig.privileged() : false;
this.portBindings = new HashMap<>();
if(hostConfig != null && hostConfig.portBindings() != null) {
for(Entry<String, List<PortBinding>> entry : hostConfig.portBindings().entrySet()) {
@@ -60,7 +61,8 @@ public class DockerHostConfig implements IDockerHostConfig {
}
}
this.links = hostConfig.links();
- this.publishAllPorts = hostConfig.publishAllPorts();
+ this.publishAllPorts = hostConfig.publishAllPorts() != null
+ ? hostConfig.publishAllPorts() : false;
this.dns = hostConfig.dns();
this.dnsSearch = hostConfig.dnsSearch();
this.volumesFrom = hostConfig.volumesFrom();
@@ -71,10 +73,12 @@ public class DockerHostConfig implements IDockerHostConfig {
this.binds = builder.binds;
this.containerIDFile = builder.containerIDFile;
this.lxcConf = builder.lxcConf;
- this.privileged = builder.privileged;
+ this.privileged = builder.privileged != null ? builder.privileged
+ : false;
this.portBindings = builder.portBindings;
this.links = builder.links;
- this.publishAllPorts = builder.publishAllPorts;
+ this.publishAllPorts = builder.publishAllPorts != null
+ ? builder.publishAllPorts : false;
this.dns = builder.dns;
this.dnsSearch = builder.dnsSearch;
this.volumesFrom = builder.volumesFrom;
@@ -97,7 +101,7 @@ public class DockerHostConfig implements IDockerHostConfig {
}
@Override
- public Boolean privileged() {
+ public boolean privileged() {
return privileged;
}
@@ -112,7 +116,7 @@ public class DockerHostConfig implements IDockerHostConfig {
}
@Override
- public Boolean publishAllPorts() {
+ public boolean publishAllPorts() {
return publishAllPorts;
}
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImage.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImage.java
index 80cdd1e54c..4bb3444096 100644
--- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImage.java
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImage.java
@@ -14,7 +14,9 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.eclipse.linuxtools.docker.core.IDockerImage;
@@ -43,13 +45,13 @@ public class DockerImage implements IDockerImage {
private final boolean intermediateImage;
private final boolean danglingImage;
- public DockerImage(final DockerConnection parent, final List<String> repoTags,
+ public DockerImage(final DockerConnection parent, @Deprecated final List<String> repoTags, final String repo, final List<String> tags,
final String id, final String parentId, final String created, final Long size,
final Long virtualSize, final boolean intermediateImage, final boolean danglingImage) {
this.parent = parent;
this.repoTags = repoTags;
- this.repo = extractRepo(repoTags);
- this.tags = extractTags(repoTags);
+ this.repo = repo;
+ this.tags = tags;
this.id = id;
this.parentId = parentId;
this.created = created;
@@ -61,21 +63,24 @@ public class DockerImage implements IDockerImage {
}
/**
- * Extracts the org/repo from the list of repo tags, assuming that the given repoTags elements have the following format:
+ * Extracts the org/repo and all the associated tags from the given {@code repoTags}, assuming that the given repoTags elements have the following format:
* <pre>org/repo:tag</pre> or <pre>repo:tag</pre>.
* @param repoTags the list of repo/tags to analyze
- * @return the repo or org/repo name or {@code null} if none was found.
+ * @return the tags indexed by org/repo
*/
- public static String extractRepo(final List<String> repoTags) {
- if(repoTags.isEmpty()) {
- return null;
- }
- final String firstRepoTag = repoTags.get(0);
- final int indexOfColonChar = firstRepoTag.indexOf(':');
- if(indexOfColonChar == -1) {
- return firstRepoTag;
+ public static Map<String, List<String>> extractTagsByRepo(final List<String> repoTags) {
+ final Map<String, List<String>> results = new HashMap<>();
+ for(String entry : repoTags) {
+ final int indexOfColonChar = entry.indexOf(':');
+ final String repo = (indexOfColonChar > -1) ? entry.substring(0, indexOfColonChar) : entry;
+ if(!results.containsKey(repo)) {
+ results.put(repo, new ArrayList<String>());
+ }
+ if(indexOfColonChar > -1) {
+ results.get(repo).add(entry.substring(indexOfColonChar+1));
+ }
}
- return firstRepoTag.substring(0, indexOfColonChar);
+ return results;
}
/**
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImageSearchResult.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImageSearchResult.java
new file mode 100644
index 0000000000..35b1ee9740
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImageSearchResult.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2014 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.IDockerImageSearchResult;
+
+/**
+ * @author xcoulon
+ *
+ */
+public class DockerImageSearchResult implements IDockerImageSearchResult {
+
+ /** the image description. */
+ private final String description;
+ /** official image flag. */
+ private final boolean official;
+ /** automated build flag */
+ private final boolean automated;
+ /** image name */
+ private final String name;
+ /** star count */
+ private final int starCount;
+
+ /**
+ * Full constructor
+ * @param description the image description
+ * @param official official image flag
+ * @param automated automated build flag
+ * @param name image name (org/repo)
+ * @param starCount star count
+ */
+ public DockerImageSearchResult(String description, boolean official, boolean automated, String name,
+ int starCount) {
+ this.description = description;
+ this.official = official;
+ this.automated = automated;
+ this.name = name;
+ this.starCount = starCount;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.linuxtools.internal.docker.core.IDockerImageSearchResult#getDescription()
+ */
+ @Override
+ public String getDescription() {
+ return description;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.linuxtools.internal.docker.core.IDockerImageSearchResult#isOfficial()
+ */
+ @Override
+ public boolean isOfficial() {
+ return official;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.linuxtools.internal.docker.core.IDockerImageSearchResult#isAutomated()
+ */
+ @Override
+ public boolean isAutomated() {
+ return automated;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.linuxtools.internal.docker.core.IDockerImageSearchResult#getName()
+ */
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.linuxtools.internal.docker.core.IDockerImageSearchResult#getStarCount()
+ */
+ @Override
+ public int getStarCount() {
+ return starCount;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + (automated ? 1231 : 1237);
+ result = prime * result + ((description == null) ? 0 : description.hashCode());
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result + (official ? 1231 : 1237);
+ result = prime * result + starCount;
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final DockerImageSearchResult other = (DockerImageSearchResult) obj;
+ if (automated != other.automated) {
+ return false;
+ }
+ if (description == null) {
+ if (other.description != null) {
+ return false;
+ }
+ } else if (!description.equals(other.description)) {
+ return false;
+ }
+ if (name == null) {
+ if (other.name != null) {
+ return false;
+ }
+ } else if (!name.equals(other.name)) {
+ return false;
+ }
+ if (official != other.official) {
+ return false;
+ }
+ if (starCount != other.starCount) {
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/.settings/org.eclipse.core.resources.prefs b/containers/org.eclipse.linuxtools.docker.ui/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000000..99f26c0203
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/containers/org.eclipse.linuxtools.docker.ui/META-INF/MANIFEST.MF b/containers/org.eclipse.linuxtools.docker.ui/META-INF/MANIFEST.MF
index 396731336f..592940a2e1 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/META-INF/MANIFEST.MF
+++ b/containers/org.eclipse.linuxtools.docker.ui/META-INF/MANIFEST.MF
@@ -16,10 +16,14 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.ui.navigator;bundle-version="3.5.401",
org.eclipse.jface,
org.eclipse.core.expressions;bundle-version="3.4.600",
- org.eclipse.ui.views.properties.tabbed;bundle-version="3.6.0"
+ org.eclipse.ui.views.properties.tabbed;bundle-version="3.6.0",
+ org.eclipse.core.databinding;bundle-version="1.4.100",
+ org.eclipse.core.databinding.beans;bundle-version="1.2.200",
+ org.eclipse.core.databinding.property;bundle-version="1.4.200",
+ org.eclipse.jface.databinding;bundle-version="1.7.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ActivationPolicy: lazy
Bundle-Localization: plugin
Export-Package: org.eclipse.linuxtools.docker.ui,
- org.eclipse.linuxtools.docker.ui.launch
-Import-Package: com.spotify.docker.client
+ org.eclipse.linuxtools.docker.ui.launch,
+ org.eclipse.linuxtools.internal.docker.ui.preferences
diff --git a/containers/org.eclipse.linuxtools.docker.ui/icons/checked.gif b/containers/org.eclipse.linuxtools.docker.ui/icons/checked.gif
new file mode 100644
index 0000000000..e556e7df3c
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/icons/checked.gif
Binary files differ
diff --git a/containers/org.eclipse.linuxtools.docker.ui/icons/error_obj.gif b/containers/org.eclipse.linuxtools.docker.ui/icons/error_obj.gif
new file mode 100644
index 0000000000..0bc60689c6
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/icons/error_obj.gif
Binary files differ
diff --git a/containers/org.eclipse.linuxtools.docker.ui/icons/file_obj.gif b/containers/org.eclipse.linuxtools.docker.ui/icons/file_obj.gif
new file mode 100644
index 0000000000..efa7a38014
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/icons/file_obj.gif
Binary files differ
diff --git a/containers/org.eclipse.linuxtools.docker.ui/icons/folder_closed.gif b/containers/org.eclipse.linuxtools.docker.ui/icons/folder_closed.gif
new file mode 100644
index 0000000000..42e027c933
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/icons/folder_closed.gif
Binary files differ
diff --git a/containers/org.eclipse.linuxtools.docker.ui/icons/unchecked.gif b/containers/org.eclipse.linuxtools.docker.ui/icons/unchecked.gif
new file mode 100644
index 0000000000..342fa9de7e
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/icons/unchecked.gif
Binary files differ
diff --git a/containers/org.eclipse.linuxtools.docker.ui/icons/warning_obj.gif b/containers/org.eclipse.linuxtools.docker.ui/icons/warning_obj.gif
new file mode 100644
index 0000000000..1e5f5eb367
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/icons/warning_obj.gif
Binary files differ
diff --git a/containers/org.eclipse.linuxtools.docker.ui/plugin.properties b/containers/org.eclipse.linuxtools.docker.ui/plugin.properties
index db79de8f5d..ca0bb80dcd 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/plugin.properties
+++ b/containers/org.eclipse.linuxtools.docker.ui/plugin.properties
@@ -1,4 +1,4 @@
-DockerCategory.name=Docker Category
+DockerCategory.name=Docker
DockerImagesView.name=Docker Images
DockerContainersView.name=Docker Containers
DockerContainersProvider.name=Docker Containers
@@ -47,6 +47,9 @@ command.killcontainers.description=Kill the selected containers
command.removecontainers.name=&Remove Selected Containers
command.removecontainers.description=Remove the selected containers
+command.showallcontainers.name=&Show all Containers
+command.showallcontainers.description=Show all Containers, including non-running ones.
+
command.commitcontainer.name=Commit Container
command.commitcontainer.description=Commit the selected container into a new image
@@ -87,5 +90,8 @@ command.showallimages.name=&Show all Images
command.showallimages.description=Show all Images, including intermediate images.
command.refreshexplorer.label=&Refresh
-command.removeconnection.label=&Remove connection
-command.addconnection.label=&Add connection
+command.removeconnection.label=&Remove Connection
+command.addconnection.label=&Add Connection
+
+command.runimage.name=Run Image
+command.runimage.label=Run Image...
diff --git a/containers/org.eclipse.linuxtools.docker.ui/plugin.xml b/containers/org.eclipse.linuxtools.docker.ui/plugin.xml
index 6d1af83d12..aa1f7ccfbe 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/plugin.xml
+++ b/containers/org.eclipse.linuxtools.docker.ui/plugin.xml
@@ -55,15 +55,14 @@
</extension>
<extension
- point="org.eclipse.help.contexts">
- <contexts
- file="contexts.xml">
- </contexts>
- </extension>
- <extension
point="org.eclipse.ui.navigator.viewer">
<viewer
viewerId="org.eclipse.linuxtools.docker.ui.dockerExplorerView">
+ <popupMenu
+ allowsPlatformContributions="true"
+ id="org.eclipse.linuxtools.docker.ui.dockerExplorerView#PopupMenu">
+ <insertionPoint name="group.run" separator="true"/>
+ </popupMenu>
<options>
<property
name="org.eclipse.ui.navigator.hideLinkWithEditorAction"
@@ -214,11 +213,6 @@
name="%command.pushimage.name">
</command>
<command
- description="%command.createcontainer.description"
- id="org.eclipse.linuxtools.docker.ui.commands.createContainer"
- name="%command.createcontainer.name">
- </command>
- <command
description="%command.tagimage.description"
id="org.eclipse.linuxtools.docker.ui.commands.tagImage"
name="%command.tagimage.name">
@@ -251,6 +245,13 @@
class="org.eclipse.ui.handlers.RegistryToggleState:true"
id="org.eclipse.ui.commands.toggleState">
</state>
+ </command>
+ <command
+ description="%command.runimage.description"
+ id="org.eclipse.linuxtools.docker.ui.commands.runImage"
+ name="%command.runimage.name">
+ id="org.eclipse.linuxtools.docker.ui.commands.runImage"
+ name="%command.runimage.name">
</command>
</extension>
<extension
@@ -333,9 +334,14 @@
<iterate ifEmpty="false">
<and>
<instanceof value="org.eclipse.linuxtools.docker.core.IDockerContainer"></instanceof>
- <test
- forcePluginActivation="true"
- property="org.eclipse.linuxtools.docker.propertytesters.container.isStopped" value="false"/>
+ <or>
+ <test
+ forcePluginActivation="true"
+ property="org.eclipse.linuxtools.docker.propertytesters.container.isStopped" value="false"/>
+ <test
+ forcePluginActivation="true"
+ property="org.eclipse.linuxtools.docker.propertytesters.container.isUnknown" value="true"/>
+ </or>
</and>
</iterate>
</with>
@@ -349,9 +355,14 @@
<iterate ifEmpty="false">
<and>
<instanceof value="org.eclipse.linuxtools.docker.core.IDockerContainer"></instanceof>
- <test
- forcePluginActivation="true"
- property="org.eclipse.linuxtools.docker.propertytesters.container.isStopped" value="false"/>
+ <or>
+ <test
+ forcePluginActivation="true"
+ property="org.eclipse.linuxtools.docker.propertytesters.container.isStopped" value="false"/>
+ <test
+ forcePluginActivation="true"
+ property="org.eclipse.linuxtools.docker.propertytesters.container.isUnknown" value="true"/>
+ </or>
</and>
</iterate>
</with>
@@ -460,18 +471,6 @@
</enabledWhen>
</handler>
<handler
- commandId="org.eclipse.linuxtools.docker.ui.commands.createContainer"
- class="org.eclipse.linuxtools.internal.docker.ui.commands.CreateContainerCommandHandler">
- <enabledWhen>
- <with variable="selection">
- <count value="1"/>
- <iterate ifEmpty="false">
- <instanceof value="org.eclipse.linuxtools.docker.core.IDockerImage"></instanceof>
- </iterate>
- </with>
- </enabledWhen>
- </handler>
- <handler
commandId="org.eclipse.linuxtools.docker.ui.commands.buildImage"
class="org.eclipse.linuxtools.internal.docker.ui.commands.BuildImageCommandHandler">
</handler>
@@ -494,6 +493,19 @@
commandId="org.eclipse.linuxtools.docker.ui.commands.showAllImages"
class="org.eclipse.linuxtools.internal.docker.ui.commands.ShowAllImagesCommandHandler">
</handler>
+ <handler
+ commandId="org.eclipse.linuxtools.docker.ui.commands.runImage"
+ class="org.eclipse.linuxtools.internal.docker.ui.commands.RunImageCommandHandler">
+ <enabledWhen>
+ <with variable="selection">
+ <count value="1"/>
+ <iterate ifEmpty="false">
+ <instanceof value="org.eclipse.linuxtools.docker.core.IDockerImage"></instanceof>
+ </iterate>
+ </with>
+ </enabledWhen>
+ </handler>
+
</extension>
<!-- property testers -->
<extension
@@ -502,7 +514,7 @@
class="org.eclipse.linuxtools.internal.docker.ui.propertytesters.ContainerPropertyTester"
id="org.eclipse.linuxtools.docker.containerPropertyTester"
namespace="org.eclipse.linuxtools.docker.propertytesters.container"
- properties="isRunning,isStopped,isPaused,isRemovable"
+ properties="isRunning,isStopped,isPaused,isRemovable,isUnknown"
type="org.eclipse.linuxtools.docker.core.IDockerContainer">
</propertyTester>
<propertyTester
@@ -697,10 +709,10 @@
<menuContribution
locationURI="toolbar:org.eclipse.linuxtools.docker.ui.dockerImagesView">
<command
- commandId="org.eclipse.linuxtools.docker.ui.commands.createContainer"
+ commandId="org.eclipse.linuxtools.docker.ui.commands.runImage"
icon="icons/createcontainer.gif"
disabledIcon="icons/createcontainer_d.gif"
- id="org.eclipse.linuxtools.docker.ui.commands.createContainer"
+ id="org.eclipse.linuxtools.docker.ui.commands.runImage"
mnemonic="C"
style="push">
</command>
@@ -781,7 +793,32 @@
</command>
</menuContribution>
-
+ <!-- Docker Explorer View: run image -->
+ <menuContribution
+ locationURI="popup:org.eclipse.linuxtools.docker.ui.dockerExplorerView#PopupMenu?after=group.run">
+ <command
+ commandId="org.eclipse.linuxtools.docker.ui.commands.runImage"
+ icon="icons/createcontainer.gif"
+ label="%command.runimage.label"
+ mnemonic="R"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate
+ ifEmpty="false"
+ operator="and">
+ <instanceof
+ value="org.eclipse.linuxtools.docker.core.IDockerImage" />
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ </menuContribution>
</extension>
<extension point="org.eclipse.ui.views.properties.tabbed.propertyContributor">
@@ -796,7 +833,6 @@
</propertyContributor>
</extension>
-
<extension point="org.eclipse.ui.views.properties.tabbed.propertySections">
<propertySections contributorId="org.eclipse.linuxtools.docker.ui.dockerExplorerView">
<propertySection
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/Activator.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/Activator.java
index b577ae692b..087f17b8ab 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/Activator.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/Activator.java
@@ -15,7 +15,6 @@ import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
@@ -57,19 +56,6 @@ public class Activator extends AbstractUIPlugin {
return plugin;
}
- /**
- * Returns an image descriptor for the image file at the given plug-in
- * relative path
- *
- * @param path
- * the path
- * @return the image descriptor
- */
-
- public static ImageDescriptor getImageDescriptor(String path) {
- return imageDescriptorFromPlugin(PLUGIN_ID, path);
- }
-
public static void log(IStatus status) {
Activator.getDefault().getLog().log(status);
}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/launch/ContainerLauncher.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/launch/ContainerLauncher.java
index 44f8a3e4a1..cdad3d5d00 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/launch/ContainerLauncher.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/launch/ContainerLauncher.java
@@ -304,7 +304,9 @@ public class ContainerLauncher {
// Look for any Display Log console that the user may
// have opened which would be
// separate and make sure it is removed as well
- RunConsole rc2 = RunConsole.findConsole(containerId);
+ RunConsole rc2 = RunConsole
+ .findConsole(((DockerConnection) connection)
+ .getContainer(containerId));
if (rc2 != null)
RunConsole.removeConsole(rc2);
((DockerConnection) connection)
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/RunConsole.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/RunConsole.java
index 995a9720b4..85e196ac95 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/RunConsole.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/RunConsole.java
@@ -19,6 +19,7 @@ import java.nio.channels.WritableByteChannel;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.linuxtools.docker.core.IDockerConnection;
+import org.eclipse.linuxtools.docker.core.IDockerContainer;
import org.eclipse.linuxtools.internal.docker.core.DockerConnection;
import org.eclipse.linuxtools.internal.docker.ui.views.DVMessages;
import org.eclipse.swt.custom.StyledText;
@@ -42,10 +43,8 @@ public class RunConsole extends IOConsole {
/** Id of this console. */
public static final String ID = "containerLog"; //$NON-NLS-1$
public static final String CONTAINER_LOG_TITLE = "ContainerLog.title"; //$NON-NLS-1$
- public static final String DEFAULT_ID = "__DEFAULT_ID__"; //$NON-NLS-1$
private String containerId;
- private String id;
private OutputStream outputStream;
private boolean attached = false;
private final WritableByteChannel[] ptyOutRef = new WritableByteChannel[1];
@@ -54,13 +53,17 @@ public class RunConsole extends IOConsole {
* Returns a reference to the console that is for the given container id. If
* such a console does not yet exist, it will be created.
*
- * @param containerId
- * The container this console will be for. Must not be
+ * @param container
+ * The container this console will be for. Should not be
* <code>null</code>.
- * @return A console instance.
+ * @return A console instance or <code>null</code> if the given container
+ * was <code>null</code>.
*/
- public static RunConsole findConsole(String containerId) {
- return findConsole(containerId, DEFAULT_ID);
+ public static RunConsole findConsole(final IDockerContainer container) {
+ if (container == null) {
+ return null;
+ }
+ return findConsole(container.id(), container.name());
}
/**
@@ -73,31 +76,24 @@ public class RunConsole extends IOConsole {
* @param id
* The secondary id used to identify consoles belonging to
* various owners.
+ * @param name
+ * the name of the console to create if it did not already exist
* @return A console instance.
*/
- public static RunConsole findConsole(String containerId, String id) {
- return findConsole(containerId, id, containerId.substring(0, 8));
- }
-
- public static RunConsole findConsole(String containerId, String id,
- String name) {
- RunConsole ret = null;
+ public static RunConsole findConsole(final String containerId,
+ final String name) {
for (IConsole cons : ConsolePlugin.getDefault().getConsoleManager()
.getConsoles()) {
if (cons instanceof RunConsole
- && ((RunConsole) cons).containerId.equals(containerId)
- && ((RunConsole) cons).id.equals(id)) {
- ret = (RunConsole) cons;
+ && ((RunConsole) cons).containerId.equals(containerId)) {
+ return (RunConsole) cons;
}
}
// no existing console, create new one
- if (ret == null) {
- ret = new RunConsole(containerId, id, name);
- ConsolePlugin.getDefault().getConsoleManager()
- .addConsoles(new IConsole[] { ret });
- }
-
- return ret;
+ final RunConsole console = new RunConsole(containerId, name);
+ ConsolePlugin.getDefault().getConsoleManager()
+ .addConsoles(new IConsole[] { console });
+ return console;
}
@Override
@@ -221,11 +217,10 @@ public class RunConsole extends IOConsole {
* @param name
* The name to use for the console.
*/
- private RunConsole(String containerId, String id, String name) {
+ private RunConsole(String containerId, String name) {
super(DVMessages.getFormattedString(CONTAINER_LOG_TITLE, name), ID,
null, true);
this.containerId = containerId;
- this.id = id;
}
/*
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/SWTImagesFactory.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/SWTImagesFactory.java
index b2e7d3d9da..fddcd3f27e 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/SWTImagesFactory.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/SWTImagesFactory.java
@@ -44,8 +44,11 @@ public class SWTImagesFactory {
public static final String IMG_CREATE_CONTAINERD = NAME_PREFIX
+ "createcontainer_d.gif"; //$NON-NLS-1$
public static final String IMG_FOLDER = NAME_PREFIX + "folder.gif"; //$NON-NLS-1$
+ public static final String IMG_FOLDER_CLOSED = NAME_PREFIX
+ + "folder_closed.gif"; //$NON-NLS-1$
+ public static final String IMG_FILE = NAME_PREFIX + "file_obj.gif"; //$NON-NLS-1$
public static final String IMG_INSTANCE = NAME_PREFIX + "instance.gif"; //$NON-NLS-1$
- public static final String IMG_IMAGE = NAME_PREFIX + "image.gif"; //$NON-NLS-1$
+ public static final String IMG_IMAGE = NAME_PREFIX + "image.png"; //$NON-NLS-1$
public static final String IMG_COLLAPSE_ALL = NAME_PREFIX
+ "collapseall.gif"; //$NON-NLS-1$
public static final String IMG_DOCKER_LARGE = NAME_PREFIX
@@ -73,12 +76,29 @@ public class SWTImagesFactory {
public static final String IMG_REFRESH = NAME_PREFIX + "refresh_tab.gif"; //$NON-NLS-1$
public static final String IMG_REBOOT = NAME_PREFIX + "reboot.gif"; //$NON-NLS-1$
public static final String IMG_REBOOTD = NAME_PREFIX + "rebootd.gif"; //$NON-NLS-1$
+
+ public static final String IMG_REPOSITORY_MIDDLE = NAME_PREFIX
+ + "repository-middle.gif"; //$NON-NLS-1$
+ public static final String IMG_DB_GROUP = NAME_PREFIX + "dbgroup_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_CONTAINER = NAME_PREFIX + "container.png"; //$NON-NLS-1$
+ public static final String IMG_SYSTEM_PROCESS = NAME_PREFIX
+ + "systemprocess.gif"; //$NON-NLS-1$
+ public static final String IMG_CHECKED = NAME_PREFIX + "checked.gif"; //$NON-NLS-1$
+ public static final String IMG_UNCHECKED = NAME_PREFIX + "unchecked.gif"; //$NON-NLS-1$
+ public static final String IMG_BANNER_REPOSITORY = NAME_PREFIX
+ + "banner-repository.gif"; //$NON-NLS-1$
+ public static final String IMG_WARNING = NAME_PREFIX + "warning_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_ERROR = NAME_PREFIX + "error_obj.gif"; //$NON-NLS-1$
+
public static final ImageDescriptor DESC_CONNECTION = createManaged("",
IMG_CONNECTION);
public static final ImageDescriptor DESC_CREATE_CONTAINER = createManaged(
"", IMG_CREATE_CONTAINER);
public static final ImageDescriptor DESC_FOLDER = createManaged("",
IMG_FOLDER);
+ public static final ImageDescriptor DESC_FOLDER_CLOSED = createManaged("",
+ IMG_FOLDER_CLOSED);
+ public static final ImageDescriptor DESC_FILE = createManaged("", IMG_FILE);
public static final ImageDescriptor DESC_INSTANCE = createManaged("",
IMG_INSTANCE);
public static final ImageDescriptor DESC_IMAGE = createManaged("",
@@ -125,6 +145,24 @@ public class SWTImagesFactory {
IMG_REFRESH);
public static final ImageDescriptor DESC_REBOOTD = createManaged("",
IMG_REBOOTD);
+ public static final ImageDescriptor DESC_REPOSITORY_MIDDLE = createManaged(
+ "", IMG_REPOSITORY_MIDDLE);
+ public static final ImageDescriptor DESC_DB_GROUP = createManaged("",
+ IMG_DB_GROUP);
+ public static final ImageDescriptor DESC_CONTAINER = createManaged("",
+ IMG_CONTAINER);
+ public static final ImageDescriptor DESC_SYSTEM_PROCESS = createManaged("",
+ IMG_SYSTEM_PROCESS);
+ public static final ImageDescriptor DESC_CHECKED = createManaged("",
+ IMG_CHECKED);
+ public static final ImageDescriptor DESC_UNCHECKED = createManaged("",
+ IMG_UNCHECKED);
+ public static final ImageDescriptor DESC_BANNER_REPOSITORY = createManaged(
+ "", IMG_BANNER_REPOSITORY);
+ public static final ImageDescriptor DESC_WARNING = createManaged("",
+ IMG_WARNING);
+ public static final ImageDescriptor DESC_ERROR = createManaged("",
+ IMG_ERROR);
private static ImageDescriptor createManaged(String prefix, String name) {
return createManaged(imageRegistry, prefix, name);
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/AddConnectionCommandHandler.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/AddConnectionCommandHandler.java
index 0002385573..da89fea997 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/AddConnectionCommandHandler.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/AddConnectionCommandHandler.java
@@ -12,11 +12,7 @@ package org.eclipse.linuxtools.internal.docker.ui.commands;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.jface.window.Window;
-import org.eclipse.jface.wizard.IWizard;
-import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.linuxtools.internal.docker.ui.wizards.NewDockerConnection;
-import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.ui.navigator.CommonNavigator;
@@ -32,20 +28,13 @@ public class AddConnectionCommandHandler extends AbstractHandler {
public Object execute(ExecutionEvent event) {
final IWorkbenchPart activePart = HandlerUtil.getActivePart(event);
if(activePart instanceof CommonNavigator) {
- final boolean connectionAdded = openWizard(new NewDockerConnection(), HandlerUtil.getActiveShell(event));
+ final boolean connectionAdded = CommandUtils.openWizard(new NewDockerConnection(), HandlerUtil.getActiveShell(event));
if(connectionAdded) {
final CommonViewer viewer = ((CommonNavigator)activePart).getCommonViewer();
viewer.refresh();
}
}
- // return must be null, javadoc says.
return null;
}
- public static boolean openWizard(final IWizard wizard, final Shell shell) {
- WizardDialog wizardDialog = new WizardDialog(shell, wizard);
- wizardDialog.create();
- return wizardDialog.open() == Window.OK;
- }
-
}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/BaseContainersCommandHandler.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/BaseContainersCommandHandler.java
index 63777c12f8..1f28ea1b57 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/BaseContainersCommandHandler.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/BaseContainersCommandHandler.java
@@ -40,7 +40,8 @@ public abstract class BaseContainersCommandHandler extends AbstractHandler {
@Override
public Object execute(ExecutionEvent event) {
final IWorkbenchPart activePart = HandlerUtil.getActivePart(event);
- final List<IDockerContainer> selectedContainers = getSelectedContainers(activePart);
+ final List<IDockerContainer> selectedContainers = getSelectedContainers(
+ activePart);
final IDockerConnection connection = getCurrentConnection(activePart);
if (connection == null || selectedContainers.isEmpty()) {
return null;
@@ -61,7 +62,7 @@ public abstract class BaseContainersCommandHandler extends AbstractHandler {
return Status.OK_STATUS;
}
};
- job.setPriority(Job.LONG);
+ // job.setPriority(Job.LONG);
job.setUser(true);
job.schedule();
return null;
@@ -72,20 +73,21 @@ public abstract class BaseContainersCommandHandler extends AbstractHandler {
@Override
public void run() {
MessageDialog.openError(Display.getCurrent().getActiveShell(),
- errorMessage,
- e.getMessage());
+ errorMessage, e.getMessage());
}
});
}
// allow commands to add confirmation dialog
- boolean confirmed(List<IDockerContainer> selectedContainers) {
+ boolean confirmed(
+ @SuppressWarnings("unused") List<IDockerContainer> selectedContainers) {
return true;
}
abstract String getJobName(final List<IDockerContainer> selectedContainers);
abstract String getTaskName(final IDockerContainer container);
-
- abstract void executeInJob(final IDockerContainer container, final IDockerConnection connection);
+
+ abstract void executeInJob(final IDockerContainer container,
+ final IDockerConnection connection);
}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/BaseImagesCommandHandler.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/BaseImagesCommandHandler.java
index 4228724bb5..d907240bfc 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/BaseImagesCommandHandler.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/BaseImagesCommandHandler.java
@@ -79,7 +79,8 @@ public abstract class BaseImagesCommandHandler extends AbstractHandler {
}
// allow commands to add confirmation dialog
- boolean confirmed(List<IDockerImage> selectedImages) {
+ boolean confirmed(
+ @SuppressWarnings("unused") List<IDockerImage> selectedImages) {
return true;
}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandUtils.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandUtils.java
index b0a93db185..95a2a50011 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandUtils.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandUtils.java
@@ -111,7 +111,6 @@ public class CommandUtils {
}
return Collections.emptyList();
}
-
/**
* @param activePart
* the active {@link IWorkbenchPart}
@@ -172,11 +171,12 @@ public class CommandUtils {
// console for the container id and get
// its stream.
if (autoLogOnStart) {
- final RunConsole console = RunConsole.findConsole(container.id(),
- RunConsole.DEFAULT_ID, container.name());
- console.attachToConsole(connection);
- console.clearConsole();
- return console;
+ final RunConsole console = RunConsole.findConsole(container);
+ if (console != null) {
+ console.attachToConsole(connection);
+ console.clearConsole();
+ return console;
+ }
}
return null;
}
@@ -198,4 +198,23 @@ public class CommandUtils {
return wizardDialog.open() == Window.OK;
}
+ /**
+ * Opens the given {@link IWizard} and returns <code>true</code> if the user
+ * finished the operation, <code>false</code> if he cancelled it.
+ *
+ * @param wizard
+ * the wizard to open
+ * @param shell
+ * the current {@link Shell}
+ * @return <code>true</code> if the wizard completed, <code>false</code>
+ * otherwise.
+ */
+ public static boolean openWizard(final IWizard wizard, final Shell shell,
+ final int width, final int height) {
+ final WizardDialog wizardDialog = new WizardDialog(shell, wizard);
+ wizardDialog.setPageSize(width, height);
+ wizardDialog.create();
+ return wizardDialog.open() == Window.OK;
+ }
+
}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CreateContainerCommandHandler.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CreateContainerCommandHandler.java
deleted file mode 100644
index fa09375b7a..0000000000
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CreateContainerCommandHandler.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*******************************************************************************
- * 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.ui.commands;
-
-import java.io.OutputStream;
-import java.util.List;
-
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.linuxtools.docker.core.DockerException;
-import org.eclipse.linuxtools.docker.core.IDockerConnection;
-import org.eclipse.linuxtools.docker.core.IDockerContainerConfig;
-import org.eclipse.linuxtools.docker.core.IDockerContainerInfo;
-import org.eclipse.linuxtools.docker.core.IDockerHostConfig;
-import org.eclipse.linuxtools.docker.core.IDockerImage;
-import org.eclipse.linuxtools.internal.docker.core.DockerConnection;
-import org.eclipse.linuxtools.internal.docker.ui.RunConsole;
-import org.eclipse.linuxtools.internal.docker.ui.views.DVMessages;
-import org.eclipse.linuxtools.internal.docker.ui.views.DockerImagesView;
-import org.eclipse.linuxtools.internal.docker.ui.wizards.ContainerCreate;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.handlers.HandlerUtil;
-
-public class CreateContainerCommandHandler extends AbstractHandler {
-
- private final static String CREATE_CONTAINER_JOB_TITLE = "ContainerCreateTitle.msg"; //$NON-NLS-1$
- private final static String CREATE_CONTAINER_MSG = "ContainerCreate.msg"; //$NON-NLS-1$
- private static final String ERROR_CREATING_IMAGE = "ContainerCreateError.msg"; //$NON-NLS-1$
-
- private IDockerConnection connection;
- private IDockerImage image;
-
- @Override
- public Object execute(final ExecutionEvent event) {
- final IWorkbenchPart activePart = HandlerUtil.getActivePart(event);
- List<IDockerImage> selectedImages = CommandUtils
- .getSelectedImages(activePart);
- if (activePart instanceof DockerImagesView) {
- connection = ((DockerImagesView) activePart).getConnection();
- }
- if (selectedImages.size() != 1 || connection == null)
- return null;
- image = selectedImages.get(0);
- final ContainerCreate wizard;
- if (!image.isDangling() && !image.isIntermediateImage())
- wizard = new ContainerCreate(connection, image.repoTags().get(0));
- else
- wizard = new ContainerCreate(connection, image.id()
- .substring(0, 12));
- final boolean tagImage = CommandUtils.openWizard(wizard,
- HandlerUtil.getActiveShell(event));
- if (tagImage) {
- if (activePart instanceof DockerImagesView) {
- connection = ((DockerImagesView) activePart)
- .getConnection();
- }
- performCreateContainer(wizard);
- }
- return null;
- }
-
- private void performCreateContainer(final ContainerCreate wizard) {
- final Job createContainerJob = new Job(
- DVMessages.getString(CREATE_CONTAINER_JOB_TITLE)) {
-
- @Override
- protected IStatus run(final IProgressMonitor monitor) {
- final IDockerContainerConfig config = wizard.getConfig();
- final IDockerHostConfig hostConfig = wizard.getHostConfig();
- final String image = wizard.getImageId();
- monitor.beginTask(DVMessages.getString(CREATE_CONTAINER_MSG), 4);
- // pull the image and let the progress
- // handler refresh the images when done
- try {
- final String containerId = ((DockerConnection) connection)
- .createContainer(config);
- monitor.worked(1);
- IDockerContainerInfo info = ((DockerConnection) connection)
- .getContainerInfo(containerId);
- String name = info.name();
- if (name.startsWith("/")) //$NON-NLS-1$
- name = name.replaceFirst("/", ""); //$NON-NLS-1$ //$NON-NLS-2$
- monitor.worked(1);
- OutputStream stream = null;
- RunConsole rc = RunConsole.findConsole(containerId,
- RunConsole.DEFAULT_ID, name);
- rc.attachToConsole(connection);
- monitor.worked(1);
- if (rc != null) {
- stream = rc.getOutputStream();
- }
- final OutputStream logstream = stream;
- ((DockerConnection) connection).startContainer(containerId,
- hostConfig, logstream);
- monitor.worked(1);
- } catch (final DockerException e) {
- Display.getDefault().syncExec(new Runnable() {
-
- @Override
- public void run() {
- MessageDialog.openError(Display.getCurrent()
- .getActiveShell(), DVMessages
- .getFormattedString(ERROR_CREATING_IMAGE,
- image), e.getMessage());
-
- }
-
- });
- // for now
- } catch (InterruptedException e) {
- // do nothing
- } finally {
- monitor.done();
- }
- return Status.OK_STATUS;
- }
-
- };
-
- createContainerJob.schedule();
-
- }
-
-}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/DisplayContainerLogCommandHandler.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/DisplayContainerLogCommandHandler.java
index f5bb60e5ee..2aad131b6c 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/DisplayContainerLogCommandHandler.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/DisplayContainerLogCommandHandler.java
@@ -50,8 +50,7 @@ public class DisplayContainerLogCommandHandler extends AbstractHandler {
final String id = container.id();
final String name = container.name();
try {
- final RunConsole rc = RunConsole
- .findConsole(id);
+ final RunConsole rc = RunConsole.findConsole(id, name);
if (!rc.isAttached()) {
rc.attachToConsole(connection);
}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/RemoveContainerLogCommandHandler.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/RemoveContainerLogCommandHandler.java
index daef2035ef..2ff1635744 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/RemoveContainerLogCommandHandler.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/RemoveContainerLogCommandHandler.java
@@ -37,10 +37,10 @@ public class RemoveContainerLogCommandHandler extends AbstractHandler {
if (selectedContainers.size() != 1 || connection == null)
return null;
container = selectedContainers.get(0);
- final String id = container.id();
- final RunConsole rc = RunConsole.findConsole(id);
- if (rc != null)
+ final RunConsole rc = RunConsole.findConsole(container);
+ if (rc != null) {
RunConsole.removeConsole(rc);
+ }
return null;
}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/RunImageCommandHandler.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/RunImageCommandHandler.java
new file mode 100644
index 0000000000..a17e7ac069
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/RunImageCommandHandler.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2014, 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.ui.commands;
+
+import java.io.OutputStream;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeSelection;
+import org.eclipse.linuxtools.docker.core.DockerException;
+import org.eclipse.linuxtools.docker.core.IDockerConnection;
+import org.eclipse.linuxtools.docker.core.IDockerContainer;
+import org.eclipse.linuxtools.docker.core.IDockerContainerConfig;
+import org.eclipse.linuxtools.docker.core.IDockerHostConfig;
+import org.eclipse.linuxtools.docker.core.IDockerImage;
+import org.eclipse.linuxtools.docker.ui.Activator;
+import org.eclipse.linuxtools.internal.docker.core.DockerConnection;
+import org.eclipse.linuxtools.internal.docker.ui.RunConsole;
+import org.eclipse.linuxtools.internal.docker.ui.views.DVMessages;
+import org.eclipse.linuxtools.internal.docker.ui.views.DockerExplorerView;
+import org.eclipse.linuxtools.internal.docker.ui.views.DockerImagesView;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRun;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.console.IConsoleConstants;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * @author xcoulon
+ *
+ */
+public class RunImageCommandHandler extends AbstractHandler {
+
+ private static final String ERROR_CREATING_CONTAINER = "ContainerCreateError.msg"; //$NON-NLS-1$
+
+ @Override
+ public Object execute(final ExecutionEvent event) {
+ final IWorkbenchPart activePart = HandlerUtil.getActivePart(event);
+ final IDockerImage selectedImage = getSelectedImage(activePart);
+ if (selectedImage == null) {
+ Activator.logErrorMessage(
+ "Unable to retrieve Docker Image from current selection.");
+ } else {
+ try {
+ final ImageRun wizard = new ImageRun(selectedImage);
+ final boolean runImage = CommandUtils.openWizard(wizard,
+ HandlerUtil.getActiveShell(event));
+ if (runImage) {
+ final IDockerContainerConfig containerConfig = wizard
+ .getDockerContainerConfig();
+ final IDockerHostConfig hostConfig = wizard
+ .getDockerHostConfig();
+ runImage(selectedImage.getConnection(), containerConfig,
+ hostConfig, wizard.getDockerContainerName());
+ }
+ } catch (DockerException e) {
+ Activator.log(e);
+ }
+ }
+ return null;
+ }
+
+ private void runImage(final IDockerConnection connection,
+ final IDockerContainerConfig containerConfig,
+ final IDockerHostConfig hostConfig, final String containerName) {
+ if (containerConfig.tty()) {
+ // show the console view
+ try {
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow()
+ .getActivePage()
+ .showView(IConsoleConstants.ID_CONSOLE_VIEW);
+ } catch (PartInitException e) {
+ Activator.log(e);
+ }
+ }
+
+ // Create the container in a non-UI thread.
+ final Job runImageJob = new Job("Create Container") {
+
+ @Override
+ protected IStatus run(final IProgressMonitor monitor) {
+ monitor.beginTask("Running image...", 2);
+ try {
+ final SubProgressMonitor createContainerMonitor = new SubProgressMonitor(
+ monitor, 1);
+ // create the container
+ createContainerMonitor.beginTask("Creating container...",
+ 1);
+ final String containerId = ((DockerConnection) connection)
+ .createContainer(containerConfig, containerName);
+ final IDockerContainer container = ((DockerConnection) connection)
+ .getContainer(containerId);
+
+ createContainerMonitor.done();
+ // abort if operation was cancelled
+ if (monitor.isCanceled()) {
+ return Status.CANCEL_STATUS;
+ }
+ // start the container
+ final SubProgressMonitor startContainerMonitor = new SubProgressMonitor(
+ monitor, 1);
+ startContainerMonitor.beginTask("Starting container...", 1);
+ final OutputStream consoleOutputStream = getConsoleOutputStream(
+ connection, container, containerConfig);
+ ((DockerConnection) connection).startContainer(containerId,
+ hostConfig, consoleOutputStream);
+ startContainerMonitor.done();
+ } catch (final DockerException | InterruptedException e) {
+ Display.getDefault().syncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ MessageDialog.openError(
+ Display.getCurrent().getActiveShell(),
+ DVMessages.getFormattedString(
+ ERROR_CREATING_CONTAINER,
+ containerConfig.image()),
+ e.getMessage());
+
+ }
+
+ });
+ } finally {
+ monitor.done();
+ }
+ return Status.OK_STATUS;
+ }
+ };
+ runImageJob.schedule();
+
+ }
+
+ private OutputStream getConsoleOutputStream(
+ final IDockerConnection connection,
+ final IDockerContainer container,
+ final IDockerContainerConfig containerConfig) {
+ if (containerConfig.tty()) {
+ final RunConsole rc = RunConsole.findConsole(container);
+ if (rc != null) {
+ rc.attachToConsole(connection);
+ final OutputStream consoleOutputStream = rc.getOutputStream();
+ return consoleOutputStream;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @param activePart
+ * the active {@link IWorkbenchPart}
+ * @return the selected {@link IDockerImage} in the given active part of
+ * <code>null</code> if none was selected
+ */
+ public static IDockerImage getSelectedImage(
+ final IWorkbenchPart activePart) {
+ if (activePart instanceof DockerExplorerView) {
+ final ITreeSelection selection = (ITreeSelection) ((DockerExplorerView) activePart)
+ .getCommonViewer().getSelection();
+ return (IDockerImage) selection.getFirstElement();
+ } else if (activePart instanceof DockerImagesView) {
+ final IStructuredSelection selection = (IStructuredSelection) (((DockerImagesView) activePart)
+ .getSelection());
+ if (!selection.isEmpty()) {
+ return (IDockerImage) selection.getFirstElement();
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/databinding/BaseDatabindingModel.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/databinding/BaseDatabindingModel.java
new file mode 100644
index 0000000000..10303c0a13
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/databinding/BaseDatabindingModel.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2014, 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.ui.databinding;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+
+/**
+ * Base class for all model classes that need Databinding support
+ *
+ * @author xcoulon
+ *
+ */
+public abstract class BaseDatabindingModel {
+
+ private PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);
+
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ changeSupport.addPropertyChangeListener(propertyName, listener);
+ }
+
+ public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ changeSupport.removePropertyChangeListener(propertyName, listener);
+ }
+
+ protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
+ changeSupport.firePropertyChange(propertyName, oldValue, newValue);
+ }
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/databinding/RequiredControlDecorationUpdater.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/databinding/RequiredControlDecorationUpdater.java
new file mode 100644
index 0000000000..71a1e6753c
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/databinding/RequiredControlDecorationUpdater.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * 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.ui.databinding;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.databinding.fieldassist.ControlDecorationUpdater;
+import org.eclipse.jface.fieldassist.FieldDecoration;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * Decorates a {@link Control} to indicate that the value is required.
+ *
+ * @author xcoulon
+ *
+ */
+public class RequiredControlDecorationUpdater extends ControlDecorationUpdater {
+
+ /**
+ * boolean to force the decorator even when the status is IStatus#CANCEL.
+ */
+
+ private final boolean showRequiredDecorator;
+
+ public RequiredControlDecorationUpdater(
+ final boolean showRequiredDecorator) {
+ this.showRequiredDecorator = showRequiredDecorator;
+ }
+
+ @Override
+ protected Image getImage(IStatus status) {
+ if (status == null) {
+ return null;
+ }
+ String fieldDecorationID = null;
+ switch (status.getSeverity()) {
+ case IStatus.INFO:
+ fieldDecorationID = FieldDecorationRegistry.DEC_INFORMATION;
+ break;
+ case IStatus.WARNING:
+ fieldDecorationID = FieldDecorationRegistry.DEC_WARNING;
+ break;
+ case IStatus.ERROR:
+ fieldDecorationID = FieldDecorationRegistry.DEC_ERROR;
+ break;
+ case IStatus.CANCEL:
+ fieldDecorationID = showRequiredDecorator
+ ? FieldDecorationRegistry.DEC_REQUIRED : null;
+ break;
+ }
+
+ final FieldDecoration fieldDecoration = FieldDecorationRegistry
+ .getDefault().getFieldDecoration(fieldDecorationID);
+ return fieldDecoration == null ? null : fieldDecoration.getImage();
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/databinding/TextCellEditingSupport.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/databinding/TextCellEditingSupport.java
new file mode 100644
index 0000000000..eed6fa52d0
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/databinding/TextCellEditingSupport.java
@@ -0,0 +1,45 @@
+package org.eclipse.linuxtools.internal.docker.ui.databinding;
+
+import org.eclipse.core.databinding.DataBindingContext;
+import org.eclipse.core.databinding.beans.BeanProperties;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.jface.databinding.swt.WidgetProperties;
+import org.eclipse.jface.databinding.viewers.ObservableValueEditingSupport;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.ColumnViewer;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.jface.viewers.ViewerCell;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Support for Cell editing
+ *
+ * @see http://www.vogella.com/tutorials/EclipseDataBinding/article.html#jfacedb_viewer
+ */
+public class TextCellEditingSupport extends ObservableValueEditingSupport {
+
+ /** The name of the property to observe during edition. */
+ private final String propertyName;
+
+ public TextCellEditingSupport(final ColumnViewer viewer, final DataBindingContext dbc, final String propertyName) {
+ super(viewer, dbc);
+ this.propertyName = propertyName;
+ }
+
+ @Override
+ protected IObservableValue doCreateCellEditorObservable(final CellEditor cellEditor) {
+ return WidgetProperties.text(SWT.Modify).observe(cellEditor.getControl());
+ }
+
+ @Override
+ protected IObservableValue doCreateElementObservable(final Object element, final ViewerCell cell) {
+ return BeanProperties.value(this.propertyName).observe(element);
+ }
+
+ @Override
+ protected CellEditor getCellEditor(final Object element) {
+ return new TextCellEditor((Composite) getViewer().getControl());
+ }
+
+} \ No newline at end of file
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/propertytesters/ContainerPropertyTester.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/propertytesters/ContainerPropertyTester.java
index bb2fef7387..31beb7e7c3 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/propertytesters/ContainerPropertyTester.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/propertytesters/ContainerPropertyTester.java
@@ -36,6 +36,11 @@ public class ContainerPropertyTester extends PropertyTester {
*/
public static final String IS_REMOVABLE = "isRemovable";
+ /**
+ * Property name to check if a given {@link IDockerContainer} is unknown.
+ */
+ public static final String IS_UNKNOWN = "isUnknwon";
+
@Override
public boolean test(final Object receiver, final String property, final Object[] args, final Object expectedValue) {
if (receiver instanceof IDockerContainer) {
@@ -44,7 +49,11 @@ public class ContainerPropertyTester extends PropertyTester {
case IS_RUNNING:
return checkIfStateMatchesExpectation(container, EnumDockerStatus.RUNNING, expectedValue);
case IS_STOPPED:
- return checkIfStateMatchesExpectation(container, EnumDockerStatus.STOPPED, expectedValue);
+ return checkIfStateMatchesExpectation(container,
+ EnumDockerStatus.STOPPED, expectedValue);
+ case IS_UNKNOWN:
+ return checkIfStateMatchesExpectation(container,
+ EnumDockerStatus.UNKNOWN, expectedValue);
case IS_PAUSED:
return checkIfStateMatchesExpectation(container, EnumDockerStatus.PAUSED, expectedValue);
case IS_REMOVABLE:
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/utils/IRunnableWithResult.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/utils/IRunnableWithResult.java
new file mode 100644
index 0000000000..d360897ff3
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/utils/IRunnableWithResult.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * 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.ui.utils;
+
+import org.eclipse.jface.operation.IRunnableWithProgress;
+
+/**
+ * An {@link IRunnableWithProgress} that can return a result.
+ *
+ * @author xcoulon
+ *
+ */
+public interface IRunnableWithResult<T> extends IRunnableWithProgress {
+
+ public T getResult();
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/ConnectionInfoContentProvider.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/ConnectionInfoContentProvider.java
index eb5e0943b3..d6f59141ae 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/ConnectionInfoContentProvider.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/ConnectionInfoContentProvider.java
@@ -42,6 +42,12 @@ public class ConnectionInfoContentProvider implements ITreeContentProvider {
new Object[]{"Execution driver", connectionInfo.getExecutionDriver()}, //$NON-NLS-1$
new Object[]{"Kernel version", connectionInfo.getKernelVersion()}, //$NON-NLS-1$
new Object[]{"Operating system", connectionInfo.getOs()}, //$NON-NLS-1$
+ new Object[] { "CPU number", //$NON-NLS-1$
+ connectionInfo.getCPUNumber() },
+ new Object[] { "Total memory", //$NON-NLS-1$
+ Long.toString(
+ connectionInfo.getTotalMemory() / 1048576)
+ + " MB" },
new Object[]{"File descriptors", connectionInfo.getFileDescriptors()}, //$NON-NLS-1$
new Object[]{"Go routines", connectionInfo.getGoroutines()}, //$NON-NLS-1$
new Object[]{"Init path", connectionInfo.getInitPath()}, //$NON-NLS-1$
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DVMessages.properties b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DVMessages.properties
index 14f5fbd520..442f91f260 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DVMessages.properties
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DVMessages.properties
@@ -70,6 +70,7 @@ ImagePullError.msg=Error pulling image <{0}>
ImagePushError.msg=Error pushing image <{0}>
ImageBuildError.msg=Error building image <{0}>
ImageRemoveError.msg=Error removing image <{0}>
+ImageTagError.msg=Error tagging image to <{0}>
ContainerCreateError.msg=Error creating container from image<{0}>
ContainerRemoveError.msg=Error removing container: <{0}>
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerContainersView.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerContainersView.java
index e16157962c..58a88520e5 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerContainersView.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerContainersView.java
@@ -144,7 +144,7 @@ public class DockerContainersView extends ViewPart implements
}
private void createTableViewer(final Composite container) {
- search = new Text(container, SWT.SEARCH);
+ search = new Text(container, SWT.SEARCH | SWT.ICON_SEARCH);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, false).applyTo(search);
search.addModifyListener(onSearch());
Composite tableArea = new Composite(container, SWT.NONE);
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerLabelProvider.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerLabelProvider.java
index 2d886f31eb..f4e164bf1b 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerLabelProvider.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerLabelProvider.java
@@ -12,7 +12,10 @@
package org.eclipse.linuxtools.internal.docker.ui.views;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.Iterator;
+import java.util.List;
import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
import org.eclipse.jface.viewers.ILabelProvider;
@@ -22,7 +25,7 @@ import org.eclipse.jface.viewers.StyledString;
import org.eclipse.linuxtools.docker.core.IDockerConnection;
import org.eclipse.linuxtools.docker.core.IDockerContainer;
import org.eclipse.linuxtools.docker.core.IDockerImage;
-import org.eclipse.linuxtools.docker.ui.Activator;
+import org.eclipse.linuxtools.internal.docker.ui.SWTImagesFactory;
import org.eclipse.linuxtools.internal.docker.ui.views.DockerExplorerContentProvider.DockerContainersCategory;
import org.eclipse.linuxtools.internal.docker.ui.views.DockerExplorerContentProvider.DockerImagesCategory;
import org.eclipse.linuxtools.internal.docker.ui.views.DockerExplorerContentProvider.LoadingStub;
@@ -54,17 +57,17 @@ public class DockerExplorerLabelProvider implements IStyledLabelProvider, ILabel
@Override
public Image getImage(final Object element) {
if(element instanceof IDockerConnection) {
- return Activator.getImageDescriptor("icons/repository-middle.gif").createImage();
+ return SWTImagesFactory.DESC_REPOSITORY_MIDDLE.createImage();
} else if(element instanceof DockerImagesCategory) {
- return Activator.getImageDescriptor("icons/dbgroup_obj.gif").createImage();
+ return SWTImagesFactory.DESC_DB_GROUP.createImage();
} else if(element instanceof DockerContainersCategory) {
- return Activator.getImageDescriptor("icons/dbgroup_obj.gif").createImage();
+ return SWTImagesFactory.DESC_DB_GROUP.createImage();
} else if(element instanceof IDockerImage) {
- return Activator.getImageDescriptor("icons/image.png").createImage();
+ return SWTImagesFactory.DESC_IMAGE.createImage();
} else if(element instanceof IDockerContainer) {
- return Activator.getImageDescriptor("icons/container.png").createImage();
+ return SWTImagesFactory.DESC_CONTAINER.createImage();
} else if(element instanceof LoadingStub) {
- return Activator.getImageDescriptor("icons/systemprocess.gif").createImage();
+ return SWTImagesFactory.DESC_SYSTEM_PROCESS.createImage();
}
return null;
}
@@ -110,11 +113,15 @@ public class DockerExplorerLabelProvider implements IStyledLabelProvider, ILabel
final StringBuilder messageBuilder = new StringBuilder(dockerImage.repo());
final int startTags = messageBuilder.length();
if(!dockerImage.tags().isEmpty()) {
+ final List<String> tags = new ArrayList<>(
+ dockerImage.tags());
+ Collections.sort(tags);
messageBuilder.append(": ");
- for(Iterator<String> tagIterator = dockerImage.tags().iterator(); tagIterator.hasNext();) {
+ for (Iterator<String> tagIterator = tags
+ .iterator(); tagIterator.hasNext();) {
messageBuilder.append(tagIterator.next());
if(tagIterator.hasNext()) {
- messageBuilder.append(", ");
+ messageBuilder.append(" / ");
}
}
}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerView.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerView.java
index efa5a00654..adacc982b1 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerView.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerView.java
@@ -17,6 +17,7 @@ import org.eclipse.jface.viewers.AbstractTreeViewer;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.linuxtools.docker.core.DockerConnectionManager;
import org.eclipse.linuxtools.docker.core.IDockerConnectionManagerListener;
@@ -101,8 +102,7 @@ public class DockerExplorerView extends CommonNavigator implements
final FormToolkit toolkit = new FormToolkit(parent.getDisplay());
this.pageBook = new PageBook(parent, SWT.NONE);
this.connectionsPane = createConnectionsPane(pageBook, toolkit);
- this.explanationsPane = createExplanationPane(connectionsPane,
- pageBook, toolkit);
+ this.explanationsPane = createExplanationPane(pageBook, toolkit);
showConnectionsOrExplanations();
this.containersAndImagesSearchFilter = getContainersAndImagesSearchFilter();
getCommonViewer().addFilter(containersAndImagesSearchFilter);
@@ -138,7 +138,7 @@ public class DockerExplorerView extends CommonNavigator implements
final Composite container = form.getBody();
GridLayoutFactory.fillDefaults().numColumns(1).margins(5, 5)
.applyTo(container);
- this.search = new Text(container, SWT.SEARCH);
+ this.search = new Text(container, SWT.SEARCH | SWT.ICON_SEARCH);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL)
.grab(true, false).applyTo(search);
search.addModifyListener(onSearch());
@@ -175,8 +175,8 @@ public class DockerExplorerView extends CommonNavigator implements
};
}
- private Control createExplanationPane(final Control connectionsPane,
- final PageBook pageBook, final FormToolkit toolkit) {
+ private Control createExplanationPane(final PageBook pageBook,
+ final FormToolkit toolkit) {
final Form form = toolkit.createForm(pageBook);
final Composite container = form.getBody();
GridLayoutFactory.fillDefaults().numColumns(1).margins(5, 5)
@@ -188,12 +188,11 @@ public class DockerExplorerView extends CommonNavigator implements
SWT.COLOR_LIST_BACKGROUND));
GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.FILL)
.grab(true, false).applyTo(link);
- link.addSelectionListener(onExplanationClicked(connectionsPane, link));
+ link.addSelectionListener(onExplanationClicked());
return form;
}
- private SelectionAdapter onExplanationClicked(
- final Control connectionsPane, final Control explanationPane) {
+ private SelectionAdapter onExplanationClicked() {
return new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
@@ -201,7 +200,7 @@ public class DockerExplorerView extends CommonNavigator implements
final WizardDialog dialog = new WizardDialog(PlatformUI
.getWorkbench().getModalDialogShellProvider()
.getShell(), wizard);
- if (dialog.open() == WizardDialog.OK) {
+ if (dialog.open() == Window.OK) {
getCommonViewer().refresh();
}
// if a (first) connection is added, the
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerImagesView.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerImagesView.java
index 313cc7b316..e811076290 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerImagesView.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerImagesView.java
@@ -151,7 +151,7 @@ public class DockerImagesView extends ViewPart implements IDockerImageListener,
}
private void createTableViewer(final Composite container) {
- search = new Text(container, SWT.SEARCH);
+ search = new Text(container, SWT.SEARCH | SWT.ICON_SEARCH);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, false).applyTo(search);
search.addModifyListener(onSearch());
Composite tableArea = new Composite(container, SWT.NONE);
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/LabelUtils.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/LabelUtils.java
index 24bb547668..7d221f2cac 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/LabelUtils.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/LabelUtils.java
@@ -136,5 +136,5 @@ public class LabelUtils {
}
return value.toString();
}
-
+
}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerCreate.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerCreate.java
deleted file mode 100644
index a3daa21c00..0000000000
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerCreate.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2014 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.ui.wizards;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.jface.wizard.Wizard;
-import org.eclipse.linuxtools.docker.core.IDockerConnection;
-import org.eclipse.linuxtools.docker.core.IDockerContainerConfig;
-import org.eclipse.linuxtools.docker.core.IDockerHostConfig;
-import org.eclipse.linuxtools.docker.core.IDockerPortBinding;
-import org.eclipse.linuxtools.internal.docker.core.DockerContainerConfig;
-import org.eclipse.linuxtools.internal.docker.core.DockerHostConfig;
-
-public class ContainerCreate extends Wizard {
-
- private IDockerConnection connection;
- private IDockerContainerConfig config;
- private IDockerHostConfig hostConfig;
- private String image;
- private ContainerCreatePage mainPage;
-
- public ContainerCreate(IDockerConnection connection, String image) {
- this.connection = connection;
- this.image = image;
- }
-
- public IDockerContainerConfig getConfig() {
- return config;
- }
-
- public IDockerHostConfig getHostConfig() {
- return hostConfig;
- }
-
- public String getImageId() {
- return image;
- }
-
- @Override
- public void addPages() {
- // TODO Auto-generated method stub
- mainPage = new ContainerCreatePage(connection, image);
- addPage(mainPage);
- }
-
- @Override
- public boolean canFinish() {
- return mainPage.isPageComplete();
- }
-
- @Override
- public boolean performFinish() {
- final String hostName = mainPage.getHostName();
- final String domainName = mainPage.getDomainName();
- final String user = mainPage.getUser();
- final Long memory = mainPage.getMemory();
- final Long memorySwap = mainPage.getMemorySwap();
- final Long cpuShares = mainPage.getCpuShares();
- final String cpuSet = mainPage.getCpuSet();
- final Boolean attachStdin = mainPage.getAttachStdin();
- final Boolean attachStdout = mainPage.getAttachStdout();
- final Boolean attachStderr = mainPage.getAttachStderr();
- final List<String> portSpecs = mainPage.getPortSpecs();
- final Set<String> exposedPorts = mainPage.getExposedPorts();
- final Boolean tty = mainPage.getTty();
- final Boolean openStdin = mainPage.getOpenStdin();
- final Boolean stdinOnce = mainPage.getStdinOnce();
- final List<String> env = mainPage.getEnv();
- final List<String> cmd = mainPage.getCmd();
- final Set<String> volumes = mainPage.getVolumes();
- final String workingDir = mainPage.getWorkingDir();
- final List<String> entryPoint = mainPage.getEntryPoint();
- final Boolean networkDisabled = mainPage.getNetworkDisabled();
- final List<String> onBuild = mainPage.getOnBuild();
-
- image = mainPage.getImageId();
-
- DockerContainerConfig.Builder builder = new DockerContainerConfig.Builder()
- .hostname(hostName).domainname(domainName).user(user)
- .memory(memory).memorySwap(memorySwap).cpuShares(cpuShares)
- .cpuset(cpuSet).attachStdin(attachStdin)
- .attachStdout(attachStdout).attachStderr(attachStderr).tty(tty)
- .openStdin(openStdin).stdinOnce(stdinOnce).cmd(cmd)
- .image(image).workingDir(workingDir)
- .networkDisabled(networkDisabled);
- if (portSpecs != null)
- builder = builder.portSpecs(portSpecs);
- if (exposedPorts != null)
- builder = builder.exposedPorts(exposedPorts);
- if (onBuild != null)
- builder = builder.onBuild(onBuild);
- if (entryPoint != null)
- builder = builder.entryPoint(entryPoint);
- if (env != null)
- builder = builder.env(env);
- if (volumes != null)
- builder = builder.volumes(volumes);
-
- config = builder.build();
-
- final List<String> hostVolumes = mainPage.getHostVolumes();
- final String networkMode = mainPage.getNetworkMode();
- final Boolean privileged = mainPage.getPrivileged();
- final Boolean publishAllPorts = mainPage.getPublishAllPorts();
- final Map<String, List<IDockerPortBinding>> portBindings = mainPage
- .getPortBindings();
-
- final DockerHostConfig.Builder builder2 = DockerHostConfig.builder()
- .networkMode(networkMode).privileged(privileged)
- .publishAllPorts(publishAllPorts);
-
- if (hostVolumes != null && hostVolumes.size() > 0) {
- builder2.binds(hostVolumes);
- }
-
- if (portBindings != null && portBindings.size() > 0) {
- builder2.portBindings(portBindings);
- }
- hostConfig = builder2.build();
- return true;
- }
-}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerCreatePage.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerCreatePage.java
deleted file mode 100644
index 59443f2cfb..0000000000
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerCreatePage.java
+++ /dev/null
@@ -1,939 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2014 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.ui.wizards;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.eclipse.jface.wizard.WizardPage;
-import org.eclipse.linuxtools.docker.core.IDockerConnection;
-import org.eclipse.linuxtools.docker.core.IDockerPortBinding;
-import org.eclipse.linuxtools.internal.docker.core.DockerPortBinding;
-import org.eclipse.linuxtools.internal.docker.ui.SWTImagesFactory;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.ScrolledComposite;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
-import org.eclipse.swt.layout.FormLayout;
-import org.eclipse.swt.widgets.Button;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Text;
-
-public class ContainerCreatePage extends WizardPage {
-
- private final static String NAME = "ContainerCreate.name"; //$NON-NLS-1$
- private final static String TITLE = "ContainerCreate.title"; //$NON-NLS-1$
- private final static String DESC = "ContainerCreate.desc"; //$NON-NLS-1$
- private final static String CREATE_LABEL = "ContainerCreate.label"; //$NON-NLS-1$
- private final static String IMAGE_LABEL = "Image.label"; //$NON-NLS-1$
- private final static String CMD_LABEL = "Cmd.label"; //$NON-NLS-1$
- private final static String USER_LABEL = "User.label"; //$NON-NLS-1$
- private final static String WORKING_DIR_LABEL = "WorkingDir.label"; //$NON-NLS-1$
- private final static String ENV_LABEL = "Env.label"; //$NON-NLS-1$
- private final static String HOSTNAME_LABEL = "Hostname.label"; //$NON-NLS-1$
- private final static String DOMAINNAME_LABEL = "Domainname.label"; //$NON-NLS-1$
- private final static String MEMORY_LABEL = "Memory.label"; //$NON-NLS-1$
- private final static String MEMORY_SWAP_LABEL = "MemorySwap.label"; //$NON-NLS-1$
- private final static String CPU_SHARES_LABEL = "CpuShares.label"; //$NON-NLS-1$
- private final static String VOLUMES_LABEL = "Volumes.label"; //$NON-NLS-1$
- private final static String PORT_SPECS_LABEL = "PortSpecs.label"; //$NON-NLS-1$
- private final static String EXPOSED_PORTS_LABEL = "ExposedPorts.label"; //$NON-NLS-1$
- private final static String ON_BUILD_LABEL = "OnBuild.label"; //$NON-NLS-1$
- private final static String ENTRY_POINT_LABEL = "EntryPoint.label"; //$NON-NLS-1$
- private final static String CPU_SET_LABEL = "CpuSet.label"; //$NON-NLS-1$
- private final static String ATTACH_STDIN_LABEL = "AttachStdin.label"; //$NON-NLS-1$
- private final static String ATTACH_STDOUT_LABEL = "AttachStdout.label"; //$NON-NLS-1$
- private final static String ATTACH_STDERR_LABEL = "AttachStderr.label"; //$NON-NLS-1$
- private final static String TTY_LABEL = "Tty.label"; //$NON-NLS-1$
- private final static String OPEN_STDIN_LABEL = "OpenStdin.label"; //$NON-NLS-1$
- private final static String STDIN_ONCE_LABEL = "StdinOnce.label"; //$NON-NLS-1$
- private final static String NETWORK_DISABLED_LABEL = "NetworkDisabled.label"; //$NON-NLS-1$
- private final static String PRIVILEGED_LABEL = "Privileged.label"; //$NON-NLS-1$
- private final static String PUBLISH_ALL_LABEL = "PublishAll.label"; //$NON-NLS-1$
- private final static String NETWORK_MODE_LABEL = "NetworkMode.label"; //$NON-NLS-1$
-
- @SuppressWarnings("unused")
- private IDockerConnection connection;
- private String image;
-
- private Text imageText;
- private Text hostnameText;
- private Text domainnameText;
- private Text userText;
- private Text cmdText;
- private Text envText;
- private Text cpuSetText;
- private Text workingDirText;
- private Text portSpecsText;
- private Text exposedPortsText;
- private Text volumesText;
- private Text entryPointText;
- private Text onBuildText;
- private Text networkModeText;
-
- private Text memoryWidget;
- private Text memorySwapWidget;
- private Text cpuSharesWidget;
-
- private Button attachStdinButton;
- private Button attachStdoutButton;
- private Button attachStderrButton;
- private Button ttyButton;
- private Button openStdinButton;
- private Button stdinOnceButton;
- private Button networkDisabledButton;
- private Button privilegedButton;
- private Button publishAllPortsButton;
-
- public ContainerCreatePage(IDockerConnection connection, String image) {
- super(WizardMessages.getString(NAME));
- this.connection = connection;
- this.image = image;
- setDescription(WizardMessages.getString(DESC));
- setTitle(WizardMessages.getString(TITLE));
- setImageDescriptor(SWTImagesFactory.DESC_WIZARD);
- }
-
- public String getImageId() {
- return imageText.getText();
- }
-
- public String getHostName() {
- return hostnameText.getText();
- }
-
- public String getDomainName() {
- return domainnameText.getText();
- }
-
- public String getUser() {
- return userText.getText();
- }
-
- public List<String> getCmd() {
- return getCmdList(cmdText.getText());
- }
-
- private List<String> getCmdList(String s) {
- ArrayList<String> list = new ArrayList<>();
- int length = s.length();
- boolean insideQuote1 = false; // single-quote
- boolean insideQuote2 = false; // double-quote
- boolean escaped = false;
- StringBuffer buffer = new StringBuffer();
- // Parse the string and break it up into chunks that are
- // separated by white-space or are quoted. Ignore characters
- // that have been escaped, including the escape character.
- for (int i = 0; i < length; ++i) {
- char c = s.charAt(i);
- if (escaped) {
- buffer.append(c);
- escaped = false;
- }
- switch (c) {
- case '\'':
- if (!insideQuote2)
- insideQuote1 = insideQuote1 ^ true;
- else
- buffer.append(c);
- break;
- case '\"':
- if (!insideQuote1)
- insideQuote2 = insideQuote2 ^ true;
- else
- buffer.append(c);
- break;
- case '\\':
- escaped = true;
- break;
- case ' ':
- case '\t':
- case '\r':
- case '\n':
- if (insideQuote1 || insideQuote2)
- buffer.append(c);
- else {
- String item = buffer.toString();
- buffer.setLength(0);
- if (item.length() > 0)
- list.add(item);
- }
- break;
- default:
- buffer.append(c);
- break;
- }
- }
- // add last item of string that will be in the buffer
- String item = buffer.toString();
- if (item.length() > 0)
- list.add(item);
- return list;
- }
-
- public List<String> getEnv() {
- return getEnvList(envText.getText());
- }
-
- private List<String> getEnvList(String str) {
- ArrayList<String> envVars = new ArrayList<>();
-
- Pattern p1 = Pattern.compile("(\\w+[=]\\\".*?\\\"\\s*).*"); //$NON-NLS-1$
- Pattern p2 = Pattern.compile("(\\w+[=]'.*?'\\s*).*"); //$NON-NLS-1$
- Pattern p3 = Pattern.compile("(\\w+[=][^\\s]+).*"); //$NON-NLS-1$
- Pattern p4 = Pattern.compile("(\\w+[=][\\s]*$)"); //$NON-NLS-1$
- boolean finished = false;
- while (!finished) {
- Matcher m1 = p1.matcher(str);
- if (m1.matches()) {
- str = str.replaceFirst("\\w+[=]\\\".*?\\\"", "").trim(); //$NON-NLS-1$ //$NON-NLS-2$
- String s = m1.group(1).trim();
- envVars.add(s.replaceAll("\\\"", "")); //$NON-NLS-1$ //$NON-NLS-2$
- } else {
- Matcher m2 = p2.matcher(str);
- if (m2.matches()) {
- str = str.replaceFirst("\\w+[=]'.*?'", "").trim(); //$NON-NLS-1$ //$NON-NLS-2$
- String s = m2.group(1).trim();
- envVars.add(s.replaceAll("'", ""));//$NON-NLS-1$ //$NON-NLS-2$
- } else {
- Matcher m3 = p3.matcher(str);
- if (m3.matches()) {
- str = str.replaceFirst("\\w+[=][^\\s]+", "").trim(); //$NON-NLS-1$ //$NON-NLS-2$
- envVars.add(m3.group(1).trim());
- } else {
- Matcher m4 = p4.matcher(str);
- if (m4.matches()) {
- str = str.replaceFirst("\\w+[=][\\s]*$", "").trim(); //$NON-NLS-1$ //$NON-NLS-2$
- envVars.add(m4.group(1).trim());
- } else {
- finished = true;
- }
- }
- }
- }
- }
- return envVars;
- }
-
- public String getWorkingDir() {
- return workingDirText.getText();
- }
-
- public Long getMemory() {
- return getDigitalValue(memoryWidget.getText());
- }
-
- public Long getMemorySwap() {
- return getDigitalValue(memorySwapWidget.getText());
- }
-
- private Long getDigitalValue(String s) {
- s = s.trim();
- int len = s.length();
- long factor = 1;
- if (len > 0) {
- char c = s.charAt(len - 1);
- boolean foundSpecifier = false;
- switch (c) {
- case 'k':
- factor = 1000;
- foundSpecifier = true;
- break;
- case 'K':
- factor = 1024;
- foundSpecifier = true;
- break;
- case 'm':
- factor = 1000000;
- foundSpecifier = true;
- break;
- case 'M':
- factor = 1024 * 1024;
- foundSpecifier = true;
- break;
- case 'g':
- factor = 1000000000;
- foundSpecifier = true;
- break;
- case 'G':
- factor = 1024 * 1024 * 1024;
- foundSpecifier = true;
- break;
- case 't':
- factor = 1000000000000L;
- foundSpecifier = true;
- break;
- case 'T':
- factor = 1024 * 1024 * 1024 * 1024;
- foundSpecifier = true;
- break;
- }
- if (foundSpecifier) {
- s = s.substring(len - 1);
- }
- }
- return Long.valueOf(Long.parseLong(s) * factor);
- }
-
- public Long getCpuShares() {
- return Long.valueOf(cpuSharesWidget.getText());
- }
-
- public String getCpuSet() {
- return cpuSetText.getText();
- }
-
- public Boolean getAttachStdin() {
- return attachStdinButton.getSelection();
- }
-
- public Boolean getAttachStdout() {
- return attachStdoutButton.getSelection();
- }
-
- public Boolean getAttachStderr() {
- return attachStderrButton.getSelection();
- }
-
- public Boolean getTty() {
- return ttyButton.getSelection();
- }
-
- public Boolean getOpenStdin() {
- return openStdinButton.getSelection();
- }
-
- public Boolean getStdinOnce() {
- return stdinOnceButton.getSelection();
- }
-
- public Boolean getNetworkDisabled() {
- return networkDisabledButton.getSelection();
- }
-
- public Boolean getPrivileged() {
- return privilegedButton.getSelection();
- }
-
- public Boolean getPublishAllPorts() {
- return publishAllPortsButton.getSelection();
- }
-
- public String getNetworkMode() {
- return networkModeText.getText();
- }
-
- public Set<String> getVolumes() {
- String s = volumesText.getText().trim();
- if (s.length() == 0)
- return null;
- Set<String> volumeSet = new HashSet<>();
- String[] volumes = s.split("\\s+");
- for (String volume : volumes) {
- volume = volume.trim();
- if (volume.length() > 0 && !volume.contains(":")) //$NON-NLS-1$
- volumeSet.add(volume);
- }
- return volumeSet;
- }
-
- public List<String> getHostVolumes() {
- String s = volumesText.getText().trim();
- if (s.length() == 0)
- return null;
- List<String> hostVolumes = new ArrayList<>();
- String[] volumes = s.split("\\s+");
- for (String volume : volumes) {
- volume = volume.trim();
- if (volume.length() > 0 && volume.contains(":")) //$NON-NLS-1$
- hostVolumes.add(volume);
- }
- return hostVolumes;
- }
-
- public List<String> getPortSpecs() {
- String s = portSpecsText.getText().trim();
- if (s.length() == 0)
- return null;
- List<String> specList = new ArrayList<>();
- String[] specs = s.split("\\s+");
- for (String spec : specs) {
- spec = spec.trim();
- if (spec.length() > 0)
- specList.add(spec);
- }
- return specList;
- }
-
- public Set<String> getExposedPorts() {
- String s = exposedPortsText.getText().trim();
- if (s.length() == 0)
- return null;
- Set<String> exposedPortsSet = new HashSet<>();
- String[] exposedPorts = s.split("\\s+");
- for (String exposedPort : exposedPorts) {
- exposedPort = exposedPort.trim();
- if (exposedPort.length() > 0) {
- String[] segments = exposedPort.split(":"); //$NON-NLS-1$
- if (segments.length == 1) { // containerPort
- exposedPortsSet.add(segments[0]);
- } else if (segments.length == 2) { // hostPort:containerPort
- exposedPortsSet.add(segments[1]);
- } else if (segments.length == 3) { // either
- // ip:hostPort:containerPort
- // or ip::containerPort
- exposedPortsSet.add(segments[2]);
- }
- }
- }
- return exposedPortsSet;
- }
-
- public Map<String, List<IDockerPortBinding>> getPortBindings() {
- String s = exposedPortsText.getText().trim();
- if (s.length() == 0)
- return null;
- Map<String, List<IDockerPortBinding>> portBindingsMap = new HashMap<>();
- String[] exposedPorts = s.split("\\s+");
- for (String exposedPort : exposedPorts) {
- exposedPort = exposedPort.trim();
- if (exposedPort.length() > 0) {
- String[] segments = exposedPort.split(":"); //$NON-NLS-1$
- if (segments.length == 1) { // containerPort
- portBindingsMap.put(segments[0], Arrays
- .asList((IDockerPortBinding) new DockerPortBinding(
- "", ""))); //$NON-NLS-1$ //$NON-NLS-2$
- } else if (segments.length == 2) { // hostPort:containerPort
- portBindingsMap.put(segments[1], Arrays
- .asList((IDockerPortBinding) new DockerPortBinding(
- "", segments[0]))); //$NON-NLS-1$ //$NON-NLS-2$
- } else if (segments.length == 3) { // either
- // ip:hostPort:containerPort
- // or ip::containerPort
- if (segments[1].isEmpty()) {
- portBindingsMap
- .put(segments[2],
- Arrays.asList((IDockerPortBinding) new DockerPortBinding(
- "", segments[0]))); //$NON-NLS-1$ //$NON-NLS-2$
- } else {
- portBindingsMap
- .put(segments[2],
- Arrays.asList((IDockerPortBinding) new DockerPortBinding(
- segments[0], segments[1]))); //$NON-NLS-1$ //$NON-NLS-2$
- }
- }
- }
- }
- return portBindingsMap;
- }
-
- public List<String> getOnBuild() {
- String s = onBuildText.getText().trim();
- if (s.length() == 0)
- return null;
- List<String> onBuildList = new ArrayList<>();
- String[] onBuildStrings = s.split("\\s+");
- for (String onBuildString : onBuildStrings) {
- onBuildString = onBuildString.trim();
- if (onBuildString.length() > 0)
- onBuildList.add(onBuildString);
- }
- return onBuildList;
- }
-
- public List<String> getEntryPoint() {
- String s = entryPointText.getText().trim();
- if (s.length() == 0)
- return null;
- List<String> entryPointList = new ArrayList<>();
- String[] entryPoints = s.split("\\s+");
- for (String entryPoint : entryPoints) {
- entryPoint = entryPoint.trim();
- if (entryPoint.length() > 0)
- entryPointList.add(entryPoint);
- }
- return entryPointList;
- }
-
- private ModifyListener Listener = new ModifyListener() {
-
- @Override
- public void modifyText(ModifyEvent e) {
- // TODO Auto-generated method stub
- validate();
- }
- };
-
- private void validate() {
- boolean complete = true;
- boolean error = false;
-
- if (imageText.getText().length() == 0)
- complete = false;
- if (!error)
- setErrorMessage(null);
- setPageComplete(complete && !error);
- }
-
- @Override
- public void createControl(Composite parent) {
- final ScrolledComposite sc = new ScrolledComposite(parent, SWT.V_SCROLL);
- final Composite container = new Composite(sc, SWT.NULL);
- sc.setContent(container);
- FormLayout layout = new FormLayout();
- layout.marginHeight = 5;
- layout.marginWidth = 5;
- container.setLayout(layout);
-
- Label label = new Label(container, SWT.NULL);
- label.setText(WizardMessages.getString(CREATE_LABEL));
-
- Label imageLabel = new Label(container, SWT.NULL);
- imageLabel.setText(WizardMessages.getString(IMAGE_LABEL));
-
- imageText = new Text(container, SWT.BORDER | SWT.SINGLE);
- if (image != null) {
- imageText.setText(image);
- imageText.setEditable(false);
- }
- imageText.addModifyListener(Listener);
-
- Label cmdLabel = new Label(container, SWT.NULL);
- cmdLabel.setText(WizardMessages.getString(CMD_LABEL));
-
- cmdText = new Text(container, SWT.BORDER | SWT.SINGLE);
- cmdText.addModifyListener(Listener);
-
- Label userLabel = new Label(container, SWT.NULL);
- userLabel.setText(WizardMessages.getString(USER_LABEL));
-
- userText = new Text(container, SWT.BORDER | SWT.SINGLE);
- userText.addModifyListener(Listener);
-
- Label workingDirLabel = new Label(container, SWT.NULL);
- workingDirLabel.setText(WizardMessages.getString(WORKING_DIR_LABEL));
-
- workingDirText = new Text(container, SWT.BORDER | SWT.SINGLE);
- workingDirText.addModifyListener(Listener);
-
- Label envLabel = new Label(container, SWT.NULL);
- envLabel.setText(WizardMessages.getString(ENV_LABEL));
-
- envText = new Text(container, SWT.BORDER | SWT.SINGLE);
- envText.addModifyListener(Listener);
-
- Label hostnameLabel = new Label(container, SWT.NULL);
- hostnameLabel.setText(WizardMessages.getString(HOSTNAME_LABEL));
-
- hostnameText = new Text(container, SWT.BORDER | SWT.SINGLE);
- hostnameText.addModifyListener(Listener);
-
- Label domainnameLabel = new Label(container, SWT.NULL);
- domainnameLabel.setText(WizardMessages.getString(DOMAINNAME_LABEL));
-
- domainnameText = new Text(container, SWT.BORDER | SWT.SINGLE);
- domainnameText.addModifyListener(Listener);
-
- Label memoryLabel = new Label(container, SWT.NULL);
- memoryLabel.setText(WizardMessages.getString(MEMORY_LABEL));
-
- memoryWidget = new Text(container, SWT.BORDER | SWT.SINGLE);
- memoryWidget.setText("0"); //$NON-NLS-1$
- memoryWidget.addModifyListener(Listener);
-
- Label memorySwapLabel = new Label(container, SWT.NULL);
- memorySwapLabel.setText(WizardMessages.getString(MEMORY_SWAP_LABEL));
-
- memorySwapWidget = new Text(container, SWT.BORDER | SWT.SINGLE);
- memorySwapWidget.setText("0"); //$NON-NLS-1$
- memorySwapWidget.addModifyListener(Listener);
-
- Label cpuSharesLabel = new Label(container, SWT.NULL);
- cpuSharesLabel.setText(WizardMessages.getString(CPU_SHARES_LABEL));
-
- cpuSharesWidget = new Text(container, SWT.BORDER | SWT.SINGLE);
- cpuSharesWidget.setText("0"); //$NON-NLS-1$
- cpuSharesWidget.addModifyListener(Listener);
-
- Label cpuSetLabel = new Label(container, SWT.NULL);
- cpuSetLabel.setText(WizardMessages.getString(CPU_SET_LABEL));
-
- cpuSetText = new Text(container, SWT.BORDER | SWT.SINGLE);
- cpuSetText.addModifyListener(Listener);
-
- Label volumesLabel = new Label(container, SWT.NULL);
- volumesLabel.setText(WizardMessages.getString(VOLUMES_LABEL));
-
- volumesText = new Text(container, SWT.BORDER | SWT.SINGLE);
- volumesText.addModifyListener(Listener);
-
- Label portSpecsLabel = new Label(container, SWT.NULL);
- portSpecsLabel.setText(WizardMessages.getString(PORT_SPECS_LABEL));
-
- portSpecsText = new Text(container, SWT.BORDER | SWT.SINGLE);
- portSpecsText.addModifyListener(Listener);
-
- Label exposedPortsLabel = new Label(container, SWT.NULL);
- exposedPortsLabel
- .setText(WizardMessages.getString(EXPOSED_PORTS_LABEL));
-
- exposedPortsText = new Text(container, SWT.BORDER | SWT.SINGLE);
- exposedPortsText.addModifyListener(Listener);
-
- Label onBuildLabel = new Label(container, SWT.NULL);
- onBuildLabel.setText(WizardMessages.getString(ON_BUILD_LABEL));
-
- onBuildText = new Text(container, SWT.BORDER | SWT.SINGLE);
- onBuildText.addModifyListener(Listener);
-
- Label entryPointLabel = new Label(container, SWT.NULL);
- entryPointLabel.setText(WizardMessages.getString(ENTRY_POINT_LABEL));
-
- entryPointText = new Text(container, SWT.BORDER | SWT.SINGLE);
- entryPointText.addModifyListener(Listener);
-
- Label networkModeLabel = new Label(container, SWT.NULL);
- networkModeLabel.setText(WizardMessages.getString(NETWORK_MODE_LABEL));
-
- networkModeText = new Text(container, SWT.BORDER | SWT.SINGLE);
- networkModeText.addModifyListener(Listener);
-
- attachStdinButton = new Button(container, SWT.CHECK);
- attachStdinButton.setText(WizardMessages.getString(ATTACH_STDIN_LABEL));
-
- attachStdoutButton = new Button(container, SWT.CHECK);
- attachStdoutButton.setText(WizardMessages
- .getString(ATTACH_STDOUT_LABEL));
-
- attachStderrButton = new Button(container, SWT.CHECK);
- attachStderrButton.setText(WizardMessages
- .getString(ATTACH_STDERR_LABEL));
-
- ttyButton = new Button(container, SWT.CHECK);
- ttyButton.setText(WizardMessages.getString(TTY_LABEL));
-
- openStdinButton = new Button(container, SWT.CHECK);
- openStdinButton.setText(WizardMessages.getString(OPEN_STDIN_LABEL));
-
- stdinOnceButton = new Button(container, SWT.CHECK);
- stdinOnceButton.setText(WizardMessages.getString(STDIN_ONCE_LABEL));
-
- networkDisabledButton = new Button(container, SWT.CHECK);
- networkDisabledButton.setText(WizardMessages
- .getString(NETWORK_DISABLED_LABEL));
-
- privilegedButton = new Button(container, SWT.CHECK);
- privilegedButton.setText(WizardMessages.getString(PRIVILEGED_LABEL));
-
- publishAllPortsButton = new Button(container, SWT.CHECK);
- publishAllPortsButton.setText(WizardMessages
- .getString(PUBLISH_ALL_LABEL));
-
- Point p1 = label.computeSize(SWT.DEFAULT, SWT.DEFAULT);
- Point p2 = imageText.computeSize(SWT.DEFAULT, SWT.DEFAULT);
- int centering = (p2.y - p1.y + 1) / 2;
-
- FormData f = new FormData();
- f.top = new FormAttachment(0);
- label.setLayoutData(f);
-
- Control prevControl = label;
- Control longestLabel = workingDirLabel;
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(0, 0);
- imageLabel.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11);
- f.left = new FormAttachment(longestLabel, 5);
- f.right = new FormAttachment(100);
- imageText.setLayoutData(f);
-
- prevControl = imageLabel;
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(0, 0);
- cmdLabel.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11);
- f.left = new FormAttachment(longestLabel, 5);
- f.right = new FormAttachment(100);
- cmdText.setLayoutData(f);
-
- prevControl = cmdLabel;
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(0, 0);
- userLabel.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11);
- f.left = new FormAttachment(longestLabel, 5);
- f.right = new FormAttachment(100);
- userText.setLayoutData(f);
-
- prevControl = userLabel;
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(0, 0);
- workingDirLabel.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11);
- f.left = new FormAttachment(longestLabel, 5);
- f.right = new FormAttachment(100);
- workingDirText.setLayoutData(f);
-
- prevControl = workingDirLabel;
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(0, 0);
- envLabel.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11);
- f.left = new FormAttachment(longestLabel, 5);
- f.right = new FormAttachment(100);
- envText.setLayoutData(f);
-
- prevControl = envLabel;
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(0, 0);
- hostnameLabel.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11);
- f.left = new FormAttachment(longestLabel, 5);
- f.right = new FormAttachment(100);
- hostnameText.setLayoutData(f);
-
- prevControl = hostnameLabel;
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(0, 0);
- domainnameLabel.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11);
- f.left = new FormAttachment(longestLabel, 5);
- f.right = new FormAttachment(100);
- domainnameText.setLayoutData(f);
-
- prevControl = domainnameLabel;
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(0, 0);
- memoryLabel.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11);
- f.left = new FormAttachment(longestLabel, 5);
- f.right = new FormAttachment(100);
- memoryWidget.setLayoutData(f);
-
- prevControl = memoryLabel;
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(0, 0);
- memorySwapLabel.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11);
- f.left = new FormAttachment(longestLabel, 5);
- f.right = new FormAttachment(100);
- memorySwapWidget.setLayoutData(f);
-
- prevControl = memorySwapLabel;
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(0, 0);
- cpuSharesLabel.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11);
- f.left = new FormAttachment(longestLabel, 5);
- f.right = new FormAttachment(100);
- cpuSharesWidget.setLayoutData(f);
-
- prevControl = cpuSharesLabel;
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(0, 0);
- cpuSetLabel.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11);
- f.left = new FormAttachment(longestLabel, 5);
- f.right = new FormAttachment(100);
- cpuSetText.setLayoutData(f);
-
- prevControl = cpuSetLabel;
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(0, 0);
- volumesLabel.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11);
- f.left = new FormAttachment(longestLabel, 5);
- f.right = new FormAttachment(100);
- volumesText.setLayoutData(f);
-
- prevControl = volumesLabel;
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(0, 0);
- portSpecsLabel.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11);
- f.left = new FormAttachment(longestLabel, 5);
- f.right = new FormAttachment(100);
- portSpecsText.setLayoutData(f);
-
- prevControl = portSpecsLabel;
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(0, 0);
- exposedPortsLabel.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11);
- f.left = new FormAttachment(longestLabel, 5);
- f.right = new FormAttachment(100);
- exposedPortsText.setLayoutData(f);
-
- prevControl = exposedPortsLabel;
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(0, 0);
- onBuildLabel.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11);
- f.left = new FormAttachment(longestLabel, 5);
- f.right = new FormAttachment(100);
- onBuildText.setLayoutData(f);
-
- prevControl = onBuildLabel;
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(0, 0);
- entryPointLabel.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11);
- f.left = new FormAttachment(longestLabel, 5);
- f.right = new FormAttachment(100);
- entryPointText.setLayoutData(f);
-
- prevControl = entryPointLabel;
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(0, 0);
- networkModeLabel.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11);
- f.left = new FormAttachment(longestLabel, 5);
- f.right = new FormAttachment(100);
- networkModeText.setLayoutData(f);
-
- prevControl = networkModeLabel;
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(0, 0);
- attachStdinButton.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(attachStdinButton, 10);
- attachStdoutButton.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(attachStdoutButton, 10);
- attachStderrButton.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(attachStderrButton, 10);
- ttyButton.setLayoutData(f);
-
- prevControl = attachStdinButton;
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(0, 0);
- openStdinButton.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(openStdinButton, 10);
- stdinOnceButton.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(stdinOnceButton, 10);
- networkDisabledButton.setLayoutData(f);
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(networkDisabledButton, 0);
- privilegedButton.setLayoutData(f);
-
- prevControl = openStdinButton;
-
- f = new FormData();
- f.top = new FormAttachment(prevControl, 11 + centering);
- f.left = new FormAttachment(0, 0);
- publishAllPortsButton.setLayoutData(f);
-
- container.setSize(container.computeSize(SWT.DEFAULT, SWT.DEFAULT));
-
- setControl(sc);
- setPageComplete(false);
- cmdText.setFocus();
- }
-}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerDataVolumeDialog.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerDataVolumeDialog.java
new file mode 100644
index 0000000000..4740f59514
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerDataVolumeDialog.java
@@ -0,0 +1,398 @@
+/*******************************************************************************
+ * 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.ui.wizards;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.databinding.Binding;
+import org.eclipse.core.databinding.DataBindingContext;
+import org.eclipse.core.databinding.UpdateValueStrategy;
+import org.eclipse.core.databinding.beans.BeanProperties;
+import org.eclipse.core.databinding.observable.ChangeEvent;
+import org.eclipse.core.databinding.observable.IChangeListener;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.databinding.validation.ValidationStatus;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.databinding.swt.ISWTObservableValue;
+import org.eclipse.jface.databinding.swt.WidgetProperties;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.fieldassist.ComboContentAdapter;
+import org.eclipse.jface.fieldassist.ContentProposal;
+import org.eclipse.jface.fieldassist.ContentProposalAdapter;
+import org.eclipse.jface.fieldassist.ControlDecoration;
+import org.eclipse.jface.fieldassist.IContentProposal;
+import org.eclipse.jface.fieldassist.IContentProposalProvider;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.linuxtools.docker.core.IDockerConnection;
+import org.eclipse.linuxtools.docker.core.IDockerContainer;
+import org.eclipse.linuxtools.docker.core.IDockerContainerInfo;
+import org.eclipse.linuxtools.internal.docker.ui.SWTImagesFactory;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunResourceVolumesVariablesModel.MountType;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * @author xcoulon
+ *
+ */
+public class ContainerDataVolumeDialog extends Dialog {
+
+ private final DataVolumeModel model;
+
+ private final DataBindingContext dbc = new DataBindingContext();
+
+ private final List<String> containerNames;
+
+ private final IDockerConnection connection;
+
+ protected ContainerDataVolumeDialog(final Shell parentShell,
+ final IDockerConnection connection,
+ final DataVolumeModel selectedDataVolume) {
+ super(parentShell);
+ this.connection = connection;
+ this.model = new DataVolumeModel(selectedDataVolume);
+ this.containerNames = WizardUtils.getContainerNames(connection);
+ }
+
+ protected ContainerDataVolumeDialog(final Shell parentShell,
+ final IDockerConnection connection) {
+ super(parentShell);
+ this.connection = connection;
+ this.model = new DataVolumeModel();
+ this.containerNames = WizardUtils.getContainerNames(connection);
+ }
+
+ public DataVolumeModel getDataVolume() {
+ return model;
+ }
+
+ @Override
+ protected void configureShell(final Shell shell) {
+ super.configureShell(shell);
+ setShellStyle(getShellStyle() | SWT.RESIZE);
+ shell.setText("Data Volume");
+ }
+
+ @Override
+ protected Point getInitialSize() {
+ return new Point(450, super.getInitialSize().y);
+ }
+
+ @Override
+ protected Control createDialogArea(final Composite parent) {
+ final Composite container = new Composite(parent, SWT.NONE);
+ final int COLUMNS = 3;
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).span(1, 1)
+ .grab(true, true).applyTo(container);
+ GridLayoutFactory.fillDefaults().margins(6, 6).numColumns(COLUMNS)
+ .applyTo(container);
+ final Label explanationLabel = new Label(container, SWT.NONE);
+ explanationLabel.setText("Specify the Data Volume to mount:"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .span(COLUMNS, 1).grab(true, false).applyTo(explanationLabel);
+
+ // No mount
+ final Button noMountButton = new Button(container, SWT.RADIO);
+ noMountButton.setText("No external mount");
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .span(COLUMNS, 1).grab(true, false).applyTo(noMountButton);
+ bindButton(noMountButton, MountType.NONE);
+ // File System mount
+ final Button fileSystemMountButton = new Button(container, SWT.RADIO);
+ fileSystemMountButton.setText("Mount a host directory or host file");
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .span(COLUMNS, 1).grab(true, false)
+ .applyTo(fileSystemMountButton);
+ final Label hostPathLabel = new Label(container, SWT.NONE);
+ hostPathLabel.setText("Path:"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .indent(20, SWT.DEFAULT).grab(false, false)
+ .applyTo(hostPathLabel);
+ final Text hostPathText = new Text(container, SWT.BORDER);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).applyTo(hostPathText);
+ final IObservableValue hostPathObservable = BeanProperties
+ .value(DataVolumeModel.class, DataVolumeModel.HOST_PATH_MOUNT)
+ .observe(model);
+ dbc.bindValue(WidgetProperties.text(SWT.Modify).observe(hostPathText),
+ hostPathObservable);
+
+ final Button hostPathBrowseButton = new Button(container, SWT.NONE);
+ hostPathBrowseButton.setText("Browse...");
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(hostPathBrowseButton);
+ hostPathBrowseButton.addSelectionListener(onHostPathBrowse());
+ // optional read-only access
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(new Label(container, SWT.NONE));
+ final Button readOnlyButton = new Button(container, SWT.CHECK);
+ readOnlyButton.setText("Read-only access"); //$NON-NLS-1$
+ readOnlyButton.setToolTipText(
+ "Specify if the mounted host directory or path is read-only"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .span(COLUMNS - 1, 1).grab(true, false).applyTo(readOnlyButton);
+ final ISWTObservableValue readOnlyButtonObservable = WidgetProperties
+ .selection().observe(readOnlyButton);
+ dbc.bindValue(readOnlyButtonObservable,
+ BeanProperties
+ .value(DataVolumeModel.class,
+ DataVolumeModel.READ_ONLY_VOLUME)
+ .observe(model));
+ bindButton(fileSystemMountButton, MountType.HOST_FILE_SYSTEM,
+ hostPathText, hostPathBrowseButton, readOnlyButton);
+
+ // Container mount
+ final Button containerMountButton = new Button(container, SWT.RADIO);
+ containerMountButton.setText("Mount a data volume container");
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .span(COLUMNS, 1).grab(true, false)
+ .applyTo(containerMountButton);
+ final Label containerSelectionLabel = new Label(container, SWT.NONE);
+ containerSelectionLabel.setText("Container:"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .indent(20, SWT.DEFAULT).applyTo(containerSelectionLabel);
+ final Combo containerSelectionCombo = new Combo(container, SWT.BORDER);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).span(1, 1).applyTo(containerSelectionCombo);
+ new ControlDecoration(containerSelectionCombo, SWT.TOP | SWT.LEFT);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(new Label(container, SWT.NONE));
+ bindButton(containerMountButton, MountType.CONTAINER,
+ containerSelectionCombo);
+ final ComboViewer containerSelectionComboViewer = new ComboViewer(
+ containerSelectionCombo);
+ containerSelectionComboViewer
+ .setContentProvider(new ArrayContentProvider());
+ containerSelectionComboViewer.setInput(this.containerNames);
+ final IObservableValue selectedContainerObservable = BeanProperties
+ .value(DataVolumeModel.class, DataVolumeModel.CONTAINER_MOUNT)
+ .observe(model);
+ dbc.bindValue(
+ WidgetProperties.selection().observe(containerSelectionCombo),
+ selectedContainerObservable);
+ new ContentProposalAdapter(containerSelectionCombo,
+ new ComboContentAdapter() {
+ @Override
+ public void insertControlContents(Control control,
+ String text, int cursorPosition) {
+ final Combo combo = (Combo) control;
+ final Point selection = combo.getSelection();
+ combo.setText(text);
+ selection.x = text.length();
+ selection.y = selection.x;
+ combo.setSelection(selection);
+ }
+ }, getContainerNameContentProposalProvider(
+ containerSelectionCombo),
+ null, null);
+
+ // error message
+ final Composite errorContainer = new Composite(container, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL)
+ .span(COLUMNS, 1).grab(true, true).applyTo(errorContainer);
+ GridLayoutFactory.fillDefaults().margins(6, 6).numColumns(2)
+ .applyTo(errorContainer);
+
+ final Label errorMessageIcon = new Label(errorContainer, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .hint(20, SWT.DEFAULT)
+ .applyTo(errorMessageIcon);
+ final Label errorMessageLabel = new Label(errorContainer, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false)
+ .applyTo(errorMessageLabel);
+ setupValidationSupport(errorMessageIcon, errorMessageLabel);
+ return container;
+ }
+
+ private void setupValidationSupport(final Label errorMessageIcon,
+ final Label errorMessageLabel) {
+ for (@SuppressWarnings("unchecked")
+ Iterator<Binding> iterator = dbc.getBindings().iterator(); iterator
+ .hasNext();) {
+ final Binding binding = iterator.next();
+ binding.getModel().addChangeListener(onDataVolumeSettingsChanged(
+ errorMessageIcon, errorMessageLabel));
+
+ }
+ }
+
+ /**
+ * Binds the given {@link MountType} to the given {@link Button} when it is
+ * selected, and set the enablement of the associated {@link Control} at the
+ * same time (ie: the {@link Control} are only enabled when the given
+ * {@link Button} is selected.
+ *
+ * @param button
+ * the {@link Button} to bind
+ * @param mountType
+ * the {@link MountType} to bind to the {@link Button}
+ * @param controls
+ * the {@link Control}s to enable or disable when the Button is
+ * selected/unselected.
+ * @return
+ */
+ private Binding bindButton(final Button button, final MountType mountType,
+ final Control... controls) {
+ return dbc.bindValue(WidgetProperties.selection().observe(button),
+ BeanProperties.value(DataVolumeModel.class,
+ DataVolumeModel.MOUNT_TYPE).observe(model),
+ new UpdateValueStrategy() {
+ @Override
+ public Object convert(Object value) {
+ if (value.equals(Boolean.TRUE)) {
+ setEnabled(controls, true);
+ return mountType;
+ }
+ setEnabled(controls, false);
+ return null;
+ }
+
+ private void setEnabled(final Control[] controls,
+ final boolean enabled) {
+ for (Control control : controls) {
+ control.setEnabled(enabled);
+ }
+ }
+ }, new UpdateValueStrategy() {
+ @Override
+ public Object convert(final Object value) {
+ if (mountType.equals(value)) {
+ button.setEnabled(true);
+ }
+ return mountType.equals(value);
+ }
+ });
+ }
+
+ private SelectionListener onHostPathBrowse() {
+ return new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ final FileDialog fileDialog = new FileDialog(getShell());
+ final String selectedPath = fileDialog.open();
+ if (selectedPath != null) {
+ model.setHostPathMount(selectedPath);
+ }
+ }
+ };
+ }
+
+ /**
+ * Creates an {@link IContentProposalProvider} to propose
+ * {@link IDockerContainer} names based on the current text.
+ *
+ * @param items
+ * @return
+ */
+ private IContentProposalProvider getContainerNameContentProposalProvider(
+ final Combo containerSelectionCombo) {
+ return new IContentProposalProvider() {
+
+ @Override
+ public IContentProposal[] getProposals(final String contents,
+ final int position) {
+ final List<IContentProposal> proposals = new ArrayList<IContentProposal>();
+ for (String containerName : containerSelectionCombo
+ .getItems()) {
+ if (containerName.contains(contents)) {
+ proposals.add(new ContentProposal(containerName,
+ containerName, containerName, position));
+ }
+ }
+ return proposals.toArray(new IContentProposal[0]);
+ }
+ };
+ }
+
+ private IChangeListener onDataVolumeSettingsChanged(
+ final Label errorMessageIcon, final Label errorMessageLabel) {
+
+ return new IChangeListener() {
+
+ @Override
+ public void handleChange(ChangeEvent event) {
+ final IStatus status = validateInput(errorMessageLabel);
+ if (status.isOK()) {
+ errorMessageIcon.setVisible(false);
+ errorMessageLabel.setVisible(false);
+ setOkButtonEnabled(true);
+ } else if (status.matches(IStatus.WARNING)) {
+ errorMessageIcon.setVisible(true);
+ errorMessageIcon.setImage(
+ SWTImagesFactory.DESC_WARNING.createImage());
+ errorMessageLabel.setVisible(true);
+ errorMessageLabel.setText(status.getMessage());
+ setOkButtonEnabled(true);
+ } else if (status.matches(IStatus.ERROR)) {
+ errorMessageIcon.setVisible(true);
+ errorMessageIcon.setImage(
+ SWTImagesFactory.DESC_ERROR.createImage());
+ errorMessageLabel.setVisible(true);
+ errorMessageLabel.setText(status.getMessage());
+ setOkButtonEnabled(true);
+ }
+ }
+ };
+ }
+
+ private IStatus validateInput(final Label errorMessageLabel) {
+ final MountType mountType = model.getMountType();
+ final String hostPath = model.getHostPathMount();
+ if (mountType == MountType.HOST_FILE_SYSTEM
+ && (hostPath == null || hostPath.isEmpty())) {
+ return ValidationStatus.ok();
+ } else if (mountType == MountType.HOST_FILE_SYSTEM
+ && !new File(hostPath).exists()) {
+ return ValidationStatus
+ .warning("The specified path does not exist on the host."); //$NON-NLS-1$
+ } else if (mountType == MountType.CONTAINER) {
+ final IDockerContainer container = WizardUtils
+ .getContainer(connection, model.getContainerMount());
+ if (container == null) {
+ return ValidationStatus.error("");
+ }
+ final IDockerContainerInfo selectedContainerInfo = container.info();
+ if (!selectedContainerInfo.volumes()
+ .containsKey(model.getContainerPath())) {
+ return ValidationStatus
+ .warning("The selected container does not define a "
+ + model.getContainerPath() + " volume."); //$NON-NLS-1$
+ }
+ }
+ return ValidationStatus.ok();
+ }
+
+ private void setOkButtonEnabled(final boolean enabled) {
+ getButton(IDialogConstants.OK_ID).setEnabled(enabled);
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerEnvironmentVariableDialog.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerEnvironmentVariableDialog.java
new file mode 100644
index 0000000000..60539cfcb5
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerEnvironmentVariableDialog.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * 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.ui.wizards;
+
+import org.eclipse.core.databinding.DataBindingContext;
+import org.eclipse.core.databinding.beans.BeanProperties;
+import org.eclipse.core.databinding.observable.value.IValueChangeListener;
+import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
+import org.eclipse.jface.databinding.swt.ISWTObservableValue;
+import org.eclipse.jface.databinding.swt.WidgetProperties;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * @author xcoulon
+ *
+ */
+public class ContainerEnvironmentVariableDialog extends Dialog {
+
+ private final EnvironmentVariableModel model;
+
+ private final DataBindingContext dbc = new DataBindingContext();
+
+ protected ContainerEnvironmentVariableDialog(final Shell parentShell) {
+ super(parentShell);
+ this.model = new EnvironmentVariableModel();
+ }
+
+ public ContainerEnvironmentVariableDialog(final Shell parentShell,
+ final EnvironmentVariableModel selectedVariable) {
+ super(parentShell);
+ this.model = new EnvironmentVariableModel(selectedVariable);
+ }
+
+ @Override
+ protected void configureShell(final Shell shell) {
+ super.configureShell(shell);
+ setShellStyle(getShellStyle() | SWT.RESIZE);
+ shell.setText("Environment Variable");
+ }
+
+ @Override
+ protected Point getInitialSize() {
+ return new Point(400, super.getInitialSize().y);
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ final int COLUMNS = 2;
+ final Composite container = new Composite(parent, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL)
+ .span(COLUMNS, 1).grab(true, true).applyTo(container);
+ GridLayoutFactory.fillDefaults().numColumns(COLUMNS).margins(6, 6)
+ .applyTo(container);
+ final Label explanationLabel = new Label(container, SWT.NONE);
+ explanationLabel
+ .setText("Specify the environment variable name and value:"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .span(COLUMNS, 1).grab(false, false).applyTo(explanationLabel);
+ final Label variableNameLabel = new Label(container, SWT.NONE);
+ variableNameLabel.setText("Name:"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(variableNameLabel);
+ final Text variableNameText = new Text(container, SWT.BORDER);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).applyTo(variableNameText);
+ final Label variableValueLabel = new Label(container, SWT.NONE);
+ variableValueLabel.setText("Host address:"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(variableValueLabel);
+ final Text variableValueText = new Text(container, SWT.BORDER);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).applyTo(variableValueText);
+ // error message
+ final Label errorMessageLabel = new Label(container, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .span(COLUMNS, 1).grab(true, false).applyTo(errorMessageLabel);
+
+ // listening to changes
+ final ISWTObservableValue variableNameObservable = WidgetProperties
+ .text(SWT.Modify).observe(variableNameText);
+ dbc.bindValue(variableNameObservable,
+ BeanProperties.value(EnvironmentVariableModel.class,
+ EnvironmentVariableModel.NAME).observe(model));
+ final ISWTObservableValue variableValueObservable = WidgetProperties
+ .text(SWT.Modify).observe(variableValueText);
+ dbc.bindValue(variableValueObservable,
+ BeanProperties.value(EnvironmentVariableModel.class,
+ EnvironmentVariableModel.VALUE).observe(model));
+
+ variableNameObservable
+ .addValueChangeListener(onEnvironmentVariableSettingsChanged());
+ variableValueObservable
+ .addValueChangeListener(onEnvironmentVariableSettingsChanged());
+ return container;
+ }
+
+ private IValueChangeListener onEnvironmentVariableSettingsChanged() {
+ return new IValueChangeListener() {
+
+ @Override
+ public void handleValueChange(ValueChangeEvent event) {
+ validateInput();
+ }
+ };
+ }
+
+ private void validateInput() {
+ final String variableName = model.getName();
+ final String variableValue = model.getValue();
+ if (variableName == null || variableName.isEmpty()
+ || variableValue == null || variableValue.isEmpty()) {
+ setOkButtonEnabled(false);
+ } else {
+ setOkButtonEnabled(true);
+ }
+ }
+
+ private void setOkButtonEnabled(final boolean enabled) {
+ getButton(IDialogConstants.OK_ID).setEnabled(enabled);
+ }
+
+ public EnvironmentVariableModel getEnvironmentVariable() {
+ return new EnvironmentVariableModel(model.getName(), model.getValue());
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerLinkDialog.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerLinkDialog.java
new file mode 100644
index 0000000000..fcb4c64abc
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerLinkDialog.java
@@ -0,0 +1,337 @@
+/*******************************************************************************
+ * 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.ui.wizards;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.databinding.DataBindingContext;
+import org.eclipse.core.databinding.beans.BeanProperties;
+import org.eclipse.core.databinding.observable.value.IValueChangeListener;
+import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
+import org.eclipse.jface.databinding.swt.ISWTObservableValue;
+import org.eclipse.jface.databinding.swt.WidgetProperties;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.fieldassist.ComboContentAdapter;
+import org.eclipse.jface.fieldassist.ContentProposal;
+import org.eclipse.jface.fieldassist.ContentProposalAdapter;
+import org.eclipse.jface.fieldassist.IContentProposal;
+import org.eclipse.jface.fieldassist.IContentProposalProvider;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.linuxtools.docker.core.IDockerConnection;
+import org.eclipse.linuxtools.docker.core.IDockerContainer;
+import org.eclipse.linuxtools.internal.docker.ui.databinding.BaseDatabindingModel;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunSelectionModel.ContainerLinkModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * @author xcoulon
+ *
+ */
+public class ContainerLinkDialog extends Dialog {
+
+ private final IDockerConnection connection;
+
+ private final ContainerLinkDialogModel model;
+
+ private final List<String> containerNames;
+
+ private final DataBindingContext dbc = new DataBindingContext();
+
+ protected ContainerLinkDialog(final Shell shell,
+ final IDockerConnection connection) {
+ super(shell);
+ this.connection = connection;
+ this.model = new ContainerLinkDialogModel();
+ this.containerNames = WizardUtils.getContainerNames(connection);
+ }
+
+ public ContainerLinkDialog(final Shell shell,
+ final IDockerConnection connection,
+ final ContainerLinkModel selectedContainerLink) {
+ super(shell);
+ this.connection = connection;
+ this.model = new ContainerLinkDialogModel(selectedContainerLink);
+ this.containerNames = WizardUtils.getContainerNames(connection);
+ }
+
+ @Override
+ protected void configureShell(final Shell shell) {
+ super.configureShell(shell);
+ setShellStyle(getShellStyle() | SWT.RESIZE);
+ shell.setText("Container Linking");
+ }
+
+ @Override
+ protected Point getInitialSize() {
+ return new Point(400, super.getInitialSize().y);
+ }
+
+ @Override
+ protected Control createDialogArea(final Composite parent) {
+ final int COLUMNS = 2;
+ final Composite container = new Composite(parent, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL)
+ .span(COLUMNS, 1).grab(true, false).applyTo(container);
+ GridLayoutFactory.fillDefaults().numColumns(COLUMNS).margins(6, 6)
+ .applyTo(container);
+ final Label explanationLabel = new Label(container, SWT.NONE);
+ explanationLabel
+ .setText("Select a container to link and give it an alias:"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .span(COLUMNS, 1).grab(false, false).applyTo(explanationLabel);
+ final Label containerLabel = new Label(container, SWT.NONE);
+ containerLabel.setText("Container:"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(containerLabel);
+ final Combo containerSelectionCombo = new Combo(container, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).applyTo(containerSelectionCombo);
+ final ComboViewer containerSelectionComboViewer = new ComboViewer(
+ containerSelectionCombo);
+ containerSelectionComboViewer
+ .setContentProvider(new ArrayContentProvider());
+ containerSelectionComboViewer.setInput(model.getContainerNames());
+ new ContentProposalAdapter(containerSelectionCombo,
+ new ComboContentAdapter() {
+ @Override
+ public void insertControlContents(Control control,
+ String text, int cursorPosition) {
+ final Combo combo = (Combo) control;
+ final Point selection = combo.getSelection();
+ combo.setText(text);
+ selection.x = text.length();
+ selection.y = selection.x;
+ combo.setSelection(selection);
+ }
+ }, getContainerNameContentProposalProvider(
+ containerSelectionCombo),
+ null, null);
+ final Label aliasLabel = new Label(container, SWT.NONE);
+ aliasLabel.setText("Alias:"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(aliasLabel);
+ final Text containerAliasText = new Text(container, SWT.BORDER);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).applyTo(containerAliasText);
+ // error message
+ final Label errorMessageLabel = new Label(container, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .span(COLUMNS, 1).grab(true, false).applyTo(errorMessageLabel);
+
+ final ISWTObservableValue containerNameObservable = WidgetProperties
+ .selection().observe(containerSelectionComboViewer.getCombo());
+
+ dbc.bindValue(containerNameObservable,
+ BeanProperties
+ .value(ContainerLinkDialogModel.class,
+ ContainerLinkDialogModel.CONTAINER_NAME)
+ .observe(model));
+ final ISWTObservableValue containerAliasObservable = WidgetProperties
+ .text(SWT.Modify).observe(containerAliasText);
+
+ dbc.bindValue(containerAliasObservable,
+ BeanProperties
+ .value(ContainerLinkDialogModel.class,
+ ContainerLinkDialogModel.CONTAINER_ALIAS)
+ .observe(model));
+ containerNameObservable.addValueChangeListener(
+ onContainerLinkSettingsChanged(errorMessageLabel));
+ containerAliasObservable.addValueChangeListener(
+ onContainerLinkSettingsChanged(errorMessageLabel));
+ return container;
+ }
+
+ private IValueChangeListener onContainerLinkSettingsChanged(
+ final Label errorMessageLabel) {
+ return new IValueChangeListener() {
+
+ @Override
+ public void handleValueChange(ValueChangeEvent event) {
+ validateInput(errorMessageLabel);
+ }
+ };
+ }
+
+ @Override
+ protected Button createButton(Composite parent, int id, String label,
+ boolean defaultButton) {
+ final Button button = super.createButton(parent, id, label,
+ defaultButton);
+ if (id == IDialogConstants.OK_ID) {
+ button.setEnabled(false);
+ }
+ return button;
+ }
+
+ public String getContainerName() {
+ return model.getContainerName();
+ }
+
+ public String getContainerAlias() {
+ return model.getContainerAlias();
+ }
+
+ /**
+ * Creates an {@link IContentProposalProvider} to propose
+ * {@link IDockerContainer} names based on the current text.
+ *
+ * @param items
+ * @return
+ */
+ private IContentProposalProvider getContainerNameContentProposalProvider(
+ final Combo containerSelectionCombo) {
+ return new IContentProposalProvider() {
+
+ @Override
+ public IContentProposal[] getProposals(final String contents,
+ final int position) {
+ final List<IContentProposal> proposals = new ArrayList<IContentProposal>();
+ for (String containerName : containerSelectionCombo
+ .getItems()) {
+ if (containerName.contains(contents)) {
+ proposals.add(new ContentProposal(containerName,
+ containerName, containerName, position));
+ }
+ }
+ return proposals.toArray(new IContentProposal[0]);
+ }
+ };
+ }
+
+ private void validateInput(final Label errorMessageLabel) {
+ final String selectedContainerName = model.getContainerName();
+ final Object[] containerNames = model.getContainerNames().toArray();
+ final String containerAlias = model.getContainerAlias();
+ if (selectedContainerName == null || selectedContainerName.isEmpty()) {
+ setOkButtonEnabled(false);
+ } else if (Arrays.binarySearch(containerNames, 0, containerNames.length,
+ selectedContainerName) < 0) {
+ setOkButtonEnabled(false);
+ } else if (containerAlias == null || containerAlias.isEmpty()) {
+ setOkButtonEnabled(false);
+ return;
+ } else {
+ setOkButtonEnabled(true);
+ }
+ }
+
+ private void setOkButtonEnabled(final boolean enabled) {
+ getButton(IDialogConstants.OK_ID).setEnabled(enabled);
+ }
+
+ class ContainerLinkDialogModel extends BaseDatabindingModel {
+
+ public static final String CONTAINER_NAME = "containerName";
+
+ public static final String CONTAINER_ALIAS = "containerAlias";
+
+ private String containerName;
+
+ private String containerAlias;
+
+ public ContainerLinkDialogModel() {
+ }
+
+ public ContainerLinkDialogModel(
+ final ContainerLinkModel selectedContainerLink) {
+ this();
+ this.containerName = selectedContainerLink.getContainerName();
+ this.containerAlias = selectedContainerLink.getContainerAlias();
+ }
+
+ public IDockerConnection getConnection() {
+ return connection;
+ }
+
+ private List<String> getContainerNames() {
+ return containerNames;
+ }
+
+ public List<IDockerContainer> getContainers() {
+ return getConnection().getContainers();
+ }
+
+ public String getContainerName() {
+ return containerName;
+ }
+
+ public void setContainerName(final String containerName) {
+ firePropertyChange(CONTAINER_NAME, this.containerName,
+ this.containerName = containerName);
+ }
+
+ public String getContainerAlias() {
+ return containerAlias;
+ }
+
+ public void setContainerAlias(final String containerAlias) {
+ firePropertyChange(CONTAINER_ALIAS, this.containerAlias,
+ this.containerAlias = containerAlias);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + getOuterType().hashCode();
+ result = prime * result + ((containerAlias == null) ? 0
+ : containerAlias.hashCode());
+ result = prime * result
+ + ((containerName == null) ? 0 : containerName.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ContainerLinkDialogModel other = (ContainerLinkDialogModel) obj;
+ if (!getOuterType().equals(other.getOuterType()))
+ return false;
+ if (containerAlias == null) {
+ if (other.containerAlias != null)
+ return false;
+ } else if (!containerAlias.equals(other.containerAlias))
+ return false;
+ if (containerName == null) {
+ if (other.containerName != null)
+ return false;
+ } else if (!containerName.equals(other.containerName))
+ return false;
+ return true;
+ }
+
+ private ContainerLinkDialog getOuterType() {
+ return ContainerLinkDialog.this;
+ }
+
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerPortDialog.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerPortDialog.java
new file mode 100644
index 0000000000..db02a03140
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerPortDialog.java
@@ -0,0 +1,225 @@
+/*******************************************************************************
+ * 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.ui.wizards;
+
+import org.eclipse.core.databinding.DataBindingContext;
+import org.eclipse.core.databinding.beans.BeanProperties;
+import org.eclipse.core.databinding.observable.value.IValueChangeListener;
+import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
+import org.eclipse.jface.databinding.swt.ISWTObservableValue;
+import org.eclipse.jface.databinding.swt.WidgetProperties;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.linuxtools.internal.docker.ui.databinding.BaseDatabindingModel;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunSelectionModel.ExposedPortModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * @author xcoulon
+ *
+ */
+public class ContainerPortDialog extends Dialog {
+
+ private static final String PORT_TYPE = "/tcp";
+
+ private final ContainerPortDialogModel model;
+
+ private final DataBindingContext dbc = new DataBindingContext();
+
+ protected ContainerPortDialog(final Shell parentShell) {
+ super(parentShell);
+ this.model = new ContainerPortDialogModel();
+ }
+
+ public ContainerPortDialog(final Shell parentShell,
+ final ExposedPortModel selectedContainerPort) {
+ super(parentShell);
+ this.model = new ContainerPortDialogModel(
+ selectedContainerPort.getContainerPort(),
+ selectedContainerPort.getHostAddress(),
+ selectedContainerPort.getHostPort());
+ }
+
+ @Override
+ protected void configureShell(final Shell shell) {
+ super.configureShell(shell);
+ setShellStyle(getShellStyle() | SWT.RESIZE);
+ shell.setText("Exposing a Container Port");
+ }
+
+ @Override
+ protected Point getInitialSize() {
+ return new Point(400, super.getInitialSize().y);
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ final int COLUMNS = 2;
+ final Composite container = new Composite(parent, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL)
+ .span(COLUMNS, 1).grab(true, true).applyTo(container);
+ GridLayoutFactory.fillDefaults().numColumns(COLUMNS).margins(6, 6)
+ .applyTo(container);
+ final Label explanationLabel = new Label(container, SWT.NONE);
+ explanationLabel.setText("Specify the container port to expose:"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .span(COLUMNS, 1).grab(false, false).applyTo(explanationLabel);
+ final Label containerLabel = new Label(container, SWT.NONE);
+ containerLabel.setText("Container port:"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(containerLabel);
+ final Text containerPortText = new Text(container, SWT.BORDER);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).applyTo(containerPortText);
+ final Label hostAddressLabel = new Label(container, SWT.NONE);
+ hostAddressLabel.setText("Host address:"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(hostAddressLabel);
+ final Text hostAddressText = new Text(container, SWT.BORDER);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).applyTo(hostAddressText);
+ final Label hostPortLabel = new Label(container, SWT.NONE);
+ hostPortLabel.setText("Host port:"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(hostPortLabel);
+ final Text hostPortText = new Text(container, SWT.BORDER);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).applyTo(hostPortText);
+ // error message
+ final Label errorMessageLabel = new Label(container, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .span(COLUMNS, 1).grab(true, false).applyTo(errorMessageLabel);
+
+ // listening to changes
+ final ISWTObservableValue containerPortObservable = WidgetProperties
+ .text(SWT.Modify).observe(containerPortText);
+ dbc.bindValue(containerPortObservable,
+ BeanProperties
+ .value(ContainerPortDialogModel.class,
+ ContainerPortDialogModel.CONTAINER_PORT)
+ .observe(model));
+ final ISWTObservableValue hostAddressObservable = WidgetProperties
+ .text(SWT.Modify).observe(hostAddressText);
+ dbc.bindValue(hostAddressObservable,
+ BeanProperties
+ .value(ContainerPortDialogModel.class,
+ ContainerPortDialogModel.HOST_ADDRESS)
+ .observe(model));
+ final ISWTObservableValue hostPortObservable = WidgetProperties
+ .text(SWT.Modify).observe(hostPortText);
+ dbc.bindValue(hostPortObservable,
+ BeanProperties
+ .value(ContainerPortDialogModel.class,
+ ContainerPortDialogModel.HOST_PORT)
+ .observe(model));
+
+ containerPortObservable.addValueChangeListener(
+ onContainerPortSettingsChanged(errorMessageLabel));
+ hostPortObservable.addValueChangeListener(
+ onContainerPortSettingsChanged(errorMessageLabel));
+ hostAddressObservable.addValueChangeListener(
+ onContainerPortSettingsChanged(errorMessageLabel));
+ return container;
+ }
+
+ private IValueChangeListener onContainerPortSettingsChanged(
+ final Label errorMessageLabel) {
+ return new IValueChangeListener() {
+
+ @Override
+ public void handleValueChange(ValueChangeEvent event) {
+ validateInput(errorMessageLabel);
+ }
+ };
+ }
+
+ private void validateInput(final Label errorMessageLabel) {
+ final String containerPort = model.getContainerPort();
+ final String hostAddress = model.getHostAddress();
+ final String hostPort = model.getHostPort();
+ if (containerPort == null || containerPort.isEmpty()) {
+ setOkButtonEnabled(false);
+ } else {
+ setOkButtonEnabled(true);
+ }
+ }
+
+ private void setOkButtonEnabled(final boolean enabled) {
+ getButton(IDialogConstants.OK_ID).setEnabled(enabled);
+ }
+
+ public ExposedPortModel getPort() {
+ return new ExposedPortModel(model.getContainerPort(), PORT_TYPE,
+ model.getHostAddress(), model.getHostPort());
+ }
+
+ class ContainerPortDialogModel extends BaseDatabindingModel {
+
+ public static final String CONTAINER_PORT = "containerPort";
+
+ public static final String HOST_ADDRESS = "hostAddress";
+
+ public static final String HOST_PORT = "hostPort";
+
+ private String containerPort;
+
+ private String hostAddress;
+
+ private String hostPort;
+
+ public ContainerPortDialogModel() {
+ }
+
+ public ContainerPortDialogModel(final String containerPort,
+ final String hostAddress, final String hostPort) {
+ this.containerPort = containerPort;
+ this.hostAddress = hostAddress;
+ this.hostPort = hostPort;
+ }
+
+ public String getContainerPort() {
+ return containerPort;
+ }
+
+ public void setContainerPort(final String containerPort) {
+ firePropertyChange(CONTAINER_PORT, this.containerPort,
+ this.containerPort = containerPort);
+ }
+
+ public String getHostAddress() {
+ return hostAddress;
+ }
+
+ public void setHostAddress(final String hostName) {
+ firePropertyChange(HOST_ADDRESS, this.hostAddress,
+ this.hostAddress = hostName);
+ }
+
+ public String getHostPort() {
+ return hostPort;
+ }
+
+ public void setHostPort(final String hostPort) {
+ firePropertyChange(HOST_PORT, this.hostPort,
+ this.hostPort = hostPort);
+ }
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/DataVolumeModel.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/DataVolumeModel.java
new file mode 100644
index 0000000000..d071639e06
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/DataVolumeModel.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * 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.ui.wizards;
+
+import org.eclipse.linuxtools.internal.docker.ui.databinding.BaseDatabindingModel;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunResourceVolumesVariablesModel.MountType;
+
+/**
+ * @author xcoulon
+ *
+ */
+public class DataVolumeModel extends BaseDatabindingModel
+ implements Comparable<DataVolumeModel> {
+
+ public static final String CONTAINER_PATH = "containerPath";
+
+ public static final String MOUNT_TYPE = "mountType";
+
+ public static final String MOUNT = "mount";
+
+ public static final String HOST_PATH_MOUNT = "hostPathMount";
+
+ public static final String READ_ONLY_VOLUME = "readOnly";
+
+ public static final String CONTAINER_MOUNT = "containerMount";
+
+ private String containerPath;
+
+ private MountType mountType;
+
+ private String mount;
+
+ private String hostPathMount;
+
+ private String containerMount;
+
+ private boolean readOnly = false;
+
+ public DataVolumeModel() {
+ }
+
+ public DataVolumeModel(final String containerPath) {
+ this.containerPath = containerPath;
+ this.mountType = MountType.NONE;
+ }
+
+ public DataVolumeModel(final DataVolumeModel selectedDataVolume) {
+ this.containerPath = selectedDataVolume.getContainerPath();
+ this.mountType = selectedDataVolume.getMountType();
+ if (this.mountType != null) {
+ switch (this.mountType) {
+ case CONTAINER:
+ this.containerMount = selectedDataVolume.getMount();
+ break;
+ case HOST_FILE_SYSTEM:
+ this.hostPathMount = selectedDataVolume.getMount();
+ this.readOnly = selectedDataVolume.isReadOnly();
+ break;
+ case NONE:
+ break;
+ }
+ } else {
+ this.mountType = MountType.NONE;
+ }
+ }
+
+ public String getContainerPath() {
+ return this.containerPath;
+ }
+
+ public void setContainerPath(final String containerPath) {
+ firePropertyChange(CONTAINER_PATH, this.containerPath,
+ this.containerPath = containerPath);
+ }
+
+ public String getMount() {
+ return mount;
+ }
+
+ public void setMount(final String mount) {
+ firePropertyChange(MOUNT, this.mount, this.mount = mount);
+ }
+
+ public MountType getMountType() {
+ return mountType;
+ }
+
+ public void setMountType(final MountType mountType) {
+ // ignore 'null' assignments that may come from the UpdateStrategy
+ // in
+ // the EditDataVolumePage when a radion button is unselected.
+ if (mountType == null) {
+ return;
+ }
+ firePropertyChange(MOUNT_TYPE, this.mountType,
+ this.mountType = mountType);
+ if (this.mountType == MountType.NONE) {
+ setMount("");
+ }
+
+ }
+
+ public String getHostPathMount() {
+ return hostPathMount;
+ }
+
+ public void setHostPathMount(final String hostPathMount) {
+ firePropertyChange(HOST_PATH_MOUNT, this.hostPathMount,
+ this.hostPathMount = hostPathMount);
+ if (this.mountType == MountType.HOST_FILE_SYSTEM) {
+ setMount(this.hostPathMount);
+ }
+ }
+
+ public boolean isReadOnly() {
+ return readOnly;
+ }
+
+ public void setReadOnly(final boolean readOnly) {
+ firePropertyChange(READ_ONLY_VOLUME, this.readOnly,
+ this.readOnly = readOnly);
+ }
+
+ public String getContainerMount() {
+ return this.containerMount;
+ }
+
+ public void setContainerMount(final String containerMount) {
+ firePropertyChange(CONTAINER_MOUNT, this.containerMount,
+ this.containerMount = containerMount);
+ if (this.mountType == MountType.CONTAINER) {
+ setMount(this.containerMount);
+ }
+ }
+
+ @Override
+ public int compareTo(final DataVolumeModel other) {
+ return this.getContainerPath().compareTo(other.getContainerPath());
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + ((containerPath == null) ? 0 : containerPath.hashCode());
+ result = prime * result + ((mount == null) ? 0 : mount.hashCode());
+ result = prime * result
+ + ((mountType == null) ? 0 : mountType.hashCode());
+ result = prime * result + (readOnly ? 1231 : 1237);
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ DataVolumeModel other = (DataVolumeModel) obj;
+ if (containerPath == null) {
+ if (other.containerPath != null)
+ return false;
+ } else if (!containerPath.equals(other.containerPath))
+ return false;
+ if (mount == null) {
+ if (other.mount != null)
+ return false;
+ } else if (!mount.equals(other.mount))
+ return false;
+ if (mountType != other.mountType)
+ return false;
+ if (readOnly != other.readOnly)
+ return false;
+ return true;
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/EnvironmentVariableModel.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/EnvironmentVariableModel.java
new file mode 100644
index 0000000000..0704218cd8
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/EnvironmentVariableModel.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * 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.ui.wizards;
+
+import org.eclipse.linuxtools.internal.docker.ui.databinding.BaseDatabindingModel;
+
+/**
+ * Model to describe an Environment Variable in the 'Image Run...' wizard and
+ * associated dialog.
+ *
+ * @author xcoulon
+ *
+ */
+public class EnvironmentVariableModel extends BaseDatabindingModel {
+
+ public static final String NAME = "name";
+
+ public static final String VALUE = "value";
+
+ private String name;
+
+ private String value;
+
+ public EnvironmentVariableModel() {
+
+ }
+
+ public EnvironmentVariableModel(final String variableName,
+ final String variableValue) {
+ this.name = variableName;
+ this.value = variableValue;
+ }
+
+ public EnvironmentVariableModel(final EnvironmentVariableModel variable) {
+ this.name = variable.getName();
+ this.value = variable.getValue();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ firePropertyChange(NAME, this.name, this.name = name);
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(final String value) {
+ firePropertyChange(VALUE, this.value, this.value = value);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + ((name == null) ? 0 : name.hashCode());
+ result = prime * result
+ + ((value == null) ? 0 : value.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ EnvironmentVariableModel other = (EnvironmentVariableModel) obj;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ if (value == null) {
+ if (other.value != null)
+ return false;
+ } else if (!value.equals(other.value))
+ return false;
+ return true;
+ }
+
+ } \ No newline at end of file
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRun.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRun.java
new file mode 100644
index 0000000000..d82fef8308
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRun.java
@@ -0,0 +1,230 @@
+/*******************************************************************************
+ * Copyright (c) 2014, 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.ui.wizards;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.linuxtools.docker.core.DockerException;
+import org.eclipse.linuxtools.docker.core.IDockerConnection;
+import org.eclipse.linuxtools.docker.core.IDockerHostConfig;
+import org.eclipse.linuxtools.docker.core.IDockerImage;
+import org.eclipse.linuxtools.docker.core.IDockerPortBinding;
+import org.eclipse.linuxtools.internal.docker.core.DockerContainerConfig;
+import org.eclipse.linuxtools.internal.docker.core.DockerContainerConfig.Builder;
+import org.eclipse.linuxtools.internal.docker.core.DockerHostConfig;
+import org.eclipse.linuxtools.internal.docker.core.DockerPortBinding;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunSelectionModel.ContainerLinkModel;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunSelectionModel.ExposedPortModel;
+
+/**
+ * Wizard to 'docker run' a given {@link IDockerImage}.
+ *
+ * @author xcoulon
+ *
+ */
+public class ImageRun extends Wizard {
+
+ private final ImageRunSelectionPage imageRunSelectionPage;
+ private final ImageRunResourceVolumesVariablesPage imageRunResourceVolumesPage;
+
+ /**
+ * Constructor when an {@link IDockerConnection} has been selected to run an
+ * {@link IDockerImage}.
+ *
+ * @param connection
+ * the {@link IDockerConnection} pointing to a specific Docker
+ * daemon/host.
+ * @throws DockerException
+ */
+ public ImageRun(final IDockerConnection connection) throws DockerException {
+ super();
+ setWindowTitle("Run a Docker Image");
+ setNeedsProgressMonitor(true);
+ this.imageRunSelectionPage = new ImageRunSelectionPage(connection);
+ this.imageRunResourceVolumesPage = new ImageRunResourceVolumesVariablesPage(
+ connection);
+ }
+
+ /**
+ * Full constructor with a selected {@link IDockerImage} to run.
+ *
+ * @param selectedImage
+ * the {@link IDockerImage} to use to fill the wizard pages
+ * @throws DockerException
+ */
+ public ImageRun(final IDockerImage selectedImage) throws DockerException {
+ setWindowTitle("Run a Docker Image");
+ setNeedsProgressMonitor(true);
+ this.imageRunSelectionPage = new ImageRunSelectionPage(selectedImage);
+ this.imageRunResourceVolumesPage = new ImageRunResourceVolumesVariablesPage(
+ selectedImage.getConnection());
+ }
+
+ @Override
+ public void addPages() {
+ addPage(imageRunSelectionPage);
+ addPage(imageRunResourceVolumesPage);
+ }
+
+ @Override
+ public IWizardPage getNextPage(final IWizardPage page) {
+ if (page.equals(imageRunSelectionPage)) {
+ imageRunResourceVolumesPage.getModel().setSelectedImage(
+ imageRunSelectionPage.getModel().getSelectedImage());
+ }
+ return super.getNextPage(page);
+ }
+
+ @Override
+ public boolean performFinish() {
+ return true;
+ }
+
+ public String getDockerContainerName() {
+ return this.imageRunSelectionPage.getModel().getContainerName();
+ }
+
+ @SuppressWarnings("unchecked")
+ public IDockerHostConfig getDockerHostConfig() {
+ final ImageRunSelectionModel selectionModel = this.imageRunSelectionPage
+ .getModel();
+ final ImageRunResourceVolumesVariablesModel resourcesModel = this.imageRunResourceVolumesPage
+ .getModel();
+
+ final DockerHostConfig.Builder hostConfigBuilder = new DockerHostConfig.Builder();
+ if (selectionModel.isPublishAllPorts()) {
+ hostConfigBuilder.publishAllPorts(true);
+ } else {
+ final Map<String, List<IDockerPortBinding>> portBindings = new HashMap<>();
+ for (Iterator<ExposedPortModel> iterator = selectionModel
+ .getExposedPorts().iterator(); iterator.hasNext();) {
+ final ExposedPortModel exposedPort = iterator.next();
+ // only selected Ports in the CheckboxTableViewer are exposed.
+ if (!selectionModel.getSelectedPorts().contains(exposedPort)) {
+ continue;
+ }
+ final DockerPortBinding portBinding = new DockerPortBinding(
+ exposedPort.getHostAddress(),
+ exposedPort.getHostPort());
+ portBindings.put(
+ exposedPort.getContainerPort()
+ + exposedPort.getPortType(),
+ Arrays.<IDockerPortBinding> asList(portBinding));
+ }
+ hostConfigBuilder.portBindings(portBindings);
+ }
+ // container links
+ final List<String> links = new ArrayList<>();
+ for (Iterator<ContainerLinkModel> iterator = selectionModel.getLinks()
+ .iterator(); iterator.hasNext();) {
+ final ContainerLinkModel link = iterator.next();
+ links.add(link.getContainerName() + ':' + link.getContainerAlias());
+ }
+ hostConfigBuilder.links(links);
+
+ // data volumes
+ final List<String> volumesFrom = new ArrayList<>();
+ for (Iterator<DataVolumeModel> iterator = resourcesModel
+ .getDataVolumes().iterator(); iterator.hasNext();) {
+ final DataVolumeModel dataVolume = iterator.next();
+ // only data volumes selected in the CheckBoxTableViewer are
+ // included.
+ if (!resourcesModel.getSelectedDataVolumes().contains(dataVolume)) {
+ continue;
+ }
+
+ switch (dataVolume.getMountType()) {
+ case CONTAINER:
+ volumesFrom.add(dataVolume.getContainerMount());
+ break;
+ default:
+ break;
+
+ }
+ }
+ hostConfigBuilder.volumesFrom(volumesFrom);
+
+ return hostConfigBuilder.build();
+ }
+
+ @SuppressWarnings("unchecked")
+ public DockerContainerConfig getDockerContainerConfig() {
+ final ImageRunSelectionModel selectionModel = this.imageRunSelectionPage
+ .getModel();
+ final ImageRunResourceVolumesVariablesModel resourcesModel = this.imageRunResourceVolumesPage
+ .getModel();
+
+ final Builder config = new DockerContainerConfig.Builder()
+ .cmd(selectionModel.getCommand())
+ .entryPoint(selectionModel.getEntrypoint())
+ .image(selectionModel.getSelectedImageName())
+ .tty(selectionModel.isAllocatePseudoTTY())
+ .openStdin(selectionModel.isInteractiveMode());
+ if (resourcesModel.isEnableResourceLimitations()) {
+ config.memory(resourcesModel.getMemory());
+ config.cpuShares((long) resourcesModel.getCpuShareWeight());
+ }
+ // environment variables
+ final List<String> environmentVariables = new ArrayList<>();
+ for (Iterator<EnvironmentVariableModel> iterator = resourcesModel
+ .getEnvironmentVariables().iterator(); iterator.hasNext();) {
+ final EnvironmentVariableModel var = iterator.next();
+ environmentVariables.add(var.getName() + "=" + var.getValue());
+ }
+ config.env(environmentVariables);
+
+ // container data volumes
+ final Set<String> volumes = new HashSet<>();
+ for (Iterator<DataVolumeModel> iterator = resourcesModel
+ .getDataVolumes().iterator(); iterator.hasNext();) {
+ final DataVolumeModel dataVolume = iterator.next();
+ // only data volumes selected in the CheckBoxTableViewer are
+ // included.
+ if (!resourcesModel.getSelectedDataVolumes().contains(dataVolume)) {
+ continue;
+ }
+ switch (dataVolume.getMountType()) {
+ case CONTAINER:
+ // different way to configure 'volumes-from'
+ break;
+ case HOST_FILE_SYSTEM:
+ if (dataVolume.isReadOnly()) {
+ volumes.add(dataVolume.getContainerPath() + ':'
+ + dataVolume.getHostPathMount() + ':' + "ro");
+ } else {
+ volumes.add(dataVolume.getContainerPath() + ':'
+ + dataVolume.getHostPathMount());
+ }
+ break;
+ case NONE:
+ volumes.add(dataVolume.getContainerPath());
+ break;
+ default:
+ break;
+
+ }
+ }
+ config.volumes(volumes);
+
+ return config.build();
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunResourceVolumesVariablesModel.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunResourceVolumesVariablesModel.java
new file mode 100644
index 0000000000..a6b471fad5
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunResourceVolumesVariablesModel.java
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * 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.ui.wizards;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.databinding.observable.list.WritableList;
+import org.eclipse.linuxtools.docker.core.DockerException;
+import org.eclipse.linuxtools.docker.core.IDockerConnection;
+import org.eclipse.linuxtools.docker.core.IDockerConnectionInfo;
+import org.eclipse.linuxtools.docker.core.IDockerImage;
+import org.eclipse.linuxtools.docker.core.IDockerImageInfo;
+import org.eclipse.linuxtools.internal.docker.ui.databinding.BaseDatabindingModel;
+
+/**
+ * Databinding model for the {@link ImageRunResourceVolumesVariablesPage}
+ *
+ * @author xcoulon
+ *
+ */
+public class ImageRunResourceVolumesVariablesModel
+ extends BaseDatabindingModel {
+
+ public enum MountType {
+ NONE, HOST_FILE_SYSTEM, CONTAINER;
+ }
+
+ /** the 'low' CPU share weight variableValue. */
+ public static final int LOW = 512;
+
+ /** the default 'medium' CPU share weight variableValue. */
+ public static final int MEDIUM = 1024;
+
+ /** the 'high' CPU share weight variableValue. */
+ public static final int HIGH = 2048;
+
+ public static final String ENABLE_RESOURCE_LIMITATIONS = "enableResourceLimitations";
+
+ public static final String CPU_SHARE_WEIGHT = "cpuShareWeight";
+
+ public static final String MEMORY_LIMIT = "memoryLimit";
+
+ public static final String DATA_VOLUMES = "dataVolumes";
+
+ public static final String SELECTED_DATA_VOLUMES = "selectedDataVolumes";
+
+ public static final String ENVIRONMENT_VARIABLES = "environmentVariables";
+
+ private boolean enableResourceLimitations = false;
+
+ private final IDockerConnection connection;
+
+ private final IDockerConnectionInfo info;
+
+ private IDockerImageInfo imageInfo = null;
+
+ private int memoryLimit = 512;
+
+ private int cpuShareWeighting = 1024;
+
+ private Set<DataVolumeModel> selectedDataVolumes = new HashSet<>();
+
+ private WritableList dataVolumes = new WritableList();
+
+ private WritableList environmentVariables = new WritableList();
+
+ public ImageRunResourceVolumesVariablesModel(
+ final IDockerConnection connection) throws DockerException {
+ this.connection = connection;
+ this.info = connection.getInfo();
+ }
+
+ public IDockerConnection getConnection() {
+ return connection;
+ }
+
+ /**
+ * Refreshes the list of Volumes to display in the for the given
+ *
+ * @param selectedImage
+ */
+ public void setSelectedImage(final IDockerImage selectedImage) {
+ final WritableList newDataVolumes = new WritableList();
+ if (selectedImage != null) {
+ this.imageInfo = selectedImage.getConnection()
+ .getImageInfo(selectedImage.id());
+ if (this.imageInfo.config().volumes() != null) {
+ for (String volume : this.imageInfo.config().volumes()) {
+ newDataVolumes.add(new DataVolumeModel(volume));
+ }
+ }
+ }
+ setDataVolumes(newDataVolumes);
+ }
+
+ public IDockerImageInfo getSelectedImageInfo() {
+ return imageInfo;
+ }
+
+ public WritableList getDataVolumes() {
+ return dataVolumes;
+ }
+
+ public void setDataVolumes(final WritableList dataVolumes) {
+ this.dataVolumes.clear();
+ this.dataVolumes.addAll(dataVolumes);
+ }
+
+ public Set<DataVolumeModel> getSelectedDataVolumes() {
+ return selectedDataVolumes;
+ }
+
+ public void addSelectedDataVolume(
+ final DataVolumeModel selectedDataVolume) {
+ // we must use a different collection to fire an event for the change
+ // afterwards
+ final Set<DataVolumeModel> updatedDataVolumesSelection = new HashSet<>(
+ this.selectedDataVolumes);
+ updatedDataVolumesSelection.add(selectedDataVolume);
+ setSelectedDataVolumes(updatedDataVolumesSelection);
+ }
+
+ public void setSelectedDataVolumes(
+ final Set<DataVolumeModel> selectedDataVolumes) {
+ firePropertyChange(SELECTED_DATA_VOLUMES, this.selectedDataVolumes,
+ this.selectedDataVolumes = selectedDataVolumes);
+ }
+
+ public WritableList getEnvironmentVariables() {
+ return environmentVariables;
+ }
+
+ public void setEnvironmentVariables(
+ final WritableList environmentVariables) {
+ this.environmentVariables.clear();
+ this.environmentVariables.addAll(environmentVariables);
+ }
+
+ public void removeEnvironmentVariable(
+ final EnvironmentVariableModel variable) {
+ this.environmentVariables.remove(variable);
+ }
+
+ /**
+ * @return the total memory of the Docker daemon, in MB
+ * @throws DockerException
+ */
+ public int getTotalMemory() {
+ return (int) (this.info.getTotalMemory() / 1048576);
+ }
+
+ public boolean isEnableResourceLimitations() {
+ return enableResourceLimitations;
+ }
+
+ public void setEnableResourceLimitations(
+ boolean enableResourceLimitations) {
+ firePropertyChange(ENABLE_RESOURCE_LIMITATIONS,
+ this.enableResourceLimitations,
+ this.enableResourceLimitations = enableResourceLimitations);
+ }
+
+ /**
+ * The memory allocated for the container, in MB.
+ *
+ * @return
+ */
+ public int getMemoryLimit() {
+ return memoryLimit;
+ }
+
+ /**
+ * The memory allocated for the container, in Bytes.
+ *
+ * @return
+ */
+ public long getMemory() {
+ return memoryLimit * 1048576;
+ }
+
+ public void setMemoryLimit(final int memoryLimit) {
+ firePropertyChange(MEMORY_LIMIT, this.memoryLimit,
+ this.memoryLimit = memoryLimit);
+ }
+
+ public int getCpuShareWeight() {
+ return cpuShareWeighting;
+ }
+
+ public void setCpuShareWeight(final int cpuShareWeighting) {
+ firePropertyChange(CPU_SHARE_WEIGHT, this.cpuShareWeighting,
+ this.cpuShareWeighting = cpuShareWeighting);
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunResourceVolumesVariablesPage.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunResourceVolumesVariablesPage.java
new file mode 100644
index 0000000000..c5afbebecf
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunResourceVolumesVariablesPage.java
@@ -0,0 +1,643 @@
+/*******************************************************************************
+ * 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.ui.wizards;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.databinding.DataBindingContext;
+import org.eclipse.core.databinding.beans.BeanProperties;
+import org.eclipse.core.databinding.beans.IBeanValueProperty;
+import org.eclipse.core.databinding.observable.ChangeEvent;
+import org.eclipse.core.databinding.observable.IChangeListener;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.core.databinding.observable.map.IObservableMap;
+import org.eclipse.core.databinding.property.Properties;
+import org.eclipse.jface.databinding.swt.WidgetProperties;
+import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
+import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider;
+import org.eclipse.jface.databinding.viewers.ViewerSupport;
+import org.eclipse.jface.databinding.viewers.ViewersObservables;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.linuxtools.docker.core.DockerException;
+import org.eclipse.linuxtools.docker.core.IDockerConnection;
+import org.eclipse.linuxtools.internal.docker.ui.SWTImagesFactory;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunResourceVolumesVariablesModel.MountType;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Scale;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * A {@link WizardPage} to let the user select the CPU and memory allocation for
+ * the container, as well as the volumes to mount.
+ *
+ * @author xcoulon
+ *
+ */
+public class ImageRunResourceVolumesVariablesPage extends WizardPage {
+
+ private final int COLUMNS = 2;
+
+ private final DataBindingContext dbc = new DataBindingContext();
+ private final ImageRunResourceVolumesVariablesModel model;
+
+ public ImageRunResourceVolumesVariablesPage(
+ final IDockerConnection connection) throws DockerException {
+ super("ImageSelectionPage", //$NON-NLS-1$
+ "Volumes, Environment Variables and Resource Limitations", //$NON-NLS-1$
+ SWTImagesFactory.DESC_BANNER_REPOSITORY);
+ setPageComplete(true);
+ this.model = new ImageRunResourceVolumesVariablesModel(connection);
+ }
+
+ public ImageRunResourceVolumesVariablesModel getModel() {
+ return model;
+ }
+
+ @Override
+ public void createControl(Composite parent) {
+ final Composite container = new Composite(parent, SWT.NONE);
+ GridLayoutFactory.fillDefaults().numColumns(COLUMNS).margins(6, 6)
+ .applyTo(container);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL)
+ .applyTo(container);
+ createVolumeSettingsContainer(container);
+ // createSectionSeparator(container, true);
+ createEnvironmentVariablesContainer(container);
+ createSectionSeparator(container, true);
+ createResourceSettingsContainer(container);
+ setControl(container);
+ }
+
+ private void createSectionSeparator(final Composite container,
+ final boolean separator) {
+ final int SECTION_INDENT = 10;
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .span(COLUMNS, 1).grab(true, false)
+ .indent(SWT.DEFAULT, SECTION_INDENT)
+ .applyTo(new Label(container, separator
+ ? (SWT.SEPARATOR | SWT.HORIZONTAL) : SWT.NONE));
+ }
+
+ private void createResourceSettingsContainer(final Composite parent) {
+ final Composite container = new Composite(parent, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL)
+ .span(COLUMNS, 1).grab(true, false).applyTo(container);
+ GridLayoutFactory.fillDefaults().spacing(10, 2).applyTo(container);
+ final Button enableResourceLimitationButton = new Button(container,
+ SWT.CHECK);
+ enableResourceLimitationButton.setText("Enable resource limitations"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .applyTo(enableResourceLimitationButton);
+ dbc.bindValue(
+ WidgetProperties.selection()
+ .observe(enableResourceLimitationButton),
+ BeanProperties
+ .value(ImageRunResourceVolumesVariablesModel.class,
+ ImageRunResourceVolumesVariablesModel.ENABLE_RESOURCE_LIMITATIONS)
+ .observe(model));
+ final int COLUMNS = 5;
+ final int INDENT = 20;
+ final Composite subContainer = new Composite(container, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL)
+ .indent(INDENT, 0).span(COLUMNS, 1).grab(true, false)
+ .applyTo(subContainer);
+ GridLayoutFactory.fillDefaults().numColumns(COLUMNS).margins(6, 6)
+ .spacing(10, 2).applyTo(subContainer);
+
+ // specify CPU limitation
+ final Label cpuPriorityLabel = new Label(subContainer, SWT.NONE);
+ cpuPriorityLabel.setText("CPU priority:"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(cpuPriorityLabel);
+ final Button lowCPULimitationButton = new Button(subContainer,
+ SWT.RADIO);
+ lowCPULimitationButton.setText("Low");
+ lowCPULimitationButton.addSelectionListener(
+ onCpuShareWeighting(ImageRunResourceVolumesVariablesModel.LOW));
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .applyTo(lowCPULimitationButton);
+ final Button mediumCPULimitationButton = new Button(subContainer,
+ SWT.RADIO);
+ mediumCPULimitationButton.setText("Medium");
+ mediumCPULimitationButton.addSelectionListener(onCpuShareWeighting(
+ ImageRunResourceVolumesVariablesModel.MEDIUM));
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .applyTo(mediumCPULimitationButton);
+ final Button highCPULimitationButton = new Button(subContainer,
+ SWT.RADIO);
+ mediumCPULimitationButton.setSelection(true);
+ highCPULimitationButton.setText("High");
+ highCPULimitationButton.addSelectionListener(onCpuShareWeighting(
+ ImageRunResourceVolumesVariablesModel.HIGH));
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).span(2, 1)
+ .applyTo(highCPULimitationButton);
+ dbc.bindValue(
+ WidgetProperties.selection()
+ .observe(enableResourceLimitationButton),
+ BeanProperties
+ .value(ImageRunResourceVolumesVariablesModel.class,
+ ImageRunResourceVolumesVariablesModel.ENABLE_RESOURCE_LIMITATIONS)
+ .observe(model));
+
+ // Memory limitation
+ final Label memoryLimitLabel = new Label(subContainer, SWT.NONE);
+ memoryLimitLabel.setText("Memory limit:"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(memoryLimitLabel);
+ final Scale memoryLimitSpinner = new Scale(subContainer, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).span(2, 1).applyTo(memoryLimitSpinner);
+ memoryLimitSpinner.setBackground(
+ Display.getDefault().getSystemColor(SWT.COLOR_TRANSPARENT));
+ memoryLimitSpinner.setMinimum(0);
+ memoryLimitSpinner.setMaximum(this.model.getTotalMemory());
+ memoryLimitSpinner.setSelection(512);
+ memoryLimitSpinner.setPageIncrement(64);
+ dbc.bindValue(WidgetProperties.selection().observe(memoryLimitSpinner),
+ BeanProperties
+ .value(ImageRunResourceVolumesVariablesModel.class,
+ ImageRunResourceVolumesVariablesModel.MEMORY_LIMIT)
+ .observe(model));
+
+ final Text memoryLimitValueText = new Text(subContainer, SWT.BORDER);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).hint(50, SWT.DEFAULT)
+ .applyTo(memoryLimitValueText);
+ dbc.bindValue(
+ WidgetProperties.text(SWT.Modify).observe(memoryLimitValueText),
+ BeanProperties
+ .value(ImageRunResourceVolumesVariablesModel.class,
+ ImageRunResourceVolumesVariablesModel.MEMORY_LIMIT)
+ .observe(model));
+ final Label memoryLimitValueLabel = new Label(subContainer, SWT.NONE);
+ memoryLimitValueLabel.setText("MB"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(memoryLimitValueLabel);
+
+ // enable/disable controls
+ enableResourceLimitationButton
+ .addSelectionListener(onEnableResourceLimitation(subContainer));
+ toggleResourceLimitationControls(subContainer);
+
+ }
+
+ private SelectionListener onCpuShareWeighting(final int cpuShareWeigth) {
+ return new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ model.setCpuShareWeight(cpuShareWeigth);
+ }
+ };
+ }
+
+ private SelectionListener onEnableResourceLimitation(
+ final Composite container) {
+ return new SelectionAdapter() {
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ toggleResourceLimitationControls(container);
+ }
+
+ };
+ }
+
+ private void toggleResourceLimitationControls(Composite container) {
+ for (Control childControl : container.getChildren()) {
+ if (model.isEnableResourceLimitations()) {
+ childControl.setEnabled(true);
+ } else {
+ childControl.setEnabled(false);
+ }
+ }
+ }
+
+ private void createVolumeSettingsContainer(final Composite container) {
+ final Label volumesLabel = new Label(container, SWT.NONE);
+ volumesLabel.setText("Data Volumes:"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).span(COLUMNS, 1).applyTo(volumesLabel);
+ final CheckboxTableViewer dataVolumesTableViewer = createVolumesTable(
+ container);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP)
+ .grab(true, false).hint(200, 100)
+ .applyTo(dataVolumesTableViewer.getTable());
+ // buttons
+ final Composite buttonsContainers = new Composite(container, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP)
+ .grab(false, false).applyTo(buttonsContainers);
+ GridLayoutFactory.fillDefaults().numColumns(1).margins(0, 0)
+ .spacing(SWT.DEFAULT, 0).applyTo(buttonsContainers);
+
+ final Button addButton = new Button(buttonsContainers, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP)
+ .grab(true, false).applyTo(addButton);
+ addButton.setText("Add..."); //$NON-NLS-1$
+ addButton.addSelectionListener(onAddDataVolume(dataVolumesTableViewer));
+ final Button editButton = new Button(buttonsContainers, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP)
+ .grab(true, false).applyTo(editButton);
+ editButton.setText("Edit..."); //$NON-NLS-1$
+ editButton
+ .addSelectionListener(onEditDataVolume(dataVolumesTableViewer));
+ editButton.setEnabled(false);
+ final Button resetButton = new Button(buttonsContainers, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP)
+ .grab(true, false).applyTo(resetButton);
+ resetButton.setText("Remove"); //$NON-NLS-1$
+ resetButton.addSelectionListener(onRemoveDataVolumes());
+ resetButton.setEnabled(false);
+ // update table content when selected image changes
+ bind(dataVolumesTableViewer, model.getDataVolumes(),
+ BeanProperties.values(DataVolumeModel.class,
+ new String[] { DataVolumeModel.CONTAINER_PATH,
+ DataVolumeModel.MOUNT,
+ DataVolumeModel.READ_ONLY_VOLUME }));
+ dbc.bindSet(
+ ViewersObservables.observeCheckedElements(
+ dataVolumesTableViewer, DataVolumeModel.class),
+ BeanProperties
+ .set(ImageRunResourceVolumesVariablesModel.SELECTED_DATA_VOLUMES)
+ .observe(model));
+ ViewersObservables.observeMultiSelection(dataVolumesTableViewer)
+ .addChangeListener(
+ onDataVolumesSelection(editButton, resetButton));
+ }
+
+ /**
+ * Same as
+ * {@link ViewerSupport#bind(StructuredViewer, IObservableList, org.eclipse.core.databinding.property.value.IValueProperty[])
+ * but with a custom LabelProvider, DataVolumesLabelProvider
+ *
+ * @param viewer
+ * @param input
+ * @param labelProperties
+ */
+ private void bind(final StructuredViewer viewer,
+ final IObservableList input,
+ final IBeanValueProperty[] labelProperties) {
+ final ObservableListContentProvider contentProvider = new ObservableListContentProvider();
+ if (viewer.getInput() != null) {
+ viewer.setInput(null);
+ }
+ viewer.setContentProvider(contentProvider);
+ viewer.setLabelProvider(
+ new DataVolumesLabelProvider(Properties.observeEach(
+ contentProvider.getKnownElements(), labelProperties)));
+ if (input != null) {
+ viewer.setInput(input);
+ }
+
+ }
+
+ private IChangeListener onDataVolumesSelection(
+ final Button... targetButtons) {
+ return new IChangeListener() {
+
+ @Override
+ public void handleChange(ChangeEvent event) {
+ if (event.getSource() != null) {
+ setControlsEnabled(targetButtons, true);
+ }
+ }
+ };
+ }
+
+ private SelectionListener onAddDataVolume(
+ final CheckboxTableViewer dataVolumesTableViewer) {
+ return new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ final IStructuredSelection selection = (IStructuredSelection) dataVolumesTableViewer
+ .getSelection();
+ if (selection.isEmpty()) {
+ return;
+ }
+ final ContainerDataVolumeDialog dialog = new ContainerDataVolumeDialog(
+ getShell(), model.getConnection());
+ dialog.create();
+ if (dialog.open() == IDialogConstants.OK_ID) {
+ model.getDataVolumes().add(dialog.getDataVolume());
+ dataVolumesTableViewer.refresh();
+ }
+ }
+ };
+ }
+
+ private SelectionListener onEditDataVolume(
+ final CheckboxTableViewer dataVolumesTableViewer) {
+ return new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ final IStructuredSelection selection = (IStructuredSelection) dataVolumesTableViewer
+ .getSelection();
+ if (selection.isEmpty()) {
+ return;
+ }
+ final DataVolumeModel selectedDataVolume = (DataVolumeModel) selection
+ .getFirstElement();
+ final ContainerDataVolumeDialog dialog = new ContainerDataVolumeDialog(
+ getShell(), model.getConnection(), selectedDataVolume);
+ dialog.create();
+ if (dialog.open() == IDialogConstants.OK_ID) {
+ final DataVolumeModel dialogDataVolume = dialog
+ .getDataVolume();
+ selectedDataVolume.setContainerMount(
+ dialogDataVolume.getContainerMount());
+ selectedDataVolume
+ .setMountType(dialogDataVolume.getMountType());
+ selectedDataVolume.setHostPathMount(
+ dialogDataVolume.getHostPathMount());
+ selectedDataVolume.setContainerMount(
+ dialogDataVolume.getContainerMount());
+ selectedDataVolume
+ .setReadOnly(dialogDataVolume.isReadOnly());
+ }
+ }
+ };
+ }
+
+ private SelectionListener onRemoveDataVolumes() {
+ return new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ // TODO
+ }
+ };
+ }
+
+ private CheckboxTableViewer createVolumesTable(final Composite container) {
+ final Table table = new Table(container, SWT.CHECK | SWT.BORDER
+ | SWT.FULL_SELECTION | SWT.V_SCROLL | SWT.H_SCROLL);
+ final CheckboxTableViewer tableViewer = new CheckboxTableViewer(table);
+ table.setHeaderVisible(true);
+ table.setLinesVisible(true);
+ dbc.bindSet(
+ ViewersObservables.observeCheckedElements(tableViewer,
+ DataVolumeModel.class),
+ BeanProperties
+ .set(ImageRunResourceVolumesVariablesModel.SELECTED_DATA_VOLUMES)
+ .observe(model));
+ addTableViewerColum(tableViewer, "Container Path", //$NON-NLS-1$
+ 150);
+ addTableViewerColum(tableViewer, "Mount", //$NON-NLS-1$
+ 150);
+ addTableViewerColum(tableViewer, "Read-only", //$NON-NLS-1$
+ 60);
+ return tableViewer;
+ }
+
+ private TableViewerColumn addTableViewerColum(final TableViewer tableViewer,
+ final String title, final int width) {
+ final TableViewerColumn viewerColumn = new TableViewerColumn(
+ tableViewer, SWT.NONE);
+ final TableColumn column = viewerColumn.getColumn();
+ if (title != null) {
+ column.setText(title);
+ }
+ column.setWidth(width);
+ return viewerColumn;
+ }
+
+ private void createEnvironmentVariablesContainer(
+ final Composite container) {
+ final Label volumesLabel = new Label(container, SWT.NONE);
+ volumesLabel.setText("Environment variables:"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).span(COLUMNS, 1).applyTo(volumesLabel);
+ final TableViewer environmentVariablesTableViewer = createEnvironmentVariablesTable(
+ container);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP)
+ .grab(true, false).hint(200, 100)
+ .applyTo(environmentVariablesTableViewer.getTable());
+ // buttons
+ final Composite buttonsContainers = new Composite(container, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP)
+ .grab(false, false).applyTo(buttonsContainers);
+ GridLayoutFactory.fillDefaults().numColumns(1).margins(0, 0)
+ .spacing(SWT.DEFAULT, 0).applyTo(buttonsContainers);
+
+ final Button addButton = new Button(buttonsContainers, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP)
+ .grab(true, false).applyTo(addButton);
+ addButton.setText("Add..."); //$NON-NLS-1$
+ addButton.setEnabled(true);
+ addButton.addSelectionListener(onAddEnvironmentVariable());
+ final Button editButton = new Button(buttonsContainers, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP)
+ .grab(true, false).applyTo(editButton);
+ editButton.setText("Edit..."); //$NON-NLS-1$
+ editButton.setEnabled(true);
+ editButton.addSelectionListener(
+ onEditEnvironmentVariable(environmentVariablesTableViewer));
+ editButton.setEnabled(false);
+ final Button removeButton = new Button(buttonsContainers, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP)
+ .grab(true, false).applyTo(removeButton);
+ removeButton.setText("Remove"); //$NON-NLS-1$
+ removeButton.addSelectionListener(
+ onRemoveEnvironmentVariables(environmentVariablesTableViewer));
+ removeButton.setEnabled(false);
+ // update table content when selected image changes
+ ViewerSupport.bind(environmentVariablesTableViewer,
+ model.getEnvironmentVariables(),
+ BeanProperties.values(EnvironmentVariableModel.class,
+ new String[] { EnvironmentVariableModel.NAME,
+ EnvironmentVariableModel.VALUE }));
+ environmentVariablesTableViewer.addSelectionChangedListener(
+ onEnvironmentVariableSelected(editButton, removeButton));
+ // disable the edit and removeButton if the table is empty
+ model.getEnvironmentVariables().addChangeListener(
+ onRemoveEnvironmentVariables(editButton, removeButton));
+ }
+
+ private TableViewer createEnvironmentVariablesTable(Composite container) {
+ final Table table = new Table(container,
+ SWT.BORDER | SWT.FULL_SELECTION | SWT.V_SCROLL | SWT.H_SCROLL);
+ final TableViewer tableViewer = new TableViewer(table);
+ table.setHeaderVisible(true);
+ table.setLinesVisible(true);
+ addTableViewerColum(tableViewer, "Name", //$NON-NLS-1$
+ 200);
+ addTableViewerColum(tableViewer, "Value", //$NON-NLS-1$
+ 200);
+ return tableViewer;
+ }
+
+ private ISelectionChangedListener onEnvironmentVariableSelected(
+ final Control... controls) {
+ return new ISelectionChangedListener() {
+
+ @Override
+ public void selectionChanged(final SelectionChangedEvent e) {
+ if (e.getSelection().isEmpty()) {
+ setControlsEnabled(controls, false);
+ } else {
+ setControlsEnabled(controls, true);
+ }
+ }
+
+ };
+ }
+
+ private SelectionListener onAddEnvironmentVariable() {
+ return new SelectionAdapter() {
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ final ContainerEnvironmentVariableDialog dialog = new ContainerEnvironmentVariableDialog(
+ getShell());
+ dialog.create();
+ if (dialog.open() == IDialogConstants.OK_ID) {
+ model.getEnvironmentVariables()
+ .add(dialog.getEnvironmentVariable());
+
+ }
+ }
+ };
+ }
+
+ private SelectionListener onEditEnvironmentVariable(
+ final TableViewer environmentVariablesTableViewer) {
+ return new SelectionAdapter() {
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ final EnvironmentVariableModel selectedVariable = (EnvironmentVariableModel) environmentVariablesTableViewer
+ .getStructuredSelection().getFirstElement();
+ final ContainerEnvironmentVariableDialog dialog = new ContainerEnvironmentVariableDialog(
+ getShell(), selectedVariable);
+ dialog.create();
+ if (dialog.open() == IDialogConstants.OK_ID) {
+ selectedVariable.setName(
+ dialog.getEnvironmentVariable().getName());
+ selectedVariable.setValue(
+ dialog.getEnvironmentVariable().getValue());
+ environmentVariablesTableViewer.refresh();
+ }
+ }
+ };
+ }
+
+ private IChangeListener onRemoveEnvironmentVariables(
+ final Button... buttons) {
+ return new IChangeListener() {
+
+ @Override
+ public void handleChange(final ChangeEvent event) {
+ @SuppressWarnings("unchecked")
+ final List<EnvironmentVariableModel> links = (List<EnvironmentVariableModel>) event
+ .getSource();
+ if (links.isEmpty()) {
+ setControlsEnabled(buttons, false);
+ }
+ }
+ };
+ }
+
+ private SelectionListener onRemoveEnvironmentVariables(
+ final TableViewer linksTableViewer) {
+ return new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ final IStructuredSelection selection = linksTableViewer
+ .getStructuredSelection();
+ for (@SuppressWarnings("unchecked")
+ Iterator<EnvironmentVariableModel> iterator = selection
+ .iterator(); iterator.hasNext();) {
+ model.removeEnvironmentVariable(iterator.next());
+ }
+ }
+ };
+ }
+
+ private static void setControlsEnabled(final Control[] controls,
+ final boolean enabled) {
+ for (Control control : controls) {
+ control.setEnabled(enabled);
+ }
+ }
+
+ private static final class DataVolumesLabelProvider
+ extends ObservableMapLabelProvider {
+
+ public DataVolumesLabelProvider(final IObservableMap[] attributeMaps) {
+ super(attributeMaps);
+ }
+
+ @Override
+ public Image getColumnImage(Object element, int columnIndex) {
+ final DataVolumeModel dataVolume = ((DataVolumeModel) element);
+ if (dataVolume.getMountType() != null && columnIndex == 1) {
+ switch (dataVolume.getMountType()) {
+ case CONTAINER:
+ return SWTImagesFactory.DESC_CONTAINER.createImage();
+ case HOST_FILE_SYSTEM:
+ final File hostFile = new File(dataVolume.getMount());
+ if (!hostFile.exists() || hostFile.isDirectory()) {
+ return SWTImagesFactory.DESC_FOLDER_CLOSED
+ .createImage();
+ } else {
+ return SWTImagesFactory.DESC_FILE.createImage();
+ }
+ default:
+ return null;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public String getColumnText(Object element, int columnIndex) {
+ final DataVolumeModel dataVolume = ((DataVolumeModel) element);
+ switch (columnIndex) {
+ case 0:
+ return dataVolume.getContainerPath();
+ case 1:
+ return dataVolume.getMount();
+ case 2:
+ if (dataVolume.getMountType() != MountType.HOST_FILE_SYSTEM) {
+ return null;
+ } else if (dataVolume.isReadOnly()) {
+ return "true";
+ }
+ return "false";
+ default:
+ return null;
+ }
+ }
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionModel.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionModel.java
new file mode 100644
index 0000000000..1d30513cb5
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionModel.java
@@ -0,0 +1,516 @@
+/*******************************************************************************
+ * Copyright (c) 2014, 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.ui.wizards;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.databinding.observable.list.WritableList;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.linuxtools.docker.core.IDockerConnection;
+import org.eclipse.linuxtools.docker.core.IDockerImage;
+import org.eclipse.linuxtools.internal.docker.ui.databinding.BaseDatabindingModel;
+
+/**
+ * Databinding model for the {@link ImageRunSelectionPage}
+ *
+ * @author xcoulon
+ *
+ */
+public class ImageRunSelectionModel extends BaseDatabindingModel {
+
+ public static final String SELECTED_IMAGE_NAME = "selectedImageName"; //$NON-NLS-1$
+
+ public static final String SELECTED_IMAGE = "selectedImage"; //$NON-NLS-1$
+
+ public static final String SELECTED_IMAGE_NEEDS_PULLING = "selectedImageNeedsPulling"; //$NON-NLS-1$
+
+ public static final String IMAGE_NAMES = "imageNames";
+
+ public static final String CONTAINER_NAME = "containerName";
+
+ public static final String COMMAND = "command";
+
+ public static final String ENTRYPOINT = "entrypoint";
+
+ public static final String PUBLISH_ALL_PORTS = "publishAllPorts";
+
+ public static final String EXPOSED_PORTS = "exposedPorts";
+
+ public static final String SELECTED_PORTS = "selectedPorts";
+
+ public static final String LINKS = "links";
+
+ public static final String INTERACTIVE_MODE = "interactiveMode";
+
+ public static final String ALLOCATE_PSEUDO_TTY = "allocatePseudoTTY";
+
+ public static final String REMOVE_WHEN_EXITS = "removeWhenExits";
+
+ private final IDockerConnection selectedConnection;
+
+ private String selectedImageName;
+
+ private boolean selectedImageNeedsPulling = false;
+
+ private List<String> imageNames;
+
+ private Map<String, IDockerImage> images;
+
+ private String containerName;
+
+ private String command;
+
+ private String entrypoint;
+
+ private boolean publishAllPorts = true;
+
+ private WritableList exposedPorts = new WritableList();
+
+ private Set<ExposedPortModel> selectedPorts = new HashSet<>();
+
+ private WritableList links = new WritableList();
+
+ private boolean interactiveMode = true;
+
+ private boolean allocatePseudoTTY = true;
+
+ private boolean removeWhenExits = false;
+
+ public ImageRunSelectionModel(
+ final IDockerConnection selectedConnection) {
+ this.selectedConnection = selectedConnection;
+ refreshImageNames();
+ }
+
+ public void refreshImageNames() {
+ this.imageNames = new ArrayList<>();
+ this.images = new HashMap<>();
+ for (IDockerImage image : this.selectedConnection.getImages()) {
+ if (!image.isIntermediateImage() && !image.isDangling()) {
+ for (String tag : image.tags()) {
+ final String imageName = ImageRunSelectionModel
+ .getImageName(image.repo(), tag);
+ images.put(imageName, image);
+ imageNames.add(imageName);
+ }
+ }
+ }
+ }
+
+ public ImageRunSelectionModel(final IDockerImage selectedImage) {
+ this(selectedImage.getConnection());
+ if (selectedImage.tags().contains("latest")) { //$NON-NLS-1$
+ setSelectedImageName(ImageRunSelectionModel
+ .getImageName(selectedImage.repo(), "latest")); //$NON-NLS-1$
+ } else {
+ final String lastTag = selectedImage.tags()
+ .get(selectedImage.tags().size() - 1);
+ setSelectedImageName(ImageRunSelectionModel
+ .getImageName(selectedImage.repo(), lastTag)); // $NON-NLS-1$
+ }
+ }
+
+ public boolean isPublishAllPorts() {
+ return publishAllPorts;
+ }
+
+ public void setPublishAllPorts(boolean publishAllPorts) {
+ firePropertyChange(PUBLISH_ALL_PORTS, this.publishAllPorts,
+ this.publishAllPorts = publishAllPorts);
+ }
+
+ public List<String> getImageNames() {
+ return imageNames;
+ }
+
+ public void setImageNames(final List<String> imageNames) {
+ firePropertyChange(IMAGE_NAMES, this.imageNames,
+ this.imageNames = imageNames);
+ }
+
+ public IDockerConnection getSelectedConnection() {
+ return selectedConnection;
+ }
+
+ public String getSelectedImageName() {
+ return selectedImageName;
+ }
+
+ public boolean isSelectedImageNeedsPulling() {
+ return selectedImageNeedsPulling;
+ }
+
+ public void setSelectedImageNeedsPulling(
+ final boolean selectedImageNeedsPulling) {
+ firePropertyChange(SELECTED_IMAGE_NEEDS_PULLING,
+ this.selectedImageNeedsPulling,
+ this.selectedImageNeedsPulling = selectedImageNeedsPulling);
+ }
+
+ public void setSelectedImageName(final String selectedImageName) {
+ firePropertyChange(SELECTED_IMAGE_NAME, this.selectedImageName,
+ this.selectedImageName = selectedImageName);
+ }
+
+ /**
+ * @return the selected {@link IDockerImage} or <code>null</code> if none
+ * was found.
+ */
+ public IDockerImage getSelectedImage() {
+ return this.images.get(selectedImageName);
+ }
+
+ public String getContainerName() {
+ return containerName;
+ }
+
+ public void setContainerName(final String containerName) {
+ firePropertyChange(CONTAINER_NAME, this.containerName,
+ this.containerName = containerName);
+ }
+
+ public String getCommand() {
+ return command;
+ }
+
+ public void setCommand(final String command) {
+ firePropertyChange(COMMAND, this.command, this.command = command);
+ }
+
+ public void setCommand(final List<String> cmdElements) {
+ final StringBuilder commandBuilder = new StringBuilder();
+ if (cmdElements != null) {
+ for (String cmdElement : cmdElements) {
+ commandBuilder.append(cmdElement).append(' ');
+ }
+ }
+ setCommand(commandBuilder.toString());
+ }
+
+ public String getEntrypoint() {
+ return entrypoint;
+ }
+
+ public void setEntrypoint(final String entrypoint) {
+ firePropertyChange(ENTRYPOINT, this.entrypoint,
+ this.entrypoint = entrypoint);
+ }
+
+ public void setEntrypoint(final List<String> entrypointElements) {
+ final StringBuilder entrypointBuilder = new StringBuilder();
+ if (entrypointElements != null) {
+ for (String entrypoint : entrypointElements) {
+ entrypointBuilder.append(entrypoint).append(' ');
+ }
+ }
+ setEntrypoint(entrypointBuilder.toString());
+ }
+
+ public WritableList getExposedPorts() {
+ return exposedPorts;
+ }
+
+ public void addAvailablePort(final ExposedPortModel port) {
+ this.exposedPorts.add(port);
+ }
+
+ public void removeAvailablePort(final ExposedPortModel port) {
+ this.exposedPorts.remove(port);
+ }
+
+ public void setExposedPorts(final WritableList ports) {
+ // firePropertyChange(EXPOSED_PORTS, this.availablePorts,
+ // this.availablePorts = ports);
+ this.exposedPorts.clear();
+ this.exposedPorts.addAll(ports);
+ }
+
+ public Set<ExposedPortModel> getSelectedPorts() {
+ return selectedPorts;
+ }
+
+ public void setSelectedPorts(final Set<ExposedPortModel> ports) {
+ firePropertyChange(SELECTED_PORTS, this.selectedPorts,
+ this.selectedPorts = ports);
+ }
+
+ public WritableList getLinks() {
+ return links;
+ }
+
+ public void addLink(final String containerName,
+ final String containerAlias) {
+ links.add(new ContainerLinkModel(containerName, containerAlias));
+ }
+
+ public void addLink(final int index, final String containerName,
+ final String containerAlias) {
+ links.add(index, new ContainerLinkModel(containerName, containerAlias));
+ }
+
+ public void removeLink(final ContainerLinkModel link) {
+ links.remove(link);
+ }
+
+ public void setLinks(final WritableList links) {
+ firePropertyChange(LINKS, this.links, this.links = links);
+ }
+
+ public static String getImageName(final String repo, final String tag) {
+ return repo + ":" + tag;
+ }
+
+ public boolean isAllocatePseudoTTY() {
+ return allocatePseudoTTY;
+ }
+
+ public void setAllocatePseudoTTY(boolean allocatePseudoTTY) {
+ firePropertyChange(ALLOCATE_PSEUDO_TTY, this.allocatePseudoTTY,
+ this.allocatePseudoTTY = allocatePseudoTTY);
+ }
+
+ public boolean isInteractiveMode() {
+ return interactiveMode;
+ }
+
+ public void setInteractiveMode(boolean interactiveMode) {
+ firePropertyChange(INTERACTIVE_MODE, this.interactiveMode,
+ this.interactiveMode = interactiveMode);
+ }
+
+ public boolean isRemoveWhenExits() {
+ return removeWhenExits;
+ }
+
+ public void setRemoveWhenExits(boolean removeWhenExits) {
+ firePropertyChange(REMOVE_WHEN_EXITS, this.removeWhenExits,
+ this.removeWhenExits = removeWhenExits);
+ }
+
+ public static class ExposedPortModel extends BaseDatabindingModel
+ implements Comparable<ExposedPortModel> {
+
+ public static final String SELECTED = "selected";
+
+ public static final String CONTAINER_PORT = "containerPort";
+
+ public static final String PORT_TYPE = "portType";
+
+ public static final String HOST_ADDRESS = "hostAddress";
+
+ public static final String HOST_PORT = "hostPort";
+
+ private boolean selected;
+
+ private String containerPort;
+
+ private String portType;
+
+ private String hostAddress;
+
+ private String hostPort;
+
+ /**
+ * Full constructor
+ *
+ * @param privatePort
+ * @param portType
+ * @param hostAddress
+ * @param hostPort
+ */
+ public ExposedPortModel(final String privatePort, final String type,
+ final String hostAddress, final String hostPort) {
+ Assert.isNotNull(privatePort,
+ "Port Mapping privatePort cannot be null");
+ Assert.isNotNull(type, "Port Mapping portType cannot be null");
+ this.containerPort = privatePort;
+ this.hostPort = hostPort;
+ this.portType = type;
+ this.hostAddress = hostAddress;
+ }
+
+ public String getContainerPort() {
+ return containerPort;
+ }
+
+ public void setContainerPort(final String containerPort) {
+ firePropertyChange(SELECTED, this.containerPort,
+ this.containerPort = containerPort);
+ }
+
+ public String getPortType() {
+ return portType;
+ }
+
+ public void setPortType(final String type) {
+ firePropertyChange(SELECTED, this.portType, this.portType = type);
+ }
+
+ public boolean getSelected() {
+ return selected;
+ }
+
+ public void setSelected(final boolean selected) {
+ firePropertyChange(SELECTED, this.selected,
+ this.selected = selected);
+ }
+
+ public String getHostPort() {
+ return hostPort;
+ }
+
+ public void setHostPort(final String hostPort) {
+ firePropertyChange(HOST_PORT, this.hostPort,
+ this.hostPort = hostPort);
+ }
+
+ public String getHostAddress() {
+ return hostAddress;
+ }
+
+ public void setHostAddress(final String hostAddress) {
+ firePropertyChange(HOST_ADDRESS, this.hostAddress,
+ this.hostAddress = hostAddress);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + ((hostAddress == null) ? 0 : hostAddress.hashCode());
+ result = prime * result
+ + ((containerPort == null) ? 0 : containerPort.hashCode());
+ result = prime * result
+ + ((hostPort == null) ? 0 : hostPort.hashCode());
+ result = prime * result
+ + ((portType == null) ? 0 : portType.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ExposedPortModel other = (ExposedPortModel) obj;
+ if (hostAddress == null) {
+ if (other.hostAddress != null)
+ return false;
+ } else if (!hostAddress.equals(other.hostAddress))
+ return false;
+ if (containerPort == null) {
+ if (other.containerPort != null)
+ return false;
+ } else if (!containerPort.equals(other.containerPort))
+ return false;
+ if (hostPort == null) {
+ if (other.hostPort != null)
+ return false;
+ } else if (!hostPort.equals(other.hostPort))
+ return false;
+ if (portType == null) {
+ if (other.portType != null)
+ return false;
+ } else if (!portType.equals(other.portType))
+ return false;
+ return true;
+ }
+
+ @Override
+ public int compareTo(final ExposedPortModel other) {
+ return this.containerPort.compareTo(other.containerPort);
+ }
+
+ }
+
+ public class ContainerLinkModel extends BaseDatabindingModel {
+
+ public static final String CONTAINER_NAME = "containerName";
+
+ public static final String CONTAINER_ALIAS = "containerAlias";
+
+ private String containerName;
+
+ private String containerAlias;
+
+ /**
+ * Default constructor
+ */
+ public ContainerLinkModel() {
+ }
+
+ public ContainerLinkModel(final String containerName,
+ final String alias) {
+ this.containerName = containerName;
+ this.containerAlias = alias;
+ }
+
+ public String getContainerName() {
+ return containerName;
+ }
+
+ public void setContainerName(String containerName) {
+ firePropertyChange(CONTAINER_NAME, this.containerName,
+ this.containerName = containerName);
+ }
+
+ public String getContainerAlias() {
+ return containerAlias;
+ }
+
+ public void setContainerAlias(String alias) {
+ firePropertyChange(CONTAINER_ALIAS, this.containerAlias, this.containerAlias = alias);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((containerAlias == null) ? 0 : containerAlias.hashCode());
+ result = prime * result
+ + ((containerName == null) ? 0 : containerName.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ContainerLinkModel other = (ContainerLinkModel) obj;
+ if (containerAlias == null) {
+ if (other.containerAlias != null)
+ return false;
+ } else if (!containerAlias.equals(other.containerAlias))
+ return false;
+ if (containerName == null) {
+ if (other.containerName != null)
+ return false;
+ } else if (!containerName.equals(other.containerName))
+ return false;
+ return true;
+ }
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionPage.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionPage.java
new file mode 100644
index 0000000000..afd833574c
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionPage.java
@@ -0,0 +1,900 @@
+/*******************************************************************************
+ * Copyright (c) 2014, 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.ui.wizards;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.databinding.DataBindingContext;
+import org.eclipse.core.databinding.beans.BeanProperties;
+import org.eclipse.core.databinding.observable.ChangeEvent;
+import org.eclipse.core.databinding.observable.IChangeListener;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.core.databinding.observable.list.WritableList;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.databinding.observable.value.IValueChangeListener;
+import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
+import org.eclipse.core.databinding.validation.MultiValidator;
+import org.eclipse.core.databinding.validation.ValidationStatus;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.databinding.swt.WidgetProperties;
+import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
+import org.eclipse.jface.databinding.viewers.ViewerSupport;
+import org.eclipse.jface.databinding.viewers.ViewersObservables;
+import org.eclipse.jface.databinding.wizard.WizardPageSupport;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.fieldassist.ComboContentAdapter;
+import org.eclipse.jface.fieldassist.ContentProposal;
+import org.eclipse.jface.fieldassist.ContentProposalAdapter;
+import org.eclipse.jface.fieldassist.ControlDecoration;
+import org.eclipse.jface.fieldassist.IContentProposal;
+import org.eclipse.jface.fieldassist.IContentProposalProvider;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.linuxtools.docker.core.DockerException;
+import org.eclipse.linuxtools.docker.core.IDockerConnection;
+import org.eclipse.linuxtools.docker.core.IDockerImage;
+import org.eclipse.linuxtools.docker.core.IDockerImageInfo;
+import org.eclipse.linuxtools.docker.core.IDockerImageSearchResult;
+import org.eclipse.linuxtools.docker.ui.Activator;
+import org.eclipse.linuxtools.internal.docker.ui.SWTImagesFactory;
+import org.eclipse.linuxtools.internal.docker.ui.commands.CommandUtils;
+import org.eclipse.linuxtools.internal.docker.ui.utils.IRunnableWithResult;
+import org.eclipse.linuxtools.internal.docker.ui.views.DVMessages;
+import org.eclipse.linuxtools.internal.docker.ui.views.ImagePullProgressHandler;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunSelectionModel.ContainerLinkModel;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunSelectionModel.ExposedPortModel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * A {@link WizardPage} to let the user select the {@link IDockerImage} to run
+ * and select the most common arguments (container name, port settings, etc.)
+ *
+ * @author xcoulon
+ *
+ */
+public class ImageRunSelectionPage extends WizardPage {
+
+ private static final int INDENT = 30;
+
+ private static final String ERROR_PULLING_IMAGE = "ImagePullError.msg"; //$NON-NLS-1$
+
+ private final DataBindingContext dbc = new DataBindingContext();
+ private final ImageRunSelectionModel model;
+ private CheckboxTableViewer exposedPortsTableViewer;
+
+ private static final int COLUMNS = 3;
+
+ /**
+ * Default constructor.
+ *
+ * @param selectedImage
+ * the {@link IDockerImage} to run
+ *
+ */
+ public ImageRunSelectionPage(final IDockerImage selectedImage) {
+ super("ImageSelectionPage", "Docker Container settings", //$NON-NLS-1$ //$NON-NLS-2$
+ SWTImagesFactory.DESC_BANNER_REPOSITORY);
+ setMessage("Run a Docker Image"); //$NON-NLS-1$
+ setPageComplete(true);
+ this.model = new ImageRunSelectionModel(selectedImage);
+ }
+
+ /**
+ * Default constructor.
+ *
+ * @param selectedConnection
+ * the {@link IDockerConnection} to run
+ *
+ */
+ public ImageRunSelectionPage(final IDockerConnection selectedConnection) {
+ super("ImageSelectionPage", //$NON-NLS-1$
+ "Image Selection and Exposed Port Publishing", //$NON-NLS-1$
+ SWTImagesFactory.DESC_BANNER_REPOSITORY);
+ setMessage("Select the Docker Image to run and the ports to expose"); //$NON-NLS-1$
+ setPageComplete(false);
+ this.model = new ImageRunSelectionModel(selectedConnection);
+ }
+
+ /**
+ * @return the {@link ImageRunSelectionModel} model associated
+ */
+ public ImageRunSelectionModel getModel() {
+ return model;
+ }
+
+ @Override
+ public void dispose() {
+ dbc.dispose();
+ super.dispose();
+ }
+
+ @Override
+ public void createControl(final Composite parent) {
+ final Composite container = new Composite(parent, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).span(1, 1)
+ .grab(true, false).applyTo(container);
+ GridLayoutFactory.fillDefaults().numColumns(COLUMNS).margins(6, 6)
+ .applyTo(container);
+ createImageSettingsSection(container);
+ createSectionSeparator(container, true);
+ createPortSettingsSection(container);
+ // addSectionSeparator(container, false);
+ createLinkSettingsSection(container);
+ // addSectionSeparator(container, false);
+ createRunOptionsSection(container);
+ // Observe model changes to propagate to the UI via listeners.
+ final IObservableValue imageSelectionObservable = BeanProperties
+ .value(ImageRunSelectionModel.class,
+ ImageRunSelectionModel.SELECTED_IMAGE_NAME)
+ .observe(model);
+ imageSelectionObservable
+ .addValueChangeListener(onImageSelectionChange());
+ setDefaultValues();
+ // setup validation support
+ WizardPageSupport.create(this, dbc);
+ // set validation
+ final ImageSelectionValidator imageSelectionValidator = new ImageSelectionValidator(
+ imageSelectionObservable);
+ dbc.addValidationStatusProvider(imageSelectionValidator);
+ //
+ setControl(container);
+ }
+
+ private void createSectionSeparator(final Composite container,
+ final boolean separator) {
+ final int SECTION_INDENT = 10;
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .span(COLUMNS, 1).grab(true, false)
+ .indent(SWT.DEFAULT, SECTION_INDENT)
+ .applyTo(new Label(container, separator
+ ? (SWT.SEPARATOR | SWT.HORIZONTAL) : SWT.NONE));
+ }
+
+ /**
+ * Creates the {@link Composite} container that will display widgets to
+ * select an {@link IDockerImage}, name it and specify the command to run.
+ *
+ * @param container
+ * the parent {@link Composite}
+ */
+ private void createImageSettingsSection(final Composite container) {
+ // Image selection name
+ final Label imageSelectionLabel = new Label(container, SWT.NONE);
+ imageSelectionLabel.setText("Image:"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(imageSelectionLabel);
+ final Combo imageSelectionCombo = new Combo(container, SWT.BORDER);
+ final ComboViewer imageSelectionComboViewer = new ComboViewer(
+ imageSelectionCombo);
+ imageSelectionCombo.setToolTipText("Select the Docker Image to run"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).span(1, 1).applyTo(imageSelectionCombo);
+ new ControlDecoration(imageSelectionCombo, SWT.TOP | SWT.LEFT);
+ new ContentProposalAdapter(imageSelectionCombo,
+ new ComboContentAdapter() {
+ @Override
+ public void insertControlContents(Control control,
+ String text, int cursorPosition) {
+ final Combo combo = (Combo) control;
+ final Point selection = combo.getSelection();
+ combo.setText(text);
+ selection.x = text.length();
+ selection.y = selection.x;
+ combo.setSelection(selection);
+ }
+ }, getImageNameContentProposalProvider(imageSelectionCombo),
+ null, null);
+ // image search
+ final Button searchImageButton = new Button(container, SWT.NONE);
+ searchImageButton.setText("Search..."); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).span(1, 1).applyTo(searchImageButton);
+ searchImageButton.addSelectionListener(onSearchImage());
+ // link to pull image
+ final Label fillerLabel = new Label(container, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).span(1, 1).applyTo(fillerLabel);
+ final Link pullImageLink = new Link(container, SWT.NONE);
+ pullImageLink.setText("<a>Pull this image...</a>");
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).span(COLUMNS - 1, 1).applyTo(pullImageLink);
+ pullImageLink.addSelectionListener(onPullImage());
+ dbc.bindValue(WidgetProperties.enabled().observe(pullImageLink),
+ BeanProperties
+ .value(ImageRunSelectionModel.class,
+ ImageRunSelectionModel.SELECTED_IMAGE_NEEDS_PULLING)
+ .observe(model));
+ // bind combo with model (for values and selection)
+ imageSelectionComboViewer
+ .setContentProvider(new ObservableListContentProvider());
+ dbc.bindList(WidgetProperties.items().observe(imageSelectionCombo),
+ BeanProperties
+ .list(ImageRunSelectionModel.class,
+ ImageRunSelectionModel.IMAGE_NAMES)
+ .observe(model));
+ dbc.bindValue(WidgetProperties.selection().observe(imageSelectionCombo),
+ BeanProperties
+ .value(ImageRunSelectionModel.class,
+ ImageRunSelectionModel.SELECTED_IMAGE_NAME)
+ .observe(model));
+ // Container name (optional)
+ final Label containerNameLabel = new Label(container, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(imageSelectionLabel);
+ containerNameLabel.setText("Name:"); //$NON-NLS-1$
+ final Text containerNameText = new Text(container, SWT.BORDER);
+ containerNameText.setToolTipText(
+ "a UUID long identifier, a UUID short identifier or a String"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).span(1, 1).applyTo(containerNameText);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).span(1, 1)
+ .applyTo(new Label(container, SWT.NONE));
+ dbc.bindValue(
+ WidgetProperties.text(SWT.Modify).observe(containerNameText),
+ BeanProperties
+ .value(ImageRunSelectionModel.class,
+ ImageRunSelectionModel.CONTAINER_NAME)
+ .observe(model));
+
+ // EntryPoint (optional)
+ final Label entrypointLabel = new Label(container, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(imageSelectionLabel);
+ entrypointLabel.setText("Entrypoint:"); //$NON-NLS-1$
+ // TODO: include SWT.SEARCH | SWT.ICON_SEARCH to support value reset
+ final Text entrypointText = new Text(container, SWT.BORDER);
+
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).span(1, 1).applyTo(entrypointText);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).span(1, 1)
+ .applyTo(new Label(container, SWT.NONE));
+ dbc.bindValue(WidgetProperties.text(SWT.Modify).observe(entrypointText),
+ BeanProperties
+ .value(ImageRunSelectionModel.class,
+ ImageRunSelectionModel.ENTRYPOINT)
+ .observe(model));
+
+ // Command (optional)
+ final Label commandLabel = new Label(container, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(imageSelectionLabel);
+ commandLabel.setText("Command:"); //$NON-NLS-1$
+ final Text commandText = new Text(container, SWT.BORDER);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).span(1, 1).applyTo(commandText);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).span(1, 1)
+ .applyTo(new Label(container, SWT.NONE));
+ dbc.bindValue(WidgetProperties.text(SWT.Modify).observe(commandText),
+ BeanProperties.value(ImageRunSelectionModel.class,
+ ImageRunSelectionModel.COMMAND).observe(model));
+ }
+
+ private void createPortSettingsSection(final Composite container) {
+ final Button publishAllPortsButton = new Button(container, SWT.CHECK);
+ publishAllPortsButton.setText(
+ "Publish all exposed ports to random ports on the host interfaces"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .span(COLUMNS, 1).grab(true, false)
+ .applyTo(publishAllPortsButton);
+ dbc.bindValue(
+ WidgetProperties.selection().observe(publishAllPortsButton),
+ BeanProperties
+ .value(ImageRunSelectionModel.class,
+ ImageRunSelectionModel.PUBLISH_ALL_PORTS)
+ .observe(model));
+ // specify ports
+ final Label portSettingsLabel = new Label(container, SWT.NONE);
+ portSettingsLabel.setText(
+ "Only publish the selected container ports below to the host:");
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).span(COLUMNS, 1).indent(INDENT, 0)
+ .applyTo(portSettingsLabel);
+ exposedPortsTableViewer = createPortSettingsTable(container);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP)
+ .grab(true, false).span(COLUMNS - 1, 1).indent(INDENT, 0)
+ .hint(200, 70).applyTo(exposedPortsTableViewer.getTable());
+ // buttons
+ final Composite buttonsContainers = new Composite(container, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP)
+ .grab(false, false).applyTo(buttonsContainers);
+ GridLayoutFactory.fillDefaults().numColumns(1).margins(0, 0)
+ .spacing(SWT.DEFAULT, 0).applyTo(buttonsContainers);
+
+ final Button addButton = new Button(buttonsContainers, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP)
+ .grab(true, false).applyTo(addButton);
+ addButton.setText("Add"); //$NON-NLS-1$
+ addButton.addSelectionListener(onAddPort());
+ final Button editButton = new Button(buttonsContainers, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP)
+ .grab(true, false).applyTo(editButton);
+ editButton.setText("Edit..."); //$NON-NLS-1$
+ editButton.setEnabled(false);
+ editButton.addSelectionListener(onEditPort(exposedPortsTableViewer));
+ final Button removeButton = new Button(buttonsContainers, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP)
+ .grab(true, false).applyTo(removeButton);
+ removeButton.setText("Remove"); //$NON-NLS-1$
+ removeButton
+ .addSelectionListener(onRemovePorts(exposedPortsTableViewer));
+ BeanProperties
+ .value(ImageRunSelectionModel.class,
+ ImageRunSelectionModel.PUBLISH_ALL_PORTS)
+ .observe(model)
+ .addValueChangeListener(onPublishAllPortsChange(
+ exposedPortsTableViewer.getTable(), addButton,
+ removeButton));
+ ViewerSupport.bind(exposedPortsTableViewer, model.getExposedPorts(),
+ BeanProperties.values(ExposedPortModel.class,
+ new String[] { ExposedPortModel.CONTAINER_PORT,
+ ExposedPortModel.PORT_TYPE,
+ ExposedPortModel.HOST_ADDRESS,
+ ExposedPortModel.HOST_PORT }));
+ dbc.bindSet(
+ ViewersObservables.observeCheckedElements(
+ exposedPortsTableViewer, ExposedPortModel.class),
+ BeanProperties.set(ImageRunSelectionModel.SELECTED_PORTS)
+ .observe(model));
+
+ togglePortMappingControls(exposedPortsTableViewer.getTable(), addButton,
+ removeButton);
+ }
+
+ private CheckboxTableViewer createPortSettingsTable(
+ final Composite container) {
+ final Table table = new Table(container, SWT.BORDER | SWT.FULL_SELECTION
+ | SWT.V_SCROLL | SWT.H_SCROLL | SWT.CHECK);
+ final CheckboxTableViewer tableViewer = new CheckboxTableViewer(table);
+ table.setHeaderVisible(true);
+ table.setLinesVisible(true);
+ createTableViewerColum(tableViewer, "Container Port", //$NON-NLS-1$
+ 100);
+ createTableViewerColum(tableViewer, "Type", //$NON-NLS-1$
+ 50);
+ createTableViewerColum(tableViewer, "Host Address", //$NON-NLS-1$
+ 100);
+ createTableViewerColum(tableViewer, "Host Port", //$NON-NLS-1$
+ 100);
+ tableViewer.setContentProvider(new ObservableListContentProvider());
+ return tableViewer;
+ }
+
+ private TableViewerColumn createTableViewerColum(
+ final TableViewer tableViewer, final String title,
+ final int width) {
+ final TableViewerColumn viewerColumn = new TableViewerColumn(
+ tableViewer, SWT.NONE);
+ final TableColumn column = viewerColumn.getColumn();
+ if (title != null) {
+ column.setText(title);
+ }
+ column.setWidth(width);
+ return viewerColumn;
+ }
+
+ private void createLinkSettingsSection(final Composite container) {
+ final Label linksLabel = new Label(container, SWT.NONE);
+ linksLabel.setText("Links to other containers:");
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).span(COLUMNS, 1).applyTo(linksLabel);
+ final TableViewer linksTableViewer = createLinksTable(container);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP).grab(true, true)
+ .span(COLUMNS - 1, 1).hint(200, 50).indent(INDENT, SWT.DEFAULT)
+ .applyTo(linksTableViewer.getTable());
+ // buttons
+ final Composite buttonsContainers = new Composite(container, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP)
+ .grab(false, false).applyTo(buttonsContainers);
+ GridLayoutFactory.fillDefaults().numColumns(1).margins(0, 0)
+ .spacing(SWT.DEFAULT, 0).applyTo(buttonsContainers);
+
+ final Button addButton = new Button(buttonsContainers, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP)
+ .grab(true, false).applyTo(addButton);
+ addButton.setText("Add..."); //$NON-NLS-1$
+ addButton.addSelectionListener(onAddLink());
+ final Button editButton = new Button(buttonsContainers, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP)
+ .grab(true, false).applyTo(editButton);
+ editButton.setText("Edit..."); //$NON-NLS-1$
+ editButton.setEnabled(false);
+ editButton.addSelectionListener(onEditLink(linksTableViewer));
+ final Button removeButton = new Button(buttonsContainers, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP)
+ .grab(true, false).applyTo(removeButton);
+ removeButton.setText("Remove"); //$NON-NLS-1$
+ removeButton.addSelectionListener(onRemoveLinks(linksTableViewer));
+ removeButton.setEnabled(false);
+ ViewerSupport
+ .bind(linksTableViewer, model.getLinks(),
+ BeanProperties.values(ContainerLinkModel.class,
+ new String[] {
+ ContainerLinkModel.CONTAINER_NAME,
+ ContainerLinkModel.CONTAINER_ALIAS }));
+ linksTableViewer.addSelectionChangedListener(
+ onLinkSelected(editButton, removeButton));
+ // disable the edit and removeButton if the table is empty
+ model.getLinks()
+ .addChangeListener(onRemoveLinks(editButton, removeButton));
+ }
+
+ private ISelectionChangedListener onLinkSelected(
+ final Control... controls) {
+ return new ISelectionChangedListener() {
+
+ @Override
+ public void selectionChanged(final SelectionChangedEvent e) {
+ if (e.getSelection().isEmpty()) {
+ setControlsEnabled(controls, false);
+ } else {
+ setControlsEnabled(controls, true);
+ }
+ }
+
+ };
+ }
+
+ private TableViewer createLinksTable(final Composite container) {
+ final Table table = new Table(container,
+ SWT.BORDER | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
+ final TableViewer tableViewer = new TableViewer(table);
+ table.setHeaderVisible(true);
+ table.setLinesVisible(true);
+ createTableViewerColum(tableViewer, "Container Name", //$NON-NLS-1$
+ 200);
+ createTableViewerColum(tableViewer, "Alias", //$NON-NLS-1$
+ 150);
+ return tableViewer;
+ }
+
+ private SelectionListener onAddLink() {
+ return new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ final ContainerLinkDialog dialog = new ContainerLinkDialog(
+ getShell(), model.getSelectedConnection());
+ dialog.create();
+ if (dialog.open() == IDialogConstants.OK_ID) {
+ model.addLink(dialog.getContainerName(),
+ dialog.getContainerAlias());
+ }
+ }
+ };
+ }
+
+ private SelectionListener onEditLink(final TableViewer linksTableViewer) {
+ return new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ final IStructuredSelection selection = linksTableViewer
+ .getStructuredSelection();
+
+ final ContainerLinkModel selectedContainerLink = (ContainerLinkModel) selection
+ .getFirstElement();
+ final ContainerLinkDialog dialog = new ContainerLinkDialog(
+ getShell(), model.getSelectedConnection(),
+ selectedContainerLink);
+ dialog.create();
+ if (dialog.open() == IDialogConstants.OK_ID) {
+ selectedContainerLink
+ .setContainerName(dialog.getContainerName());
+ selectedContainerLink
+ .setContainerAlias(dialog.getContainerAlias());
+ linksTableViewer.refresh();
+ }
+ }
+ };
+ }
+
+ private IChangeListener onRemoveLinks(final Button... buttons) {
+ return new IChangeListener() {
+
+ @Override
+ public void handleChange(final ChangeEvent event) {
+ @SuppressWarnings("unchecked")
+ final List<ContainerLinkModel> links = (List<ContainerLinkModel>) event
+ .getSource();
+ if (links.isEmpty()) {
+ setControlsEnabled(buttons, false);
+ }
+ }
+ };
+ }
+
+ private SelectionListener onRemoveLinks(
+ final TableViewer linksTableViewer) {
+ return new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ final IStructuredSelection selection = linksTableViewer
+ .getStructuredSelection();
+ for (@SuppressWarnings("unchecked")
+ Iterator<ContainerLinkModel> iterator = selection
+ .iterator(); iterator.hasNext();) {
+ model.removeLink(iterator.next());
+ }
+ }
+ };
+ }
+
+ private void createRunOptionsSection(final Composite container) {
+ // interactive/show in console mode
+ final Button interactiveButton = new Button(container, SWT.CHECK);
+ interactiveButton.setText(
+ "Keep STDIN open to Console even if not attached (-i)"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .span(COLUMNS, 1).grab(true, false).applyTo(interactiveButton);
+ dbc.bindValue(WidgetProperties.selection().observe(interactiveButton),
+ BeanProperties
+ .value(ImageRunSelectionModel.class,
+ ImageRunSelectionModel.INTERACTIVE_MODE)
+ .observe(model));
+ // allocate pseudo-TTY
+ final Button allocatePseudoTTY = new Button(container, SWT.CHECK);
+ allocatePseudoTTY.setText("Allocate pseudo-TTY from Console (-t)"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .span(COLUMNS, 1).grab(true, false).applyTo(allocatePseudoTTY);
+ dbc.bindValue(WidgetProperties.selection().observe(allocatePseudoTTY),
+ BeanProperties
+ .value(ImageRunSelectionModel.class,
+ ImageRunSelectionModel.ALLOCATE_PSEUDO_TTY)
+ .observe(model));
+
+ // remove when exits
+ final Button removeWhenExitsButton = new Button(container, SWT.CHECK);
+ removeWhenExitsButton.setText(
+ "Automatically remove the container when it exits (--rm)"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .span(COLUMNS, 1).grab(true, false)
+ .applyTo(removeWhenExitsButton);
+ dbc.bindValue(
+ WidgetProperties.selection().observe(removeWhenExitsButton),
+ BeanProperties
+ .value(ImageRunSelectionModel.class,
+ ImageRunSelectionModel.REMOVE_WHEN_EXITS)
+ .observe(model));
+ }
+
+ /**
+ * Creates an {@link IContentProposalProvider} to propose
+ * {@link IDockerImage} names based on the current text.
+ *
+ * @param items
+ * @return
+ */
+ private IContentProposalProvider getImageNameContentProposalProvider(
+ final Combo imageSelectionCombo) {
+ return new IContentProposalProvider() {
+
+ @Override
+ public IContentProposal[] getProposals(final String contents,
+ final int position) {
+ final List<IContentProposal> proposals = new ArrayList<>();
+ for (String imageName : imageSelectionCombo.getItems()) {
+ if (imageName.contains(contents)) {
+ proposals.add(new ContentProposal(imageName, imageName,
+ imageName, position));
+ }
+ }
+ return proposals.toArray(new IContentProposal[0]);
+ }
+ };
+ }
+
+ private IValueChangeListener onImageSelectionChange() {
+ return new IValueChangeListener() {
+
+ @Override
+ public void handleValueChange(final ValueChangeEvent event) {
+ final IDockerImage selectedImage = model.getSelectedImage();
+ // skip if the selected image does not exist in the local Docker
+ // host
+ if (selectedImage == null) {
+ model.setExposedPorts(new WritableList());
+ return;
+ }
+ findImageInfo(selectedImage);
+ }
+ };
+ }
+
+ private SelectionListener onPullImage() {
+ return new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ pullSelectedImage();
+ }
+ };
+ }
+
+ private IValueChangeListener onPublishAllPortsChange(
+ final Control... controls) {
+ return new IValueChangeListener() {
+
+ @Override
+ public void handleValueChange(final ValueChangeEvent event) {
+ togglePortMappingControls(controls);
+ }
+ };
+ }
+
+ private SelectionListener onSearchImage() {
+ return new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ final ImageSearch imageSearchWizard = new ImageSearch(
+ ImageRunSelectionPage.this.model
+ .getSelectedConnection());
+ final boolean completed = CommandUtils
+ .openWizard(imageSearchWizard, getShell());
+ if (completed) {
+ final IDockerImageSearchResult selectedSearchImage = imageSearchWizard
+ .getSelectedImage();
+ if (selectedSearchImage.getName().contains(":")) {
+ model.setSelectedImageName(
+ selectedSearchImage.getName());
+ } else {
+ // assume tag is 'latest'
+ model.setSelectedImageName(
+ selectedSearchImage.getName() + ":latest"); //$NON-NLS-1$
+ }
+ }
+ }
+ };
+ }
+
+ private SelectionListener onAddPort() {
+ return new SelectionAdapter() {
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ final ContainerPortDialog dialog = new ContainerPortDialog(
+ getShell());
+ dialog.create();
+ if (dialog.open() == IDialogConstants.OK_ID) {
+ model.addAvailablePort(dialog.getPort());
+ }
+ }
+ };
+ }
+
+ private SelectionListener onEditPort(final TableViewer portsTableViewer) {
+ return new SelectionAdapter() {
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ final IStructuredSelection selection = portsTableViewer
+ .getStructuredSelection();
+ final ExposedPortModel selectedContainerPort = (ExposedPortModel) selection
+ .getFirstElement();
+ final ContainerPortDialog dialog = new ContainerPortDialog(
+ getShell(), selectedContainerPort);
+ dialog.create();
+ if (dialog.open() == IDialogConstants.OK_ID) {
+ final ExposedPortModel configuredPort = dialog.getPort();
+ selectedContainerPort.setContainerPort(
+ configuredPort.getContainerPort());
+ selectedContainerPort
+ .setHostAddress(configuredPort.getHostAddress());
+ selectedContainerPort
+ .setHostPort(configuredPort.getHostPort());
+ portsTableViewer.refresh();
+ }
+ }
+ };
+ }
+
+ private SelectionListener onRemovePorts(
+ final TableViewer portsTableViewer) {
+ return new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ final IStructuredSelection selection = portsTableViewer
+ .getStructuredSelection();
+ for (@SuppressWarnings("unchecked")
+ Iterator<ExposedPortModel> iterator = selection
+ .iterator(); iterator.hasNext();) {
+ model.removeAvailablePort(iterator.next());
+ }
+ }
+ };
+ }
+
+ private void setDefaultValues() {
+ final IDockerImage selectedImage = model.getSelectedImage();
+ if (selectedImage == null) {
+ return;
+ }
+ findImageInfo(selectedImage);
+ }
+
+ private void findImageInfo(final IDockerImage selectedImage) {
+ try {
+ final FindImageInfoRunnable findImageInfoRunnable = new FindImageInfoRunnable(
+ selectedImage);
+ getContainer().run(true, true, findImageInfoRunnable);
+ final IDockerImageInfo selectedImageInfo = findImageInfoRunnable
+ .getResult();
+ final Set<String> exposedPorts = selectedImageInfo.config()
+ .exposedPorts();
+ final WritableList availablePorts = new WritableList();
+ if (exposedPorts != null) {
+ for (String exposedPort : exposedPorts) {
+ final String privatePort = exposedPort.substring(0,
+ exposedPort.indexOf('/'));
+ final String type = exposedPort
+ .substring(exposedPort.indexOf('/'));
+ availablePorts.add(
+ new ExposedPortModel(privatePort, type, "", ""));
+ }
+ }
+ model.setExposedPorts(availablePorts);
+ model.setCommand(selectedImageInfo.config().cmd());
+ model.setEntrypoint(selectedImageInfo.config().entrypoint());
+
+ } catch (InvocationTargetException | InterruptedException e) {
+ Activator.log(e);
+ }
+ }
+
+ private void togglePortMappingControls(final Control... controls) {
+ for (Control control : controls) {
+ if (model.isPublishAllPorts()) {
+ control.setEnabled(false);
+ } else {
+ control.setEnabled(true);
+ }
+ }
+ }
+
+ private void pullSelectedImage() {
+ try {
+ getContainer().run(true, true, new IRunnableWithProgress() {
+
+ @Override
+ public void run(final IProgressMonitor monitor)
+ throws InterruptedException {
+ final IDockerConnection connection = model
+ .getSelectedConnection();
+ final String imageName = model.getSelectedImageName();
+ monitor.beginTask("Pulling image '" + imageName + "'", 1);
+ try {
+ connection.pullImage(imageName,
+ new ImagePullProgressHandler(connection,
+ imageName));
+ } catch (final DockerException e) {
+ Display.getDefault().syncExec(new Runnable() {
+ @Override
+ public void run() {
+ MessageDialog.openError(
+ Display.getCurrent().getActiveShell(),
+ DVMessages.getFormattedString(
+ ERROR_PULLING_IMAGE, imageName),
+ e.getMessage());
+ }
+ });
+ } finally {
+ monitor.done();
+ // refresh the widgets
+ model.refreshImageNames();
+ if (model.getImageNames().contains(imageName)) {
+ model.setSelectedImageName(imageName);
+ }
+ }
+ }
+ });
+ } catch (InvocationTargetException | InterruptedException e) {
+ Activator.log(e);
+ }
+ }
+
+ private static void setControlsEnabled(final Control[] controls,
+ final boolean enabled) {
+ for (Control control : controls) {
+ control.setEnabled(enabled);
+ }
+ }
+
+ private static final class FindImageInfoRunnable
+ implements IRunnableWithResult<IDockerImageInfo> {
+ private final IDockerImage selectedImage;
+ private IDockerImageInfo selectedImageInfo;
+
+ private FindImageInfoRunnable(IDockerImage selectedImage) {
+ this.selectedImage = selectedImage;
+ }
+
+ @Override
+ public void run(final IProgressMonitor monitor) {
+ selectedImageInfo = selectedImage.getConnection()
+ .getImageInfo(selectedImage.id());
+ }
+
+ @Override
+ public IDockerImageInfo getResult() {
+ return selectedImageInfo;
+ }
+ }
+
+ private class ImageSelectionValidator extends MultiValidator {
+
+ private final IObservableValue imageSelectionObservable;
+
+ ImageSelectionValidator(
+ final IObservableValue imageSelectionObservable) {
+ this.imageSelectionObservable = imageSelectionObservable;
+ }
+
+ @Override
+ protected IStatus validate() {
+ final String selectedImageName = (String) imageSelectionObservable
+ .getValue();
+ if (selectedImageName.isEmpty()) {
+ model.setSelectedImageNeedsPulling(false);
+ return ValidationStatus
+ .error("Please specify the image to run."); //$NON-NLS-1$
+ }
+ if (model.getSelectedImage() != null) {
+ model.setSelectedImageNeedsPulling(false);
+ return ValidationStatus.ok();
+ }
+ model.setSelectedImageNeedsPulling(true);
+ return ValidationStatus.warning("Image named '" + selectedImageName
+ + "' does not exist locally. Click on the link under the 'Image' combo to start pulling it."); //$NON-NLS-1$
+ }
+
+ @Override
+ public IObservableList getTargets() {
+ WritableList targets = new WritableList();
+ targets.add(imageSelectionObservable);
+ return targets;
+ }
+
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearch.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearch.java
new file mode 100644
index 0000000000..efbb20621d
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearch.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2014, 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.ui.wizards;
+
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.linuxtools.docker.core.IDockerConnection;
+import org.eclipse.linuxtools.docker.core.IDockerImageSearchResult;;
+
+/**
+ * Wizard to search for images.
+ *
+ * @author xcoulon
+ *
+ */
+public class ImageSearch extends Wizard {
+
+ /** the Image Search {@link WizardPage}. */
+ private final ImageSearchPage searchPage;
+
+ /** the databinding model for the {@link ImageSearchPage}. */
+ private final ImageSearchModel model;
+
+ /**
+ * Default Constructor
+ */
+ public ImageSearch(final IDockerConnection connection) {
+ setNeedsProgressMonitor(true);
+ this.model = new ImageSearchModel(connection);
+ this.searchPage = new ImageSearchPage(this.model);
+ }
+
+ @Override
+ public void addPages() {
+ addPage(searchPage);
+ }
+
+ @Override
+ public boolean canFinish() {
+ return this.searchPage.isPageComplete();
+ }
+
+ @Override
+ public boolean performFinish() {
+ return true;
+ }
+
+ public IDockerImageSearchResult getSelectedImage() {
+ return this.model.getSelectedImage();
+ }
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearchModel.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearchModel.java
new file mode 100644
index 0000000000..a43985393e
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearchModel.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2014, 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.ui.wizards;
+
+import java.util.List;
+
+import org.eclipse.linuxtools.docker.core.IDockerConnection;
+import org.eclipse.linuxtools.docker.core.IDockerImageSearchResult;
+import org.eclipse.linuxtools.internal.docker.ui.databinding.BaseDatabindingModel;
+
+/**
+ * Databinding model for the {@link ImageSearchPage}
+ *
+ * @author xcoulon
+ *
+ */
+public class ImageSearchModel extends BaseDatabindingModel {
+
+ public static final String TERM = "term"; //$NON-NLS-1$
+
+ public static final String SELECTED_IMAGE = "selectedImage"; //$NON-NLS-1$
+
+ public static final String SEARCH_RESULT = "searchResult"; //$NON-NLS-1$
+
+ private final IDockerConnection selectedConnection;
+
+ private String term = null;
+
+ private IDockerImageSearchResult selectedImage;
+
+ private List<IDockerImageSearchResult> searchResult;
+
+ public ImageSearchModel(final IDockerConnection selectedConnection) {
+ this.selectedConnection = selectedConnection;
+ }
+
+ public IDockerConnection getSelectedConnection() {
+ return selectedConnection;
+ }
+
+ public String getTerm() {
+ return term;
+ }
+
+ public void setTerm(final String term) {
+ firePropertyChange(TERM, this.term, this.term = term);
+ }
+
+ public IDockerImageSearchResult getSelectedImage() {
+ return this.selectedImage;
+ }
+
+ public void setSelectedImage(final IDockerImageSearchResult selectedImage) {
+ firePropertyChange(SELECTED_IMAGE, this.selectedImage,
+ this.selectedImage = selectedImage);
+ }
+
+ public List<IDockerImageSearchResult> getSearchResult() {
+ return searchResult;
+ }
+
+ public void setSearchResult(
+ final List<IDockerImageSearchResult> searchResult) {
+ firePropertyChange(SEARCH_RESULT, this.searchResult,
+ this.searchResult = searchResult);
+ // set the first item as the selected image
+ if (!this.searchResult.isEmpty()) {
+ setSelectedImage(this.searchResult.get(0));
+ }
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearchPage.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearchPage.java
new file mode 100644
index 0000000000..2b860a0afb
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearchPage.java
@@ -0,0 +1,395 @@
+/*******************************************************************************
+ * Copyright (c) 2014, 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.ui.wizards;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.core.databinding.DataBindingContext;
+import org.eclipse.core.databinding.beans.BeanProperties;
+import org.eclipse.core.databinding.beans.PojoProperties;
+import org.eclipse.core.databinding.observable.ChangeEvent;
+import org.eclipse.core.databinding.observable.IChangeListener;
+import org.eclipse.core.databinding.observable.list.IObservableList;
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.databinding.observable.value.IValueChangeListener;
+import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.databinding.swt.WidgetProperties;
+import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
+import org.eclipse.jface.databinding.viewers.ViewerProperties;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.CellLabelProvider;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.StyledCellLabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.linuxtools.docker.core.DockerException;
+import org.eclipse.linuxtools.docker.core.IDockerImageSearchResult;
+import org.eclipse.linuxtools.docker.ui.Activator;
+import org.eclipse.linuxtools.internal.docker.ui.SWTImagesFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.events.TraverseEvent;
+import org.eclipse.swt.events.TraverseListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * @author xcoulon
+ *
+ */
+public class ImageSearchPage extends WizardPage {
+
+ private final ImageSearchModel model;
+ private Button searchImageButton;
+ private final DataBindingContext ctx = new DataBindingContext();
+
+ /**
+ * Default constructor.
+ */
+ public ImageSearchPage(final ImageSearchModel model) {
+ super("ImageSearchPage", "Search the Docker Registry for images", //$NON-NLS-1$ //$NON-NLS-2$
+ SWTImagesFactory.DESC_BANNER_REPOSITORY);
+ setMessage("Search the Docker Registry for images"); //$NON-NLS-1$
+ this.model = model;
+ }
+
+ @Override
+ public void dispose() {
+ ctx.dispose();
+ super.dispose();
+ }
+
+ @Override
+ public void createControl(final Composite parent) {
+ final int COLUMNS = 3;
+ final Composite container = new Composite(parent, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).span(1, 1)
+ .grab(true, false).applyTo(container);
+ GridLayoutFactory.fillDefaults().numColumns(COLUMNS).margins(6, 6)
+ .spacing(10, 2).applyTo(container);
+ // search text
+ final Label searchImageLabel = new Label(container, SWT.NONE);
+ searchImageLabel.setText("Image:"); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(searchImageLabel);
+ final Text searchImageText = new Text(container,
+ SWT.BORDER | SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).applyTo(searchImageText);
+ searchImageText.addKeyListener(onKeyPressed());
+ searchImageText.addTraverseListener(onSearchImageTextTraverse());
+ searchImageButton = new Button(container, SWT.NONE);
+ searchImageButton.setText("Search");
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(searchImageButton);
+ searchImageButton.addSelectionListener(onSearchImageButtonSelected());
+ searchImageButton.setEnabled(!searchImageText.getText().isEmpty());
+ // result table
+ final Label searchResultLabel = new Label(container, SWT.NONE);
+ searchResultLabel.setText("Matching images");
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).span(COLUMNS, 1).applyTo(searchResultLabel);
+ final Table table = new Table(container,
+ SWT.BORDER | SWT.FULL_SELECTION | SWT.V_SCROLL | SWT.H_SCROLL);
+ final TableViewer searchResultTableViewer = new TableViewer(table);
+ table.setHeaderVisible(true);
+ table.setLinesVisible(true);
+ addTableViewerColum(searchResultTableViewer, "Name", SWT.NONE, //$NON-NLS-1$
+ SWT.RIGHT, 290, new ImageNameColumnLabelProvider());
+ addTableViewerColum(searchResultTableViewer, "Stars", SWT.NONE, //$NON-NLS-1$
+ SWT.RIGHT,
+ 70, new ImageStarsColumnLabelProvider());
+ addTableViewerColum(searchResultTableViewer, "Official", SWT.NONE, //$NON-NLS-1$
+ SWT.CENTER,
+ 70, new ImageOfficialColumnLabelProvider());
+ addTableViewerColum(searchResultTableViewer, "Automated", SWT.NONE, //$NON-NLS-1$
+ SWT.CENTER,
+ 70, new ImageAutomatedColumnLabelProvider());
+ searchResultTableViewer
+ .setContentProvider(new ObservableListContentProvider());
+ // searchResultTableViewer.addSelectionChangedListener(onImageSelected());
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).span(COLUMNS, 1).hint(200, 100)
+ .applyTo(table);
+ // description text area
+ final Group selectedImageDescriptionGroup = new Group(container,
+ SWT.BORDER);
+ selectedImageDescriptionGroup.setText("Description");
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, true).span(COLUMNS, 1)
+ .applyTo(selectedImageDescriptionGroup);
+ GridLayoutFactory.fillDefaults().margins(6, 6).spacing(10, 2)
+ .applyTo(selectedImageDescriptionGroup);
+ final Label selectedImageDescription = new Label(
+ selectedImageDescriptionGroup, SWT.WRAP);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, true).hint(200, 100)
+ .applyTo(selectedImageDescription);
+ // bind the search term
+ final IObservableValue observableTermModel = BeanProperties
+ .value(ImageSearchModel.class, ImageSearchModel.TERM)
+ .observe(model);
+ ctx.bindValue(
+ WidgetProperties.text(SWT.Modify).observe(searchImageText),
+ observableTermModel);
+ // enable/disable the search button
+ observableTermModel.addValueChangeListener(new IValueChangeListener() {
+
+ @Override
+ public void handleValueChange(final ValueChangeEvent event) {
+ final String term = (String) event.getObservableValue()
+ .getValue();
+ if (term.isEmpty()) {
+ searchImageButton.setEnabled(false);
+ } else {
+ searchImageButton.setEnabled(true);
+ }
+ }
+ });
+ // observe the viewer content
+ final IObservableList observableSearchResultModel = BeanProperties
+ .list(ImageSearchModel.class,
+ ImageSearchModel.SEARCH_RESULT)
+ .observe(model);
+ observableSearchResultModel.addChangeListener(new IChangeListener() {
+
+ @Override
+ public void handleChange(ChangeEvent event) {
+ searchResultTableViewer.setInput(event.getObservable());
+
+ }
+ });
+ // observe the viewer selection
+ ctx.bindValue(
+ ViewerProperties.singleSelection()
+ .observe(searchResultTableViewer),
+ BeanProperties.value(ImageSearchModel.SELECTED_IMAGE)
+ .observe(model));
+ // observe the viewer selection to update the description label
+ final IObservableValue observableSelectedImageDescription = PojoProperties
+ .value("description", String.class)
+ .observeDetail(ViewerProperties.singleSelection()
+ .observe(searchResultTableViewer));
+ ctx.bindValue(WidgetProperties.text().observe(selectedImageDescription),
+ observableSelectedImageDescription);
+ searchImageText.setFocus();
+ setControl(parent);
+ }
+
+ private TableViewerColumn addTableViewerColum(final TableViewer tableViewer,
+ final String title, final int style, final int alignment,
+ final int width, final CellLabelProvider columnLabelProvider) {
+ final TableViewerColumn viewerColumn = new TableViewerColumn(
+ tableViewer, style);
+ final TableColumn column = viewerColumn.getColumn();
+ if (title != null) {
+ column.setText(title);
+ }
+ column.setAlignment(alignment);
+ column.setWidth(width);
+ viewerColumn.setLabelProvider(columnLabelProvider);
+ return viewerColumn;
+ }
+
+ private TraverseListener onSearchImageTextTraverse() {
+ return new TraverseListener() {
+
+ @Override
+ public void keyTraversed(final TraverseEvent e) {
+ if (e.keyCode == SWT.CR) {
+ e.doit = false;
+ }
+ }
+ };
+ }
+
+ private KeyListener onKeyPressed() {
+ return new KeyAdapter() {
+
+ @Override
+ public void keyReleased(final KeyEvent event) {
+ if (event.character == SWT.CR
+ && !ImageSearchPage.this.model.getTerm().isEmpty()) {
+ searchImages();
+ }
+ }
+ };
+ }
+
+ private SelectionListener onSearchImageButtonSelected() {
+ return new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(final SelectionEvent event) {
+ searchImages();
+ }
+ };
+ }
+
+ private void searchImages() {
+ final String term = this.model.getTerm();
+ if (term.isEmpty()) {
+ return;
+ }
+ try {
+ final BlockingQueue<List<IDockerImageSearchResult>> searchResultQueue = new ArrayBlockingQueue<>(
+ 1);
+ ImageSearchPage.this.getContainer().run(true, true,
+ new IRunnableWithProgress() {
+ @Override
+ public void run(IProgressMonitor monitor)
+ throws InvocationTargetException,
+ InterruptedException {
+ monitor.beginTask("Searching...", 1);
+ try {
+ final List<IDockerImageSearchResult> searchResults = ImageSearchPage.this.model
+ .getSelectedConnection()
+ .searchImages(term);
+ monitor.beginTask("Searching...", 1);
+ searchResultQueue.offer(searchResults);
+ } catch (DockerException e) {
+ Activator.log(e);
+ }
+ monitor.done();
+ }
+ });
+ final List<IDockerImageSearchResult> searchResult = searchResultQueue
+ .poll(10, TimeUnit.SECONDS);
+ Display.getCurrent().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ ImageSearchPage.this.model.setSearchResult(searchResult);
+ // refresh the wizard buttons
+ getWizard().getContainer().updateButtons();
+ }
+ });
+ // display a warning in the title area if the search result is empty
+ if (searchResult.isEmpty()) {
+ this.setMessage("No image matched the specified term.",
+ WARNING);
+ } else if (searchResult.size() == 1) {
+ this.setMessage("1 image matched the specified term.",
+ INFORMATION);
+ } else {
+ this.setMessage(
+ searchResult.size()
+ + " images matched the specified term.",
+ INFORMATION);
+ }
+ } catch (InvocationTargetException | InterruptedException e) {
+ Activator.log(e);
+ }
+ }
+
+ @Override
+ public boolean isPageComplete() {
+ return this.model.getSelectedImage() != null;
+ }
+
+ static class ImageNameColumnLabelProvider extends ColumnLabelProvider {
+
+ @Override
+ public String getText(final Object element) {
+ if (element instanceof IDockerImageSearchResult) {
+ return ((IDockerImageSearchResult) element).getName();
+ }
+ return super.getText(element);
+ }
+ }
+
+ static class ImageStarsColumnLabelProvider extends ColumnLabelProvider {
+
+ @Override
+ public String getText(final Object element) {
+ if (element instanceof IDockerImageSearchResult) {
+ return Integer.toString(
+ ((IDockerImageSearchResult) element).getStarCount());
+ }
+ return super.getText(element);
+ }
+ }
+
+ static class ImageOfficialColumnLabelProvider
+ extends IconColumnLabelProvider {
+
+ @Override
+ boolean doPaint(final Object element) {
+ return element instanceof IDockerImageSearchResult
+ && ((IDockerImageSearchResult) element).isOfficial();
+ }
+
+ }
+
+ static class ImageAutomatedColumnLabelProvider
+ extends IconColumnLabelProvider {
+
+ @Override
+ boolean doPaint(final Object element) {
+ return element instanceof IDockerImageSearchResult
+ && ((IDockerImageSearchResult) element).isAutomated();
+ }
+
+ }
+
+ static abstract class IconColumnLabelProvider
+ extends StyledCellLabelProvider {
+
+ private static final Image ICON = SWTImagesFactory.DESC_CHECKED
+ .createImage();
+
+ @Override
+ protected void measure(Event event, Object element) {
+ Rectangle rectangle = ICON.getBounds();
+ event.setBounds(new Rectangle(event.x, event.y,
+ rectangle.width + 200, rectangle.height));
+
+ }
+
+ @Override
+ protected void paint(final Event event, final Object element) {
+ final TableColumn column = ((TableViewerColumn) getColumn())
+ .getColumn();
+ final int columnWidth = column.getWidth();
+ if (doPaint(element)) {
+ final Rectangle bounds = event.getBounds();
+ event.gc.drawImage(ICON,
+ bounds.x + (columnWidth - ICON.getBounds().width) / 2,
+ bounds.y + 1);
+ }
+ }
+
+ abstract boolean doPaint(final Object element);
+
+ }
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/NewDockerConnection.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/NewDockerConnection.java
index 2c4e12d297..293dbd5d58 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/NewDockerConnection.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/NewDockerConnection.java
@@ -40,9 +40,6 @@ public class NewDockerConnection extends Wizard {
addPage(wizardPage);
}
- /* (non-Javadoc)
- * @see org.eclipse.jface.wizard.Wizard#performFinish()
- */
@Override
public boolean performFinish() {
try {
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/NewDockerConnectionPage.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/NewDockerConnectionPage.java
index 8dd5f4ab6b..54ef2921b6 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/NewDockerConnectionPage.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/NewDockerConnectionPage.java
@@ -28,6 +28,7 @@ import org.eclipse.linuxtools.docker.core.DockerException;
import org.eclipse.linuxtools.docker.core.EnumDockerConnectionSettings;
import org.eclipse.linuxtools.docker.ui.Activator;
import org.eclipse.linuxtools.internal.docker.core.DockerConnection;
+import org.eclipse.linuxtools.internal.docker.ui.SWTImagesFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
@@ -42,8 +43,6 @@ import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
-import com.spotify.docker.client.DockerCertificateException;
-
/**
* @author xcoulon
*
@@ -70,8 +69,8 @@ public class NewDockerConnectionPage extends WizardPage {
private Text tcpCertPathText;
public NewDockerConnectionPage() {
- super("NewDockerConnectionPage", "Connect to a Docker daemon", Activator
- .getImageDescriptor("icons/banner-repository.gif"));
+ super("NewDockerConnectionPage", "Connect to a Docker daemon",
+ SWTImagesFactory.DESC_BANNER_REPOSITORY);
setMessage("Select the binding mode to connect to the Docker daemon");
}
@@ -112,7 +111,6 @@ public class NewDockerConnectionPage extends WizardPage {
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).applyTo(connectionNameLabel);
connectionNameText = new Text(container, SWT.BORDER);
connectionNameText.setToolTipText("Name of the connection");
- //connectionNameText.setText(this.connectionName);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).span(2, 1)
.applyTo(connectionNameText);
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/WizardUtils.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/WizardUtils.java
new file mode 100644
index 0000000000..d2c390e0da
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/WizardUtils.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * 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.ui.wizards;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.linuxtools.docker.core.IDockerConnection;
+import org.eclipse.linuxtools.docker.core.IDockerContainer;
+
+/**
+ * @author xcoulon
+ *
+ */
+public class WizardUtils {
+
+ /**
+ * @param connection
+ * the current {@link IDockerContainer}
+ * @return the {@link List} of name of the {@link IDockerContainer}
+ */
+ public static List<String> getContainerNames(
+ final IDockerConnection connection) {
+ final List<String> containerNames = new ArrayList<>();
+ for (IDockerContainer container : connection.getContainers()) {
+ containerNames.add(container.name());
+ }
+ Collections.sort(containerNames);
+ return containerNames;
+ }
+
+ /**
+ * Finds and returns the {@link IDockerContainer} with the given name
+ *
+ * @param connection
+ * the current {@link IDockerConnection}
+ * @param containerName
+ * the {@link IDockerContainer} name
+ * @return the matching {@link IDockerContainer} of <code>null</code> if
+ * none was found.
+ */
+ public static IDockerContainer getContainer(
+ final IDockerConnection connection, final String containerName) {
+ if (containerName != null && !containerName.isEmpty()) {
+ for (IDockerContainer container : connection.getContainers()) {
+ if (container.name().equals(containerName)) {
+ return container;
+ }
+ }
+ }
+ return null;
+
+ }
+
+}
diff --git a/releng/org.eclipse.linuxtools.target/.project b/releng/org.eclipse.linuxtools.target/.project
index 7ea15ad813..085f734c6c 100644
--- a/releng/org.eclipse.linuxtools.target/.project
+++ b/releng/org.eclipse.linuxtools.target/.project
@@ -5,7 +5,13 @@
<projects>
</projects>
<buildSpec>
+ <buildCommand>
+ <name>org.eclipse.m2e.core.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
</buildSpec>
<natures>
+ <nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>
diff --git a/releng/org.eclipse.linuxtools.target/.settings/org.eclipse.core.resources.prefs b/releng/org.eclipse.linuxtools.target/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000000..99f26c0203
--- /dev/null
+++ b/releng/org.eclipse.linuxtools.target/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/releng/org.eclipse.linuxtools.target/.settings/org.eclipse.m2e.core.prefs b/releng/org.eclipse.linuxtools.target/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000000..f897a7f1cb
--- /dev/null
+++ b/releng/org.eclipse.linuxtools.target/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1

Back to the top