Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Johnston2015-11-19 19:33:27 +0000
committerJeff Johnston2015-11-27 20:29:07 +0000
commit973a63e7cf4f298667cb06c5aa76982bf27a71bc (patch)
treede4f09f76495df318916f1c9e413c5dafff9c84e
parenta3ab852e583f4174ff460aa4cac114104896d68e (diff)
downloadorg.eclipse.linuxtools-973a63e7cf4f298667cb06c5aa76982bf27a71bc.tar.gz
org.eclipse.linuxtools-973a63e7cf4f298667cb06c5aa76982bf27a71bc.tar.xz
org.eclipse.linuxtools-973a63e7cf4f298667cb06c5aa76982bf27a71bc.zip
Bug 471662 - Refactor the run image wizard into a launcher
- fill in the RunDockerImageLaunchConfigurationDelegate - create main, ports, links, volumes, and environment tabs using existing Run Image wizard models and a tab group to group them - add launch extensions to Docker UI plug-in - change some existing wizard model classes to add toString() methods and create methods that take an output string Change-Id: I2aefcde43e9b3f239fd89b13db7ec22fd319b9bc Reviewed-on: https://git.eclipse.org/r/60825 Reviewed-by: Xavier Coulon <xcoulon@redhat.com> Tested-by: Hudson CI Reviewed-by: Jeff Johnston <jjohnstn@redhat.com>
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/icons/environment_co.gifbin0 -> 614 bytes
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/icons/links_obj.gifbin0 -> 159 bytes
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/icons/main_tab.gifbin0 -> 360 bytes
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/icons/ports_tab.gifbin0 -> 152 bytes
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/icons/volumes.gifbin0 -> 588 bytes
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/plugin.xml8
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/SWTImagesFactory.java17
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/RunImageCommandHandler.java2
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/IRunDockerImageLaunchConfigurationConstants.java10
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/LaunchConfigurationUtils.java39
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/LaunchMessages.properties9
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunDockerImageLaunchConfigurationDelegate.java291
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageEnvironmentTab.java317
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageLaunchConfigurationTabGroup.java63
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageLinksTab.java300
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageMainTab.java633
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImagePortsTab.java428
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageResourcesTab.java297
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageVolumesTab.java549
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerDataVolumeDialog.java4
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerEnvironmentVariableDialog.java2
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerLinkDialog.java2
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ContainerPortDialog.java2
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/DataVolumeModel.java64
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/EnvironmentVariableModel.java11
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunResourceVolumesVariablesModel.java11
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionModel.java150
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/WizardMessages.properties1
28 files changed, 3178 insertions, 32 deletions
diff --git a/containers/org.eclipse.linuxtools.docker.ui/icons/environment_co.gif b/containers/org.eclipse.linuxtools.docker.ui/icons/environment_co.gif
new file mode 100644
index 0000000000..716df436f9
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/icons/environment_co.gif
Binary files differ
diff --git a/containers/org.eclipse.linuxtools.docker.ui/icons/links_obj.gif b/containers/org.eclipse.linuxtools.docker.ui/icons/links_obj.gif
new file mode 100644
index 0000000000..6123b270e8
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/icons/links_obj.gif
Binary files differ
diff --git a/containers/org.eclipse.linuxtools.docker.ui/icons/main_tab.gif b/containers/org.eclipse.linuxtools.docker.ui/icons/main_tab.gif
new file mode 100644
index 0000000000..0193dbeab7
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/icons/main_tab.gif
Binary files differ
diff --git a/containers/org.eclipse.linuxtools.docker.ui/icons/ports_tab.gif b/containers/org.eclipse.linuxtools.docker.ui/icons/ports_tab.gif
new file mode 100644
index 0000000000..68d40f7e2d
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/icons/ports_tab.gif
Binary files differ
diff --git a/containers/org.eclipse.linuxtools.docker.ui/icons/volumes.gif b/containers/org.eclipse.linuxtools.docker.ui/icons/volumes.gif
new file mode 100644
index 0000000000..c13bea1ca4
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/icons/volumes.gif
Binary files differ
diff --git a/containers/org.eclipse.linuxtools.docker.ui/plugin.xml b/containers/org.eclipse.linuxtools.docker.ui/plugin.xml
index 49e7208b77..1d40098d8a 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/plugin.xml
+++ b/containers/org.eclipse.linuxtools.docker.ui/plugin.xml
@@ -1455,4 +1455,12 @@
</contextualLaunch>
</shortcut>
</extension>
+ <extension
+ point="org.eclipse.debug.ui.launchConfigurationTabGroups">
+ <launchConfigurationTabGroup
+ class="org.eclipse.linuxtools.internal.docker.ui.launch.RunImageLaunchConfigurationTabGroup"
+ id="org.eclipse.linuxtools.docker.ui.runLaunchConfigurationTabGroup"
+ type="org.eclipse.linuxtools.docker.ui.runDockerImageLaunchConfigurationType">
+ </launchConfigurationTabGroup>
+ </extension>
</plugin>
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 1f7d7b89e8..b500320a20 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
@@ -57,16 +57,21 @@ public class SWTImagesFactory {
+ "docker_small.gif"; //$NON-NLS-1$
public static final String IMG_WIZARD = NAME_PREFIX
+ "banner-repository.gif"; //$NON-NLS-1$
+ public static final String IMG_ENV = NAME_PREFIX + "environment_co.gif"; //$NON-NLS-1$
public static final String IMG_FILTER = NAME_PREFIX + "filter_ps.gif"; //$NON-NLS-1$
public static final String IMG_KILL = NAME_PREFIX + "kill.gif"; //$NON-NLS-1$
public static final String IMG_KILLD = NAME_PREFIX + "killd.gif"; //$NON-NLS-1$
+ public static final String IMG_LINKS = NAME_PREFIX + "links_obj.gif"; //$NON-NLS-1$
+ public static final String IMG_MAIN_TAB = NAME_PREFIX + "main_tab.gif"; //$NON-NLS-1$
public static final String IMG_PULL = NAME_PREFIX + "pull.gif"; //$NON-NLS-1$
public static final String IMG_PUSH = NAME_PREFIX + "push.gif"; //$NON-NLS-1$
public static final String IMG_BUILD = NAME_PREFIX + "build_exec.png"; //$NON-NLS-1$
public static final String IMG_PAUSE = NAME_PREFIX + "suspend.gif"; //$NON-NLS-1$
public static final String IMG_PAUSE_D = NAME_PREFIX + "suspendd.gif"; //$NON-NLS-1$
+ public static final String IMG_PORTS_TAB = NAME_PREFIX + "ports_tab.gif"; //$NON-NLS-1$
public static final String IMG_REMOVE = NAME_PREFIX + "delete.gif"; //$NON-NLS-1$
public static final String IMG_REMOVE_D = NAME_PREFIX + "delete_d.gif"; //$NON-NLS-1$
+ public static final String IMG_RESOURCE = NAME_PREFIX + "resource_obj.gif"; //$NON-NLS-1$
public static final String IMG_RESUME = NAME_PREFIX + "resume.gif"; //$NON-NLS-1$
public static final String IMG_RESUME_D = NAME_PREFIX + "resumed.gif"; //$NON-NLS-1$
public static final String IMG_START = NAME_PREFIX + "running.gif"; //$NON-NLS-1$
@@ -100,6 +105,7 @@ public class SWTImagesFactory {
public static final String IMG_RESOLVED = NAME_PREFIX + "resolved.gif"; //$NON-NLS-1$
public static final String IMG_BANNER_REPOSITORY = NAME_PREFIX
+ "banner-repository.gif"; //$NON-NLS-1$
+ public static final String IMG_VOLUMES = NAME_PREFIX + "volumes.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$
@@ -107,6 +113,7 @@ public class SWTImagesFactory {
IMG_CONNECTION);
public static final ImageDescriptor DESC_CREATE_CONTAINER = createManaged(
"", IMG_CREATE_CONTAINER);
+ public static final ImageDescriptor DESC_ENV = createManaged("", IMG_ENV);
public static final ImageDescriptor DESC_FOLDER = createManaged("",
IMG_FOLDER);
public static final ImageDescriptor DESC_FOLDER_CLOSED = createManaged("",
@@ -121,6 +128,8 @@ public class SWTImagesFactory {
public static final ImageDescriptor DESC_KILL = createManaged("", IMG_KILL);
public static final ImageDescriptor DESC_KILLD = createManaged("",
IMG_KILLD);
+ public static final ImageDescriptor DESC_LINKS = createManaged("",
+ IMG_LINKS);
public static final ImageDescriptor DESC_DOCKER_LARGE = createManaged("",
IMG_DOCKER_LARGE);
public static final ImageDescriptor DESC_DOCKER_SMALL = createManaged("",
@@ -129,6 +138,8 @@ public class SWTImagesFactory {
IMG_WIZARD);
public static final ImageDescriptor DESC_FILTER = createManaged("",
IMG_FILTER);
+ public static final ImageDescriptor DESC_MAIN_TAB = createManaged("",
+ IMG_MAIN_TAB);
public static final ImageDescriptor DESC_PULL = createManaged("", IMG_PULL);
public static final ImageDescriptor DESC_PUSH = createManaged("", IMG_PUSH);
public static final ImageDescriptor DESC_BUILD = createManaged("",
@@ -137,10 +148,14 @@ public class SWTImagesFactory {
IMG_PAUSE);
public static final ImageDescriptor DESC_PAUSE_D = createManaged("",
IMG_PAUSE_D);
+ public static final ImageDescriptor DESC_PORTS_TAB = createManaged("",
+ IMG_PORTS_TAB);
public static final ImageDescriptor DESC_REMOVE = createManaged("",
IMG_REMOVE);
public static final ImageDescriptor DESC_REMOVE_D = createManaged("",
IMG_REMOVE_D);
+ public static final ImageDescriptor DESC_RESOURCE = createManaged("",
+ IMG_RESOURCE);
public static final ImageDescriptor DESC_RESUME = createManaged("",
IMG_RESUME);
public static final ImageDescriptor DESC_RESUME_D = createManaged("",
@@ -186,6 +201,8 @@ public class SWTImagesFactory {
IMG_RESOLVED);
public static final ImageDescriptor DESC_BANNER_REPOSITORY = createManaged(
"", IMG_BANNER_REPOSITORY);
+ public static final ImageDescriptor DESC_VOLUMES = createManaged("",
+ IMG_VOLUMES);
public static final ImageDescriptor DESC_WARNING = createManaged("",
IMG_WARNING);
public static final ImageDescriptor DESC_ERROR = createManaged("",
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
index f4c151caa5..3366b39b0e 100644
--- 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
@@ -81,7 +81,7 @@ public class RunImageCommandHandler extends AbstractHandler {
return null;
}
- private void runImage(final IDockerConnection connection,
+ public static void runImage(final IDockerConnection connection,
final IDockerContainerConfig containerConfig,
final IDockerHostConfig hostConfig, final String containerName,
final boolean removeWhenExits) {
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/IRunDockerImageLaunchConfigurationConstants.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/IRunDockerImageLaunchConfigurationConstants.java
index 08690ba432..421ce39d8d 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/IRunDockerImageLaunchConfigurationConstants.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/IRunDockerImageLaunchConfigurationConstants.java
@@ -28,7 +28,7 @@ public interface IRunDockerImageLaunchConfigurationConstants {
public static final String PUBLISH_ALL_PORTS = "publishAllPorts"; //$NON-NLS-1$
- public static final String PUBLISH_PORTS = "publishPorts"; //$NON-NLS-1$
+ public static final String PUBLISHED_PORTS = "publishedPorts"; //$NON-NLS-1$
public static final String LINKS = "links"; //$NON-NLS-1$
@@ -40,10 +40,18 @@ public interface IRunDockerImageLaunchConfigurationConstants {
public static final String DATA_VOLUME = "volumes"; //$NON-NLS-1$
+ public static final String VOLUMES_FROM = "volumesFrom"; //$NON-NLS-1$
+
+ public static final String BINDS = "binds"; //$NON-NLS-1$
+
public static final String ENV_VARIABLES = "envVariables"; //$NON-NLS-1$
+ public static final String ENABLE_LIMITS = "enableLimits"; //$NON-NLS-1$
+
public static final String CPU_PRIORITY = "cpuPriority"; //$NON-NLS-1$
public static final String MEMORY_LIMIT = "memoryLimit"; //$NON-NLS-1$
+ public static final String CONNECTION_NAME = "connectionName"; //$NON-NLS-1$
+
}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/LaunchConfigurationUtils.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/LaunchConfigurationUtils.java
index d6bfe12699..da431b0487 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/LaunchConfigurationUtils.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/LaunchConfigurationUtils.java
@@ -15,16 +15,24 @@ import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLa
import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.CONTAINER_NAME;
import static org.eclipse.linuxtools.internal.docker.ui.launch.IRunDockerImageLaunchConfigurationConstants.IMAGE_NAME;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.layout.PixelConverter;
import org.eclipse.linuxtools.docker.core.IDockerContainer;
import org.eclipse.linuxtools.docker.ui.Activator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Button;
/**
* Utility class to manage {@link ILaunchConfiguration}
@@ -75,6 +83,15 @@ public class LaunchConfigurationUtils {
return null;
}
+ public static int getButtonWidthHint(Button button) {
+ /* button.setFont(JFaceResources.getDialogFont()); */
+ PixelConverter converter = new PixelConverter(button);
+ int widthHint = converter
+ .convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
+ return Math.max(widthHint,
+ button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
+ }
+
public static ILaunchConfiguration getLaunchConfiguration(
final ILaunchConfigurationType type, final String name)
throws CoreException {
@@ -89,4 +106,26 @@ public class LaunchConfigurationUtils {
return null;
}
+ public static String convertToUnixPath(String path) {
+ String unixPath = path;
+
+ if (Platform.OS_WIN32.equals(Platform.getOS())) {
+ // replace backslashes with slashes
+ unixPath = unixPath.replaceAll("\\\\", "/");
+
+ // replace "C:/" with "/c/"
+ Matcher m = Pattern.compile("([a-zA-Z]):/").matcher(unixPath);
+ if (m.find()) {
+ StringBuffer b = new StringBuffer();
+ b.append('/');
+ m.appendReplacement(b, m.group(1).toLowerCase());
+ b.append('/');
+ m.appendTail(b);
+ unixPath = b.toString();
+ }
+ }
+
+ return unixPath;
+ }
+
}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/LaunchMessages.properties b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/LaunchMessages.properties
index 0ee5026d15..0f26bfc90a 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/LaunchMessages.properties
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/LaunchMessages.properties
@@ -40,5 +40,14 @@ ImageBuildShortcutChooseConnection.msg=Choose the Docker Connection to use
MissingConnectionError.msg=No Docker connection named ''{0}'' exists.
RunDockerImageLaunchConfiguration.creation.failure=Failed to save launch configuration for the image to run
+RunDockerImageLaunchConfiguration.load.failure=Failed to load launch configuration
+
+RunMainTab.name=Main
+RunMainTabSelectConnection.tooltip=Select the Docker Connection to use
+RunVolumesTab.name=Volumes
+RunPortsTab.name=Ports
+RunLinksTab.name=Links
+RunResourcesTab.name=Resources
+RunEnvTab.name=Environment
NoConnectionError.msg=No Docker connection exists \ No newline at end of file
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunDockerImageLaunchConfigurationDelegate.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunDockerImageLaunchConfigurationDelegate.java
index 22649da1f0..49801052b4 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunDockerImageLaunchConfigurationDelegate.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunDockerImageLaunchConfigurationDelegate.java
@@ -11,10 +11,37 @@
package org.eclipse.linuxtools.internal.docker.ui.launch;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.model.ILaunchConfigurationDelegate;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.IDebugModelPresentation;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.linuxtools.docker.core.DockerConnectionManager;
+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.docker.ui.Activator;
+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.SWTImagesFactory;
+import org.eclipse.linuxtools.internal.docker.ui.commands.RunImageCommandHandler;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.ElementListSelectionDialog;
/**
* Launch configuration delegate for running Docker Images
@@ -22,11 +49,273 @@ import org.eclipse.debug.core.model.ILaunchConfigurationDelegate;
public class RunDockerImageLaunchConfigurationDelegate
implements ILaunchConfigurationDelegate {
+ private static final String LaunchShortcut_Connection_Selection = "ImageBuildShortcutConnectionSelection.title"; //$NON-NLS-1$
+ private static final String LaunchShortcut_Choose_Connection = "ImageBuildShortcutChooseConnection.msg"; //$NON-NLS-1$
+
@Override
public void launch(ILaunchConfiguration configuration, String mode,
ILaunch launch, IProgressMonitor monitor) {
- // TODO Auto-generated method stub
+ try {
+ ILaunchConfiguration config = launch.getLaunchConfiguration();
+ final IDockerContainerConfig containerConfig = getDockerContainerConfig(
+ config);
+ final IDockerHostConfig hostConfig = getDockerHostConfig(config);
+ final IDockerConnection connection = getDockerConnection(config);
+ if (connection == null)
+ return;
+ RunImageCommandHandler.runImage(connection, containerConfig,
+ hostConfig,
+ config.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.CONTAINER_NAME,
+ (String) null),
+ config.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.AUTO_REMOVE,
+ false));
+ } catch (CoreException e) {
+ Activator.log(e);
+ }
+ }
+
+ public IDockerHostConfig getDockerHostConfig(ILaunchConfiguration config)
+ throws CoreException {
+
+ final DockerHostConfig.Builder hostConfigBuilder = new DockerHostConfig.Builder();
+ if (config.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.PUBLISH_ALL_PORTS,
+ false)) {
+ hostConfigBuilder.publishAllPorts(true);
+ } else {
+ final Map<String, List<IDockerPortBinding>> portBindings = new HashMap<>();
+ Map<String, String> ports = config.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.PUBLISHED_PORTS,
+ new HashMap<String, String>());
+ for (Map.Entry<String, String> entry : ports.entrySet()) {
+ String key = entry.getKey();
+ String entryValue = entry.getValue();
+
+ String[] portPairs = entryValue.split("\\s*,\\s*"); //$NON-NLS-1$
+
+ for (int i = 0; i < portPairs.length; i += 2) {
+ DockerPortBinding portBinding = new DockerPortBinding(
+ portPairs[i], portPairs[i + 1]);
+ portBindings.put(key,
+ Arrays.<IDockerPortBinding> asList(portBinding));
+ }
+ }
+ hostConfigBuilder.portBindings(portBindings);
+ }
+ // container links
+ final List<String> links = config.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.LINKS,
+ new ArrayList<String>());
+ hostConfigBuilder.links(links);
+
+ // data volumes
+
+ List<String> volumesFromList = config.getAttribute(IRunDockerImageLaunchConfigurationConstants.VOLUMES_FROM, new ArrayList<String>());
+ hostConfigBuilder.volumesFrom(volumesFromList);
+
+ final List<String> binds = new ArrayList<>();
+
+ List<String> bindsList = config.getAttribute(IRunDockerImageLaunchConfigurationConstants.BINDS, new ArrayList<String>());
+
+ for (String bindsListEntry : bindsList) {
+ String[] bindsEntryParms = bindsListEntry.split(":"); //$NON-NLS-1$
+ String bind = LaunchConfigurationUtils.convertToUnixPath(
+ bindsEntryParms[0]) + ':'
+ + bindsEntryParms[1] + ':' + 'Z';
+ if (bindsEntryParms[2].equals("true")) {
+ bind += ",ro"; //$NON-NLS-1$
+ }
+ binds.add(bind);
+
+ }
+ hostConfigBuilder.binds(binds);
+
+ return hostConfigBuilder.build();
+ }
+
+ public IDockerContainerConfig getDockerContainerConfig(
+ ILaunchConfiguration lconfig) throws CoreException {
+
+ String commandAsString = lconfig.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.COMMAND, ""); //$NON-NLS-1$
+ List<String> command = getCmdList(commandAsString);
+ String entrypoint = lconfig.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.ENTRYPOINT, ""); //$NON-NLS-1$
+ String imageName = lconfig.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.IMAGE_NAME, ""); //$NON-NLS-1$
+ boolean useTTY = lconfig.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.ALLOCATE_PSEUDO_CONSOLE,
+ false);
+ boolean interactive = lconfig.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.INTERACTIVE, false);
+
+ final Builder config = new DockerContainerConfig.Builder().cmd(command)
+ .entryPoint(entrypoint).image(imageName).tty(useTTY)
+ .openStdin(interactive);
+ boolean limits_enabled = lconfig.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.ENABLE_LIMITS,
+ false);
+ if (limits_enabled) {
+ int memory = lconfig.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.MEMORY_LIMIT,
+ 0);
+ int cpuShares = lconfig.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.CPU_PRIORITY,
+ 0);
+ config.memory(Long.valueOf(memory) * 1048576);
+ config.cpuShares(Long.valueOf(cpuShares));
+ }
+ // environment variables
+ final List<String> environmentVariables = lconfig.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.ENV_VARIABLES,
+ new ArrayList<String>());
+ config.env(environmentVariables);
+ return config.build();
+ }
+
+ private IDockerConnection getDockerConnection(ILaunchConfiguration config)
+ throws CoreException {
+ String configName = config.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.CONNECTION_NAME,
+ ""); //$NON-NLS-1$
+ IDockerConnection connection = DockerConnectionManager.getInstance()
+ .findConnection(configName);
+ if (connection == null) {
+ connection = chooseConnection(
+ DockerConnectionManager.getInstance().getConnections());
+ }
+ return connection;
+ }
+
+ // Create a proper command list after handling quotation.
+ 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;
+ }
+
+ private class ConnectionSelectionLabelProvider implements ILabelProvider {
+ @Override
+ public void removeListener(ILabelProviderListener listener) {
+ }
+
+ @Override
+ public boolean isLabelProperty(Object element, String property) {
+ return false;
+ }
+
+ @Override
+ public void dispose() {
+ }
+
+ @Override
+ public void addListener(ILabelProviderListener listener) {
+ }
+
+ @Override
+ public String getText(Object element) {
+ return element.toString();
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ return SWTImagesFactory.DESC_REPOSITORY_MIDDLE.createImage();
+ }
+ }
+
+ /**
+ * Show a selection dialog that allows the user to choose one of the
+ * connections to use to build the Image.
+ *
+ * @param connections
+ * Array of connections.
+ * @return The chosen connection, or <code>null</code> if the user cancelled
+ * the dialog.
+ */
+ protected IDockerConnection chooseConnection(
+ final IDockerConnection[] connections) {
+ IDebugModelPresentation labelProvider = DebugUITools
+ .newDebugModelPresentation();
+ ElementListSelectionDialog dialog = new ElementListSelectionDialog(
+ getActiveWorkbenchShell(),
+ new ConnectionSelectionLabelProvider() {
+
+ });
+
+ dialog.setElements(connections);
+ dialog.setTitle(
+ LaunchMessages.getString(LaunchShortcut_Connection_Selection));
+ dialog.setMessage(
+ LaunchMessages.getString(LaunchShortcut_Choose_Connection));
+ dialog.setMultipleSelection(false);
+ int result = dialog.open();
+ labelProvider.dispose();
+ if (result == IStatus.OK) {
+ return (IDockerConnection) dialog.getFirstResult();
+ }
+ return null;
+ }
+ /**
+ * Get the active Workbench shell.
+ *
+ * @return active shell as returned by the plug-in
+ */
+ protected Shell getActiveWorkbenchShell() {
+ return Activator.getActiveWorkbenchShell();
}
}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageEnvironmentTab.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageEnvironmentTab.java
new file mode 100644
index 0000000000..d5fce1e7e7
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageEnvironmentTab.java
@@ -0,0 +1,317 @@
+/*******************************************************************************
+ * 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.launch;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.databinding.beans.BeanProperties;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
+import org.eclipse.jface.databinding.viewers.ViewerSupport;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+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.linuxtools.docker.ui.Activator;
+import org.eclipse.linuxtools.internal.docker.ui.SWTImagesFactory;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ContainerEnvironmentVariableDialog;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.EnvironmentVariableModel;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunResourceVolumesVariablesModel;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.WizardMessages;
+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.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+public class RunImageEnvironmentTab extends AbstractLaunchConfigurationTab {
+
+ private static final String TAB_NAME = "RunEnvTab.name"; //$NON-NLS-1$
+
+ private static final int COLUMNS = 3;
+
+ private ImageRunResourceVolumesVariablesModel model = null;
+
+ public RunImageEnvironmentTab(ImageRunResourceVolumesVariablesModel model) {
+ this.model = model;
+ }
+
+ @Override
+ public void createControl(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);
+ if (model == null) {
+ setErrorMessage(LaunchMessages.getString("NoConnectionError.msg"));
+ } else {
+ setErrorMessage(null);
+ createEnvironmentVariablesContainer(container);
+ }
+ setControl(container);
+ }
+
+ private void createEnvironmentVariablesContainer(
+ final Composite container) {
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).span(3, 1)
+ .applyTo(new Label(container, SWT.NONE));
+ final Label envVarLabel = new Label(container, SWT.NONE);
+ envVarLabel.setText(WizardMessages
+ .getString("ImageRunResourceVolVarPage.envVarLabel")); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).span(COLUMNS, 1).applyTo(envVarLabel);
+ 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(WizardMessages
+ .getString("ImageRunResourceVolVarPage.addButton")); //$NON-NLS-1$
+ addButton.setEnabled(true);
+ addButton.addSelectionListener(
+ onAddEnvironmentVariable(environmentVariablesTableViewer));
+ final Button editButton = new Button(buttonsContainers, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP)
+ .grab(true, false).applyTo(editButton);
+ editButton.setText(WizardMessages
+ .getString("ImageRunResourceVolVarPage.editButton")); //$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(WizardMessages
+ .getString("ImageRunResourceVolVarPage.removeButton")); //$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 }));
+
+ // disable the edit and removeButton if the table is empty
+ environmentVariablesTableViewer.addSelectionChangedListener(
+ onSelectionChanged(editButton, removeButton));
+ }
+
+ private ISelectionChangedListener onSelectionChanged(
+ final Button... targetButtons) {
+ return new ISelectionChangedListener() {
+
+ @Override
+ public void selectionChanged(final SelectionChangedEvent e) {
+ if (e.getSelection().isEmpty()) {
+ setControlsEnabled(targetButtons, false);
+ } else {
+ setControlsEnabled(targetButtons, true);
+ }
+ updateLaunchConfigurationDialog();
+ }
+
+ };
+ }
+
+ private TableViewerColumn addTableViewerColumn(
+ 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 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);
+ addTableViewerColumn(tableViewer,
+ WizardMessages
+ .getString("ImageRunResourceVolVarPage.nameColumn"), //$NON-NLS-1$
+ 200);
+ addTableViewerColumn(tableViewer,
+ WizardMessages
+ .getString("ImageRunResourceVolVarPage.valueColumn"), //$NON-NLS-1$
+ 200);
+ tableViewer.setContentProvider(new ObservableListContentProvider());
+ return tableViewer;
+ }
+
+ private SelectionListener onAddEnvironmentVariable(
+ final TableViewer environmentVariablesTableViewer) {
+ 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());
+ environmentVariablesTableViewer
+ .add(dialog.getEnvironmentVariable());
+ environmentVariablesTableViewer.refresh();
+ updateLaunchConfigurationDialog();
+ }
+ }
+ };
+ }
+
+ 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();
+ }
+ updateLaunchConfigurationDialog();
+ }
+ };
+ }
+
+ private SelectionListener onRemoveEnvironmentVariables(
+ final TableViewer environmentVariablesTableViewer) {
+ return new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ final IStructuredSelection selection = environmentVariablesTableViewer
+ .getStructuredSelection();
+ for (@SuppressWarnings("unchecked")
+ Iterator<EnvironmentVariableModel> iterator = selection
+ .iterator(); iterator.hasNext();) {
+ EnvironmentVariableModel m = iterator.next();
+ model.removeEnvironmentVariable(m);
+ environmentVariablesTableViewer.remove(m);
+ environmentVariablesTableViewer.refresh();
+ }
+ updateLaunchConfigurationDialog();
+ }
+ };
+ }
+
+ private static void setControlsEnabled(final Control[] controls,
+ final boolean enabled) {
+ for (Control control : controls) {
+ control.setEnabled(enabled);
+ }
+ }
+
+ @Override
+ public Image getImage() {
+ return SWTImagesFactory.get(SWTImagesFactory.IMG_ENV);
+ }
+
+ @Override
+ public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
+ }
+
+ @Override
+ public void initializeFrom(ILaunchConfiguration configuration) {
+ try {
+ model.removeEnvironmentVariables();
+ final List<String> environmentVariables = configuration
+ .getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.ENV_VARIABLES,
+ new ArrayList<String>());
+ for (String environmenVariable : environmentVariables) {
+ model.addEnvironmentVariable(EnvironmentVariableModel
+ .createEnvironmentVariableModel(environmenVariable));
+ }
+ } catch (CoreException e) {
+ Activator.logErrorMessage(
+ LaunchMessages.getString(
+ "RunDockerImageLaunchConfiguration.load.failure"), //$NON-NLS-1$
+ e);
+ }
+ // update the underlying launch config working copy on model
+ // changes.
+ model.addPropertyChangeListener(
+ new LaunchConfigurationChangeListener());
+
+ }
+
+ private class LaunchConfigurationChangeListener
+ implements PropertyChangeListener {
+
+ @Override
+ public void propertyChange(final PropertyChangeEvent evt) {
+ updateLaunchConfigurationDialog();
+ }
+ }
+
+ @Override
+ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+ ArrayList<String> envList = new ArrayList<>();
+ for (Object o : model.getEnvironmentVariables()) {
+ EnvironmentVariableModel m = (EnvironmentVariableModel) o;
+ envList.add(m.toString());
+ }
+ configuration.setAttribute(
+ IRunDockerImageLaunchConfigurationConstants.ENV_VARIABLES,
+ envList);
+ }
+
+ @Override
+ public String getName() {
+ return LaunchMessages.getString(TAB_NAME);
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageLaunchConfigurationTabGroup.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageLaunchConfigurationTabGroup.java
new file mode 100644
index 0000000000..50f095f606
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageLaunchConfigurationTabGroup.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * 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.launch;
+
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
+import org.eclipse.debug.ui.ILaunchConfigurationDialog;
+import org.eclipse.linuxtools.docker.core.DockerConnectionManager;
+import org.eclipse.linuxtools.docker.core.DockerException;
+import org.eclipse.linuxtools.docker.core.IDockerConnection;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunResourceVolumesVariablesModel;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunSelectionModel;
+
+public class RunImageLaunchConfigurationTabGroup
+ extends AbstractLaunchConfigurationTabGroup {
+
+ private ImageRunSelectionModel runSelectionModel;
+ private ImageRunResourceVolumesVariablesModel runVolumesModel;
+
+ public RunImageLaunchConfigurationTabGroup() {
+ }
+
+ public ImageRunSelectionModel getRunSelectionModel() {
+ return runSelectionModel;
+ }
+
+ public ImageRunResourceVolumesVariablesModel getRunVolumesModel() {
+ return runVolumesModel;
+ }
+
+ @Override
+ public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
+ IDockerConnection[] connections = DockerConnectionManager.getInstance()
+ .getConnections();
+ runSelectionModel = null;
+ runVolumesModel = null;
+ if (connections != null && connections.length > 0) {
+ runSelectionModel = new ImageRunSelectionModel(connections[0]);
+ try {
+ runVolumesModel = new ImageRunResourceVolumesVariablesModel(
+ connections[0]);
+ } catch (DockerException e) {
+ // do nothing
+ }
+ }
+ setTabs(new AbstractLaunchConfigurationTab[] {
+ new RunImageMainTab(runSelectionModel, runVolumesModel),
+ new RunImageVolumesTab(runVolumesModel),
+ new RunImagePortsTab(runSelectionModel),
+ new RunImageLinksTab(runSelectionModel),
+ new RunImageEnvironmentTab(runVolumesModel),
+ new RunImageResourcesTab(runVolumesModel) });
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageLinksTab.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageLinksTab.java
new file mode 100644
index 0000000000..850798e51b
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageLinksTab.java
@@ -0,0 +1,300 @@
+/*******************************************************************************
+ * 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.launch;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.databinding.beans.BeanProperties;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
+import org.eclipse.jface.databinding.viewers.ViewerSupport;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+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.linuxtools.internal.docker.ui.SWTImagesFactory;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ContainerLinkDialog;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunSelectionModel;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunSelectionModel.ContainerLinkModel;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.WizardMessages;
+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.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+public class RunImageLinksTab extends AbstractLaunchConfigurationTab {
+
+ private static final String TAB_NAME = "RunLinksTab.name"; //$NON-NLS-1$
+
+ private static final int COLUMNS = 3;
+
+ private ImageRunSelectionModel model = null;
+
+ public RunImageLinksTab(ImageRunSelectionModel model) {
+ this.model = model;
+ }
+
+ @Override
+ public void createControl(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);
+ if (model == null) {
+ setErrorMessage(LaunchMessages.getString("NoConnectionError.msg"));
+ } else {
+ setErrorMessage(null);
+ createLinkSettingsSection(container);
+ }
+ setControl(container);
+ }
+
+ private TableViewerColumn createTableViewerColumn(
+ 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) {
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).span(3, 1)
+ .applyTo(new Label(container, SWT.NONE));
+ final Label linksLabel = new Label(container, SWT.NONE);
+ linksLabel.setText(
+ WizardMessages.getString("ImageRunSelectionPage.links"));
+ 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)
+ .hint(200, 100).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(
+ WizardMessages.getString("ImageRunSelectionPage.addButton")); //$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(
+ WizardMessages.getString("ImageRunSelectionPage.editButton")); //$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(
+ WizardMessages.getString("ImageRunSelectionPage.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 }));
+ // disable the edit and removeButton if the table is empty
+ linksTableViewer.addSelectionChangedListener(
+ onSelectionChanged(editButton, removeButton));
+
+ }
+
+ private ISelectionChangedListener onSelectionChanged(
+ final Button... targetButtons) {
+ return new ISelectionChangedListener() {
+
+ @Override
+ public void selectionChanged(final SelectionChangedEvent e) {
+ if (e.getSelection().isEmpty()) {
+ setControlsEnabled(targetButtons, false);
+ } else {
+ setControlsEnabled(targetButtons, true);
+ }
+ updateLaunchConfigurationDialog();
+ }
+ };
+ }
+
+ private TableViewer createLinksTable(final 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);
+ createTableViewerColumn(tableViewer,
+ WizardMessages
+ .getString("ImageRunSelectionPage.containerNameColumn"), //$NON-NLS-1$
+ 200);
+ createTableViewerColumn(tableViewer,
+ WizardMessages.getString("ImageRunSelectionPage.aliasColumn"), //$NON-NLS-1$
+ 150);
+ tableViewer.setContentProvider(new ObservableListContentProvider());
+ 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());
+ }
+ updateLaunchConfigurationDialog();
+ }
+ };
+ }
+
+ 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();
+ updateLaunchConfigurationDialog();
+ }
+ }
+ };
+ }
+
+ 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());
+ }
+ updateLaunchConfigurationDialog();
+ }
+ };
+ }
+
+ private static void setControlsEnabled(final Control[] controls,
+ final boolean enabled) {
+ for (Control control : controls) {
+ control.setEnabled(enabled);
+ }
+ }
+
+ @Override
+ public Image getImage() {
+ return SWTImagesFactory.get(SWTImagesFactory.IMG_CONTAINER_LINK);
+ }
+
+ @Override
+ public void setDefaults(
+ final ILaunchConfigurationWorkingCopy configuration) {
+ }
+
+ @Override
+ public void initializeFrom(final ILaunchConfiguration configuration) {
+ try {
+ // model needs to be recycled
+ model.removeLinks();
+ final List<String> containerLinks = configuration.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.LINKS,
+ new ArrayList<String>());
+ for (String containerLink : containerLinks) {
+ model.addLink(ImageRunSelectionModel.ContainerLinkModel
+ .createContainerLinkModel(containerLink));
+ }
+ } catch (CoreException e) {
+ // do nothing
+ }
+ // update the underlying launch config working copy on model
+ // changes.
+ model.addPropertyChangeListener(
+ new LaunchConfigurationChangeListener());
+ }
+
+ @Override
+ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+ ArrayList<String> linksList = new ArrayList<>();
+ for (Object o : model.getLinks()) {
+ ImageRunSelectionModel.ContainerLinkModel m = (ImageRunSelectionModel.ContainerLinkModel) o;
+ linksList.add(m.toString());
+ }
+ configuration.setAttribute(
+ IRunDockerImageLaunchConfigurationConstants.LINKS, linksList);
+ }
+
+ @Override
+ public String getName() {
+ return LaunchMessages.getString(TAB_NAME);
+ }
+
+ private class LaunchConfigurationChangeListener
+ implements PropertyChangeListener {
+
+ @Override
+ public void propertyChange(final PropertyChangeEvent evt) {
+ updateLaunchConfigurationDialog();
+ }
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageMainTab.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageMainTab.java
new file mode 100644
index 0000000000..3a83d56f5e
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageMainTab.java
@@ -0,0 +1,633 @@
+/*******************************************************************************
+ * 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.launch;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+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.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.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.jface.databinding.swt.WidgetProperties;
+import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+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.DockerConnectionManager;
+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.ui.Activator;
+import org.eclipse.linuxtools.docker.ui.wizards.ImageSearch;
+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.wizards.ImageRunResourceVolumesVariablesModel;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunSelectionModel;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunSelectionModel.ExposedPortModel;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.WizardMessages;
+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.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.Text;
+
+public class RunImageMainTab extends AbstractLaunchConfigurationTab {
+
+ private static final String TAB_NAME = "RunMainTab.name"; //$NON-NLS-1$
+ // private static final String ERROR_PULLING_IMAGE = "ImagePullError.msg";
+ // //$NON-NLS-1$
+
+ private static final int COLUMNS = 3;
+
+ private final DataBindingContext dbc = new DataBindingContext();
+ private final ImageRunSelectionModel model;
+ private final ImageRunResourceVolumesVariablesModel volumesModel;
+
+ public RunImageMainTab(ImageRunSelectionModel model,
+ ImageRunResourceVolumesVariablesModel volumesModel) {
+ this.model = model;
+ this.volumesModel = volumesModel;
+ }
+
+ public ImageRunSelectionModel getModel() {
+ return model;
+ }
+
+ 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(WizardMessages
+ .getString("ImageRunSelectionPage.specifyImageMsg")); //$NON-NLS-1$
+ }
+ if (model.getSelectedImage() != null) {
+ model.setSelectedImageNeedsPulling(false);
+ return ValidationStatus.ok();
+ }
+ model.setSelectedImageNeedsPulling(true);
+ return ValidationStatus.warning(WizardMessages.getFormattedString(
+ "ImageRunSelectionPage.imageNotFoundMessage", //$NON-NLS-1$
+ selectedImageName));
+ }
+
+ @Override
+ public IObservableList getTargets() {
+ WritableList targets = new WritableList();
+ targets.add(imageSelectionObservable);
+ return targets;
+ }
+ }
+
+ @Override
+ public void createControl(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);
+ if (model == null) {
+ setErrorMessage(LaunchMessages.getString("NoConnectionError.msg"));
+ return;
+ } else {
+ setErrorMessage(null);
+ setDefaultValues();
+ createImageSettingsSection(container);
+ createSectionSeparator(container, true);
+ createRunOptionsSection(container);
+ final IObservableValue connectionSelectionObservable = BeanProperties
+ .value(ImageRunSelectionModel.class,
+ ImageRunSelectionModel.SELECTED_CONNECTION_NAME)
+ .observe(model);
+ connectionSelectionObservable
+ .addValueChangeListener(onConnectionSelectionChange());
+ final IObservableValue imageSelectionObservable = BeanProperties
+ .value(ImageRunSelectionModel.class,
+ ImageRunSelectionModel.SELECTED_IMAGE_NAME)
+ .observe(model);
+ imageSelectionObservable
+ .addValueChangeListener(onImageSelectionChange());
+ final ImageSelectionValidator imageSelectionValidator = new ImageSelectionValidator(
+ imageSelectionObservable);
+ dbc.addValidationStatusProvider(imageSelectionValidator);
+ }
+ setControl(container);
+ }
+
+ private void setDefaultValues() {
+ final IDockerImage selectedImage = model.getSelectedImage();
+ if (selectedImage == null) {
+ return;
+ }
+ findImageInfo(selectedImage);
+ }
+
+ 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) {
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).span(3, 1)
+ .applyTo(new Label(container, SWT.NONE));
+ final Label connectionSelectionLabel = new Label(container, SWT.NONE);
+ connectionSelectionLabel
+ .setText(WizardMessages.getString("Connection.label")); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(connectionSelectionLabel);
+ final Combo connectionSelectionCombo = new Combo(container, SWT.BORDER);
+ connectionSelectionCombo.setToolTipText(
+ LaunchMessages.getString("RunMainTabSelectConnection.tooltip")); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).span(1, 1).applyTo(connectionSelectionCombo);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).span(1, 1)
+ .applyTo(new Label(container, SWT.NONE));
+ new ControlDecoration(connectionSelectionCombo, SWT.TOP | SWT.LEFT);
+ final ComboViewer connectionSelectionComboViewer = new ComboViewer(
+ connectionSelectionCombo);
+ connectionSelectionComboViewer
+ .setContentProvider(new ArrayContentProvider());
+ connectionSelectionComboViewer.setInput(getConnectionNames());
+ dbc.bindValue(
+ WidgetProperties.selection().observe(connectionSelectionCombo),
+ BeanProperties
+ .value(ImageRunSelectionModel.class,
+ ImageRunSelectionModel.SELECTED_CONNECTION_NAME)
+ .observe(model));
+ // Image selection name
+ final Label imageSelectionLabel = new Label(container, SWT.NONE);
+ imageSelectionLabel.setText(WizardMessages.getString("Image.label")); //$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(WizardMessages
+ .getString("ImageRunSelectionPage.selectTooltip")); //$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(
+ WizardMessages.getString("ImageRunSelectionPage.search")); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).span(1, 1)
+ // .hint(LaunchConfigurationUtils
+ // .getButtonWidthHint(searchImageButton), SWT.DEFAULT)
+ .applyTo(searchImageButton);
+ searchImageButton.addSelectionListener(onSearchImage());
+ 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(WizardMessages
+ .getString("ImageRunSelectionPage.containerTooltip")); //$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(
+ WizardMessages.getString("ImageRunSelectionPage.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(
+ WizardMessages.getString("ImageRunSelectionPage.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 String[] getConnectionNames() {
+ IDockerConnection[] connections = DockerConnectionManager.getInstance().getConnections();
+ ArrayList<String> connectionNames = new ArrayList<>();
+ for (IDockerConnection connection : connections) {
+ connectionNames.add(connection.getName());
+ }
+ return connectionNames.toArray(new String[] {});
+ }
+
+ /**
+ * 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);
+ volumesModel.setSelectedImage(selectedImage);
+ }
+ };
+ }
+
+ private IValueChangeListener onConnectionSelectionChange() {
+ return new IValueChangeListener() {
+
+ @Override
+ public void handleValueChange(final ValueChangeEvent event) {
+ IDockerImage selectedImage = model.getSelectedImage();
+ // skip if the selected image does not exist in the local Docker
+ // host
+ if (selectedImage == null) {
+ List<String> imageNames = model.getImageNames();
+ if (imageNames.size() > 0) {
+ model.setSelectedImageName(imageNames.get(0));
+ selectedImage = model.getSelectedImage();
+ } else {
+ model.setExposedPorts(new WritableList());
+ return;
+ }
+ }
+ findImageInfo(selectedImage);
+ volumesModel.setSelectedImage(selectedImage);
+ }
+ };
+ }
+
+ 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 void findImageInfo(final IDockerImage selectedImage) {
+ try {
+ final FindImageInfoRunnable findImageInfoRunnable = new FindImageInfoRunnable(
+ selectedImage);
+ ProgressMonitorDialog dialog = new ProgressMonitorDialog(
+ this.getShell());
+ dialog.run(true, true, findImageInfoRunnable);
+ final IDockerImageInfo selectedImageInfo = findImageInfoRunnable
+ .getResult();
+ final Set<String> exposedPortInfos = selectedImageInfo.config()
+ .exposedPorts();
+ final WritableList availablePorts = new WritableList();
+ if (exposedPortInfos != null) {
+ for (String exposedPortInfo : exposedPortInfos) {
+ final String privatePort = exposedPortInfo.substring(0,
+ exposedPortInfo.indexOf('/'));
+ final String type = exposedPortInfo
+ .substring(exposedPortInfo.indexOf('/')); // $NON-NLS-1$
+ final ExposedPortModel exposedPort = new ExposedPortModel(
+ privatePort, type, "", privatePort);
+ availablePorts.add(exposedPort); // $NON-NLS-1$
+ }
+ }
+ model.setExposedPorts(availablePorts);
+ model.setCommand(selectedImageInfo.config().cmd());
+ model.setEntrypoint(selectedImageInfo.config().entrypoint());
+
+ } catch (InvocationTargetException | InterruptedException e) {
+ Activator.log(e);
+ }
+ }
+
+ private void createRunOptionsSection(final Composite container) {
+ // interactive/show in console mode
+ final Button interactiveButton = new Button(container, SWT.CHECK);
+ interactiveButton.setText(
+ WizardMessages.getString("ImageRunSelectionPage.openStdin")); //$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(WizardMessages.getString("ImageRunSelectionPage.tty")); //$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(
+ WizardMessages.getString("ImageRunSelectionPage.autoRemove")); //$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));
+ }
+
+ private SelectionListener onSearchImage() {
+ return new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ final ImageSearch imageSearchWizard = new ImageSearch(
+ RunImageMainTab.this.model.getSelectedConnection(),
+ RunImageMainTab.this.model.getSelectedImageName());
+ final boolean completed = CommandUtils
+ .openWizard(imageSearchWizard, getShell());
+ if (completed) {
+ model.setSelectedImageName(
+ imageSearchWizard.getSelectedImage());
+ }
+ }
+ };
+ }
+
+ @Override
+ public Image getImage() {
+ return SWTImagesFactory.get(SWTImagesFactory.IMG_MAIN_TAB);
+ }
+
+ @Override
+ public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
+
+ }
+
+ @Override
+ public void initializeFrom(ILaunchConfiguration configuration) {
+ final IDockerConnection[] connections = DockerConnectionManager
+ .getInstance()
+ .getConnections();
+ try {
+ String connectionName = configuration.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.CONNECTION_NAME,
+ connections[0].getName());
+ model.setSelectedConnectionName(connectionName);
+ String imageName = configuration.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.IMAGE_NAME, ""); //$NON-NLS-1$
+ model.setSelectedImageName(imageName);
+ String command = configuration.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.COMMAND, ""); //$NON-NLS-1$
+ model.setCommand(command);
+ String entryPoint = configuration.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.ENTRYPOINT, ""); //$NON-NLS-1$
+ model.setEntrypoint(entryPoint);
+ String containerName = configuration.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.CONTAINER_NAME,
+ ""); //$NON-NLS-1$
+ model.setContainerName(containerName);
+ boolean removeContainer = configuration.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.AUTO_REMOVE,
+ false);
+ model.setRemoveWhenExits(removeContainer);
+ boolean interactive = configuration.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.INTERACTIVE,
+ false);
+ model.setInteractiveMode(interactive);
+ boolean useTTY = configuration.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.ALLOCATE_PSEUDO_CONSOLE,
+ false);
+ model.setAllocatePseudoTTY(useTTY);
+ } catch (CoreException e) {
+ Activator.logErrorMessage(
+ LaunchMessages.getString(
+ "RunDockerImageLaunchConfiguration.load.failure"), //$NON-NLS-1$
+ e);
+ }
+ // update the underlying launch config working copy on model
+ // changes.
+ model.addPropertyChangeListener(
+ new LaunchConfigurationChangeListener());
+
+ }
+
+ @Override
+ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+ configuration.setAttribute(
+ IRunDockerImageLaunchConfigurationConstants.CONNECTION_NAME,
+ model.getSelectedConnectionName());
+ configuration.setAttribute(
+ IRunDockerImageLaunchConfigurationConstants.IMAGE_NAME,
+ model.getSelectedImageName());
+ configuration.setAttribute(
+ IRunDockerImageLaunchConfigurationConstants.COMMAND,
+ model.getCommand());
+ configuration.setAttribute(
+ IRunDockerImageLaunchConfigurationConstants.ENTRYPOINT,
+ "".equals(model.getEntrypoint()) ? null //$NON-NLS-1$
+ : model.getEntrypoint());
+ configuration.setAttribute(
+ IRunDockerImageLaunchConfigurationConstants.CONTAINER_NAME,
+ "".equals(model.getContainerName()) ? null //$NON-NLS-1$
+ : model.getContainerName());
+ configuration.setAttribute(
+ IRunDockerImageLaunchConfigurationConstants.ALLOCATE_PSEUDO_CONSOLE,
+ model.isAllocatePseudoTTY());
+ configuration.setAttribute(
+ IRunDockerImageLaunchConfigurationConstants.AUTO_REMOVE,
+ model.isRemoveWhenExits());
+ configuration.setAttribute(
+ IRunDockerImageLaunchConfigurationConstants.INTERACTIVE,
+ model.isInteractiveMode());
+ }
+
+ @Override
+ public boolean isValid(ILaunchConfiguration launchConfig) {
+ try {
+ if (launchConfig.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.CONNECTION_NAME,
+ "").isEmpty()) {
+ return false;
+ }
+ } catch (CoreException e) {
+ Activator.log(e);
+ }
+ return super.isValid(launchConfig);
+ }
+
+ private class LaunchConfigurationChangeListener
+ implements PropertyChangeListener {
+
+ @Override
+ public void propertyChange(final PropertyChangeEvent evt) {
+ updateLaunchConfigurationDialog();
+ }
+ }
+
+ @Override
+ public void dispose() {
+ super.dispose();
+ }
+
+ @Override
+ public String getName() {
+ return LaunchMessages.getString(TAB_NAME);
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImagePortsTab.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImagePortsTab.java
new file mode 100644
index 0000000000..3a721db448
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImagePortsTab.java
@@ -0,0 +1,428 @@
+/*******************************************************************************
+ * 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.launch;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import java.util.HashSet;
+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.value.IValueChangeListener;
+import org.eclipse.core.databinding.observable.value.ValueChangeEvent;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+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.dialogs.IDialogConstants;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+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.linuxtools.docker.ui.Activator;
+import org.eclipse.linuxtools.internal.docker.ui.SWTImagesFactory;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ContainerPortDialog;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunSelectionModel;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunSelectionModel.ExposedPortModel;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.WizardMessages;
+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.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+public class RunImagePortsTab extends AbstractLaunchConfigurationTab
+ implements PropertyChangeListener {
+
+ private static final String TAB_NAME = "RunPortsTab.name"; //$NON-NLS-1$
+
+ private static final int INDENT = 30;
+
+ private static final int COLUMNS = 3;
+
+ private final DataBindingContext dbc = new DataBindingContext();
+
+ private final ImageRunSelectionModel model;
+
+ public RunImagePortsTab(ImageRunSelectionModel model) {
+ this.model = model;
+ }
+
+ @Override
+ public void createControl(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);
+ if (model == null) {
+ setErrorMessage(LaunchMessages.getString("NoConnectionError.msg"));
+ } else {
+ setErrorMessage(null);
+ createPortSettingsSection(container);
+ }
+ setControl(container);
+ }
+
+ private void createPortSettingsSection(final Composite container) {
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).span(3, 1)
+ .applyTo(new Label(container, SWT.NONE));
+ final Button publishAllPortsButton = new Button(container, SWT.CHECK);
+ publishAllPortsButton.setText(WizardMessages
+ .getString("ImageRunSelectionPage.publishAllPorts")); //$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(
+ WizardMessages.getString("ImageRunSelectionPage.portSettings")); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).span(COLUMNS, 1).indent(INDENT, 0)
+ .applyTo(portSettingsLabel);
+ final CheckboxTableViewer 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(WizardMessages.getString("ImageRunSelectionPage.add")); //$NON-NLS-1$
+ addButton.addSelectionListener(onAddPort(exposedPortsTableViewer));
+ final Button editButton = new Button(buttonsContainers, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP)
+ .grab(true, false).applyTo(editButton);
+ editButton.setText(
+ WizardMessages.getString("ImageRunSelectionPage.editButton")); //$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(
+ WizardMessages.getString("ImageRunSelectionPage.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));
+
+ // disable the edit and removeButton if the table is empty
+ exposedPortsTableViewer.addSelectionChangedListener(
+ onSelectionChanged(editButton, removeButton));
+ exposedPortsTableViewer.addCheckStateListener(onCheckStateChanged());
+
+ togglePortMappingControls(exposedPortsTableViewer.getTable(), addButton,
+ removeButton);
+ }
+
+ private static void setControlsEnabled(final Control[] controls,
+ final boolean enabled) {
+ for (Control control : controls) {
+ control.setEnabled(enabled);
+ }
+ }
+
+ private ISelectionChangedListener onSelectionChanged(
+ final Button... targetButtons) {
+ return new ISelectionChangedListener() {
+
+ @Override
+ public void selectionChanged(final SelectionChangedEvent e) {
+ if (e.getSelection().isEmpty()) {
+ setControlsEnabled(targetButtons, false);
+ } else {
+ setControlsEnabled(targetButtons, true);
+ }
+ }
+ };
+ }
+
+ private ICheckStateListener onCheckStateChanged() {
+ return new ICheckStateListener() {
+
+ @Override
+ public void checkStateChanged(final CheckStateChangedEvent e) {
+ ImageRunSelectionModel.ExposedPortModel element = (ImageRunSelectionModel.ExposedPortModel) e
+ .getElement();
+ if (e.getChecked()) {
+ model.getSelectedPorts().add(element);
+ element.setSelected(true);
+ } else {
+ model.getSelectedPorts().remove(element);
+ element.setSelected(false);
+ }
+ updateLaunchConfigurationDialog();
+ }
+ };
+ }
+
+ 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);
+ createTableViewerColumn(tableViewer,
+ WizardMessages
+ .getString("ImageRunSelectionPage.containerPortColumn"), //$NON-NLS-1$
+ 100);
+ createTableViewerColumn(tableViewer,
+ WizardMessages.getString("ImageRunSelectionPage.typeColumn"), //$NON-NLS-1$
+ 50);
+ createTableViewerColumn(tableViewer,
+ WizardMessages
+ .getString("ImageRunSelectionPage.hostAddressColumn"), //$NON-NLS-1$
+ 100);
+ createTableViewerColumn(tableViewer,
+ WizardMessages
+ .getString("ImageRunSelectionPage.hostPortColumn"), //$NON-NLS-1$
+ 100);
+ tableViewer.setContentProvider(new ObservableListContentProvider());
+ return tableViewer;
+ }
+
+ private TableViewerColumn createTableViewerColumn(
+ 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 IValueChangeListener onPublishAllPortsChange(
+ final Control... controls) {
+ return new IValueChangeListener() {
+
+ @Override
+ public void handleValueChange(final ValueChangeEvent event) {
+ togglePortMappingControls(controls);
+ }
+ };
+ }
+
+ private SelectionListener onAddPort(
+ final CheckboxTableViewer exposedPortsTableViewer) {
+ return new SelectionAdapter() {
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ final ContainerPortDialog dialog = new ContainerPortDialog(
+ getShell());
+ dialog.create();
+ if (dialog.open() == IDialogConstants.OK_ID) {
+ final ExposedPortModel port = dialog.getPort();
+ model.addAvailablePort(port);
+ model.getSelectedPorts().add(port);
+ port.setSelected(true);
+ exposedPortsTableViewer.setChecked(port, true);
+ updateLaunchConfigurationDialog();
+ }
+ }
+ };
+ }
+
+ private SelectionListener onEditPort(
+ final CheckboxTableViewer exposedPortsTableViewer) {
+ return new SelectionAdapter() {
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ final IStructuredSelection selection = exposedPortsTableViewer
+ .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());
+ }
+ updateLaunchConfigurationDialog();
+ }
+ };
+ }
+
+ 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();) {
+ final ExposedPortModel port = iterator.next();
+ model.removeAvailablePort(port);
+ model.getSelectedPorts().remove(port);
+ }
+ updateLaunchConfigurationDialog();
+ }
+ };
+ }
+
+ private void togglePortMappingControls(final Control... controls) {
+ for (Control control : controls) {
+ if (model.isPublishAllPorts()) {
+ control.setEnabled(false);
+ } else {
+ control.setEnabled(true);
+ }
+ updateLaunchConfigurationDialog();
+ }
+ }
+
+ @Override
+ public Image getImage() {
+ return SWTImagesFactory.get(SWTImagesFactory.IMG_CONTAINER_PORT);
+ }
+
+ @Override
+ public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
+
+ }
+
+ @Override
+ public void initializeFrom(ILaunchConfiguration configuration) {
+ try {
+ // recycle the model
+ model.removeExposedPorts();
+ final boolean publishAllPorts = configuration.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.PUBLISH_ALL_PORTS,
+ true);
+ model.setPublishAllPorts(publishAllPorts);
+ final List<String> publishedPorts = configuration.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.PUBLISHED_PORTS,
+ new ArrayList<String>());
+ final Set<ExposedPortModel> selectedPorts = new HashSet<>();
+ for (String port : publishedPorts) {
+ final ImageRunSelectionModel.ExposedPortModel exposedPort = ImageRunSelectionModel.ExposedPortModel
+ .createPortModel(port);
+ model.addExposedPort(exposedPort);
+ if (exposedPort.getSelected()) {
+ selectedPorts.add(exposedPort);
+ }
+ }
+ // select ports
+ model.setSelectedPorts(selectedPorts);
+
+ // update the underlying launch config working copy on model
+ // changes.
+ model.addPropertyChangeListener(
+ new LaunchConfigurationChangeListener());
+ } catch (CoreException e) {
+ Activator.logErrorMessage(
+ LaunchMessages.getString(
+ "RunDockerImageLaunchConfiguration.load.failure"), //$NON-NLS-1$
+ e);
+ }
+
+ }
+
+ @Override
+ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+ configuration.setAttribute(
+ IRunDockerImageLaunchConfigurationConstants.PUBLISH_ALL_PORTS,
+ model.isPublishAllPorts());
+ List<String> portsList = new ArrayList<>();
+ for (Object o : model.getExposedPorts().toArray()) {
+ ImageRunSelectionModel.ExposedPortModel m = (ImageRunSelectionModel.ExposedPortModel) o;
+ portsList.add(m.toString());
+ }
+ configuration.setAttribute(
+ IRunDockerImageLaunchConfigurationConstants.PUBLISHED_PORTS,
+ portsList);
+ }
+
+ @Override
+ public String getName() {
+ return LaunchMessages.getString(TAB_NAME);
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ // TODO Auto-generated method stub
+
+ }
+
+ private class LaunchConfigurationChangeListener
+ implements PropertyChangeListener {
+
+ @Override
+ public void propertyChange(final PropertyChangeEvent evt) {
+ updateLaunchConfigurationDialog();
+ }
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageResourcesTab.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageResourcesTab.java
new file mode 100644
index 0000000000..292b45a40e
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageResourcesTab.java
@@ -0,0 +1,297 @@
+/*******************************************************************************
+ * 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.launch;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import org.eclipse.core.databinding.DataBindingContext;
+import org.eclipse.core.databinding.beans.BeanProperties;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.jface.databinding.swt.WidgetProperties;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.linuxtools.docker.ui.Activator;
+import org.eclipse.linuxtools.internal.docker.ui.SWTImagesFactory;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunResourceVolumesVariablesModel;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.WizardMessages;
+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.Text;
+
+public class RunImageResourcesTab extends AbstractLaunchConfigurationTab {
+
+ private static final String TAB_NAME = "RunResourcesTab.name"; //$NON-NLS-1$
+
+ private static final int COLUMNS = 2;
+
+ private final DataBindingContext dbc = new DataBindingContext();
+ private ImageRunResourceVolumesVariablesModel model = null;
+
+ private Composite container;
+
+ public RunImageResourcesTab(ImageRunResourceVolumesVariablesModel model) {
+ this.model = model;
+ }
+
+ @Override
+ public void createControl(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);
+ if (model == null) {
+ setErrorMessage(LaunchMessages.getString("NoConnectionError.msg"));
+ } else {
+ setErrorMessage(null);
+ createResourceSettingsContainer(container);
+ }
+ setControl(container);
+ }
+
+ 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(WizardMessages.getString(
+ "ImageRunResourceVolVarPage.enableLimitationButton")); //$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);
+ setContainer(subContainer);
+ 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(WizardMessages
+ .getString("ImageRunResourceVolVarPage.cpuPriorityLabel")); //$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(WizardMessages
+ .getString("ImageRunResourceVolVarPage.lowButton")); //$NON-NLS-1$
+ lowCPULimitationButton.addSelectionListener(
+ onCpuShareWeighting(ImageRunResourceVolumesVariablesModel.LOW));
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .applyTo(lowCPULimitationButton);
+ final Button mediumCPULimitationButton = new Button(subContainer,
+ SWT.RADIO);
+ mediumCPULimitationButton.setText(WizardMessages
+ .getString("ImageRunResourceVolVarPage.mediumButton")); //$NON-NLS-1$
+ 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(WizardMessages
+ .getString("ImageRunResourceVolVarPage.highButton")); //$NON-NLS-1$
+ 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(WizardMessages
+ .getString("ImageRunResourceVolVarPage.memoryLimit")); //$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);
+ int maxMemory = this.model.getTotalMemory();
+ memoryLimitSpinner.setMaximum(this.model.getTotalMemory());
+ memoryLimitSpinner.setSelection(Math.min(512, maxMemory));
+ 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));
+ dbc.bindValue(WidgetProperties.selection().observe(memoryLimitSpinner),
+ 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 void setContainer(final Composite container) {
+ this.container = container;
+ }
+
+ private Composite getContainer() {
+ return container;
+ }
+
+ 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);
+ }
+ updateLaunchConfigurationDialog();
+ }
+ }
+
+
+ @Override
+ public Image getImage() {
+ return SWTImagesFactory.get(SWTImagesFactory.IMG_RESOURCE);
+ }
+
+ @Override
+ public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void initializeFrom(ILaunchConfiguration configuration) {
+ try {
+ boolean enableLimits = configuration.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.ENABLE_LIMITS,
+ false);
+ model.setEnableResourceLimitations(enableLimits);
+
+ int cpuShareWeight = configuration.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.CPU_PRIORITY,
+ 1024);
+ model.setCpuShareWeight(cpuShareWeight);
+
+ int maxMemory = this.model.getTotalMemory();
+ int memoryLimit = Math.min(512, maxMemory);
+ memoryLimit = configuration.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.MEMORY_LIMIT,
+ memoryLimit);
+ model.setMemoryLimit(memoryLimit);
+ toggleResourceLimitationControls(getContainer());
+ } catch (CoreException e) {
+ Activator.logErrorMessage(
+ LaunchMessages.getString(
+ "RunDockerImageLaunchConfiguration.load.failure"), //$NON-NLS-1$
+ e);
+ }
+ model.addPropertyChangeListener(
+ new LaunchConfigurationChangeListener());
+ }
+
+ @Override
+ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+ configuration.setAttribute(
+ IRunDockerImageLaunchConfigurationConstants.ENABLE_LIMITS,
+ model.isEnableResourceLimitations());
+ configuration.setAttribute(
+ IRunDockerImageLaunchConfigurationConstants.MEMORY_LIMIT,
+ model.getMemoryLimit());
+ configuration.setAttribute(
+ IRunDockerImageLaunchConfigurationConstants.CPU_PRIORITY,
+ model.getCpuShareWeight());
+ }
+
+ @Override
+ public String getName() {
+ return LaunchMessages.getString(TAB_NAME);
+ }
+
+ private class LaunchConfigurationChangeListener
+ implements PropertyChangeListener {
+
+ @Override
+ public void propertyChange(final PropertyChangeEvent evt) {
+ updateLaunchConfigurationDialog();
+ }
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageVolumesTab.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageVolumesTab.java
new file mode 100644
index 0000000000..067514cf43
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/RunImageVolumesTab.java
@@ -0,0 +1,549 @@
+/*******************************************************************************
+ * 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.launch;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+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.list.IObservableList;
+import org.eclipse.core.databinding.observable.list.WritableList;
+import org.eclipse.core.databinding.observable.map.IObservableMap;
+import org.eclipse.core.databinding.observable.set.IObservableSet;
+import org.eclipse.core.databinding.property.Properties;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+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.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+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.linuxtools.docker.ui.Activator;
+import org.eclipse.linuxtools.internal.docker.ui.SWTImagesFactory;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ContainerDataVolumeDialog;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.DataVolumeModel;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunResourceVolumesVariablesModel;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunResourceVolumesVariablesModel.MountType;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.WizardMessages;
+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.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+public class RunImageVolumesTab extends AbstractLaunchConfigurationTab {
+
+ private static final String TAB_NAME = "RunVolumesTab.name"; //$NON-NLS-1$
+
+ private static final int COLUMNS = 3;
+
+ private final DataBindingContext dbc = new DataBindingContext();
+ private ImageRunResourceVolumesVariablesModel model = null;
+
+ public RunImageVolumesTab(ImageRunResourceVolumesVariablesModel model) {
+ this.model = model;
+ }
+
+ 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);
+ if (model == null) {
+ setErrorMessage(LaunchMessages.getString("NoConnectionError.msg"));
+ } else {
+ setErrorMessage(null);
+ createVolumeSettingsContainer(container);
+ }
+ setControl(container);
+ }
+
+ private void createVolumeSettingsContainer(final Composite container) {
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).span(3, 1)
+ .applyTo(new Label(container, SWT.NONE));
+ final Label volumesLabel = new Label(container, SWT.NONE);
+ volumesLabel.setText(WizardMessages
+ .getString("ImageRunResourceVolVarPage.dataVolumesLabel")); //$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());
+ // 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 }));
+ final IObservableSet selectedVolumesObservable = BeanProperties
+ .set(ImageRunResourceVolumesVariablesModel.SELECTED_DATA_VOLUMES)
+ .observe(model);
+ dbc.bindSet(
+ ViewersObservables.observeCheckedElements(
+ dataVolumesTableViewer, DataVolumeModel.class),
+ selectedVolumesObservable);
+ dataVolumesTableViewer.addCheckStateListener(onCheckStateChanged());
+
+ // initializes the checkboxes selection upon loading the model.
+ // remove ?
+ // selectedVolumesObservable.addChangeListener(new
+ // IChangeListener() {
+ //
+ // @Override
+ // public void handleChange(ChangeEvent event) {
+ // final IObservableSet observable = (IObservableSet) event
+ // .getObservable();
+ // for (Iterator<?> iterator = observable.iterator(); iterator
+ // .hasNext();) {
+ // final DataVolumeModel volume = (DataVolumeModel) iterator
+ // .next();
+ // dataVolumesTableViewer.setChecked(volume, true);
+ // }
+ // updateLaunchConfigurationDialog();
+ // }
+ // });
+
+ // 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(WizardMessages
+ .getString("ImageRunResourceVolVarPage.addButton")); //$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(WizardMessages
+ .getString("ImageRunResourceVolVarPage.editButton")); //$NON-NLS-1$
+ editButton
+ .addSelectionListener(onEditDataVolume(dataVolumesTableViewer));
+ 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(WizardMessages
+ .getString("ImageRunResourceVolVarPage.removeButton")); //$NON-NLS-1$
+ removeButton.addSelectionListener(
+ onRemoveDataVolumes(dataVolumesTableViewer));
+ removeButton.setEnabled(false);
+ // disable the edit and removeButton if the table is empty
+ dataVolumesTableViewer.addSelectionChangedListener(
+ onSelectionChanged(editButton, removeButton));
+
+ }
+
+ private ICheckStateListener onCheckStateChanged() {
+ return new ICheckStateListener() {
+
+ @Override
+ public void checkStateChanged(final CheckStateChangedEvent e) {
+ DataVolumeModel element = (DataVolumeModel) e.getElement();
+ if (e.getChecked()) {
+ model.getSelectedDataVolumes().add(element);
+ element.setSelected(true);
+ } else {
+ model.getSelectedDataVolumes().remove(element);
+ element.setSelected(false);
+ }
+ updateLaunchConfigurationDialog();
+ }
+ };
+ }
+
+ /**
+ * 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 ISelectionChangedListener onSelectionChanged(
+ final Button... targetButtons) {
+ return new ISelectionChangedListener() {
+
+ @Override
+ public void selectionChanged(final SelectionChangedEvent e) {
+ if (e.getSelection().isEmpty()) {
+ setControlsEnabled(targetButtons, false);
+ updateLaunchConfigurationDialog();
+ } else {
+ setControlsEnabled(targetButtons, true);
+ updateLaunchConfigurationDialog();
+ }
+ }
+
+ };
+ }
+
+ private SelectionListener onAddDataVolume(
+ final CheckboxTableViewer dataVolumesTableViewer) {
+ return new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ final ContainerDataVolumeDialog dialog = new ContainerDataVolumeDialog(
+ getShell(), model.getConnection());
+ dialog.create();
+ if (dialog.open() == IDialogConstants.OK_ID) {
+ model.getDataVolumes().add(dialog.getDataVolume());
+ model.getSelectedDataVolumes().add(dialog.getDataVolume());
+ dialog.getDataVolume().setSelected(true);
+ dataVolumesTableViewer.setChecked(dialog.getDataVolume(),
+ true);
+ updateLaunchConfigurationDialog();
+ }
+ }
+ };
+ }
+
+ 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());
+ model.getSelectedDataVolumes().add(selectedDataVolume);
+ dataVolumesTableViewer.setChecked(selectedDataVolume, true);
+ updateLaunchConfigurationDialog();
+ }
+ }
+ };
+ }
+
+ private SelectionListener onRemoveDataVolumes(
+ final TableViewer dataVolumesTableViewer) {
+ return new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ final IStructuredSelection selection = dataVolumesTableViewer
+ .getStructuredSelection();
+ for (@SuppressWarnings("unchecked")
+ Iterator<DataVolumeModel> iterator = selection
+ .iterator(); iterator.hasNext();) {
+ final DataVolumeModel volume = iterator.next();
+ model.removeDataVolume(volume);
+ model.getSelectedDataVolumes().remove(volume);
+ }
+ updateLaunchConfigurationDialog();
+ }
+ };
+ }
+
+ 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);
+ addTableViewerColumn(tableViewer,
+ WizardMessages.getString(
+ "ImageRunResourceVolVarPage.containerPathColumn"), //$NON-NLS-1$
+ 150);
+ addTableViewerColumn(tableViewer,
+ WizardMessages
+ .getString("ImageRunResourceVolVarPage.mountColumn"), //$NON-NLS-1$
+ 150);
+ addTableViewerColumn(tableViewer,
+ WizardMessages
+ .getString("ImageRunResourceVolVarPage.readonlyColumn"), //$NON-NLS-1$
+ 60);
+ return tableViewer;
+ }
+
+ private TableViewerColumn addTableViewerColumn(
+ 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 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 WizardMessages
+ .getString("ImageRunResourceVolVarPage.true"); //$NON-NLS-1$
+ }
+ return WizardMessages
+ .getString("ImageRunResourceVolVarPage.false"); //$NON-NLS-1$
+ default:
+ return null;
+ }
+ }
+ }
+
+ @Override
+ public Image getImage() {
+ return SWTImagesFactory.get(SWTImagesFactory.IMG_CONTAINER_VOLUME);
+ }
+
+ @Override
+ public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
+ }
+
+ @Override
+ public void initializeFrom(ILaunchConfiguration configuration) {
+ final WritableList volumes = new WritableList();
+ try {
+ final List<String> volumesList = configuration.getAttribute(
+ IRunDockerImageLaunchConfigurationConstants.DATA_VOLUME,
+ new ArrayList<String>());
+ final Set<DataVolumeModel> selectedVolumes = new HashSet<>();
+ for (String volume : volumesList) {
+ DataVolumeModel volumeModel = DataVolumeModel
+ .createDataVolumeModel(volume);
+ volumes.add(volumeModel);
+ if (volumeModel.getSelected()) {
+ selectedVolumes.add(volumeModel);
+ }
+ }
+ model.setDataVolumes(volumes);
+ model.setSelectedDataVolumes(selectedVolumes);
+
+ } catch (CoreException e) {
+ Activator.logErrorMessage(
+ LaunchMessages.getString(
+ "RunDockerImageLaunchConfiguration.load.failure"), //$NON-NLS-1$
+ e);
+ }
+ // update the underlying launch config working copy on model
+ // changes.
+ model.addPropertyChangeListener(
+ new LaunchConfigurationChangeListener());
+ }
+
+ @Override
+ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+ WritableList volumes = model.getDataVolumes();
+ Set<DataVolumeModel> selectedVolumes = model.getSelectedDataVolumes();
+
+ ArrayList<String> binds = new ArrayList<>();
+ ArrayList<String> volumesFrom = new ArrayList<>();
+ ArrayList<String> volumesList = new ArrayList<>();
+ Set<String> selectedVolumesSet = new TreeSet<>();
+
+ for (@SuppressWarnings("unchecked")
+ Iterator<DataVolumeModel> iterator = volumes.iterator(); iterator
+ .hasNext();) {
+ DataVolumeModel volume = iterator.next();
+ StringBuffer buffer = new StringBuffer();
+ volumesList.add(volume.toString());
+ switch (volume.getMountType()) {
+ case HOST_FILE_SYSTEM:
+ buffer.append(volume.getHostPathMount() + ","
+ + volume.getHostPathMount() + ","
+ + volume.isReadOnly());
+ if (selectedVolumes.contains(volume)) {
+ selectedVolumesSet.add(volume.toString());
+ String bind = convertToUnixPath(volume.getHostPathMount())
+ + ':' + volume.getContainerPath() + ':' + 'Z';
+ if (volume.isReadOnly()) {
+ bind += ",ro"; //$NON-NLS-1$
+ }
+ binds.add(bind);
+ }
+ break;
+ case CONTAINER:
+ if (selectedVolumes.contains(volume)) {
+ selectedVolumesSet.add(volume.toString());
+ volumesFrom.add(volume.getContainerMount());
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ configuration.setAttribute(
+ IRunDockerImageLaunchConfigurationConstants.BINDS, binds);
+ configuration.setAttribute(
+ IRunDockerImageLaunchConfigurationConstants.VOLUMES_FROM,
+ volumesFrom);
+ configuration.setAttribute(
+ IRunDockerImageLaunchConfigurationConstants.DATA_VOLUME,
+ volumesList);
+ }
+
+ private String convertToUnixPath(String path) {
+ String unixPath = path;
+
+ if (Platform.OS_WIN32.equals(Platform.getOS())) {
+ // replace backslashes with slashes
+ unixPath = unixPath.replaceAll("\\\\", "/");
+
+ // replace "C:/" with "/c/"
+ Matcher m = Pattern.compile("([a-zA-Z]):/").matcher(unixPath);
+ if (m.find()) {
+ StringBuffer b = new StringBuffer();
+ b.append('/');
+ m.appendReplacement(b, m.group(1).toLowerCase());
+ b.append('/');
+ m.appendTail(b);
+ unixPath = b.toString();
+ }
+ }
+
+ return unixPath;
+ }
+
+ @Override
+ public String getName() {
+ return LaunchMessages.getString(TAB_NAME);
+ }
+
+ private class LaunchConfigurationChangeListener
+ implements PropertyChangeListener {
+
+ @Override
+ public void propertyChange(final PropertyChangeEvent evt) {
+ updateLaunchConfigurationDialog();
+ }
+ }
+
+}
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
index 6573415476..5874c09852 100644
--- 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
@@ -74,7 +74,7 @@ public class ContainerDataVolumeDialog extends Dialog {
private final IDockerConnection connection;
- protected ContainerDataVolumeDialog(final Shell parentShell,
+ public ContainerDataVolumeDialog(final Shell parentShell,
final IDockerConnection connection,
final DataVolumeModel selectedDataVolume) {
super(parentShell);
@@ -83,7 +83,7 @@ public class ContainerDataVolumeDialog extends Dialog {
this.containerNames = WizardUtils.getContainerNames(connection);
}
- protected ContainerDataVolumeDialog(final Shell parentShell,
+ public ContainerDataVolumeDialog(final Shell parentShell,
final IDockerConnection connection) {
super(parentShell);
this.connection = connection;
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
index cf2b61d6d5..e05c0af222 100644
--- 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
@@ -40,7 +40,7 @@ public class ContainerEnvironmentVariableDialog extends Dialog {
private final DataBindingContext dbc = new DataBindingContext();
- protected ContainerEnvironmentVariableDialog(final Shell parentShell) {
+ public ContainerEnvironmentVariableDialog(final Shell parentShell) {
super(parentShell);
this.model = new EnvironmentVariableModel();
}
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
index 8a9e2e3526..08fe996552 100644
--- 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
@@ -56,7 +56,7 @@ public class ContainerLinkDialog extends Dialog {
private final DataBindingContext dbc = new DataBindingContext();
- protected ContainerLinkDialog(final Shell shell,
+ public ContainerLinkDialog(final Shell shell,
final IDockerConnection connection) {
super(shell);
this.connection = connection;
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
index 01acccdf79..85009b59e6 100644
--- 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
@@ -44,7 +44,7 @@ public class ContainerPortDialog extends Dialog {
private final DataBindingContext dbc = new DataBindingContext();
- protected ContainerPortDialog(final Shell parentShell) {
+ public ContainerPortDialog(final Shell parentShell) {
super(parentShell);
this.model = new ContainerPortDialogModel();
}
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
index 9cc4a14021..57e27530d9 100644
--- 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
@@ -22,6 +22,8 @@ import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageRunResourceVolumes
public class DataVolumeModel extends BaseDatabindingModel
implements Comparable<DataVolumeModel> {
+ private static final String SEPARATOR = ":"; //$NON-NLS-1$
+
public static final String CONTAINER_PATH = "containerPath"; //$NON-NLS-1$
public static final String MOUNT_TYPE = "mountType"; //$NON-NLS-1$
@@ -34,6 +36,8 @@ public class DataVolumeModel extends BaseDatabindingModel
public static final String CONTAINER_MOUNT = "containerMount"; //$NON-NLS-1$
+ public static final String SELECTED = "selected"; //$NON-NLS-1$
+
private final String id = UUID.randomUUID().toString();
private String containerPath;
@@ -48,6 +52,8 @@ public class DataVolumeModel extends BaseDatabindingModel
private boolean readOnly = false;
+ private boolean selected;
+
public DataVolumeModel() {
}
@@ -76,6 +82,35 @@ public class DataVolumeModel extends BaseDatabindingModel
}
}
+ /**
+ * Create a DataVolumeModel from a toString() output.
+ *
+ * @param fromString
+ * @return DataVolumeModel
+ */
+ public static DataVolumeModel createDataVolumeModel(
+ final String fromString) {
+ final DataVolumeModel model = new DataVolumeModel();
+ final String[] items = fromString.split(SEPARATOR); // $NON-NLS-1$
+ model.containerPath = items[0];
+ model.mountType = MountType.valueOf(items[1]);
+ switch (model.mountType) {
+ case CONTAINER:
+ model.setContainerMount(items[2]);
+ model.setSelected(Boolean.valueOf(items[3]));
+ break;
+ case HOST_FILE_SYSTEM:
+ model.setHostPathMount(items[2]);
+ model.setReadOnly(Boolean.valueOf(items[3]));
+ model.setSelected(Boolean.valueOf(items[4]));
+ break;
+ case NONE:
+ model.setSelected(Boolean.valueOf(items[2]));
+ break;
+ }
+ return model;
+ }
+
public String getContainerPath() {
return this.containerPath;
}
@@ -145,11 +180,40 @@ public class DataVolumeModel extends BaseDatabindingModel
}
}
+ public boolean getSelected() {
+ return selected;
+ }
+
+ public void setSelected(final boolean selected) {
+ firePropertyChange(SELECTED, this.selected, this.selected = selected);
+ }
+
@Override
public int compareTo(final DataVolumeModel other) {
return this.getContainerPath().compareTo(other.getContainerPath());
}
+ // FIXME we should have a dedicated method to serialize the bean
+ @Override
+ public String toString() {
+ final StringBuffer buffer = new StringBuffer();
+ buffer.append(
+ this.containerPath + SEPARATOR + getMountType() + SEPARATOR);
+ switch (getMountType()) {
+ case CONTAINER:
+ buffer.append(getContainerMount());
+ break;
+ case HOST_FILE_SYSTEM:
+ buffer.append(getHostPathMount() + SEPARATOR); // $NON-NLS-1$
+ buffer.append(isReadOnly());
+ break;
+ case NONE:
+ break;
+ }
+ buffer.append(SEPARATOR).append(this.selected);
+ return buffer.toString();
+ }
+
@Override
public int hashCode() {
final int prime = 31;
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
index 4a354f7296..22a922479e 100644
--- 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
@@ -44,6 +44,12 @@ public class EnvironmentVariableModel extends BaseDatabindingModel {
this.value = variable.getValue();
}
+ public static EnvironmentVariableModel createEnvironmentVariableModel(
+ String fromString) {
+ String[] s = fromString.split("="); //$NON-NLS-1$
+ return new EnvironmentVariableModel(s[0], s[1]);
+ }
+
public String getName() {
return name;
}
@@ -61,6 +67,11 @@ public class EnvironmentVariableModel extends BaseDatabindingModel {
}
@Override
+ public String toString() {
+ return name + "=" + value; //$NON-NLS-1$
+ }
+
+ @Override
public int hashCode() {
final int prime = 31;
int result = 1;
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
index cd61b0847f..24aeb9154f 100644
--- 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
@@ -141,8 +141,17 @@ public class ImageRunResourceVolumesVariablesModel
public void setEnvironmentVariables(
final WritableList environmentVariables) {
+ firePropertyChange(ENVIRONMENT_VARIABLES, this.environmentVariables,
+ this.environmentVariables = environmentVariables);
+ }
+
+ public void addEnvironmentVariable(
+ final EnvironmentVariableModel variable) {
+ this.environmentVariables.add(variable);
+ }
+
+ public void removeEnvironmentVariables() {
this.environmentVariables.clear();
- this.environmentVariables.addAll(environmentVariables);
}
public void removeEnvironmentVariable(
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
index 173dd2a48a..69c2fb50b1 100644
--- 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
@@ -13,7 +13,6 @@ 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;
@@ -21,6 +20,7 @@ import java.util.UUID;
import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.core.runtime.Assert;
+import org.eclipse.linuxtools.docker.core.DockerConnectionManager;
import org.eclipse.linuxtools.docker.core.IDockerConnection;
import org.eclipse.linuxtools.docker.core.IDockerImage;
import org.eclipse.linuxtools.internal.docker.ui.databinding.BaseDatabindingModel;
@@ -33,6 +33,10 @@ import org.eclipse.linuxtools.internal.docker.ui.databinding.BaseDatabindingMode
*/
public class ImageRunSelectionModel extends BaseDatabindingModel {
+ public static final String CONNECTION_NAMES = "connectionNames"; //$NON-NLS-1$
+
+ public static final String SELECTED_CONNECTION_NAME = "selectedConnectionName"; //$NON-NLS-1$
+
public static final String SELECTED_IMAGE_NAME = "selectedImageName"; //$NON-NLS-1$
public static final String SELECTED_IMAGE = "selectedImage"; //$NON-NLS-1$
@@ -61,7 +65,11 @@ public class ImageRunSelectionModel extends BaseDatabindingModel {
public static final String REMOVE_WHEN_EXITS = "removeWhenExits"; //$NON-NLS-1$
- private final IDockerConnection selectedConnection;
+ private String selectedConnectionName;
+
+ private List<String> connectionNames;
+
+ private Map<String, IDockerConnection> connections;
private String selectedImageName;
@@ -79,11 +87,11 @@ public class ImageRunSelectionModel extends BaseDatabindingModel {
private boolean publishAllPorts = true;
- private WritableList exposedPorts = new WritableList();
+ private final WritableList exposedPorts = new WritableList();
- private Set<ExposedPortModel> selectedPorts = new HashSet<>();
+ private Set<ExposedPortModel> selectedPorts;
- private WritableList links = new WritableList();
+ private final WritableList links = new WritableList();
private boolean interactiveMode = false;
@@ -93,20 +101,34 @@ public class ImageRunSelectionModel extends BaseDatabindingModel {
public ImageRunSelectionModel(
final IDockerConnection selectedConnection) {
- this.selectedConnection = selectedConnection;
+ refreshConnectionNames();
+ setSelectedConnectionName(selectedConnection.getName());
refreshImageNames();
}
+ public void refreshConnectionNames() {
+ this.connectionNames = new ArrayList<>();
+ this.connections = new HashMap<>();
+ for (IDockerConnection connection : DockerConnectionManager
+ .getInstance().getConnections()) {
+ String name = connection.getName();
+ connections.put(name, connection);
+ connectionNames.add(name);
+ }
+ }
+
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);
+ if (getSelectedConnection() != null) {
+ for (IDockerImage image : getSelectedConnection().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);
+ }
}
}
}
@@ -134,6 +156,30 @@ public class ImageRunSelectionModel extends BaseDatabindingModel {
this.publishAllPorts = publishAllPorts);
}
+ public List<String> getConnectionNames() {
+ return connectionNames;
+ }
+
+ public void setConnectionNames(final List<String> connectionNames) {
+ firePropertyChange(CONNECTION_NAMES, this.connectionNames,
+ this.connectionNames = connectionNames);
+ }
+
+ public String getSelectedConnectionName() {
+ return selectedConnectionName;
+ }
+
+ public void setSelectedConnectionName(final String selectedConnectionName) {
+ firePropertyChange(SELECTED_CONNECTION_NAME,
+ this.selectedConnectionName,
+ this.selectedConnectionName = selectedConnectionName);
+ refreshImageNames();
+ }
+
+ public IDockerConnection getSelectedConnection() {
+ return this.connections.get(selectedConnectionName);
+ }
+
public List<String> getImageNames() {
return imageNames;
}
@@ -143,10 +189,6 @@ public class ImageRunSelectionModel extends BaseDatabindingModel {
this.imageNames = imageNames);
}
- public IDockerConnection getSelectedConnection() {
- return selectedConnection;
- }
-
public String getSelectedImageName() {
return selectedImageName;
}
@@ -238,8 +280,22 @@ public class ImageRunSelectionModel extends BaseDatabindingModel {
this.exposedPorts.addAll(ports);
}
+ public void removeExposedPorts() {
+ this.exposedPorts.clear();
+ }
+
+ public void addExposedPort(final ExposedPortModel exposedPort) {
+ if (!this.exposedPorts.contains(exposedPort)) {
+ this.exposedPorts.add(exposedPort);
+ }
+ }
+
+ public void removeExposedPort(final ExposedPortModel exposedPort) {
+ this.exposedPorts.remove(exposedPort);
+ }
+
public Set<ExposedPortModel> getSelectedPorts() {
- return selectedPorts;
+ return this.selectedPorts;
}
public void setSelectedPorts(final Set<ExposedPortModel> ports) {
@@ -253,7 +309,11 @@ public class ImageRunSelectionModel extends BaseDatabindingModel {
public void addLink(final String containerName,
final String containerAlias) {
- links.add(new ContainerLinkModel(containerName, containerAlias));
+ addLink(new ContainerLinkModel(containerName, containerAlias));
+ }
+
+ public void addLink(final ContainerLinkModel containerLink) {
+ links.add(containerLink);
}
public void addLink(final int index, final String containerName,
@@ -265,8 +325,13 @@ public class ImageRunSelectionModel extends BaseDatabindingModel {
links.remove(link);
}
+ public void removeLinks() {
+ this.links.clear();
+ }
+
public void setLinks(final WritableList links) {
- firePropertyChange(LINKS, this.links, this.links = links);
+ this.links.clear();
+ this.links.addAll(links);
}
public static String getImageName(final String repo, final String tag) {
@@ -303,6 +368,8 @@ public class ImageRunSelectionModel extends BaseDatabindingModel {
public static class ExposedPortModel extends BaseDatabindingModel
implements Comparable<ExposedPortModel> {
+ private static final String SEPARATOR = ":"; //$NON-NLS-1$
+
public static final String SELECTED = "selected"; //$NON-NLS-1$
public static final String CONTAINER_PORT = "containerPort"; //$NON-NLS-1$
@@ -344,12 +411,26 @@ public class ImageRunSelectionModel extends BaseDatabindingModel {
this.hostAddress = hostAddress;
}
+ /**
+ * Create an ExposedPortModel from its toString output
+ *
+ * @param fromString
+ * @return ExposedPortModel
+ */
+ static public ExposedPortModel createPortModel(String fromString) {
+ String[] s = fromString.split(SEPARATOR);
+ ExposedPortModel model = new ExposedPortModel(s[0], s[1], s[2],
+ s[3]);
+ model.selected = Boolean.valueOf(s[4]);
+ return model;
+ }
+
public String getContainerPort() {
return containerPort;
}
public void setContainerPort(final String containerPort) {
- firePropertyChange(SELECTED, this.containerPort,
+ firePropertyChange(CONTAINER_PORT, this.containerPort,
this.containerPort = containerPort);
}
@@ -358,7 +439,7 @@ public class ImageRunSelectionModel extends BaseDatabindingModel {
}
public void setPortType(final String type) {
- firePropertyChange(SELECTED, this.portType, this.portType = type);
+ firePropertyChange(PORT_TYPE, this.portType, this.portType = type);
}
public boolean getSelected() {
@@ -418,9 +499,21 @@ public class ImageRunSelectionModel extends BaseDatabindingModel {
return this.containerPort.compareTo(other.containerPort);
}
+ // FIXME we should have a dedicated method to serialize the bean
+ @Override
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(containerPort + SEPARATOR + portType
+ + SEPARATOR + hostAddress + SEPARATOR + hostPort
+ + SEPARATOR + selected);
+ return buffer.toString();
+ }
+
}
- public class ContainerLinkModel extends BaseDatabindingModel {
+ public static class ContainerLinkModel extends BaseDatabindingModel {
+
+ private static final String CONTAINER_SEPARATOR = ":"; //$NON-NLS-1$
public static final String CONTAINER_NAME = "containerName"; //$NON-NLS-1$
@@ -442,6 +535,12 @@ public class ImageRunSelectionModel extends BaseDatabindingModel {
this.containerAlias = alias;
}
+ public static ContainerLinkModel createContainerLinkModel(
+ final String fromString) {
+ String[] s = fromString.split(CONTAINER_SEPARATOR);
+ return new ContainerLinkModel(s[0], s[1]);
+ }
+
public String getContainerName() {
return containerName;
}
@@ -460,6 +559,11 @@ public class ImageRunSelectionModel extends BaseDatabindingModel {
}
@Override
+ public String toString() {
+ return containerName + CONTAINER_SEPARATOR + containerAlias;
+ }
+
+ @Override
public int hashCode() {
final int prime = 31;
int result = 1;
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/WizardMessages.properties b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/WizardMessages.properties
index 6e69e92a97..4e68b667e6 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/WizardMessages.properties
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/WizardMessages.properties
@@ -65,6 +65,7 @@ NetworkDisabled.label=Network Disabled
Privileged.label=Privileged
PublishAll.label=Publish All Ports
NetworkMode.label=Network Mode
+Connection.label=Connection:
Name.label=Name:
Author.label=Author:

Back to the top