Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/DockerConnectionManager.java13
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnection.java23
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerContainerListener.java7
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerImageBuildOptions.java38
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerImageListener.java9
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java55
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImage.java16
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/validators/BuildDockerImageUtilsTest.java92
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/validators/package-info.java15
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImagePullPatternTest.java30
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/META-INF/MANIFEST.MF2
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/launch/ContainerLauncher.java2
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/jobs/BuildDockerImageJob.java47
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/BuildDockerImageLaunchConfigurationDelegate.java54
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/BuildDockerImageLaunchConfigurationMainTab.java383
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/BuildDockerImageShortcut.java125
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/BuildDockerImageUtils.java106
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/IBuildDockerImageLaunchConfigurationConstants.java14
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/LaunchConfigurationUtils.java11
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/LaunchMessages.properties23
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/validators/ImageNameValidator.java38
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/validators/package-info.java15
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageBuildDialog.java340
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImagePullPage.java45
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionPage.java3
-rw-r--r--containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/WizardMessages.properties9
26 files changed, 1291 insertions, 224 deletions
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/DockerConnectionManager.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/DockerConnectionManager.java
index 8b46f1f6c2..99c8bca7a1 100644
--- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/DockerConnectionManager.java
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/DockerConnectionManager.java
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.linuxtools.docker.core;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import org.eclipse.core.runtime.IStatus;
@@ -72,6 +74,17 @@ public class DockerConnectionManager {
return connections.toArray(new IDockerConnection[connections.size()]);
}
+ /**
+ * @return an immutable {@link List} of the {@link IDockerConnection} names
+ */
+ public List<String> getConnectionNames() {
+ final List<String> connectionNames = new ArrayList<>();
+ for (IDockerConnection connection : this.connections) {
+ connectionNames.add(connection.getName());
+ }
+ return Collections.unmodifiableList(connectionNames);
+ }
+
public IDockerConnection findConnection(final String name) {
if (name != null) {
for (IDockerConnection connection : connections) {
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnection.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnection.java
index ca6d18d5be..939b615b1c 100644
--- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnection.java
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerConnection.java
@@ -13,6 +13,7 @@ package org.eclipse.linuxtools.docker.core;
import java.io.OutputStream;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import org.eclipse.core.runtime.IPath;
import org.eclipse.linuxtools.internal.docker.core.DockerContainerRefreshManager;
@@ -199,6 +200,28 @@ public interface IDockerConnection {
String createContainer(IDockerContainerConfig c, IDockerHostConfig hc)
throws DockerException, InterruptedException;
+ /**
+ * Builds an {@link IDockerImage}
+ *
+ * @param path
+ * path to the build context
+ * @param name
+ * optional name and tag of the image to build
+ * @param handler
+ * progress handler
+ * @param buildOptions
+ * build options
+ * @return the id of the {@link IDockerImage} that was build
+ * @throws DockerException
+ * if building image failed
+ * @throws InterruptedException
+ * if the thread was interrupted
+ */
+ String buildImage(final IPath path, final String name,
+ final IDockerProgressHandler handler,
+ final Map<String, Object> buildOptions)
+ throws DockerException, InterruptedException;
+
public String createContainer(final IDockerContainerConfig config,
final IDockerHostConfig hc, final String containerName)
throws DockerException, InterruptedException;
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerContainerListener.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerContainerListener.java
index 5b9b89be94..063272708c 100644
--- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerContainerListener.java
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerContainerListener.java
@@ -21,9 +21,10 @@ public interface IDockerContainerListener {
*
* @param connection
* - the Docker connection
- * @param list
- * - the new list of {@link IDockerContainer}
+ * @param containers
+ * the new list of containers
*/
- void listChanged(IDockerConnection connection, List<IDockerContainer> list);
+ void listChanged(IDockerConnection connection,
+ List<IDockerContainer> containers);
}
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerImageBuildOptions.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerImageBuildOptions.java
new file mode 100644
index 0000000000..240d0dfaf2
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerImageBuildOptions.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Red Hat.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat - Initial Contribution
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.docker.core;
+
+/**
+ * Name of options passed to the Docker daemon to build an {@link IDockerImage}
+ *
+ */
+public interface IDockerImageBuildOptions {
+
+ /** name of the connection to use to build the Image. */
+ public final static String DOCKER_CONNECTION = "dockerConnection"; //$NON-NLS-1$
+
+ /** repo and optionally tag of Image to build. */
+ public final static String REPO_NAME = "repoName"; //$NON-NLS-1$
+
+ /** quiet build option. */
+ public static final String QUIET_BUILD = "quietBuild"; //$NON-NLS-1$
+
+ /** no cache option. */
+ public static final String NO_CACHE = "noCache"; //$NON-NLS-1$
+
+ /** remove intermediate containers option on successful build. */
+ public static final String RM_INTERMEDIATE_CONTAINERS = "rm"; //$NON-NLS-1$
+
+ /** always remove intermediate containers option. */
+ public static final String FORCE_RM_INTERMEDIATE_CONTAINERS = "forcerm"; //$NON-NLS-1$
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerImageListener.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerImageListener.java
index f01bd7951d..1ec64e747b 100644
--- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerImageListener.java
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerImageListener.java
@@ -18,11 +18,12 @@ public interface IDockerImageListener {
* Called when the list of {@link IDockerImage} for the given
* {@link IDockerConnection} changed
*
- * @param manager
- * - the Docker connection
+ * @param connection
+ * the {@link IDockerConnection} in which the list of
+ * {@link IDockerImage} changed
* @param images
- * - the new list of {@link IDockerImage}
+ * the new list of {@link IDockerImage}
*/
- void listChanged(IDockerConnection manager, List<IDockerImage> images);
+ void listChanged(IDockerConnection connection, List<IDockerImage> images);
}
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java
index a67f905e5e..6212ce1904 100644
--- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java
@@ -54,6 +54,7 @@ import org.eclipse.linuxtools.docker.core.IDockerContainerInfo;
import org.eclipse.linuxtools.docker.core.IDockerContainerListener;
import org.eclipse.linuxtools.docker.core.IDockerHostConfig;
import org.eclipse.linuxtools.docker.core.IDockerImage;
+import org.eclipse.linuxtools.docker.core.IDockerImageBuildOptions;
import org.eclipse.linuxtools.docker.core.IDockerImageInfo;
import org.eclipse.linuxtools.docker.core.IDockerImageListener;
import org.eclipse.linuxtools.docker.core.IDockerImageSearchResult;
@@ -853,11 +854,63 @@ public class DockerConnection implements IDockerConnection, Closeable {
}
}
+ @Override
+ public String buildImage(final IPath path, final String name,
+ final IDockerProgressHandler handler,
+ final Map<String, Object> buildOptions)
+ throws DockerException, InterruptedException {
+ try {
+ final DockerProgressHandler d = new DockerProgressHandler(handler);
+ final java.nio.file.Path p = FileSystems.getDefault()
+ .getPath(path.makeAbsolute().toOSString());
+ return client.build(p, name, d, getBuildParameters(buildOptions));
+ } catch (com.spotify.docker.client.DockerRequestException e) {
+ throw new DockerException(e.message());
+ } catch (com.spotify.docker.client.DockerException | IOException e) {
+ DockerException f = new DockerException(e);
+ throw f;
+ }
+ }
+
+ /**
+ * Converts the given {@link Map} of build options into an array of
+ * {@link BuildParameter} when the build options are set a value different from the default value.
+ *
+ * @param buildOptions
+ * the build options
+ * @return an array of relevant {@link BuildParameter}
+ */
+ private BuildParameter[] getBuildParameters(
+ final Map<String, Object> buildOptions) {
+ final List<BuildParameter> buildParameters = new ArrayList<>();
+ for (Entry<String, Object> entry : buildOptions.entrySet()) {
+ final Object optionName = entry.getKey();
+ final Object optionValue = entry.getValue();
+
+ if (optionName.equals(IDockerImageBuildOptions.QUIET_BUILD)
+ && optionValue.equals(true)) {
+ buildParameters.add(BuildParameter.QUIET);
+ } else if (optionName.equals(IDockerImageBuildOptions.NO_CACHE)
+ && optionValue.equals(true)) {
+ buildParameters.add(BuildParameter.NO_CACHE);
+ } else if (optionName
+ .equals(IDockerImageBuildOptions.RM_INTERMEDIATE_CONTAINERS)
+ && optionValue.equals(false)) {
+ buildParameters.add(BuildParameter.NO_RM);
+ } else if (optionName
+ .equals(IDockerImageBuildOptions.FORCE_RM_INTERMEDIATE_CONTAINERS)
+ && optionValue.equals(true)) {
+ buildParameters.add(BuildParameter.FORCE_RM);
+ }
+ }
+ return buildParameters.toArray(new BuildParameter[0]);
+ }
+
public void save() {
// Currently we have to save all clouds instead of just this one
DockerConnectionManager.getInstance().saveConnections();
}
-
+
@Override
@Deprecated
public String createContainer(IDockerContainerConfig c)
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImage.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImage.java
index a29a124d1d..47a9233135 100644
--- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImage.java
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImage.java
@@ -17,17 +17,31 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.regex.Pattern;
import org.eclipse.linuxtools.docker.core.IDockerImage;
public class DockerImage implements IDockerImage {
+ private static final String REGISTRY_HOST = "[a-zA-Z0-9]+([\\._-][a-zA-Z0-9]+)*"; //$NON-NLS-1$
+ private static final String REGISTRY_PORT = "[0-9]+"; //$NON-NLS-1$
+ private static final String REPOSITORY = "[a-z0-9]+([\\._-][a-z0-9]+)*"; //$NON-NLS-1$
+ private static final String NAME = "[a-z0-9]+([\\._-][a-z0-9]+)*"; //$NON-NLS-1$
+ private static final String TAG = "[a-zA-Z0-9]+([\\._-][a-zA-Z0-9]+)*"; //$NON-NLS-1$
+
+ /** the image name pattern. */
+ public static final Pattern imageNamePattern = Pattern.compile("(" //$NON-NLS-1$
+ + REGISTRY_HOST + "\\:" + REGISTRY_PORT + "/)?" //$NON-NLS-1$ //$NON-NLS-2$
+ + "((?<repository>" + REPOSITORY + ")/)?" //$NON-NLS-1$ //$NON-NLS-2$
+ + "(?<name>" + NAME + ")" //$NON-NLS-1$ //$NON-NLS-2$
+ + "(\\:(?<tag>" + TAG + "))?"); //$NON-NLS-1$ //$NON-NLS-2$
+
// SimpleDateFormat is not thread-safe, so give one to each thread
private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){
@Override
protected SimpleDateFormat initialValue()
{
- return new SimpleDateFormat("yyyy-MM-dd");
+ return new SimpleDateFormat("yyyy-MM-dd"); //$NON-NLS-1$
}
};
diff --git a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/validators/BuildDockerImageUtilsTest.java b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/validators/BuildDockerImageUtilsTest.java
new file mode 100644
index 0000000000..0968467c72
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/validators/BuildDockerImageUtilsTest.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * 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.validators;
+
+import org.eclipse.linuxtools.internal.docker.ui.launch.BuildDockerImageUtils;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * Testing the {@link BuildDockerImageUtils}.
+ */
+@RunWith(Parameterized.class)
+public class BuildDockerImageUtilsTest {
+
+ private static Object[] match(final String imageName, final String expectedRepository, final String expectedName, final String expectedTag) {
+ return new Object[] { imageName, expectedRepository, expectedName, expectedTag };
+ }
+
+ @Parameters(name = "{0} -> {1}/{2}:{3}")
+ public static Object[][] data() {
+ return new Object[][] { match("", null, null, null),
+ match("£", null, null, null), // because £ is an invalid character
+ match("wildfly", null, "wildfly", null),
+ match("jboss/", null, null, null),
+ match("jboss/wildfly", "jboss", "wildfly", null),
+ match("jboss/wildfly:", null , null, null), // because ':' causes invalid value
+ match("jboss/wildfly:latest", "jboss", "wildfly", "latest"),
+ match("localhost/wildfly/", null, null, null), // because registry is missing port number
+ match("localhost/jboss/wildfly", null, null, null), // because registry is missing port number
+ match("localhost/jboss/wildfly:", null, null, null), // because registry is missing port number
+ match("localhost/jboss/wildfly:latest", null, null, null), // because registry is missing port number
+ match("localhost/jboss/wildfly:9", null, null, null), // because registry is missing port number
+ match("localhost/jboss/wildfly:9.", null, null, null), // because registry is missing port number
+ match("localhost/jboss/wildfly:9.0.1.Final", null, null, null), // because registry is missing port number
+ match("localhost:", null, null, null), // because trailing ':' causes invalid value
+ match("localhost:5000", null, "localhost", "5000"), // bc it matches the REPO:TAG pattern.
+ match("localhost:5000/", null, null, null), // because trailing '/' causes invalid value
+ match("localhost:5000/jboss/wildfly", "jboss", "wildfly", null),
+ match("localhost:5000/jboss/wildfly/", null, null, null), // because trailing '/' causes invalid value
+ match("localhost:5000/jboss/wildfly", "jboss", "wildfly", null),
+ match("localhost:5000/jboss/wildfly:", null, null, null), // because ':' causes invalid value
+ match("localhost:5000/jboss/wildfly:latest", "jboss", "wildfly", "latest"),
+ };
+ }
+
+ @Parameter(value = 0)
+ public String imageName;
+ @Parameter(value = 1)
+ public String expectedRepository;
+ @Parameter(value = 2)
+ public String expectedName;
+ @Parameter(value = 3)
+ public String expectedTag;
+
+ @Test
+ public void verifyRepository() {
+ // when
+ final String actualRepository = BuildDockerImageUtils.getRepository(imageName);
+ // then
+ Assert.assertEquals(expectedRepository, actualRepository);
+ }
+
+ @Test
+ public void verifyName() {
+ // when
+ final String actualName = BuildDockerImageUtils.getName(imageName);
+ // then
+ Assert.assertEquals(expectedName, actualName);
+ }
+
+ @Test
+ public void verifyTag() {
+ // when
+ final String actualTagName = BuildDockerImageUtils.getTag(imageName);
+ // then
+ Assert.assertEquals(expectedTag, actualTagName);
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/validators/package-info.java b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/validators/package-info.java
new file mode 100644
index 0000000000..319edc510a
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/validators/package-info.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * 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.validators; \ No newline at end of file
diff --git a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImagePullPatternTest.java b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImagePullPatternTest.java
index dc6bff7e9d..2fe4e05910 100644
--- a/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImagePullPatternTest.java
+++ b/containers/org.eclipse.linuxtools.docker.ui.tests/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImagePullPatternTest.java
@@ -11,6 +11,7 @@
package org.eclipse.linuxtools.internal.docker.ui.wizards;
import org.eclipse.core.runtime.IStatus;
+import org.eclipse.linuxtools.internal.docker.ui.validators.ImageNameValidator;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -19,13 +20,12 @@ import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
-public class ImagePullPatternTest {
+public class ImagePullPatternTest {
private static Object[] match(final String imageName, final int expectedSeverity) {
return new Object[]{imageName, expectedSeverity};
}
-
@Parameters(name="{0} -> {1}")
public static Object[][] data() {
return new Object[][] {
@@ -37,21 +37,21 @@ public class ImagePullPatternTest {
match("jboss/wildfly:", IStatus.WARNING),
match("jboss/wildfly:latest", IStatus.OK),
match("localhost/wildfly/", IStatus.WARNING),
- match("localhost/wildfly/jboss", IStatus.WARNING),
- match("localhost/wildfly/jboss:", IStatus.WARNING),
- match("localhost/wildfly/jboss:latest", IStatus.OK),
- match("localhost/wildfly/jboss:9", IStatus.OK),
- match("localhost/wildfly/jboss:9.", IStatus.WARNING),
- match("localhost/wildfly/jboss:9.0.1.", IStatus.WARNING),
- match("localhost/wildfly/jboss:9.0.1.Final", IStatus.OK),
+ match("localhost/jboss/wildfly", IStatus.WARNING),
+ match("localhost/jboss/wildfly:", IStatus.WARNING),
+ match("localhost/jboss/wildfly:latest", IStatus.WARNING),
+ match("localhost/jboss/wildfly:9", IStatus.WARNING),
+ match("localhost/jboss/wildfly:9.", IStatus.WARNING),
+ match("localhost/jboss/wildfly:9.0.1.", IStatus.WARNING),
+ match("localhost/jboss/wildfly:9.0.1.Final", IStatus.WARNING),
match("localhost:", IStatus.WARNING),
match("localhost:5000", IStatus.OK), // bc it matches the REPO:TAG pattern.
match("localhost:5000/", IStatus.WARNING),
- match("localhost:5000/wildfly", IStatus.WARNING),
- match("localhost:5000/wildfly/", IStatus.WARNING),
- match("localhost:5000/wildfly/jboss", IStatus.WARNING),
- match("localhost:5000/wildfly/jboss:", IStatus.WARNING),
- match("localhost:5000/wildfly/jboss:latest", IStatus.OK),
+ match("localhost:5000/jboss/wildfly", IStatus.WARNING),
+ match("localhost:5000/jboss/wildfly/", IStatus.WARNING),
+ match("localhost:5000/jboss/wildfly", IStatus.WARNING),
+ match("localhost:5000/jboss/wildfly:", IStatus.WARNING),
+ match("localhost:5000/jboss/wildfly:latest", IStatus.OK),
};
}
@@ -63,7 +63,7 @@ public class ImagePullPatternTest {
@Test
public void verifyData() {
- final IStatus status = new ImagePullPage.ImageNameValidator().validate(imageName);
+ final IStatus status = new ImageNameValidator().validate(imageName);
// then
Assert.assertEquals(expectedSeverity, status.getSeverity());
}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/META-INF/MANIFEST.MF b/containers/org.eclipse.linuxtools.docker.ui/META-INF/MANIFEST.MF
index 9150e20569..0941576aae 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/META-INF/MANIFEST.MF
+++ b/containers/org.eclipse.linuxtools.docker.ui/META-INF/MANIFEST.MF
@@ -32,4 +32,6 @@ Export-Package: org.eclipse.linuxtools.docker.ui,
org.eclipse.linuxtools.internal.docker.ui.commands;x-friends:="org.eclipse.linuxtools.docker.ui.tests",
org.eclipse.linuxtools.internal.docker.ui.preferences,
org.eclipse.linuxtools.internal.docker.ui.views;x-friends:="org.eclipse.linuxtools.docker.ui.tests",
+ org.eclipse.linuxtools.internal.docker.ui.launch;x-friends:="org.eclipse.linuxtools.docker.ui.tests",
+ org.eclipse.linuxtools.internal.docker.ui.validators;x-friends:="org.eclipse.linuxtools.docker.ui.tests",
org.eclipse.linuxtools.internal.docker.ui.wizards;x-friends:="org.eclipse.linuxtools.docker.ui.tests"
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/launch/ContainerLauncher.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/launch/ContainerLauncher.java
index 9632dced0e..0ca6f287d3 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/launch/ContainerLauncher.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/docker/ui/launch/ContainerLauncher.java
@@ -231,7 +231,7 @@ public class ContainerLauncher {
String containerId = null;
try {
containerId = ((DockerConnection) connection)
- .createContainer(config, hostConfig);
+ .createContainer(config, hostConfig, null);
OutputStream stream = null;
RunConsole oldConsole = getConsole();
final RunConsole rc = RunConsole.findConsole(containerId,
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/jobs/BuildDockerImageJob.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/jobs/BuildDockerImageJob.java
index b778f73a2f..86e672e234 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/jobs/BuildDockerImageJob.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/jobs/BuildDockerImageJob.java
@@ -16,6 +16,7 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.util.Map;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
@@ -31,6 +32,7 @@ import org.eclipse.linuxtools.docker.core.IDockerProgressHandler;
import org.eclipse.linuxtools.docker.core.IDockerProgressMessage;
import org.eclipse.linuxtools.docker.ui.Activator;
import org.eclipse.linuxtools.internal.docker.ui.BuildConsole;
+import org.eclipse.linuxtools.internal.docker.ui.launch.IBuildDockerImageLaunchConfigurationConstants;
import org.eclipse.swt.widgets.Display;
/**
@@ -51,6 +53,12 @@ public class BuildDockerImageJob extends Job implements IDockerProgressHandler {
/** The path to the source code. */
private final IPath path;
+ /** the build options. */
+ private final Map<String, Object> buildOptions;
+
+ /** the optional repoName (i.e., repo[tag]) for the image to build */
+ private final String repoName;
+
/** The number of steps to build the image. */
private final int numberOfBuildOperations;
@@ -64,21 +72,30 @@ public class BuildDockerImageJob extends Job implements IDockerProgressHandler {
* Constructor
*
* @param connection
- * the Docker connection to use (ie, on which Docker engine to
+ * the Docker connection to use (i.e., on which Docker engine to
* build the image)
* @param path
* the path to the source code
+ * @param repoName
+ * the optional repoName (i.e., repo[tag]) for the image to build
+ * @param buildOptions
+ * build options
* @throws IOException
+ * @see {@link IBuildDockerImageLaunchConfigurationConstants} for build
+ * options.
*/
public BuildDockerImageJob(final IDockerConnection connection,
- final IPath path) throws DockerException {
+ final IPath path, final String repoName,
+ final Map<String, Object> buildOptions)
+ throws DockerException {
super(JobMessages.getString(BUILD_IMAGE_JOB_TITLE));
this.connection = connection;
this.path = path;
+ this.repoName = repoName;
+ this.buildOptions = buildOptions;
this.console = BuildConsole.findConsole();
this.numberOfBuildOperations = countLines(
path.addTrailingSeparator().append("Dockerfile").toOSString()); //$NON-NLS-1$
-
}
@Override
@@ -94,13 +111,21 @@ public class BuildDockerImageJob extends Job implements IDockerProgressHandler {
this.progressMonitor.beginTask(
JobMessages.getString(BUILD_IMAGE_JOB_TITLE),
numberOfBuildOperations + 1);
- // Give the Image a default name so it can be tagged later.
- // Otherwise, the Image will be treated as an intermediate Image
- // by the view filters and Tag Image action will be disabled.
- // Use the current time in milliseconds to make it unique.
- String name = "dockerfile:" //$NON-NLS-1$
- + Long.toHexString(System.currentTimeMillis());
- connection.buildImage(path, name, this);
+ if (repoName == null) {
+ // Give the Image a default name so it can be tagged later.
+ // Otherwise, the Image will be treated as an intermediate
+ // Image
+ // by the view filters and Tag Image action will be
+ // disabled.
+ // Use the current time in milliseconds to make it unique.
+ final String name = "dockerfile:" //$NON-NLS-1$
+ + Long.toHexString(System.currentTimeMillis());
+ connection.buildImage(this.path, name, this,
+ this.buildOptions);
+ } else {
+ connection.buildImage(this.path, this.repoName, this,
+ this.buildOptions);
+ }
connection.getImages(true);
}
} catch (DockerException | InterruptedException e) {
@@ -162,7 +187,7 @@ public class BuildDockerImageJob extends Job implements IDockerProgressHandler {
* statements to execute (ignoring comments and empty lines).
*
* @param fileName
- * the full name of the Docker file to read
+ * the full repoName of the Docker file to read
* @return the number of instructions.
* @throws DockerException
* @throws IOException
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/BuildDockerImageLaunchConfigurationDelegate.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/BuildDockerImageLaunchConfigurationDelegate.java
index bb60539517..387051cb4e 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/BuildDockerImageLaunchConfigurationDelegate.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/BuildDockerImageLaunchConfigurationDelegate.java
@@ -11,16 +11,22 @@
package org.eclipse.linuxtools.internal.docker.ui.launch;
-import static org.eclipse.linuxtools.internal.docker.ui.launch.IBuildDockerImageLaunchConfigurationConstants.DOCKER_CONNECTION;
+import static org.eclipse.linuxtools.docker.core.IDockerImageBuildOptions.DOCKER_CONNECTION;
+import static org.eclipse.linuxtools.docker.core.IDockerImageBuildOptions.FORCE_RM_INTERMEDIATE_CONTAINERS;
+import static org.eclipse.linuxtools.docker.core.IDockerImageBuildOptions.NO_CACHE;
+import static org.eclipse.linuxtools.docker.core.IDockerImageBuildOptions.QUIET_BUILD;
+import static org.eclipse.linuxtools.docker.core.IDockerImageBuildOptions.REPO_NAME;
+import static org.eclipse.linuxtools.docker.core.IDockerImageBuildOptions.RM_INTERMEDIATE_CONTAINERS;
import static org.eclipse.linuxtools.internal.docker.ui.launch.IBuildDockerImageLaunchConfigurationConstants.SOURCE_PATH_LOCATION;
import static org.eclipse.linuxtools.internal.docker.ui.launch.IBuildDockerImageLaunchConfigurationConstants.SOURCE_PATH_WORKSPACE_RELATIVE_LOCATION;
-import org.eclipse.core.resources.ResourcesPlugin;
+import java.util.HashMap;
+import java.util.Map;
+
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.ILaunch;
@@ -44,18 +50,31 @@ public class BuildDockerImageLaunchConfigurationDelegate
private static final String MISSING_CONNECTION_ERROR_MSG = "MissingConnectionError.msg"; //$NON-NLS-1$
@Override
- public void launch(ILaunchConfiguration configuration, String mode,
- ILaunch launch, IProgressMonitor monitor) throws CoreException {
+ public void launch(final ILaunchConfiguration configuration,
+ final String mode, final ILaunch launch,
+ final IProgressMonitor monitor) throws CoreException {
final String sourcePathLocation = configuration
.getAttribute(SOURCE_PATH_LOCATION, (String) null);
final boolean sourcePathWorkspaceRelativeLocation = configuration
- .getAttribute(SOURCE_PATH_WORKSPACE_RELATIVE_LOCATION, false);
- final IPath sourcePath = getPath(sourcePathLocation,
+ .getAttribute(SOURCE_PATH_WORKSPACE_RELATIVE_LOCATION,
+ false);
+ final IPath sourcePath = BuildDockerImageUtils.getPath(
+ sourcePathLocation,
sourcePathWorkspaceRelativeLocation);
final String connectionName = configuration
.getAttribute(DOCKER_CONNECTION, (String) null);
+ final String repoName = configuration.getAttribute(REPO_NAME,
+ (String) null);
final DockerConnection connection = (DockerConnection) getDockerConnection(
connectionName);
+ final Map<String, Object> buildOptions = new HashMap<>();
+ buildOptions.put(QUIET_BUILD,
+ configuration.getAttribute(QUIET_BUILD, false));
+ buildOptions.put(NO_CACHE, configuration.getAttribute(NO_CACHE, false));
+ buildOptions.put(RM_INTERMEDIATE_CONTAINERS, configuration
+ .getAttribute(RM_INTERMEDIATE_CONTAINERS, true));
+ buildOptions.put(FORCE_RM_INTERMEDIATE_CONTAINERS, configuration
+ .getAttribute(FORCE_RM_INTERMEDIATE_CONTAINERS, false));
if (connection == null) {
Activator
.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
@@ -64,24 +83,21 @@ public class BuildDockerImageLaunchConfigurationDelegate
connectionName)));
}
try {
- final Job buildImageJob = new BuildDockerImageJob(connection,
- sourcePath);
- buildImageJob.schedule();
+ if (connection != null && sourcePath != null) {
+ final Job buildImageJob = new BuildDockerImageJob(connection,
+ sourcePath, repoName, buildOptions);
+ buildImageJob.schedule();
+ } else {
+ Activator.log(new Status(IStatus.WARNING, Activator.PLUGIN_ID,
+ LaunchMessages.getString(
+ "BuildDockerImageLaunchConfiguration.error.incomplete"))); //$NON-NLS-1$
+ }
} catch (DockerException e) {
Activator.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
e.getMessage(), e));
}
}
- private IPath getPath(final String sourcePathLocation,
- final boolean sourcePathWorkspaceRelativeLocation) {
- if (sourcePathWorkspaceRelativeLocation) {
- return ResourcesPlugin.getWorkspace().getRoot()
- .findMember(new Path(sourcePathLocation)).getLocation();
- }
- return new Path(sourcePathLocation);
- }
-
/**
* Finds the {@link IDockerConnection} from the given name
*
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/BuildDockerImageLaunchConfigurationMainTab.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/BuildDockerImageLaunchConfigurationMainTab.java
index 92a6077150..df658e32fe 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/BuildDockerImageLaunchConfigurationMainTab.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/BuildDockerImageLaunchConfigurationMainTab.java
@@ -11,17 +11,23 @@
package org.eclipse.linuxtools.internal.docker.ui.launch;
-import static org.eclipse.linuxtools.internal.docker.ui.launch.IBuildDockerImageLaunchConfigurationConstants.DOCKER_CONNECTION;
+import static org.eclipse.linuxtools.docker.core.IDockerImageBuildOptions.DOCKER_CONNECTION;
+import static org.eclipse.linuxtools.docker.core.IDockerImageBuildOptions.FORCE_RM_INTERMEDIATE_CONTAINERS;
+import static org.eclipse.linuxtools.docker.core.IDockerImageBuildOptions.NO_CACHE;
+import static org.eclipse.linuxtools.docker.core.IDockerImageBuildOptions.QUIET_BUILD;
+import static org.eclipse.linuxtools.docker.core.IDockerImageBuildOptions.REPO_NAME;
+import static org.eclipse.linuxtools.docker.core.IDockerImageBuildOptions.RM_INTERMEDIATE_CONTAINERS;
import static org.eclipse.linuxtools.internal.docker.ui.launch.IBuildDockerImageLaunchConfigurationConstants.SOURCE_PATH_LOCATION;
import static org.eclipse.linuxtools.internal.docker.ui.launch.IBuildDockerImageLaunchConfigurationConstants.SOURCE_PATH_WORKSPACE_RELATIVE_LOCATION;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.ILaunchConfiguration;
@@ -35,7 +41,6 @@ import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.linuxtools.docker.core.DockerConnectionManager;
-import org.eclipse.linuxtools.docker.core.IDockerConnection;
import org.eclipse.linuxtools.docker.ui.Activator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
@@ -47,6 +52,7 @@ import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
@@ -60,16 +66,40 @@ public class BuildDockerImageLaunchConfigurationMainTab
extends AbstractLaunchConfigurationTab {
private final String TAB_NAME = "BuildDockerImageLaunchConfigurationMainTab.name"; //$NON-NLS-1$
- private final String SOURCE_PATH_LOCATION_LABEL = "BuildDockerImageLaunchConfigurationMainTab.sourcePathLocation.group.label"; //$NON-NLS-1$
private final String CONNECTION_LABEL = "BuildDockerImageLaunchConfigurationMainTab.connection.group.label"; //$NON-NLS-1$
- private final String BROWSE_WORKSPACE = "BuildDockerImageLaunchConfigurationMainTab.browseworkspace.button.label"; //$NON-NLS-1$
- private final String BROWSE_WORKSPACE_DIALOG_TITLE = "BuildDockerImageLaunchConfigurationMainTab.browseworkspace.dialog.title"; //$NON-NLS-1$
- private final String BROWSE_WORKSPACE_DIALOG_MESSAGE = "BuildDockerImageLaunchConfigurationMainTab.browseworkspace.dialog.message"; //$NON-NLS-1$
- private final String BROWSE_FILESYSTEM = "BuildDockerImageLaunchConfigurationMainTab.browsefilesystem.button.label"; //$NON-NLS-1$
+ private final String CONNECTION_TOOLTIP = "BuildDockerImageLaunchConfigurationMainTab.connection.group.tooltip"; //$NON-NLS-1$
+ private final String BUILD_CONTEXT_PATH_LABEL = "BuildDockerImageLaunchConfigurationMainTab.buildContextPath.group.label"; //$NON-NLS-1$
+ private final String BUILD_CONTEXT_PATH_MISSING = "BuildDockerImageLaunchConfigurationMainTab.buildContextPath.missing"; //$NON-NLS-1$
+ private final String DOCKERFILE_PATH_LABEL = "BuildDockerImageLaunchConfigurationMainTab.dockerfilePath.group.label"; //$NON-NLS-1$
+ private final String BROWSE_WORKSPACE = "BuildDockerImageLaunchConfigurationMainTab.buildContextPath.browseworkspace.button.label"; //$NON-NLS-1$
+ private final String BROWSE_WORKSPACE_DIALOG_TITLE = "BuildDockerImageLaunchConfigurationMainTab.buildContextPath.browseworkspace.dialog.title"; //$NON-NLS-1$
+ private final String BROWSE_FILESYSTEM = "BuildDockerImageLaunchConfigurationMainTab.buildContextPath.browsefilesystem.button.label"; //$NON-NLS-1$
+ private final String REPO_NAME_LABEL = "BuildDockerImageLaunchConfigurationMainTab.repoName.label"; //$NON-NLS-1$
+ private final String REPO_NAME_MISSING = "BuildDockerImageLaunchConfigurationMainTab.repoName.missing"; //$NON-NLS-1$
+ private final String OPTIONS_LABEL = "BuildDockerImageLaunchConfigurationMainTab.options.group.label"; //$NON-NLS-1$
+ private final String OPTION_QUIET_LABEL = "BuildDockerImageLaunchConfigurationMainTab.options.quiet.button.label"; //$NON-NLS-1$
+ private final String OPTION_NOCACHE_LABEL = "BuildDockerImageLaunchConfigurationMainTab.options.noCache.button.label"; //$NON-NLS-1$
+ private final String OPTION_RM_LABEL = "BuildDockerImageLaunchConfigurationMainTab.options.rm.button.label"; //$NON-NLS-1$
+ private final String OPTION_FORCERM_LABEL = "BuildDockerImageLaunchConfigurationMainTab.options.forceRM.button.label"; //$NON-NLS-1$
- private Text sourcePathLocationText;
- private boolean sourcePathWorkspaceRelativeLocation;
+ /** the Docker daemon to use for the image build. */
private ComboViewer connectionSelectionComboViewer;
+ /** the path to the build context . */
+ private Text buildContextPathText;
+ private AtomicBoolean buildContextPathWorkspaceRelative;
+ /** the path to the Dockerfile. */
+ private Text dockerFilePathText;
+ private AtomicBoolean dockerFilePathWorkspaceRelative;
+ /** build option: name and optional tag. */
+ private Text repoNameText;
+ /** build option: do not use cache. */
+ private Button noCacheButton;
+ /** build option: quiet mode. */
+ private Button quietBuildButton;
+ /** build option: remove intermediate after successful build only. */
+ private Button removeIntermediateContainersButton;
+ /** build option: always remove intermediate. */
+ private Button alwaysRemoveIntermediateContainersButton;
@Override
public void createControl(final Composite parent) {
@@ -79,65 +109,185 @@ public class BuildDockerImageLaunchConfigurationMainTab
GridLayoutFactory.fillDefaults().margins(6, 6).applyTo(container);
setControl(container);
- // source path location
- final Group sourcePathLocationGroup = new Group(container, SWT.BORDER);
+ // connection selection
+ final Group connectionGroup = new Group(container, SWT.BORDER);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL)
+ .grab(true, false).applyTo(connectionGroup);
+ GridLayoutFactory.fillDefaults().numColumns(2).margins(6, 6)
+ .applyTo(connectionGroup);
+ connectionGroup.setText(LaunchMessages.getString(CONNECTION_LABEL));
+ connectionGroup
+ .setToolTipText(LaunchMessages.getString(CONNECTION_TOOLTIP));
+ final Combo connectionSelectionCombo = new Combo(connectionGroup,
+ SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).applyTo(connectionSelectionCombo);
+ this.connectionSelectionComboViewer = new ComboViewer(
+ connectionSelectionCombo);
+ this.connectionSelectionComboViewer
+ .setContentProvider(new ArrayContentProvider());
+ this.connectionSelectionComboViewer.setInput(
+ DockerConnectionManager.getInstance().getConnectionNames());
+ connectionSelectionCombo
+ .addSelectionListener(new LaunchConfigurationChangeListener());
+ // build context path
+ createBuildContextPathGroup(container);
+ // repository name
+ createRepoNameGroup(container);
+ // dockerfile path
+ // createDockerfilePathGroup(container);
+ // build options
+ createBuildOptionsGroup(container);
+ }
+
+ private void createBuildContextPathGroup(final Composite container) {
+ final Group buildContextPathLocationGroup = new Group(container,
+ SWT.BORDER);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL)
- .grab(true, false).applyTo(sourcePathLocationGroup);
+ .grab(true, false).applyTo(buildContextPathLocationGroup);
GridLayoutFactory.fillDefaults().margins(6, 6).numColumns(3)
- .applyTo(sourcePathLocationGroup);
- sourcePathLocationGroup
- .setText(LaunchMessages.getString(SOURCE_PATH_LOCATION_LABEL));
- sourcePathLocationText = new Text(sourcePathLocationGroup, SWT.BORDER);
- sourcePathLocationText
+ .applyTo(buildContextPathLocationGroup);
+ buildContextPathLocationGroup
+ .setText(LaunchMessages.getString(BUILD_CONTEXT_PATH_LABEL));
+ this.buildContextPathText = new Text(
+ buildContextPathLocationGroup, SWT.BORDER);
+ this.buildContextPathText
.addModifyListener(new LaunchConfigurationChangeListener());
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
- .grab(true, false).span(3, 1).applyTo(sourcePathLocationText);
+ .grab(true, false).span(3, 1)
+ .applyTo(this.buildContextPathText);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(true, false)
- .applyTo(new Label(sourcePathLocationGroup, SWT.NONE));
+ .applyTo(new Label(buildContextPathLocationGroup, SWT.NONE));
+ final Button browseWorkspaceButton = new Button(
+ buildContextPathLocationGroup, SWT.NONE);
+ browseWorkspaceButton
+ .setText(LaunchMessages.getString(BROWSE_WORKSPACE));
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(browseWorkspaceButton);
+ browseWorkspaceButton
+ .addSelectionListener(onBrowseWorkspace(buildContextPathText,
+ buildContextPathWorkspaceRelative, IContainer.class));
+ final Button browseFileSystemButton = new Button(
+ buildContextPathLocationGroup, SWT.NONE);
+ browseFileSystemButton
+ .setText(LaunchMessages.getString(BROWSE_FILESYSTEM));
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(browseFileSystemButton);
+ browseFileSystemButton.addSelectionListener(
+ onBrowseFileSystemForDirectory(this.buildContextPathText,
+ this.buildContextPathWorkspaceRelative));
+ }
- final Button browseWorkspaceButton = new Button(sourcePathLocationGroup,
- SWT.NONE);
+ @SuppressWarnings("unused")
+ private void createDockerfilePathGroup(final Composite container) {
+ final Group dockerFilePathLocationGroup = new Group(container,
+ SWT.BORDER);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL)
+ .grab(true, false).applyTo(dockerFilePathLocationGroup);
+ GridLayoutFactory.fillDefaults().margins(6, 6).numColumns(3)
+ .applyTo(dockerFilePathLocationGroup);
+ dockerFilePathLocationGroup
+ .setText(LaunchMessages.getString(DOCKERFILE_PATH_LABEL));
+ this.dockerFilePathText = new Text(
+ dockerFilePathLocationGroup, SWT.BORDER);
+ this.dockerFilePathText
+ .addModifyListener(new LaunchConfigurationChangeListener());
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).span(3, 1).applyTo(this.dockerFilePathText);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false)
+ .applyTo(new Label(dockerFilePathLocationGroup, SWT.NONE));
+ final Button browseWorkspaceButton = new Button(
+ dockerFilePathLocationGroup, SWT.NONE);
browseWorkspaceButton
.setText(LaunchMessages.getString(BROWSE_WORKSPACE));
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(false, false).applyTo(browseWorkspaceButton);
- browseWorkspaceButton.addSelectionListener(onBrowseWorkspace());
+ browseWorkspaceButton
+ .addSelectionListener(onBrowseWorkspace(dockerFilePathText,
+ dockerFilePathWorkspaceRelative, IFile.class));
final Button browseFileSystemButton = new Button(
- sourcePathLocationGroup,
- SWT.NONE);
+ dockerFilePathLocationGroup, SWT.NONE);
browseFileSystemButton
.setText(LaunchMessages.getString(BROWSE_FILESYSTEM));
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
.grab(false, false).applyTo(browseFileSystemButton);
- browseFileSystemButton.addSelectionListener(onBrowseFileSystem());
+ browseFileSystemButton.addSelectionListener(onBrowseFileSystemForFile(
+ this.dockerFilePathText, this.dockerFilePathWorkspaceRelative));
+ }
- // connection
- final Group connectionGroup = new Group(container, SWT.BORDER);
+ private void createRepoNameGroup(final Composite container) {
+ final Group repoNameGroup = new Group(container, SWT.BORDER);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL)
- .grab(true, false).applyTo(connectionGroup);
- GridLayoutFactory.fillDefaults().numColumns(2).margins(6, 6)
- .applyTo(connectionGroup);
- connectionGroup.setText(LaunchMessages.getString(CONNECTION_LABEL));
- final Combo connectionSelectionCombo = new Combo(connectionGroup,
- SWT.NONE);
+ .grab(true, false).applyTo(repoNameGroup);
+ GridLayoutFactory.fillDefaults().margins(6, 6).numColumns(1)
+ .applyTo(repoNameGroup);
+ repoNameGroup.setText(LaunchMessages.getString(REPO_NAME_LABEL));
+
+ this.repoNameText = new Text(repoNameGroup, SWT.BORDER);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
- .grab(true, false).applyTo(connectionSelectionCombo);
- connectionSelectionComboViewer = new ComboViewer(
- connectionSelectionCombo);
- connectionSelectionComboViewer
- .setContentProvider(new ArrayContentProvider());
- connectionSelectionComboViewer.setInput(getConnectionNames());
- connectionSelectionCombo.addSelectionListener(new LaunchConfigurationChangeListener());
+ .grab(true, false).applyTo(this.repoNameText);
+ this.repoNameText
+ .addModifyListener(new LaunchConfigurationChangeListener());
}
- private List<String> getConnectionNames() {
- final List<String> connectionNames = new ArrayList<>();
- for (IDockerConnection connection : DockerConnectionManager
- .getInstance().getConnections()) {
- connectionNames.add(connection.getName());
- }
- return connectionNames;
+ private void createBuildOptionsGroup(final Composite container) {
+ final Group optionsGroup = new Group(container, SWT.BORDER);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL)
+ .grab(true, false).applyTo(optionsGroup);
+ GridLayoutFactory.fillDefaults().margins(6, 6).numColumns(2)
+ .applyTo(optionsGroup);
+ optionsGroup.setText(LaunchMessages.getString(OPTIONS_LABEL));
+
+ this.quietBuildButton = new Button(optionsGroup, SWT.CHECK);
+ this.quietBuildButton
+ .setText(LaunchMessages.getString(OPTION_QUIET_LABEL));
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).span(2, 1)
+ .grab(true, false).applyTo(this.quietBuildButton);
+ this.quietBuildButton
+ .addSelectionListener(new LaunchConfigurationChangeListener());
+
+ this.noCacheButton = new Button(optionsGroup, SWT.CHECK);
+ this.noCacheButton
+ .setText(LaunchMessages.getString(OPTION_NOCACHE_LABEL));
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).span(2, 1)
+ .grab(true, false).applyTo(this.noCacheButton);
+ this.noCacheButton
+ .addSelectionListener(new LaunchConfigurationChangeListener());
+
+ this.removeIntermediateContainersButton = new Button(optionsGroup,
+ SWT.CHECK);
+ this.removeIntermediateContainersButton
+ .setText(LaunchMessages.getString(OPTION_RM_LABEL));
+ this.removeIntermediateContainersButton
+ .addSelectionListener(new LaunchConfigurationChangeListener());
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).span(2, 1)
+ .grab(true, false)
+ .applyTo(this.removeIntermediateContainersButton);
+
+ this.alwaysRemoveIntermediateContainersButton = new Button(optionsGroup,
+ SWT.CHECK);
+ this.alwaysRemoveIntermediateContainersButton
+ .setText(LaunchMessages.getString(OPTION_FORCERM_LABEL));
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).span(2, 1)
+ .grab(true, false)
+ .applyTo(this.alwaysRemoveIntermediateContainersButton);
+ this.alwaysRemoveIntermediateContainersButton
+ .addSelectionListener(onAlwaysRemoveIntermediateContainers());
+ this.alwaysRemoveIntermediateContainersButton
+ .addSelectionListener(new LaunchConfigurationChangeListener());
+ }
+
+ private SelectionListener onAlwaysRemoveIntermediateContainers() {
+ return new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ toggleRemoveIntermediateContainersButtonState();
+ }
+
+ };
}
/**
@@ -145,7 +295,9 @@ public class BuildDockerImageLaunchConfigurationMainTab
*
* @return
*/
- private SelectionListener onBrowseWorkspace() {
+ private SelectionListener onBrowseWorkspace(final Text pathText,
+ final AtomicBoolean workspaceRelativePath,
+ final Class<?> expectedType) {
return new SelectionAdapter() {
@Override
@@ -156,8 +308,6 @@ public class BuildDockerImageLaunchConfigurationMainTab
dialog.setInput(ResourcesPlugin.getWorkspace().getRoot());
dialog.setTitle(LaunchMessages
.getString(BROWSE_WORKSPACE_DIALOG_TITLE));
- dialog.setMessage(LaunchMessages
- .getString(BROWSE_WORKSPACE_DIALOG_MESSAGE));
dialog.setComparator(
new ResourceComparator(ResourceComparator.NAME));
dialog.setAllowMultiple(false);
@@ -165,8 +315,8 @@ public class BuildDockerImageLaunchConfigurationMainTab
// only accept a single file as the valid selection
@Override
public IStatus validate(Object[] selection) {
- if (selection.length == 1
- && selection[0] instanceof IContainer) {
+ if (selection.length == 1 && expectedType
+ .isAssignableFrom(selection[0].getClass())) {
return new Status(IStatus.OK, Activator.PLUGIN_ID,
null);
}
@@ -177,20 +327,20 @@ public class BuildDockerImageLaunchConfigurationMainTab
if (dialog.open() == IDialogConstants.OK_ID) {
final IResource selection = (IResource) dialog
.getFirstResult();
- sourcePathLocationText
- .setText(selection.getFullPath().toOSString());
- sourcePathWorkspaceRelativeLocation = true;
+ pathText.setText(selection.getFullPath().toOSString());
+ workspaceRelativePath.set(true);
}
}
};
}
/**
- * Opens a dialog to browse the file system
+ * Opens a dialog to browse the file system and select a directory
*
* @return
*/
- private SelectionListener onBrowseFileSystem() {
+ private SelectionListener onBrowseFileSystemForDirectory(final Text pathText,
+ final AtomicBoolean workspaceRelativePath) {
return new SelectionAdapter() {
@Override
@@ -198,8 +348,29 @@ public class BuildDockerImageLaunchConfigurationMainTab
final DirectoryDialog dialog = new DirectoryDialog(getShell());
final String selection = dialog.open();
if (selection != null) {
- sourcePathLocationText.setText(selection);
- sourcePathWorkspaceRelativeLocation = false;
+ pathText.setText(selection);
+ workspaceRelativePath.set(false);
+ }
+ }
+ };
+ }
+
+ /**
+ * Opens a dialog to browse the file system and select a file
+ *
+ * @return
+ */
+ private SelectionListener onBrowseFileSystemForFile(final Text pathText,
+ final AtomicBoolean workspaceRelativePath) {
+ return new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ final FileDialog dialog = new FileDialog(getShell());
+ final String selection = dialog.open();
+ if (selection != null) {
+ pathText.setText(selection);
+ workspaceRelativePath.set(false);
}
}
};
@@ -214,23 +385,58 @@ public class BuildDockerImageLaunchConfigurationMainTab
@Override
public void initializeFrom(final ILaunchConfiguration configuration) {
try {
- this.sourcePathLocationText.setText(
- configuration.getAttribute(SOURCE_PATH_LOCATION, ""));
- this.sourcePathWorkspaceRelativeLocation = configuration
- .getAttribute(SOURCE_PATH_WORKSPACE_RELATIVE_LOCATION, false);
this.connectionSelectionComboViewer
.setSelection(new StructuredSelection(
configuration.getAttribute(DOCKER_CONNECTION, "")));
+ this.buildContextPathText.setText(
+ configuration.getAttribute(SOURCE_PATH_LOCATION, ""));
+ this.buildContextPathWorkspaceRelative = new AtomicBoolean(
+ configuration.getAttribute(
+ SOURCE_PATH_WORKSPACE_RELATIVE_LOCATION, false));
+ // this.dockerFilePathText.setText(
+ // configuration.getAttribute(DOCKERFILE_PATH, "Dockerfile"));
+ // this.dockerFilePathWorkspaceRelative = new AtomicBoolean(
+ // configuration.getAttribute(
+ // DOCKERFILE_PATH_WORKSPACE_RELATIVE_LOCATION,
+ // false));
+ this.repoNameText
+ .setText(configuration.getAttribute(REPO_NAME, ""));
+ this.quietBuildButton.setSelection(
+ configuration.getAttribute(QUIET_BUILD, false));
+ this.noCacheButton
+ .setSelection(configuration.getAttribute(NO_CACHE, false));
+ this.removeIntermediateContainersButton.setSelection(configuration
+ .getAttribute(RM_INTERMEDIATE_CONTAINERS, false));
+ this.alwaysRemoveIntermediateContainersButton.setSelection(
+ configuration.getAttribute(FORCE_RM_INTERMEDIATE_CONTAINERS,
+ false));
+ toggleRemoveIntermediateContainersButtonState();
} catch (CoreException e) {
Activator.log(e);
}
}
@Override
- public boolean isValid(ILaunchConfiguration launchConfig) {
+ public boolean isValid(final ILaunchConfiguration launchConfig) {
try {
- if (launchConfig.getAttribute(SOURCE_PATH_LOCATION, "").isEmpty()) {
+ final String sourcePathLocation = launchConfig
+ .getAttribute(SOURCE_PATH_LOCATION, ""); // $NON-NLS-1$
+ final boolean sourcePathWorkspaceRelativeLocation = launchConfig.getAttribute(SOURCE_PATH_WORKSPACE_RELATIVE_LOCATION, false);
+ final IPath sourcePath = BuildDockerImageUtils.getPath(
+ sourcePathLocation, sourcePathWorkspaceRelativeLocation);
+ if (sourcePathLocation.isEmpty() || sourcePath == null) {
+ setErrorMessage(
+ LaunchMessages.getString(BUILD_CONTEXT_PATH_MISSING));
return false;
+ } else {
+ setErrorMessage(null);
+ }
+ final String repoName = launchConfig.getAttribute(REPO_NAME, ""); // $NON-NLS-1$
+ if (repoName.isEmpty()) {
+ setWarningMessage(
+LaunchMessages.getString(REPO_NAME_MISSING));
+ } else {
+ setWarningMessage(null);
}
} catch (CoreException e) {
Activator.log(e);
@@ -241,16 +447,31 @@ public class BuildDockerImageLaunchConfigurationMainTab
@Override
public void performApply(
final ILaunchConfigurationWorkingCopy configuration) {
- configuration.setAttribute(SOURCE_PATH_LOCATION,
- this.sourcePathLocationText.getText());
- configuration.setAttribute(SOURCE_PATH_WORKSPACE_RELATIVE_LOCATION,
- this.sourcePathWorkspaceRelativeLocation);
final IStructuredSelection connectionSelection = (IStructuredSelection) this.connectionSelectionComboViewer
.getSelection();
if (connectionSelection.getFirstElement() != null) {
configuration.setAttribute(DOCKER_CONNECTION,
connectionSelection.getFirstElement().toString());
}
+ configuration.setAttribute(SOURCE_PATH_LOCATION,
+ this.buildContextPathText.getText());
+ configuration.setAttribute(SOURCE_PATH_WORKSPACE_RELATIVE_LOCATION,
+ this.buildContextPathWorkspaceRelative.get());
+ // configuration.setAttribute(DOCKERFILE_PATH,
+ // this.dockerFilePathText.getText());
+ // configuration.setAttribute(DOCKERFILE_PATH_WORKSPACE_RELATIVE_LOCATION,
+ // this.dockerFilePathWorkspaceRelative.get());
+ if (!this.repoNameText.getText().isEmpty()) {
+ configuration.setAttribute(REPO_NAME, this.repoNameText.getText());
+ }
+ configuration.setAttribute(QUIET_BUILD,
+ this.quietBuildButton.getSelection());
+ configuration.setAttribute(NO_CACHE, this.noCacheButton.getSelection());
+ configuration.setAttribute(RM_INTERMEDIATE_CONTAINERS,
+ this.removeIntermediateContainersButton.getSelection());
+ configuration.setAttribute(FORCE_RM_INTERMEDIATE_CONTAINERS,
+ this.alwaysRemoveIntermediateContainersButton.getSelection());
+
}
@Override
@@ -258,7 +479,24 @@ public class BuildDockerImageLaunchConfigurationMainTab
return LaunchMessages.getString(TAB_NAME);
}
- protected class LaunchConfigurationChangeListener extends SelectionAdapter
+ /**
+ * Enables or disables the
+ * {@link BuildDockerImageLaunchConfigurationMainTab#removeIntermediateContainersButton}
+ * given the selection of
+ * {@link BuildDockerImageLaunchConfigurationMainTab#alwaysRemoveIntermediateContainersButton}
+ */
+ private void toggleRemoveIntermediateContainersButtonState() {
+ if (BuildDockerImageLaunchConfigurationMainTab.this.alwaysRemoveIntermediateContainersButton
+ .getSelection()) {
+ BuildDockerImageLaunchConfigurationMainTab.this.removeIntermediateContainersButton
+ .setEnabled(false);
+ } else {
+ BuildDockerImageLaunchConfigurationMainTab.this.removeIntermediateContainersButton
+ .setEnabled(true);
+ }
+ }
+
+ private class LaunchConfigurationChangeListener extends SelectionAdapter
implements ModifyListener {
@Override
@@ -271,4 +509,5 @@ public class BuildDockerImageLaunchConfigurationMainTab
updateLaunchConfigurationDialog();
}
}
+
}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/BuildDockerImageShortcut.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/BuildDockerImageShortcut.java
index dac9302215..f780ef3d7f 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/BuildDockerImageShortcut.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/BuildDockerImageShortcut.java
@@ -29,6 +29,7 @@ import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugModelPresentation;
import org.eclipse.debug.ui.ILaunchShortcut;
+import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
@@ -36,8 +37,10 @@ import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.linuxtools.docker.core.DockerConnectionManager;
import org.eclipse.linuxtools.docker.core.IDockerConnection;
+import org.eclipse.linuxtools.docker.core.IDockerImageBuildOptions;
import org.eclipse.linuxtools.docker.ui.Activator;
import org.eclipse.linuxtools.internal.docker.ui.SWTImagesFactory;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageBuildDialog;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
@@ -67,7 +70,7 @@ public class BuildDockerImageShortcut implements ILaunchShortcut {
}
public void launch(IResource resource, String mode) {
- ILaunchConfiguration config = findLaunchConfiguration(resource, mode);
+ ILaunchConfiguration config = findLaunchConfiguration(resource);
if (config != null) {
DebugUITools.launch(config, mode);
}
@@ -79,13 +82,10 @@ public class BuildDockerImageShortcut implements ILaunchShortcut {
*
* @param resource
* The Dockerfile to look up launch for.
- * @param mode
- * Launch mode.
*
* @return A re-useable config or <code>null</code> if none.
*/
- protected ILaunchConfiguration findLaunchConfiguration(IResource resource,
- String mode) {
+ protected ILaunchConfiguration findLaunchConfiguration(IResource resource) {
ILaunchConfiguration configuration = null;
ILaunchConfigurationType configType = getLaunchConfigType();
List<ILaunchConfiguration> candidateConfigs = Collections.emptyList();
@@ -97,8 +97,9 @@ public class BuildDockerImageShortcut implements ILaunchShortcut {
String sourcePath = config.getAttribute(
IBuildDockerImageLaunchConfigurationConstants.SOURCE_PATH_LOCATION,
""); //$NON-NLS-1$
- boolean workspaceRelative = config
- .getAttribute(IBuildDockerImageLaunchConfigurationConstants.SOURCE_PATH_WORKSPACE_RELATIVE_LOCATION, false);
+ boolean workspaceRelative = config.getAttribute(
+ IBuildDockerImageLaunchConfigurationConstants.SOURCE_PATH_WORKSPACE_RELATIVE_LOCATION,
+ false);
IPath dockerfilePath = getPath(sourcePath, workspaceRelative);
if (dockerfilePath
.equals(resource.getLocation().removeLastSegments(1))) {
@@ -118,7 +119,7 @@ public class BuildDockerImageShortcut implements ILaunchShortcut {
// one.
int candidateCount = candidateConfigs.size();
if (candidateCount < 1) {
- configuration = createConfiguration(resource, mode, true);
+ configuration = createConfiguration(resource);
} else if (candidateCount == 1) {
configuration = candidateConfigs.get(0);
} else {
@@ -166,29 +167,12 @@ public class BuildDockerImageShortcut implements ILaunchShortcut {
*
* @param resource
* a Dockerfile file to build
- * @param save
- * true if the configuration should be saved to the underlying
- * resource, and false if it should not be saved.
* @return a launch configuration generated for the Dockerfile build.
*/
- protected ILaunchConfiguration createConfiguration(IResource resource,
- @SuppressWarnings("unused") String mode, boolean save) {
- ILaunchConfiguration config = null;
+ protected ILaunchConfiguration createConfiguration(
+ final IResource resource) {
try {
- ILaunchConfigurationType configType = getLaunchConfigType();
- ILaunchConfigurationWorkingCopy wc = configType.newInstance(null,
- getLaunchManager()
- .generateLaunchConfigurationName("Dockerfile[" //$NON-NLS-1$
- + resource.getProject().getName() + "]")); //$NON-NLS-1$
-
- wc.setAttribute(
- IBuildDockerImageLaunchConfigurationConstants.SOURCE_PATH_LOCATION,
- resource.getFullPath().removeLastSegments(1).toString());
- wc.setAttribute(
- IBuildDockerImageLaunchConfigurationConstants.SOURCE_PATH_WORKSPACE_RELATIVE_LOCATION,
- true);
-
- IDockerConnection[] connections = DockerConnectionManager
+ final IDockerConnection[] connections = DockerConnectionManager
.getInstance().getConnections();
if (connections.length == 0) {
Display.getDefault().syncExec(new Runnable() {
@@ -205,27 +189,78 @@ public class BuildDockerImageShortcut implements ILaunchShortcut {
});
return null;
- } else if (connections.length == 1) {
- wc.setAttribute(
- IBuildDockerImageLaunchConfigurationConstants.DOCKER_CONNECTION,
- connections[0].getName());
} else {
- IDockerConnection connection = chooseConnection(connections);
- if (connection == null)
- return null;
- wc.setAttribute(
- IBuildDockerImageLaunchConfigurationConstants.DOCKER_CONNECTION,
- connection.getName());
- }
- if (save) {
- config = wc.doSave();
- } else {
- config = wc;
+ final ImageBuildDialog dialog = new ImageBuildDialog(
+ getActiveWorkbenchShell());
+ final int result = dialog.open();
+ if (result == IDialogConstants.OK_ID) {
+ final ILaunchConfigurationType configType = LaunchConfigurationUtils
+ .getLaunchConfigType(
+ IBuildDockerImageLaunchConfigurationConstants.CONFIG_TYPE_ID);
+ final ILaunchConfigurationWorkingCopy wc = configType
+ .newInstance(null,
+ DebugPlugin.getDefault().getLaunchManager()
+ .generateLaunchConfigurationName(
+ createLaunchConfigurationName(
+ dialog.getRepoName(),
+ resource))); // $NON-NLS-1$
+ wc.setAttribute(
+ IBuildDockerImageLaunchConfigurationConstants.SOURCE_PATH_LOCATION,
+ resource.getFullPath().removeLastSegments(1)
+ .toString());
+ wc.setAttribute(
+ IBuildDockerImageLaunchConfigurationConstants.SOURCE_PATH_WORKSPACE_RELATIVE_LOCATION,
+ true);
+
+ final IDockerConnection connection = dialog.getConnection();
+ final String repoName = dialog.getRepoName();
+ wc.setAttribute(IDockerImageBuildOptions.DOCKER_CONNECTION,
+ connection.getName());
+ wc.setAttribute(IDockerImageBuildOptions.REPO_NAME,
+ repoName);
+ return wc.doSave();
+ }
}
} catch (CoreException e) {
- e.printStackTrace();
+ Activator.log(e);
+ }
+ return null;
+ }
+
+ /**
+ * Creates a Launch Configuration name from the given repoName or from the
+ * given resource's project if the repoName was <code>null</code>.
+ *
+ * @param imageName the full image name
+ * @param resource the Dockerfile to use to build the image
+ * @return the {@link ILaunchConfiguration} name
+ */
+ public static String createLaunchConfigurationName(final String imageName,
+ final IResource resource) {
+ if (imageName != null) {
+ final String repository = BuildDockerImageUtils
+ .getRepository(imageName);
+ final String name = BuildDockerImageUtils.getName(imageName);
+ final String tag = BuildDockerImageUtils.getTag(imageName);
+ final StringBuilder configNameBuilder = new StringBuilder();
+ // image name is the minimum requirement
+ if (name != null) {
+ if (repository != null) {
+ configNameBuilder.append(repository).append('_'); // $NON-NLS-1$
+ }
+ if (name != null) {
+ configNameBuilder.append(name);
+ }
+ if (tag != null) {
+ configNameBuilder.append(" [").append(tag).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
+ } else {
+ configNameBuilder.append(" [latest]"); //$NON-NLS-1$
+ }
+ return configNameBuilder.toString();
+ }
}
- return config;
+ return "Dockerfile [" //$NON-NLS-1$
+ + resource.getProject().getName() + "]"; //$NON-NLS-1$
}
/**
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/BuildDockerImageUtils.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/BuildDockerImageUtils.java
new file mode 100644
index 0000000000..4bacf534f7
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/BuildDockerImageUtils.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * 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.io.File;
+import java.util.regex.Matcher;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.linuxtools.internal.docker.core.DockerImage;
+
+/**
+ * Utility class for building Docker Images
+ */
+public class BuildDockerImageUtils {
+
+ /**
+ * Computes the path that can be relative to the workspace or absolute.
+ *
+ * @param pathLocation
+ * the base location
+ * @param workspaceRelativeLocation
+ * flag to indicate if the path is relative to the workspace
+ * location or not.
+ * @return the path or <code>null</code> if it does not exist
+ */
+ public static IPath getPath(final String pathLocation,
+ final boolean workspaceRelativeLocation) {
+ if (workspaceRelativeLocation) {
+ final IResource member = ResourcesPlugin.getWorkspace().getRoot()
+ .findMember(new Path(pathLocation));
+ if (member != null) {
+ return member.getLocation();
+ }
+ } else if (new File(pathLocation).exists()) {
+ return new Path(pathLocation);
+ }
+ return null;
+ }
+
+ /**
+ * Finds and returns the <code>name</code> part of the given full image
+ * name.
+ *
+ * @param imageName
+ * the full image name
+ * @return the <code>name</code> part of the given full name or
+ * <code>null</code> if it could not be found.
+ */
+ public static String getRepository(final String imageName) {
+ final Matcher imageNameMatcher = DockerImage.imageNamePattern
+ .matcher(imageName);
+ if (imageNameMatcher.matches()) {
+ final String repository = imageNameMatcher.group("repository");
+ return repository; //$NON-NLS-1$
+ }
+ return null;
+ }
+
+ /**
+ * Finds and returns the <code>name</code> part of the given full image
+ * name.
+ *
+ * @param imageName
+ * the full image name
+ * @return the <code>name</code> part of the given full name or
+ * <code>null</code> if it could not be found.
+ */
+ public static String getName(final String imageName) {
+ final Matcher imageNameMatcher = DockerImage.imageNamePattern
+ .matcher(imageName);
+ if (imageNameMatcher.matches()) {
+ return imageNameMatcher.group("name"); //$NON-NLS-1$
+ }
+ return null;
+ }
+
+ /**
+ * Finds and returns the <code>tag</code> part of the given full image name.
+ *
+ * @param imageName
+ * the full image name
+ * @return the <code>tag</code> part of the given full name or
+ * <code>null</code> if it could not be found.
+ */
+ public static String getTag(final String imageName) {
+ final Matcher imageNameMatcher = DockerImage.imageNamePattern
+ .matcher(imageName);
+ if (imageNameMatcher.matches()) {
+ final String tag = imageNameMatcher.group("tag"); //$NON-NLS-1$
+ return tag; //$NON-NLS-1$
+ }
+ return null;
+ }
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/IBuildDockerImageLaunchConfigurationConstants.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/IBuildDockerImageLaunchConfigurationConstants.java
index 52b32c93ad..ec195da431 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/IBuildDockerImageLaunchConfigurationConstants.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/launch/IBuildDockerImageLaunchConfigurationConstants.java
@@ -12,13 +12,15 @@
package org.eclipse.linuxtools.internal.docker.ui.launch;
import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.linuxtools.docker.core.IDockerImageBuildOptions;
/**
* Constants used to pass values in the {@link ILaunchConfiguration} to build
* Docker Images.
*
*/
-public interface IBuildDockerImageLaunchConfigurationConstants {
+public interface IBuildDockerImageLaunchConfigurationConstants
+ extends IDockerImageBuildOptions {
/**
* the launch id
@@ -34,7 +36,13 @@ public interface IBuildDockerImageLaunchConfigurationConstants {
*/
public final static String SOURCE_PATH_WORKSPACE_RELATIVE_LOCATION = "sourcePathWorkspaceRelativeLocation"; //$NON-NLS-1$
- /** name of the connection to use to build the Image. */
- public final static String DOCKER_CONNECTION = "dockerConnection"; //$NON-NLS-1$
+ /** the path to the dockerfile. */
+ public final static String DOCKERFILE_PATH = "dockerfilePath"; //$NON-NLS-1$
+
+ /**
+ * marker to indicate if the location above is a workspace-relative
+ * location.
+ */
+ public final static String DOCKERFILE_PATH_WORKSPACE_RELATIVE_LOCATION = "dockerfilePathWorkspaceRelativeLocation"; //$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 c3d2d73fd9..d6bfe12699 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
@@ -39,6 +39,17 @@ public class LaunchConfigurationUtils {
private LaunchConfigurationUtils() {
// empty
}
+
+ /**
+ * @return the ILaunchConfigurationType for the given configuration type.
+ * @param configType
+ * the id of the configuration type
+ */
+ public static ILaunchConfigurationType getLaunchConfigType(
+ final String configType) {
+ return DebugPlugin.getDefault().getLaunchManager()
+ .getLaunchConfigurationType(configType);
+ }
public static ILaunchConfiguration saveLaunchConfiguration(
final IDockerContainer container) {
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 5581b6d00d..0ee5026d15 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
@@ -9,13 +9,24 @@
# Red Hat - Initial Contribution
###############################################################################
+BuildDockerImageLaunchConfiguration.error.incomplete=Launch configuration to build Docker image is incomplete.
+
BuildDockerImageLaunchConfigurationMainTab.name=Main
-BuildDockerImageLaunchConfigurationMainTab.sourcePathLocation.group.label=Source Path:
BuildDockerImageLaunchConfigurationMainTab.connection.group.label=Docker Connection
-BuildDockerImageLaunchConfigurationMainTab.browseworkspace.button.label=Browse Workspace...
-BuildDockerImageLaunchConfigurationMainTab.browseworkspace.dialog.title=Browse Workspace...
-BuildDockerImageLaunchConfigurationMainTab.browseworkspace.dialog.message=Browse Workspace for a Dockerfile
-BuildDockerImageLaunchConfigurationMainTab.browsefilesystem.button.label=Browse File System...
+BuildDockerImageLaunchConfigurationMainTab.connection.group.tooltip=The docker daemon that will be used to build the image
+BuildDockerImageLaunchConfigurationMainTab.buildContextPath.group.label=Build Context Path:
+BuildDockerImageLaunchConfigurationMainTab.buildContextPath.missing=Build Context Path is missing or invalid
+BuildDockerImageLaunchConfigurationMainTab.buildContextPath.browseworkspace.button.label=Browse Workspace...
+BuildDockerImageLaunchConfigurationMainTab.buildContextPath.browseworkspace.dialog.title=Browse Workspace...
+BuildDockerImageLaunchConfigurationMainTab.buildContextPath.browsefilesystem.button.label=Browse File System...
+BuildDockerImageLaunchConfigurationMainTab.dockerfilePath.group.label=Dockerfile Path:
+BuildDockerImageLaunchConfigurationMainTab.repoName.label=Repository name (and optional tag)
+BuildDockerImageLaunchConfigurationMainTab.repoName.missing=A repository name is recommended
+BuildDockerImageLaunchConfigurationMainTab.options.group.label=Options
+BuildDockerImageLaunchConfigurationMainTab.options.quiet.button.label=Suppress the verbose output generated by the containers
+BuildDockerImageLaunchConfigurationMainTab.options.noCache.button.label=Do not use cache when building the image
+BuildDockerImageLaunchConfigurationMainTab.options.rm.button.label=Remove intermediate containers after a successful build
+BuildDockerImageLaunchConfigurationMainTab.options.forceRM.button.label=Always remove intermediate containers
ImageBuild.msg=Building Docker Image
ImageBuild.error.msg=Error while building Docker Image
@@ -25,7 +36,9 @@ ImageBuildShortcutChooseLaunch.msg=Choose a launch configuration to run
ImageBuildShortcutConnectionSelection.title=Launch Configuration Selection
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
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/validators/ImageNameValidator.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/validators/ImageNameValidator.java
new file mode 100644
index 0000000000..402c249b57
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/validators/ImageNameValidator.java
@@ -0,0 +1,38 @@
+package org.eclipse.linuxtools.internal.docker.ui.validators;
+
+import java.util.regex.Matcher;
+
+import org.eclipse.core.databinding.validation.IValidator;
+import org.eclipse.core.databinding.validation.ValidationStatus;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.linuxtools.internal.docker.core.DockerImage;
+import org.eclipse.linuxtools.internal.docker.ui.wizards.WizardMessages;
+
+/**
+ * Validates that the image name matches
+ * [REGISTRY_HOST[:REGISTRY_PORT]/]IMAGE_NAME[:TAG]
+ */
+public class ImageNameValidator implements IValidator {
+
+ @Override
+ public IStatus validate(final Object value) {
+ final String imageName = (String) value;
+ if (imageName.isEmpty()) {
+ return ValidationStatus
+ .cancel(WizardMessages.getString("ImagePull.desc")); //$NON-NLS-1$
+ }
+ final Matcher matcher = DockerImage.imageNamePattern
+ .matcher(imageName);
+ if (!matcher.matches()) {
+ return ValidationStatus.warning(WizardMessages
+ .getString("ImagePull.name.invalidformat.msg")); //$NON-NLS-1$
+ } else if (matcher.group("tag") == null) { //$NON-NLS-1$
+ return ValidationStatus.warning(
+ WizardMessages.getString("ImagePull.assumeLatest.msg")); //$NON-NLS-1$
+
+ }
+ return Status.OK_STATUS;
+ }
+
+} \ No newline at end of file
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/validators/package-info.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/validators/package-info.java
new file mode 100644
index 0000000000..319edc510a
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/validators/package-info.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * 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.validators; \ No newline at end of file
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageBuildDialog.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageBuildDialog.java
new file mode 100644
index 0000000000..581d44a0c2
--- /dev/null
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageBuildDialog.java
@@ -0,0 +1,340 @@
+/*******************************************************************************
+ * Copyright (c) 2015 Red Hat.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat - Initial Contribution
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.internal.docker.ui.wizards;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.databinding.Binding;
+import org.eclipse.core.databinding.DataBindingContext;
+import org.eclipse.core.databinding.beans.BeanProperties;
+import org.eclipse.core.databinding.observable.ChangeEvent;
+import org.eclipse.core.databinding.observable.IChangeListener;
+import org.eclipse.core.databinding.validation.ValidationStatus;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.databinding.swt.ISWTObservableValue;
+import org.eclipse.jface.databinding.swt.WidgetProperties;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.fieldassist.ComboContentAdapter;
+import org.eclipse.jface.fieldassist.ContentProposal;
+import org.eclipse.jface.fieldassist.ContentProposalAdapter;
+import org.eclipse.jface.fieldassist.IContentProposal;
+import org.eclipse.jface.fieldassist.IContentProposalProvider;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ComboViewer;
+import org.eclipse.linuxtools.docker.core.DockerConnectionManager;
+import org.eclipse.linuxtools.docker.core.IDockerConnection;
+import org.eclipse.linuxtools.docker.core.IDockerContainer;
+import org.eclipse.linuxtools.internal.docker.ui.SWTImagesFactory;
+import org.eclipse.linuxtools.internal.docker.ui.databinding.BaseDatabindingModel;
+import org.eclipse.linuxtools.internal.docker.ui.validators.ImageNameValidator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * {@link Dialog} to specify Docker Image build options at launch time.
+ */
+public class ImageBuildDialog extends Dialog {
+
+ private final ImageBuildDialogModel model = new ImageBuildDialogModel();
+ private final DataBindingContext dbc = new DataBindingContext();
+
+ public ImageBuildDialog(Shell parentShell) {
+ super(parentShell);
+ }
+
+ @Override
+ protected void configureShell(final Shell shell) {
+ super.configureShell(shell);
+ setShellStyle(getShellStyle() | SWT.RESIZE);
+ shell.setText(WizardMessages.getString("ImageBuildDialog.title")); //$NON-NLS-1$
+ }
+
+ @Override
+ protected Point getInitialSize() {
+ return new Point(400, super.getInitialSize().y);
+ }
+
+ /**
+ * Disable the 'OK' button by default
+ */
+ @Override
+ protected Button createButton(Composite parent, int id, String label,
+ boolean defaultButton) {
+ final Button button = super.createButton(parent, id, label,
+ defaultButton);
+ if (id == IDialogConstants.OK_ID) {
+ button.setEnabled(false);
+ }
+ return button;
+ }
+
+ @Override
+ protected Control createDialogArea(final Composite parent) {
+ final int COLUMNS = 2;
+ final Composite container = new Composite(parent, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL)
+ .span(COLUMNS, 1).grab(true, false).applyTo(container);
+ GridLayoutFactory.fillDefaults().numColumns(COLUMNS).margins(10, 10)
+ .applyTo(container);
+ final Label explanationLabel = new Label(container, SWT.NONE);
+ explanationLabel.setText(
+ WizardMessages.getString("ImageBuildDialog.explanationLabel")); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .span(COLUMNS, 1).grab(false, false).applyTo(explanationLabel);
+ final Label containerLabel = new Label(container, SWT.NONE);
+ containerLabel.setText(
+ WizardMessages.getString("ImageBuildDialog.connectionLabel")); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(containerLabel);
+ final Combo containerSelectionCombo = new Combo(container, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).applyTo(containerSelectionCombo);
+ final ComboViewer connectionSelectionComboViewer = new ComboViewer(
+ containerSelectionCombo);
+ connectionSelectionComboViewer
+ .setContentProvider(new ArrayContentProvider());
+ final List<String> connectionNames = model.getConnectionNames();
+ connectionSelectionComboViewer.setInput(connectionNames);
+ new ContentProposalAdapter(containerSelectionCombo,
+ new ComboContentAdapter() {
+ @Override
+ public void insertControlContents(Control control,
+ String text, int cursorPosition) {
+ final Combo combo = (Combo) control;
+ final Point selection = combo.getSelection();
+ combo.setText(text);
+ selection.x = text.length();
+ selection.y = selection.x;
+ combo.setSelection(selection);
+ }
+ }, getConnectionNameContentProposalProvider(
+ containerSelectionCombo),
+ null, null);
+ final Label repoNameLabel = new Label(container, SWT.NONE);
+ repoNameLabel.setText(
+ WizardMessages.getString("ImageBuildDialog.repoNameLabel")); //$NON-NLS-1$
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(false, false).applyTo(repoNameLabel);
+ final Text repoNameText = new Text(container, SWT.BORDER);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).applyTo(repoNameText);
+ final ISWTObservableValue connnectionNameObservable = WidgetProperties
+ .selection().observe(connectionSelectionComboViewer.getCombo());
+ // pre-select with first connection
+ if (!connectionNames.isEmpty()) {
+ model.setConnectionName(connectionNames.get(0));
+ }
+ // error message
+ final Composite errorContainer = new Composite(container, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL)
+ .span(COLUMNS, 1).grab(true, true).applyTo(errorContainer);
+ GridLayoutFactory.fillDefaults().margins(6, 6).numColumns(2)
+ .applyTo(errorContainer);
+
+ final Label errorMessageIcon = new Label(errorContainer, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .hint(20, SWT.DEFAULT).applyTo(errorMessageIcon);
+ final Label errorMessageLabel = new Label(errorContainer, SWT.NONE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
+ .grab(true, false).applyTo(errorMessageLabel);
+ dbc.bindValue(connnectionNameObservable,
+ BeanProperties
+ .value(ImageBuildDialogModel.class,
+ ImageBuildDialogModel.CONNECTION_NAME)
+ .observe(model));
+ final ISWTObservableValue repoNameObservable = WidgetProperties
+ .text(SWT.Modify).observe(repoNameText);
+
+ dbc.bindValue(repoNameObservable,
+ BeanProperties
+ .value(ImageBuildDialogModel.class,
+ ImageBuildDialogModel.REPO_NAME)
+ .observe(model));
+ // must be called after bindings were set
+ setupValidationSupport(errorMessageIcon, errorMessageLabel);
+ return container;
+ }
+
+ private void setupValidationSupport(final Label errorMessageIcon,
+ final Label errorMessageLabel) {
+ for (@SuppressWarnings("unchecked")
+ Iterator<Binding> iterator = dbc.getBindings().iterator(); iterator
+ .hasNext();) {
+ final Binding binding = iterator.next();
+ binding.getModel().addChangeListener(onBuildSettingsChanged(
+ errorMessageIcon, errorMessageLabel));
+ }
+ }
+
+ private IChangeListener onBuildSettingsChanged(final Label errorMessageIcon,
+ final Label errorMessageLabel) {
+
+ return new IChangeListener() {
+
+ @Override
+ public void handleChange(ChangeEvent event) {
+ final IStatus status = validateInput();
+ if (Display.getCurrent() == null) {
+ return;
+ }
+ Display.getCurrent().syncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ if (status.isOK()) {
+ errorMessageIcon.setVisible(false);
+ errorMessageLabel.setVisible(false);
+ setOkButtonEnabled(true);
+ } else if (status.matches(IStatus.WARNING)) {
+ errorMessageIcon.setVisible(true);
+ errorMessageIcon
+ .setImage(SWTImagesFactory.DESC_WARNING
+ .createImage());
+ errorMessageLabel.setVisible(true);
+ errorMessageLabel.setText(status.getMessage());
+ setOkButtonEnabled(true);
+ } else if (status.matches(IStatus.ERROR)) {
+ if (status.getMessage() != null
+ && !status.getMessage().isEmpty()) {
+ errorMessageIcon.setVisible(true);
+ errorMessageIcon
+ .setImage(SWTImagesFactory.DESC_ERROR
+ .createImage());
+ errorMessageLabel.setVisible(true);
+ errorMessageLabel.setText(status.getMessage());
+ }
+ setOkButtonEnabled(false);
+ }
+ }
+ });
+ }
+ };
+ }
+
+ /**
+ * Validates that the selected {@link IDockerConnection} exists and that the
+ * optional image name is valid.
+ *
+ * @return a validation status
+ */
+ private IStatus validateInput() {
+ final String selectedConnectionName = model.getConnectionName();
+ final String repoName = model.getRepoName();
+ if (selectedConnectionName == null
+ || selectedConnectionName.isEmpty()) {
+ return Status.CANCEL_STATUS;
+ } else
+ if (!model.getConnectionNames().contains(selectedConnectionName)) {
+ return ValidationStatus.error(WizardMessages.getFormattedString(
+ "ImageBuildDialog.error.unknownConnection", //$NON-NLS-1$
+ selectedConnectionName));
+ } else if (repoName == null || repoName.isEmpty()) {
+ return ValidationStatus.warning(WizardMessages
+ .getString("ImageBuildDialog.warning.missingRepoName")); //$NON-NLS-1$
+ } else {
+ final ImageNameValidator imageNameValidator = new ImageNameValidator();
+ return imageNameValidator.validate(repoName);
+ }
+ }
+
+ public IDockerConnection getConnection() {
+ return DockerConnectionManager.getInstance()
+ .findConnection(model.connectionName);
+ }
+
+ public String getRepoName() {
+ return model.getRepoName();
+ }
+
+ /**
+ * Creates an {@link IContentProposalProvider} to propose
+ * {@link IDockerContainer} names based on the current text.
+ *
+ * @param items
+ * @return
+ */
+ private IContentProposalProvider getConnectionNameContentProposalProvider(
+ final Combo connectionNamesSelectionCombo) {
+ return new IContentProposalProvider() {
+
+ @Override
+ public IContentProposal[] getProposals(final String contents,
+ final int position) {
+ final List<IContentProposal> proposals = new ArrayList<>();
+ for (String connectionName : connectionNamesSelectionCombo
+ .getItems()) {
+ if (connectionName.contains(contents)) {
+ proposals.add(new ContentProposal(connectionName,
+ connectionName, connectionName, position));
+ }
+ }
+ return proposals.toArray(new IContentProposal[0]);
+ }
+ };
+ }
+
+ private void setOkButtonEnabled(final boolean enabled) {
+ getButton(IDialogConstants.OK_ID).setEnabled(enabled);
+ }
+
+ class ImageBuildDialogModel extends BaseDatabindingModel {
+
+ public static final String CONNECTION_NAME = "connectionName"; //$NON-NLS-1$
+
+ public static final String REPO_NAME = "repoName"; //$NON-NLS-1$
+
+ private String connectionName;
+
+ private String repoName;
+
+ private final List<String> connectionNames = DockerConnectionManager
+ .getInstance().getConnectionNames();
+
+ public String getRepoName() {
+ return repoName;
+ }
+
+ public List<String> getConnectionNames() {
+ return connectionNames;
+ }
+
+ public void setRepoName(final String repoName) {
+ firePropertyChange(REPO_NAME, this.repoName,
+ this.repoName = repoName);
+ }
+
+ public String getConnectionName() {
+ return connectionName;
+ }
+
+ public void setConnectionName(final String connectionName) {
+ firePropertyChange(CONNECTION_NAME, this.connectionName,
+ this.connectionName = connectionName);
+ }
+
+ }
+
+}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImagePullPage.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImagePullPage.java
index cc88749b5b..07ed83344d 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImagePullPage.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImagePullPage.java
@@ -12,16 +12,11 @@
package org.eclipse.linuxtools.internal.docker.ui.wizards;
import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.core.databinding.observable.value.IObservableValue;
-import org.eclipse.core.databinding.validation.IValidator;
-import org.eclipse.core.databinding.validation.ValidationStatus;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.databinding.wizard.WizardPageSupport;
import org.eclipse.jface.layout.GridDataFactory;
@@ -29,8 +24,10 @@ import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.linuxtools.docker.core.IDockerConnection;
import org.eclipse.linuxtools.docker.ui.wizards.ImageSearch;
+import org.eclipse.linuxtools.internal.docker.core.DockerImage;
import org.eclipse.linuxtools.internal.docker.ui.SWTImagesFactory;
import org.eclipse.linuxtools.internal.docker.ui.commands.CommandUtils;
+import org.eclipse.linuxtools.internal.docker.ui.validators.ImageNameValidator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
@@ -50,15 +47,6 @@ public class ImagePullPage extends WizardPage {
private final DataBindingContext dbc;
private final IDockerConnection connection;
- private static final String REGISTRY_HOST = "[a-zA-Z0-9]+([._-][a-zA-Z0-9]+)*"; //$NON-NLS-1$
- private static final String REGISTRY_PORT = "[0-9]+"; //$NON-NLS-1$
- private static final String REPOSITORY = "[a-z0-9]+([._-][a-z0-9]+)*"; //$NON-NLS-1$
- private static final String NAME = "[a-z0-9]+([._-][a-z0-9]+)*"; //$NON-NLS-1$
- private static final String TAG = "[a-zA-Z0-9]+([._-][a-zA-Z0-9]+)*"; //$NON-NLS-1$
- private static final Pattern imageNamePattern = Pattern.compile("(" //$NON-NLS-1$
- + REGISTRY_HOST + "(\\:" + REGISTRY_PORT + ")?/)?" + "(" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- + REPOSITORY + "/)?" + NAME + "(?<tag>\\:" + TAG + ")?"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-
public ImagePullPage(final IDockerConnection connection) {
super("ImagePullPage", //$NON-NLS-1$
WizardMessages.getString("ImagePull.label"), //$NON-NLS-1$
@@ -76,7 +64,7 @@ public class ImagePullPage extends WizardPage {
}
public String getImageName() {
- final Matcher matcher = imageNamePattern
+ final Matcher matcher = DockerImage.imageNamePattern
.matcher(this.model.getImageName());
// Matcher#matches() must be called before any attempt to access a given
// named capturing-group.
@@ -151,31 +139,4 @@ public class ImagePullPage extends WizardPage {
};
}
- /**
- * Validates that the image name matches
- * [REGISTRY_HOST[:REGISTRY_PORT]/]IMAGE_NAME[:TAG]
- */
- public static class ImageNameValidator implements IValidator {
-
- @Override
- public IStatus validate(final Object value) {
- final String imageName = (String) value;
- if (imageName.isEmpty()) {
- return ValidationStatus
- .cancel(WizardMessages.getString("ImagePull.desc")); //$NON-NLS-1$
- }
- final Matcher matcher = imageNamePattern.matcher(imageName);
- if (!matcher.matches()) {
- return ValidationStatus.warning(WizardMessages
- .getString("ImagePull.name.invalidformat.msg")); //$NON-NLS-1$
- } else if (matcher.group("tag") == null) { //$NON-NLS-1$
- return ValidationStatus.warning(
- WizardMessages.getString("ImagePull.assumeLatest.msg")); //$NON-NLS-1$
-
- }
- return Status.OK_STATUS;
- }
-
- }
-
}
diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionPage.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionPage.java
index 880ca13f9e..76d4e7572f 100644
--- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionPage.java
+++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageRunSelectionPage.java
@@ -174,6 +174,8 @@ public class ImageRunSelectionPage extends WizardPage {
final ImageSelectionValidator imageSelectionValidator = new ImageSelectionValidator(
imageSelectionObservable);
dbc.addValidationStatusProvider(imageSelectionValidator);
+ imageSelectionObservable
+ .addValueChangeListener(onImageSelectionChange());
final IObservableValue containerNameObservable = BeanProperties
.value(ImageRunSelectionModel.class,
ImageRunSelectionModel.CONTAINER_NAME)
@@ -181,7 +183,6 @@ public class ImageRunSelectionPage extends WizardPage {
final ContainerNameValidator containerNameValidator = new ContainerNameValidator(
model.getSelectedConnection(), containerNameObservable);
dbc.addValidationStatusProvider(containerNameValidator);
- //
setControl(container);
}
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 e8d495a389..239ae0d09f 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
@@ -305,4 +305,11 @@ ContainerDataVolumeDialog.readOnlyButtonTooltip=Specify if the mounted host dire
ContainerDataVolumeDialog.fileButton=File...
ContainerDataVolumeDialog.containerMountButton=Mount a data volume container
ContainerDataVolumeDialog.containerSelectionLabel=Container:
-ContainerDataVolumeDialog.volumeWarning=The selected container does not define a {0} volume. \ No newline at end of file
+ContainerDataVolumeDialog.volumeWarning=The selected container does not define a {0} volume.
+
+ImageBuildDialog.title=Docker Image Build Configuration
+ImageBuildDialog.explanationLabel=Select a connection and a repository name
+ImageBuildDialog.connectionLabel=Connection:
+ImageBuildDialog.repoNameLabel=Repository Name:
+ImageBuildDialog.error.unknownConnection=Connection {0} does not exist.
+ImageBuildDialog.warning.missingRepoName=A repository name is recommended.

Back to the top