diff options
author | Xavier Coulon | 2015-08-10 12:44:29 +0000 |
---|---|---|
committer | Roland Grunberg | 2015-08-19 17:40:58 +0000 |
commit | c2a2ca8efb3c3fd1825f412e49810f2a84cc62f9 (patch) | |
tree | 3e2582f9a9067d792a3704959d286c2cb1452685 | |
parent | 0df4a22f0ed5cb48dab2c27308f6dc99119c791c (diff) | |
download | org.eclipse.linuxtools-c2a2ca8efb3c3fd1825f412e49810f2a84cc62f9.tar.gz org.eclipse.linuxtools-c2a2ca8efb3c3fd1825f412e49810f2a84cc62f9.tar.xz org.eclipse.linuxtools-c2a2ca8efb3c3fd1825f412e49810f2a84cc62f9.zip |
Bug 474606 - Allow for search and pull images from the Docker Explorer view
Added a view in page in the SearchImage wizard to specify the image
tag to pull:
- the list of image tags is retrieved from a new class called DockerHubRegistry
(in the core module)
- the DockerHubRegistry#getTags(String) sends an HTTP request to list the tags for
a given repository on Docker Hub, using a specific/known endpoint.
This is not part of the docker-client because the Docker client deals with CLI
commands on the Docker daemon/engine and this operation is out of scope.
This might need to be refactored/opened in the future, when support for third-party
registries will be implemented.
- Pull image command is available at the connection level in the Docker Explorer view,
too.
Other bits in this commit:
- refactored the DVMessages class to support varargs instead of an array of arguments,
which makes the API more convenient to use
- removed unused classes
- reformatted blocks of code badly indented
- removed author name in some classes/added copyright where found missing
Change-Id: I83c086c4aa8a8e73c3364a885cefcdb2d36cb7f8
Signed-off-by: Xavier Coulon <xcoulon@redhat.com>
Reviewed-on: https://git.eclipse.org/r/53481
Tested-by: Hudson CI
Reviewed-by: Roland Grunberg <rgrunber@redhat.com>
Tested-by: Roland Grunberg <rgrunber@redhat.com>
35 files changed, 820 insertions, 455 deletions
diff --git a/containers/org.eclipse.linuxtools.docker.core/META-INF/MANIFEST.MF b/containers/org.eclipse.linuxtools.docker.core/META-INF/MANIFEST.MF index f51cfb59d6..5009642a69 100644 --- a/containers/org.eclipse.linuxtools.docker.core/META-INF/MANIFEST.MF +++ b/containers/org.eclipse.linuxtools.docker.core/META-INF/MANIFEST.MF @@ -13,7 +13,11 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.10.0", org.eclipse.osgi, com.spotify.docker.client;bundle-version="3.1.1", jnr.unixsocket;bundle-version="0.4.0", - jnr.enxio;bundle-version="0.5.0" + jnr.enxio;bundle-version="0.5.0", + javax.ws.rs;bundle-version="2.0.1", + org.glassfish.jersey.core.jersey-client;bundle-version="2.14.0", + org.glassfish.jersey.media.jersey-media-json-jackson;bundle-version="2.14.0", + org.glassfish.jersey.core.jersey-common;bundle-version="2.14.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.linuxtools.docker.core, 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 bd5372394f..14203a3f50 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 @@ -85,22 +85,34 @@ public interface IDockerConnection { public List<IDockerImage> getImages(); /** + * Checks if an entry in the current list of {@link IDockerImage} exists + * with the same <code>name</code> and <code>tag</code> + * + * @param repository + * the repository of the {@link IDockerImage} to find + * @param tag + * the tag of the {@link IDockerImage} to find + * @return <code>true</code> if an {@link IDockerImage} was found, + * <code>false</code> otherwise. + */ + public boolean hasImage(String repository, String tag); + + /** + * @return Boolean flag to indicate if the list of {@link IDockerImage} has + * already been loaded ({@code true}) or not ({@code false}). + */ + public boolean isImagesLoaded(); + + /** * Get the list of {@link IDockerImage} of the remote Docker daemon. * * @param force * {@code true} to force a new retrieval of the list of - * {@link IDockerImage}, {@code false} to use the cached - * list. + * {@link IDockerImage}, {@code false} to use the cached list. * @return an unmodifiable list of {@link IDockerImage} or * {@link Collections#emptyList()} if no container exists yet. */ public List<IDockerImage> getImages(final boolean force); - - /** - * @return Boolean flag to indicate if the list of {@link IDockerImage} - * has already been loaded ({@code true}) or not ({@code false}). - */ - public boolean isImagesLoaded(); public String getName(); diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerImageSearchResult.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerImageSearchResult.java index bfd44454ae..2d29e39147 100644 --- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerImageSearchResult.java +++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerImageSearchResult.java @@ -1,3 +1,13 @@ +/******************************************************************************* + * 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; public interface IDockerImageSearchResult { diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerRegistry.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerRegistry.java new file mode 100644 index 0000000000..a755a73c00 --- /dev/null +++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerRegistry.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2015 Red Hat. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat - Initial Contribution + *******************************************************************************/ + +package org.eclipse.linuxtools.docker.core; + +import java.util.List; +import java.util.concurrent.ExecutionException; + +import com.spotify.docker.client.DockerRequestException; + +/** + * An interface for Docker registries. + */ +public interface IDockerRegistry { + + /** + * @return the {@link List} of available {@link IDockerImageTagSearchResult} + * for the given repository on this IDockerRegistry. + * @param repository + * the image repository + * @throws InterruptedException + * @throws DockerRequestException + * @throws ExecutionException + */ + List<IRepositoryTag> getTags(String repository) + throws InterruptedException, ExecutionException, DockerException; + +} diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IRepositoryTag.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IRepositoryTag.java new file mode 100644 index 0000000000..16a8ed1f0c --- /dev/null +++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IRepositoryTag.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * 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; + +/** + * A tag (or version) for a given repository. + */ +public interface IRepositoryTag { + + /** + * @return Name of the tag. + */ + String getName(); + + /** + * @return The corresponding image layer for this specific tag + */ + String getLayer(); +} diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/Messages.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/Messages.java index 19b6cbe46e..abab16b1e2 100644 --- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/Messages.java +++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/Messages.java @@ -32,6 +32,7 @@ public class Messages extends NLS { public static String List_Docker_Containers_Failure; public static String Docker_General_Info_Failure; public static String Docker_No_Settings_Description_Script; + public static String Registry_Version_Mismatch; static { // Initialize resource bundle. diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/Messages.properties b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/Messages.properties index 5a6fd27dc0..76642a6864 100644 --- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/Messages.properties +++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/Messages.properties @@ -25,4 +25,5 @@ Docker_Daemon_Ping_Failure=Failed to ping the Docker daemon Retrieve_Docker_Certificates_Failure=Unable to retrieve certificates to connect to the Docker daemon List_Docker_Containers_Failure=Failed to load list of Docker containers from {0} Docker_General_Info_Failure=Failed to get Docker connection info -Docker_No_Settings_Description_Script=There is no settings detection script for this OS
\ No newline at end of file +Docker_No_Settings_Description_Script=There is no settings detection script for this OS +Registry_Version_Mismatch=Target Docker registry located at {0} does not support API v1
\ No newline at end of file diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java index cfdb7d5a2f..e205a6b6a1 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 @@ -1009,6 +1009,20 @@ public class DockerConnection implements IDockerConnection { } @Override + public boolean hasImage(final String repository, final String tag) { + for (IDockerImage image : getImages()) { + if (image.repo().equals(repository)) { + for (String imageTag : image.tags()) { + if (imageTag.startsWith(tag)) { + return true; + } + } + } + } + return false; + } + + @Override public void pullImage(final String id, final IDockerProgressHandler handler) throws DockerException, InterruptedException { try { @@ -1036,8 +1050,6 @@ public class DockerConnection implements IDockerConnection { } } - - @Override public void pushImage(final String name, final IDockerProgressHandler handler) throws DockerException, InterruptedException { diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerHubRegistry.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerHubRegistry.java new file mode 100644 index 0000000000..23b40730af --- /dev/null +++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerHubRegistry.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2015 Red Hat. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat - Initial Contribution + *******************************************************************************/ + +package org.eclipse.linuxtools.internal.docker.core; + +import static javax.ws.rs.HttpMethod.GET; +import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ExecutionException; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.eclipse.linuxtools.docker.core.Activator; +import org.eclipse.linuxtools.docker.core.DockerException; +import org.eclipse.linuxtools.docker.core.IDockerRegistry; +import org.eclipse.linuxtools.docker.core.IRepositoryTag; +import org.eclipse.linuxtools.docker.core.Messages; +import org.eclipse.osgi.util.NLS; +import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.jackson.JacksonFeature; + +import com.spotify.docker.client.ObjectMapperProvider; + +/** + * The default implementation is the Docker Hub registry (running Docker + * registry version 0.6.3) + */ +public class DockerHubRegistry implements IDockerRegistry { + + private static final String REGISTRY_LOCATION = "https://registry.hub.docker.com/"; //$NON-NLS-1$ + + @Override + public List<IRepositoryTag> getTags(final String repository) + throws InterruptedException, ExecutionException, DockerException { + // check that the registry supports the version 1 API + // see + // https://github.com/docker/docker-registry/blob/master/docker_registry/app.py + final ClientConfig DEFAULT_CONFIG = new ClientConfig( + ObjectMapperProvider.class, JacksonFeature.class); + + final Client client = ClientBuilder.newClient(DEFAULT_CONFIG); + final WebTarget pingApiv1Resource = client.target(REGISTRY_LOCATION) + .path("v1").path("_ping"); //$NON-NLS-1$ //$NON-NLS-2$ + try { + final Response response = pingApiv1Resource + .request(APPLICATION_JSON_TYPE).async().get().get(); + if (response.getStatus() != Status.OK.getStatusCode()) { + throw new DockerException( + NLS.bind(Messages.List_Docker_Containers_Failure, + REGISTRY_LOCATION)); + } + } catch (ExecutionException e) { + Activator.log(e); + return Collections.emptyList(); + } + // now, query the registry + final WebTarget queryTagsResource = client.target(REGISTRY_LOCATION) + .path("v1").path("repositories").path(repository).path("tags"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + final GenericType<List<RepositoryTag>> REPOSITORY_TAGS_RESULT_LIST = new GenericType<List<RepositoryTag>>() { + }; + final List<RepositoryTag> result = queryTagsResource + .request(APPLICATION_JSON_TYPE).async() + .method(GET, REPOSITORY_TAGS_RESULT_LIST).get(); + + return new ArrayList<IRepositoryTag>(result); + } + +} diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImageSearchResult.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImageSearchResult.java index 22a9f4448d..f0d1b39b64 100644 --- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImageSearchResult.java +++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImageSearchResult.java @@ -13,10 +13,10 @@ package org.eclipse.linuxtools.internal.docker.core; import org.eclipse.linuxtools.docker.core.IDockerImageSearchResult; /** - * @author xcoulon * */ -public class DockerImageSearchResult implements IDockerImageSearchResult { +public class DockerImageSearchResult + implements IDockerImageSearchResult { /** the image description. */ private final String description; @@ -31,14 +31,20 @@ public class DockerImageSearchResult implements IDockerImageSearchResult { /** * Full constructor - * @param description the image description - * @param official official image flag - * @param automated automated build flag - * @param name image name (org/repo) - * @param starCount star count + * + * @param description + * the image description + * @param official + * official image flag + * @param automated + * automated build flag + * @param name + * image name (org/repo) + * @param starCount + * star count */ - public DockerImageSearchResult(String description, boolean official, boolean automated, String name, - int starCount) { + public DockerImageSearchResult(String description, boolean official, + boolean automated, String name, int starCount) { this.description = description; this.official = official; this.automated = automated; @@ -75,11 +81,7 @@ public class DockerImageSearchResult implements IDockerImageSearchResult { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + (automated ? 1231 : 1237); - result = prime * result + ((description == null) ? 0 : description.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + (official ? 1231 : 1237); - result = prime * result + starCount; return result; } @@ -95,16 +97,6 @@ public class DockerImageSearchResult implements IDockerImageSearchResult { return false; } final DockerImageSearchResult other = (DockerImageSearchResult) obj; - if (automated != other.automated) { - return false; - } - if (description == null) { - if (other.description != null) { - return false; - } - } else if (!description.equals(other.description)) { - return false; - } if (name == null) { if (other.name != null) { return false; @@ -112,12 +104,6 @@ public class DockerImageSearchResult implements IDockerImageSearchResult { } else if (!name.equals(other.name)) { return false; } - if (official != other.official) { - return false; - } - if (starCount != other.starCount) { - return false; - } return true; } diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/RepositoryTag.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/RepositoryTag.java new file mode 100644 index 0000000000..657a2a95ae --- /dev/null +++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/RepositoryTag.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat - Initial Contribution + *******************************************************************************/ +package org.eclipse.linuxtools.internal.docker.core; + +import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY; +import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE; + +import org.eclipse.linuxtools.docker.core.IRepositoryTag; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.base.Objects; + +/** + * Repository tag retrieved from Docker Registry version 0.6.3 + * + */ +@JsonAutoDetect(fieldVisibility = ANY, getterVisibility = NONE, setterVisibility = NONE) +public class RepositoryTag implements IRepositoryTag { + + @JsonProperty("layer") //$NON-NLS-1$ + private String layer; + @JsonProperty("name") //$NON-NLS-1$ + private String name; + + /** + * @return the layer + */ + @Override + public String getLayer() { + return layer; + } + + /** + * @param layer + * the layer to set + */ + public void setLayer(String layer) { + this.layer = layer; + } + + /** + * @return the name + */ + @Override + public String getName() { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return Objects.toStringHelper(this).add("name", getName()) //$NON-NLS-1$ + .add("layer", getLayer()).toString(); //$NON-NLS-1$ + } + +} diff --git a/containers/org.eclipse.linuxtools.docker.ui/icons/resolved.gif b/containers/org.eclipse.linuxtools.docker.ui/icons/resolved.gif Binary files differnew file mode 100644 index 0000000000..8202d32d00 --- /dev/null +++ b/containers/org.eclipse.linuxtools.docker.ui/icons/resolved.gif diff --git a/containers/org.eclipse.linuxtools.docker.ui/plugin.properties b/containers/org.eclipse.linuxtools.docker.ui/plugin.properties index 3aa40b1470..c05787980b 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/plugin.properties +++ b/containers/org.eclipse.linuxtools.docker.ui/plugin.properties @@ -73,7 +73,7 @@ command.refreshimages.description=Refresh the list of images command.buildimage.name=&Build Image command.buildimage.description=Build Image from Dockerfile -command.pullimage.name=&Pull Image +command.pullimage.name=&Pull Image... command.pullimage.description=Pull Image from registry command.pushimage.name=P&ush Image diff --git a/containers/org.eclipse.linuxtools.docker.ui/plugin.xml b/containers/org.eclipse.linuxtools.docker.ui/plugin.xml index ef4db71198..95c3a96b02 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/plugin.xml +++ b/containers/org.eclipse.linuxtools.docker.ui/plugin.xml @@ -784,6 +784,35 @@ </visibleWhen> </command> </menuContribution> + <!-- explorer view context menu: pull image --> + <menuContribution + locationURI="popup:org.eclipse.linuxtools.docker.ui.dockerExplorerView#PopupMenu"> + <command + commandId="org.eclipse.linuxtools.docker.ui.commands.pullImage" + icon="icons/pull.gif" + id="org.eclipse.linuxtools.docker.ui.commands.pullImage" + style="push"> + <visibleWhen + checkEnabled="false"> + <with + variable="selection"> + <count + value="1"> + </count> + <iterate + ifEmpty="false" + operator="or"> + <or> + <instanceof + value="org.eclipse.linuxtools.docker.core.IDockerConnection" /> + <instanceof + value="org.eclipse.linuxtools.internal.docker.ui.views.DockerExplorerContentProvider$DockerImagesCategory" /> + </or> + </iterate> + </with> + </visibleWhen> + </command> + </menuContribution> <!-- explorer view context menu: push image --> <menuContribution locationURI="popup:org.eclipse.linuxtools.docker.ui.dockerExplorerView#PopupMenu"> diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/SWTImagesFactory.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/SWTImagesFactory.java index dbf471a944..55117df391 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/SWTImagesFactory.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/SWTImagesFactory.java @@ -91,6 +91,7 @@ public class SWTImagesFactory { + "systemprocess.gif"; //$NON-NLS-1$ public static final String IMG_CHECKED = NAME_PREFIX + "checked.gif"; //$NON-NLS-1$ public static final String IMG_UNCHECKED = NAME_PREFIX + "unchecked.gif"; //$NON-NLS-1$ + public static final String IMG_RESOLVED = NAME_PREFIX + "resolved.gif"; //$NON-NLS-1$ public static final String IMG_BANNER_REPOSITORY = NAME_PREFIX + "banner-repository.gif"; //$NON-NLS-1$ public static final String IMG_WARNING = NAME_PREFIX + "warning_obj.gif"; //$NON-NLS-1$ @@ -169,6 +170,8 @@ public class SWTImagesFactory { IMG_CHECKED); public static final ImageDescriptor DESC_UNCHECKED = createManaged("", IMG_UNCHECKED); + public static final ImageDescriptor DESC_RESOLVED = createManaged("", + IMG_RESOLVED); public static final ImageDescriptor DESC_BANNER_REPOSITORY = createManaged( "", IMG_BANNER_REPOSITORY); public static final ImageDescriptor DESC_WARNING = createManaged("", diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandUtils.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandUtils.java index 4a28ea57ed..594931f799 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandUtils.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/CommandUtils.java @@ -31,6 +31,7 @@ import org.eclipse.linuxtools.docker.ui.Activator; import org.eclipse.linuxtools.internal.docker.ui.RunConsole; import org.eclipse.linuxtools.internal.docker.ui.preferences.PreferenceConstants; import org.eclipse.linuxtools.internal.docker.ui.views.DockerContainersView; +import org.eclipse.linuxtools.internal.docker.ui.views.DockerExplorerContentProvider.DockerImagesCategory; import org.eclipse.linuxtools.internal.docker.ui.views.DockerExplorerView; import org.eclipse.linuxtools.internal.docker.ui.views.DockerImagesView; import org.eclipse.swt.widgets.Display; @@ -76,10 +77,14 @@ public class CommandUtils { final ITreeSelection selection = ((DockerExplorerView) activePart) .getCommonViewer().getStructuredSelection(); final Object firstElement = selection.getFirstElement(); - if (firstElement instanceof IDockerContainer) { + if (firstElement instanceof IDockerConnection) { + return (IDockerConnection) firstElement; + } else if (firstElement instanceof IDockerContainer) { return ((IDockerContainer) firstElement).getConnection(); } else if (firstElement instanceof IDockerImage) { return ((IDockerImage) firstElement).getConnection(); + } else if (firstElement instanceof DockerImagesCategory) { + return ((DockerImagesCategory) firstElement).getConnection(); } } return null; diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/PullImageCommandHandler.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/PullImageCommandHandler.java index cd775a8745..789e6c57f0 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/PullImageCommandHandler.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/commands/PullImageCommandHandler.java @@ -21,61 +21,64 @@ import org.eclipse.linuxtools.docker.core.DockerException; import org.eclipse.linuxtools.docker.core.IDockerConnection; import org.eclipse.linuxtools.internal.docker.core.DockerConnection; import org.eclipse.linuxtools.internal.docker.ui.views.DVMessages; -import org.eclipse.linuxtools.internal.docker.ui.views.DockerImagesView; import org.eclipse.linuxtools.internal.docker.ui.views.ImagePullProgressHandler; -import org.eclipse.linuxtools.internal.docker.ui.wizards.ImagePull; +import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageSearch; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.handlers.HandlerUtil; +/** + * Command handler that opens the {@link ImageSearch} wizard and pulls the + * selected image in background on completion. + * + */ public class PullImageCommandHandler extends AbstractHandler { private final static String PULL_IMAGE_JOB_TITLE = "ImagePull.title"; //$NON-NLS-1$ private final static String PULL_IMAGE_JOB_TASK = "ImagePull.msg"; //$NON-NLS-1$ private static final String ERROR_PULLING_IMAGE = "ImagePullError.msg"; //$NON-NLS-1$ - - private IDockerConnection connection; @Override public Object execute(final ExecutionEvent event) { final IWorkbenchPart activePart = HandlerUtil.getActivePart(event); - final ImagePull wizard = new ImagePull(); + final IDockerConnection connection = CommandUtils + .getCurrentConnection(activePart); + final ImageSearch wizard = new ImageSearch(connection); final boolean pullImage = CommandUtils.openWizard(wizard, HandlerUtil.getActiveShell(event)); if (pullImage) { - if (activePart instanceof DockerImagesView) { - connection = ((DockerImagesView) activePart) - .getConnection(); - } - performPullImage(wizard); + performPullImage(connection, wizard.getSelectedImage().getName(), + wizard.getSelectedImageTag().getName()); } return null; } - - private void performPullImage(final ImagePull wizard) { - final Job pullImageJob = new Job(DVMessages.getFormattedString( - PULL_IMAGE_JOB_TITLE, wizard.getImageId())) { + + private void performPullImage(final IDockerConnection connection, + final String imageName, final String tagName) { + final Job pullImageJob = new Job(DVMessages + .getFormattedString(PULL_IMAGE_JOB_TITLE, imageName, tagName)) { @Override protected IStatus run(final IProgressMonitor monitor) { - final String id = wizard.getImageId(); monitor.beginTask(DVMessages.getString(PULL_IMAGE_JOB_TASK), IProgressMonitor.UNKNOWN); // pull the image and let the progress // handler refresh the images when done try { - ((DockerConnection) connection).pullImage(id, - new ImagePullProgressHandler(connection, id)); + ((DockerConnection) connection).pullImage( + imageName + ":" + tagName, + new ImagePullProgressHandler(connection, + imageName)); } catch (final DockerException e) { Display.getDefault().syncExec(new Runnable() { @Override public void run() { - MessageDialog.openError(Display.getCurrent() - .getActiveShell(), + MessageDialog.openError( + Display.getCurrent().getActiveShell(), DVMessages.getFormattedString( - ERROR_PULLING_IMAGE, id), e - .getMessage()); + ERROR_PULLING_IMAGE, imageName), + e.getMessage()); } diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/databinding/BaseDatabindingModel.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/databinding/BaseDatabindingModel.java index 10303c0a13..856ea0e943 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/databinding/BaseDatabindingModel.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/databinding/BaseDatabindingModel.java @@ -17,8 +17,6 @@ import java.beans.PropertyChangeSupport; /** * Base class for all model classes that need Databinding support * - * @author xcoulon - * */ public abstract class BaseDatabindingModel { diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/databinding/RequiredControlDecorationUpdater.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/databinding/RequiredControlDecorationUpdater.java deleted file mode 100644 index 71a1e6753c..0000000000 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/databinding/RequiredControlDecorationUpdater.java +++ /dev/null @@ -1,67 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Red Hat. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Red Hat - Initial Contribution - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.docker.ui.databinding; - -import org.eclipse.core.runtime.IStatus; -import org.eclipse.jface.databinding.fieldassist.ControlDecorationUpdater; -import org.eclipse.jface.fieldassist.FieldDecoration; -import org.eclipse.jface.fieldassist.FieldDecorationRegistry; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Control; - -/** - * Decorates a {@link Control} to indicate that the value is required. - * - * @author xcoulon - * - */ -public class RequiredControlDecorationUpdater extends ControlDecorationUpdater { - - /** - * boolean to force the decorator even when the status is IStatus#CANCEL. - */ - - private final boolean showRequiredDecorator; - - public RequiredControlDecorationUpdater( - final boolean showRequiredDecorator) { - this.showRequiredDecorator = showRequiredDecorator; - } - - @Override - protected Image getImage(IStatus status) { - if (status == null) { - return null; - } - String fieldDecorationID = null; - switch (status.getSeverity()) { - case IStatus.INFO: - fieldDecorationID = FieldDecorationRegistry.DEC_INFORMATION; - break; - case IStatus.WARNING: - fieldDecorationID = FieldDecorationRegistry.DEC_WARNING; - break; - case IStatus.ERROR: - fieldDecorationID = FieldDecorationRegistry.DEC_ERROR; - break; - case IStatus.CANCEL: - fieldDecorationID = showRequiredDecorator - ? FieldDecorationRegistry.DEC_REQUIRED : null; - break; - } - - final FieldDecoration fieldDecoration = FieldDecorationRegistry - .getDefault().getFieldDecoration(fieldDecorationID); - return fieldDecoration == null ? null : fieldDecoration.getImage(); - } - -} diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/databinding/TextCellEditingSupport.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/databinding/TextCellEditingSupport.java deleted file mode 100644 index eed6fa52d0..0000000000 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/databinding/TextCellEditingSupport.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.eclipse.linuxtools.internal.docker.ui.databinding; - -import org.eclipse.core.databinding.DataBindingContext; -import org.eclipse.core.databinding.beans.BeanProperties; -import org.eclipse.core.databinding.observable.value.IObservableValue; -import org.eclipse.jface.databinding.swt.WidgetProperties; -import org.eclipse.jface.databinding.viewers.ObservableValueEditingSupport; -import org.eclipse.jface.viewers.CellEditor; -import org.eclipse.jface.viewers.ColumnViewer; -import org.eclipse.jface.viewers.TextCellEditor; -import org.eclipse.jface.viewers.ViewerCell; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Composite; - -/** - * Support for Cell editing - * - * @see http://www.vogella.com/tutorials/EclipseDataBinding/article.html#jfacedb_viewer - */ -public class TextCellEditingSupport extends ObservableValueEditingSupport { - - /** The name of the property to observe during edition. */ - private final String propertyName; - - public TextCellEditingSupport(final ColumnViewer viewer, final DataBindingContext dbc, final String propertyName) { - super(viewer, dbc); - this.propertyName = propertyName; - } - - @Override - protected IObservableValue doCreateCellEditorObservable(final CellEditor cellEditor) { - return WidgetProperties.text(SWT.Modify).observe(cellEditor.getControl()); - } - - @Override - protected IObservableValue doCreateElementObservable(final Object element, final ViewerCell cell) { - return BeanProperties.value(this.propertyName).observe(element); - } - - @Override - protected CellEditor getCellEditor(final Object element) { - return new TextCellEditor((Composite) getViewer().getControl()); - } - -}
\ No newline at end of file diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DVMessages.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DVMessages.java index f1f19cabb5..c44b34e3c8 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DVMessages.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DVMessages.java @@ -32,7 +32,7 @@ public class DVMessages { return MessageFormat.format(getString(key), new Object[] { arg }); } - public static String getFormattedString(String key, String[] args) { + public static String getFormattedString(String key, String... args) { return MessageFormat.format(getString(key), (Object[]) args); } } diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DVMessages.properties b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DVMessages.properties index 1ad5f07054..b7edfeb3ac 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DVMessages.properties +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DVMessages.properties @@ -173,7 +173,7 @@ ContainerCommitError.msg=Error committing container ImageBuild.msg=Building Image ImagePull.msg=Pulling Image -ImagePull.title=Pulling Image <{0}> +ImagePull.title=Pulling {0}:{1} ImagePush.msg=Pushing Image ImagePush.title=Pushing Image <{0}> diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerContainersView.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerContainersView.java index 7a87d07d22..7ccb44333d 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerContainersView.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerContainersView.java @@ -465,13 +465,10 @@ public class DockerContainersView extends ViewPart implements final List<ViewerFilter> filters = Arrays .asList(this.viewer.getFilters()); if (filters.contains(hideStoppedContainersViewerFilter)) { - this.form.setText( - DVMessages.getFormattedString(ViewFilteredTitle, - new String[] { connection.getName(), - Integer.toString(viewer.getTable() - .getItemCount()), - Integer.toString( - connection.getContainers().size()), })); + this.form.setText(DVMessages.getFormattedString( + ViewFilteredTitle, connection.getName(), + Integer.toString(viewer.getTable().getItemCount()), + Integer.toString(connection.getContainers().size()))); } else { this.form.setText(DVMessages.getFormattedString(ViewAllTitle, new String[] { connection.getName(), Integer.toString( diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerView.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerView.java index b83bcf8bee..6b106bc6f8 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerView.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerExplorerView.java @@ -193,8 +193,7 @@ public class DockerExplorerView extends CommonNavigator implements GridLayoutFactory.fillDefaults().numColumns(1).margins(5, 5) .applyTo(container); final Link link = new Link(container, SWT.NONE); - link.setText(DVMessages.getFormattedString(NO_CONNECTION_LABEL, - new String[0])); + link.setText(DVMessages.getString(NO_CONNECTION_LABEL)); link.setBackground(pageBook.getDisplay().getSystemColor( SWT.COLOR_LIST_BACKGROUND)); GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.FILL) diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerImagesView.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerImagesView.java index 38d41f122b..fe661f595a 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerImagesView.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/views/DockerImagesView.java @@ -396,13 +396,10 @@ public class DockerImagesView extends ViewPart implements IDockerImageListener, .asList(this.viewer.getFilters()); if (filters.contains(hideDanglingImagesFilter) || filters.contains(hideIntermediateImagesFilter)) { - this.form.setText( - DVMessages.getFormattedString(ViewFilteredTitle, - new String[] { connection.getName(), - Integer.toString(viewer.getTable() - .getItemCount()), - Integer.toString( - connection.getImages().size()), })); + this.form.setText(DVMessages.getFormattedString( + ViewFilteredTitle, connection.getName(), + Integer.toString(viewer.getTable().getItemCount()), + Integer.toString(connection.getImages().size()))); } else { this.form.setText(DVMessages.getFormattedString(ViewAllTitle, new String[] { connection.getName(), Integer diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/DockerImageTagSearchResult.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/DockerImageTagSearchResult.java new file mode 100644 index 0000000000..ace0f6a196 --- /dev/null +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/DockerImageTagSearchResult.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2015 Red Hat. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat - Initial Contribution + *******************************************************************************/ +package org.eclipse.linuxtools.internal.docker.ui.wizards; + +import org.eclipse.linuxtools.docker.core.IRepositoryTag; + +/** + * A single result of when searching for tags for a specific repository on a + * registry + */ +public class DockerImageTagSearchResult { + + /** repository name of the image. */ + private final String repository; + + /** the tag for this specific image. */ + private final String name; + + /** the corresponding image layer. */ + private final String layer; + + /** + * boolean marker to indicate if this image has already been pulled on the + * selected Docker daemon. + */ + private final boolean resolved; + + public DockerImageTagSearchResult(final String repository, final IRepositoryTag repositoryTag, final boolean resolved) { + this.repository = repository; + this.name = repositoryTag.getName(); + this.layer = repositoryTag.getLayer(); + this.resolved = resolved; + } + + /** + * @return the repository name + */ + public String getRepository() { + return repository; + } + + /** + * @return Name of the tag. + */ + public String getName() { + return this.name; + } + + /** + * @return The corresponding image layer for this specific tag + */ + public String getLayer() { + return this.layer; + } + + /** + * @return a {@link Boolean} to indicate if the corresponding image with the + * given tag has already been pulled, i.e, the exact same + * repository/tag exists on the current Docker daemon. + */ + public boolean isResolved() { + return this.resolved; + } + +}
\ No newline at end of file diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/EnvironmentVariableModel.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/EnvironmentVariableModel.java index def2eac997..4a354f7296 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/EnvironmentVariableModel.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/EnvironmentVariableModel.java @@ -29,12 +29,12 @@ public class EnvironmentVariableModel extends BaseDatabindingModel { private String value; - public EnvironmentVariableModel() { + public EnvironmentVariableModel() { - } + } - public EnvironmentVariableModel(final String variableName, - final String variableValue) { + public EnvironmentVariableModel(final String variableName, + final String variableValue) { this.name = variableName; this.value = variableValue; } @@ -42,55 +42,53 @@ public class EnvironmentVariableModel extends BaseDatabindingModel { public EnvironmentVariableModel(final EnvironmentVariableModel variable) { this.name = variable.getName(); this.value = variable.getValue(); - } + } public String getName() { return name; - } + } public void setName(final String name) { firePropertyChange(NAME, this.name, this.name = name); - } + } public String getValue() { return value; - } + } public void setValue(final String value) { firePropertyChange(VALUE, this.value, this.value = value); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result - + ((name == null) ? 0 : name.hashCode()); - result = prime * result - + ((value == null) ? 0 : value.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - EnvironmentVariableModel other = (EnvironmentVariableModel) obj; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((value == null) ? 0 : value.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + EnvironmentVariableModel other = (EnvironmentVariableModel) obj; if (name == null) { if (other.name != null) - return false; - } else if (!name.equals(other.name)) return false; + } else if (!name.equals(other.name)) + return false; if (value == null) { if (other.value != null) - return false; - } else if (!value.equals(other.value)) return false; - return true; - } + } else if (!value.equals(other.value)) + return false; + return true; + } - }
\ No newline at end of file +}
\ No newline at end of file diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImagePull.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImagePull.java deleted file mode 100644 index 5758ee445d..0000000000 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImagePull.java +++ /dev/null @@ -1,47 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Red Hat. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Red Hat - Initial Contribution - *******************************************************************************/ -package org.eclipse.linuxtools.internal.docker.ui.wizards; - -import org.eclipse.jface.wizard.Wizard; - -public class ImagePull extends Wizard { - - private ImagePullPage mainPage; - private String imageId; - - public ImagePull() { - super(); - } - - public String getImageId() { - return imageId; - } - - @Override - public void addPages() { - // TODO Auto-generated method stub - mainPage = new ImagePullPage(); - addPage(mainPage); - } - - @Override - public boolean canFinish() { - return mainPage.isPageComplete(); - } - - @Override - public boolean performFinish() { - imageId = mainPage.getImageId(); - - return true; - } - -} 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 deleted file mode 100644 index eae4691215..0000000000 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImagePullPage.java +++ /dev/null @@ -1,129 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014, 2015 Red Hat. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Red Hat - Initial Contribution - *******************************************************************************/ -package org.eclipse.linuxtools.internal.docker.ui.wizards; - -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.linuxtools.internal.docker.ui.SWTImagesFactory; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.FormAttachment; -import org.eclipse.swt.layout.FormData; -import org.eclipse.swt.layout.FormLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; - -public class ImagePullPage extends WizardPage { - - private final static String NAME = "ImagePull.name"; //$NON-NLS-1$ - private final static String TITLE = "ImagePull.title"; //$NON-NLS-1$ - private final static String DESC = "ImagePull.desc"; //$NON-NLS-1$ - private final static String NAME_LABEL = "ImagePullName.label"; //$NON-NLS-1$ - private final static String NAME_TOOLTIP = "ImagePullName.toolTip"; //$NON-NLS-1$ - private final static String NAME_EMPTY_RULE = "ErrorNameEmpty.msg"; //$NON-NLS-1$ - private final static String INVALID_ID = "ErrorInvalidImageId.msg"; //$NON-NLS-1$ - - private Text nameText; - - private String image; - - public ImagePullPage() { - super(WizardMessages.getString(NAME)); - setDescription(WizardMessages.getString(DESC)); - setTitle(WizardMessages.getString(TITLE)); - setImageDescriptor(SWTImagesFactory.DESC_WIZARD); - } - - public String getImageId() { - return image; - } - - private ModifyListener Listener = new ModifyListener() { - - @Override - public void modifyText(ModifyEvent e) { - // TODO Auto-generated method stub - validate(); - } - }; - - private void validate() { - boolean complete = true; - boolean error = false; - - String name = nameText.getText(); - - if (name.length() == 0) { - setErrorMessage(WizardMessages.getString(NAME_EMPTY_RULE)); - error = true; - } else if (name.charAt(name.length() - 1) == ':') { //$NON-NLS-1$ - // && (tag.length() > 0) || tag.contains(":")) { //$NON-NLS-1$ - setErrorMessage(WizardMessages.getString(INVALID_ID)); - error = true; - } else { - if (name.contains(":")) { //$NON-NLS-$ - if (name.substring(name.indexOf(":") + 1).contains(":")) { //$NON-NLS-1$ //$NON-NLS-2$ - setErrorMessage(WizardMessages.getString(INVALID_ID)); - error = true; - } - } - } - - if (!error) { - setErrorMessage(null); - image = name; - } - setPageComplete(complete && !error); - } - - @Override - public void createControl(Composite parent) { - final Composite container = new Composite(parent, SWT.NULL); - FormLayout layout = new FormLayout(); - layout.marginHeight = 5; - layout.marginWidth = 5; - container.setLayout(layout); - - Label label = new Label(container, SWT.NULL); - - Label repoLabel = new Label(container, SWT.NULL); - repoLabel.setText(WizardMessages.getString(NAME_LABEL)); - - nameText = new Text(container, SWT.BORDER | SWT.SINGLE); - nameText.addModifyListener(Listener); - nameText.setToolTipText(WizardMessages.getString(NAME_TOOLTIP)); - - Point p1 = label.computeSize(SWT.DEFAULT, SWT.DEFAULT); - Point p2 = nameText.computeSize(SWT.DEFAULT, SWT.DEFAULT); - int centering = (p2.y - p1.y + 1) / 2; - - FormData f = new FormData(); - f.top = new FormAttachment(0); - label.setLayoutData(f); - - f = new FormData(); - f.top = new FormAttachment(label, 11 + centering); - f.left = new FormAttachment(0, 0); - repoLabel.setLayoutData(f); - - f = new FormData(); - f.top = new FormAttachment(label, 11 + centering); - f.left = new FormAttachment(repoLabel, 5); - f.right = new FormAttachment(100); - nameText.setLayoutData(f); - - setControl(container); - setPageComplete(false); - } - -} 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 0c18773780..63a8ea3e31 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 @@ -415,7 +415,6 @@ public class ImageRunSelectionPage extends WizardPage { setControlsEnabled(targetButtons, true); } } - }; } diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearch.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearch.java index 04fd3e8fd1..376c6a4092 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearch.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearch.java @@ -19,34 +19,42 @@ import org.eclipse.linuxtools.docker.core.IDockerImageSearchResult; /** * Wizard to search for images. * - * @author xcoulon - * */ public class ImageSearch extends Wizard { /** the Image Search {@link WizardPage}. */ - private final ImageSearchPage searchPage; + private final ImageSearchPage imageSearchPage; + + /** the Image Tag selection {@link WizardPage}. */ + private final ImageTagSelectionPage imageTagSelectionPage; - /** the databinding model for the {@link ImageSearchPage}. */ - private final ImageSearchModel model; + /** + * shared databinding model for {@link ImageSearchPage} and + * {@link ImageTagSelectionPage}. + */ + private final ImageSearchModel imageSearchModel; /** * Default Constructor */ public ImageSearch(final IDockerConnection connection) { - setNeedsProgressMonitor(true); - this.model = new ImageSearchModel(connection); - this.searchPage = new ImageSearchPage(this.model); + setWindowTitle(WizardMessages.getString("ImageSearch.title")); //$NON-NLS-1$ + setNeedsProgressMonitor(true); + this.imageSearchModel = new ImageSearchModel(connection); + this.imageSearchPage = new ImageSearchPage(this.imageSearchModel); + this.imageTagSelectionPage = new ImageTagSelectionPage( + this.imageSearchModel); } @Override public void addPages() { - addPage(searchPage); + addPage(imageSearchPage); + addPage(imageTagSelectionPage); } @Override public boolean canFinish() { - return this.searchPage.isPageComplete(); + return this.imageTagSelectionPage.isPageComplete(); } @Override @@ -55,6 +63,10 @@ public class ImageSearch extends Wizard { } public IDockerImageSearchResult getSelectedImage() { - return this.model.getSelectedImage(); + return this.imageSearchPage.getSelectedImage(); + } + + public DockerImageTagSearchResult getSelectedImageTag() { + return this.imageTagSelectionPage.getSelectedImageTag(); } } diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearchModel.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearchModel.java index a43985393e..c173859459 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearchModel.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearchModel.java @@ -27,17 +27,25 @@ public class ImageSearchModel extends BaseDatabindingModel { public static final String TERM = "term"; //$NON-NLS-1$ + public static final String IMAGE_SEARCH_RESULT = "imageSearchResult"; //$NON-NLS-1$ + public static final String SELECTED_IMAGE = "selectedImage"; //$NON-NLS-1$ - public static final String SEARCH_RESULT = "searchResult"; //$NON-NLS-1$ + public static final String IMAGE_TAG_SEARCH_RESULT = "imageTagSearchResult"; //$NON-NLS-1$ + + public static final String SELECTED_IMAGE_TAG = "selectedImageTag"; //$NON-NLS-1$ private final IDockerConnection selectedConnection; private String term = null; + private List<IDockerImageSearchResult> imageSearchResult; + private IDockerImageSearchResult selectedImage; - private List<IDockerImageSearchResult> searchResult; + private List<DockerImageTagSearchResult> imageTagSearchResult; + + private DockerImageTagSearchResult selectedImageTag; public ImageSearchModel(final IDockerConnection selectedConnection) { this.selectedConnection = selectedConnection; @@ -55,6 +63,20 @@ public class ImageSearchModel extends BaseDatabindingModel { firePropertyChange(TERM, this.term, this.term = term); } + public List<IDockerImageSearchResult> getImageSearchResult() { + return imageSearchResult; + } + + public void setImageSearchResult( + final List<IDockerImageSearchResult> searchResult) { + firePropertyChange(IMAGE_SEARCH_RESULT, this.imageSearchResult, + this.imageSearchResult = searchResult); + // set the first item as the selected image + if (!this.imageSearchResult.isEmpty()) { + setSelectedImage(this.imageSearchResult.get(0)); + } + } + public IDockerImageSearchResult getSelectedImage() { return this.selectedImage; } @@ -64,18 +86,28 @@ public class ImageSearchModel extends BaseDatabindingModel { this.selectedImage = selectedImage); } - public List<IDockerImageSearchResult> getSearchResult() { - return searchResult; + public List<DockerImageTagSearchResult> getImageTagSearchResult() { + return imageTagSearchResult; } - public void setSearchResult( - final List<IDockerImageSearchResult> searchResult) { - firePropertyChange(SEARCH_RESULT, this.searchResult, - this.searchResult = searchResult); + public void setImageTagSearchResult( + final List<DockerImageTagSearchResult> searchTagResult) { + firePropertyChange(IMAGE_TAG_SEARCH_RESULT, this.imageTagSearchResult, + this.imageTagSearchResult = searchTagResult); // set the first item as the selected image - if (!this.searchResult.isEmpty()) { - setSelectedImage(this.searchResult.get(0)); + if (!this.imageTagSearchResult.isEmpty()) { + setSelectedImageTag(this.imageTagSearchResult.get(0)); } } + public DockerImageTagSearchResult getSelectedImageTag() { + return this.selectedImageTag; + } + + public void setSelectedImageTag( + final DockerImageTagSearchResult selectedImageTag) { + firePropertyChange(SELECTED_IMAGE_TAG, this.selectedImageTag, + this.selectedImageTag = selectedImageTag); + } + } diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearchPage.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearchPage.java index 08852dec59..98cf5e5816 100644 --- a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearchPage.java +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageSearchPage.java @@ -20,8 +20,6 @@ import java.util.concurrent.TimeUnit; import org.eclipse.core.databinding.DataBindingContext; import org.eclipse.core.databinding.beans.BeanProperties; import org.eclipse.core.databinding.beans.PojoProperties; -import org.eclipse.core.databinding.observable.ChangeEvent; -import org.eclipse.core.databinding.observable.IChangeListener; import org.eclipse.core.databinding.observable.list.IObservableList; import org.eclipse.core.databinding.observable.value.IObservableValue; import org.eclipse.core.databinding.observable.value.IValueChangeListener; @@ -71,7 +69,6 @@ import org.eclipse.swt.widgets.Text; public class ImageSearchPage extends WizardPage { private final ImageSearchModel model; - private Button searchImageButton; private final DataBindingContext ctx = new DataBindingContext(); /** @@ -85,6 +82,10 @@ public class ImageSearchPage extends WizardPage { this.model = model; } + public IDockerImageSearchResult getSelectedImage() { + return model.getSelectedImage(); + } + @Override public void dispose() { ctx.dispose(); @@ -111,7 +112,7 @@ public class ImageSearchPage extends WizardPage { .grab(true, false).applyTo(searchImageText); searchImageText.addKeyListener(onKeyPressed()); searchImageText.addTraverseListener(onSearchImageTextTraverse()); - searchImageButton = new Button(container, SWT.NONE); + final Button searchImageButton = new Button(container, SWT.NONE); searchImageButton .setText(WizardMessages.getString("ImageSearchPage.search")); //$NON-NLS-1$ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER) @@ -148,10 +149,7 @@ public class ImageSearchPage extends WizardPage { SWT.NONE, SWT.CENTER, 70, new ImageAutomatedColumnLabelProvider()); - searchResultTableViewer - .setContentProvider(new ObservableListContentProvider()); - // searchResultTableViewer.addSelectionChangedListener(onImageSelected()); - GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER) + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL) .grab(true, false).span(COLUMNS, 1).hint(200, 100) .applyTo(table); // description text area @@ -190,18 +188,15 @@ public class ImageSearchPage extends WizardPage { } }); // observe the viewer content + searchResultTableViewer + .setContentProvider(new ObservableListContentProvider()); + // observe the viewer content final IObservableList observableSearchResultModel = BeanProperties .list(ImageSearchModel.class, - ImageSearchModel.SEARCH_RESULT) + ImageSearchModel.IMAGE_SEARCH_RESULT) .observe(model); - observableSearchResultModel.addChangeListener(new IChangeListener() { - - @Override - public void handleChange(ChangeEvent event) { - searchResultTableViewer.setInput(event.getObservable()); + searchResultTableViewer.setInput(observableSearchResultModel); - } - }); // observe the viewer selection ctx.bindValue( ViewerProperties.singleSelection() @@ -216,7 +211,7 @@ public class ImageSearchPage extends WizardPage { ctx.bindValue(WidgetProperties.text().observe(selectedImageDescription), observableSelectedImageDescription); searchImageText.setFocus(); - setControl(parent); + setControl(container); } private TableViewerColumn addTableViewerColum(final TableViewer tableViewer, @@ -287,10 +282,6 @@ public class ImageSearchPage extends WizardPage { final List<IDockerImageSearchResult> searchResults = ImageSearchPage.this.model .getSelectedConnection() .searchImages(term); - monitor.beginTask( - WizardMessages.getString( - "ImageSearchPage.searchTask"), //$NON-NLS-1$ - 1); searchResultQueue.offer(searchResults); } catch (DockerException e) { Activator.log(e); @@ -303,7 +294,8 @@ public class ImageSearchPage extends WizardPage { Display.getCurrent().asyncExec(new Runnable() { @Override public void run() { - ImageSearchPage.this.model.setSearchResult(searchResult); + ImageSearchPage.this.model + .setImageSearchResult(searchResult); // refresh the wizard buttons getWizard().getContainer().updateButtons(); } @@ -384,7 +376,7 @@ public class ImageSearchPage extends WizardPage { static abstract class IconColumnLabelProvider extends StyledCellLabelProvider { - private static final Image ICON = SWTImagesFactory.DESC_CHECKED + private static final Image ICON = SWTImagesFactory.DESC_RESOLVED .createImage(); @Override @@ -411,4 +403,5 @@ public class ImageSearchPage extends WizardPage { abstract boolean doPaint(final Object element); } + } diff --git a/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageTagSelectionPage.java b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageTagSelectionPage.java new file mode 100644 index 0000000000..685bd92d01 --- /dev/null +++ b/containers/org.eclipse.linuxtools.docker.ui/src/org/eclipse/linuxtools/internal/docker/ui/wizards/ImageTagSelectionPage.java @@ -0,0 +1,259 @@ +/******************************************************************************* + * 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.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.beans.BeanProperties; +import org.eclipse.core.databinding.observable.list.IObservableList; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; +import org.eclipse.jface.databinding.viewers.ViewerProperties; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.viewers.CellLabelProvider; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.linuxtools.docker.core.DockerException; +import org.eclipse.linuxtools.docker.core.IDockerConnection; +import org.eclipse.linuxtools.docker.core.IRepositoryTag; +import org.eclipse.linuxtools.docker.ui.Activator; +import org.eclipse.linuxtools.internal.docker.core.DockerHubRegistry; +import org.eclipse.linuxtools.internal.docker.ui.SWTImagesFactory; +import org.eclipse.linuxtools.internal.docker.ui.wizards.ImageSearchPage.IconColumnLabelProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; + +/** + * {@link WizardPage} to select an existing tag for a given image (repository) + * on a remote registry. This page performs a call to the registry when it is + * activated. + */ +public class ImageTagSelectionPage extends WizardPage { + + private final ImageSearchModel model; + private final DataBindingContext ctx = new DataBindingContext(); + + /** + * Default constructor. + */ + public ImageTagSelectionPage(final ImageSearchModel model) { + super("ImageTagSelectionPage", //$NON-NLS-1$ + WizardMessages.getString("ImageTagSelectionPage.title"), //$NON-NLS-1$ + SWTImagesFactory.DESC_BANNER_REPOSITORY); + setMessage(WizardMessages.getString("ImageTagSelectionPage.title")); //$NON-NLS-1$ + this.model = model; + } + + @Override + public void setVisible(boolean visible) { + super.setVisible(visible); + if (visible) { + searchTags(); + } + } + + private void searchTags() { + try { + final BlockingQueue<List<DockerImageTagSearchResult>> searchResultQueue = new ArrayBlockingQueue<>( + 1); + ImageTagSelectionPage.this.getContainer().run(true, true, + new IRunnableWithProgress() { + @Override + public void run(IProgressMonitor monitor) { + try { + monitor.beginTask(WizardMessages.getString( + "ImageTagSelectionPage.searchTask"), //$NON-NLS-1$ + 2); + final String selectedImageName = ImageTagSelectionPage.this.model + .getSelectedImage() + .getName(); + final List<IRepositoryTag> repositoryTags = new DockerHubRegistry() + .getTags( + selectedImageName); + monitor.worked(1); + final List<DockerImageTagSearchResult> searchResults = new ArrayList<>(); + final IDockerConnection connection = model.getSelectedConnection(); + for (IRepositoryTag repositoryTag : repositoryTags) { + searchResults + .add(new DockerImageTagSearchResult( + selectedImageName, + repositoryTag, + connection.hasImage( + selectedImageName, + repositoryTag + .getName()))); + } + monitor.worked(1); + searchResultQueue.offer(searchResults); + } catch (DockerException | InterruptedException + | ExecutionException e) { + Activator.log(e); + } + monitor.done(); + } + }); + final List<DockerImageTagSearchResult> searchResult = searchResultQueue + .poll(10, TimeUnit.SECONDS); + Display.getCurrent().asyncExec(new Runnable() { + @Override + public void run() { + ImageTagSelectionPage.this.model + .setImageTagSearchResult(searchResult); + // refresh the wizard buttons + getWizard().getContainer().updateButtons(); + } + }); + // display a warning in the title area if the search result is empty + if (searchResult.isEmpty()) { + this.setMessage( + WizardMessages.getString( + "ImageTagSelectionPage.noTagWarning"), //$NON-NLS-1$ + WARNING); + } else if (searchResult.size() == 1) { + this.setMessage( + WizardMessages.getString( + "ImageTagSelectionPage.oneTagMatched"), //$NON-NLS-1$ + INFORMATION); + } else { + this.setMessage( + WizardMessages.getFormattedString( + "ImageTagSelectionPage.tagsMatched", //$NON-NLS-1$ + Integer.toString(searchResult.size())), + INFORMATION); + } + } catch (InvocationTargetException | InterruptedException e) { + Activator.log(e); + } + } + + public DockerImageTagSearchResult getSelectedImageTag() { + return model.getSelectedImageTag(); + } + + @Override + public boolean isPageComplete() { + return this.model.getSelectedImageTag() != null; + } + + @Override + public void dispose() { + ctx.dispose(); + super.dispose(); + } + + @Override + public void createControl(final Composite parent) { + final int COLUMNS = 1; + final Composite container = new Composite(parent, SWT.NONE); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).span(1, 1) + .grab(true, false).applyTo(container); + GridLayoutFactory.fillDefaults().numColumns(COLUMNS).margins(6, 6) + .spacing(10, 2).applyTo(container); + + // tags/layers table + final Table table = new Table(container, + SWT.BORDER | SWT.FULL_SELECTION | SWT.V_SCROLL | SWT.H_SCROLL); + GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL) + .grab(true, true).span(COLUMNS, 1).hint(200, 200) + .applyTo(table); + final TableViewer tableViewer = new TableViewer(table); + table.setHeaderVisible(true); + table.setLinesVisible(true); + addTableViewerColum(tableViewer, + WizardMessages.getString("ImageTagSelectionPage.column.tag"), //$NON-NLS-1$ + SWT.NONE, SWT.LEFT, 200, + new RepositoryTagColumnLabelProvider()); + addTableViewerColum(tableViewer, + WizardMessages.getString("ImageTagSelectionPage.column.layer"), //$NON-NLS-1$ + SWT.NONE, SWT.LEFT, 200, + new RepositoryLayerColumnLabelProvider()); + addTableViewerColum(tableViewer, + WizardMessages + .getString("ImageTagSelectionPage.column.localcopy"), //$NON-NLS-1$ + SWT.NONE, SWT.LEFT, 75, new ImagePulledColumnLabelProvider()); + tableViewer.setContentProvider(new ObservableListContentProvider()); + // observe the viewer content + final IObservableList observableSearchResultModel = BeanProperties + .list(ImageSearchModel.class, + ImageSearchModel.IMAGE_TAG_SEARCH_RESULT) + .observe(model); + tableViewer.setInput(observableSearchResultModel); + // observe the viewer selection + ctx.bindValue(ViewerProperties.singleSelection().observe(tableViewer), + BeanProperties.value(ImageSearchModel.SELECTED_IMAGE_TAG) + .observe(model)); + setControl(container); + } + + private TableViewerColumn addTableViewerColum(final TableViewer tableViewer, + final String title, final int style, final int alignment, + final int width, final CellLabelProvider columnLabelProvider) { + final TableViewerColumn viewerColumn = new TableViewerColumn( + tableViewer, style); + final TableColumn column = viewerColumn.getColumn(); + if (title != null) { + column.setText(title); + } + column.setAlignment(alignment); + column.setWidth(width); + viewerColumn.setLabelProvider(columnLabelProvider); + return viewerColumn; + } + + static class RepositoryTagColumnLabelProvider extends ColumnLabelProvider { + + @Override + public String getText(final Object element) { + if (element instanceof DockerImageTagSearchResult) { + return ((DockerImageTagSearchResult) element).getName(); + } + return super.getText(element); + } + } + + static class RepositoryLayerColumnLabelProvider + extends ColumnLabelProvider { + + @Override + public String getText(final Object element) { + if (element instanceof DockerImageTagSearchResult) { + return ((DockerImageTagSearchResult) element).getLayer(); + } + return super.getText(element); + } + } + + static class ImagePulledColumnLabelProvider + extends IconColumnLabelProvider { + + @Override + boolean doPaint(final Object element) { + return element instanceof DockerImageTagSearchResult + && ((DockerImageTagSearchResult) element).isResolved(); + } + } + +} 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 b970a19242..cc4f63df30 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 @@ -83,7 +83,6 @@ CancelButton.label=Cancel ImagePull.label=Pull an image: ImagePull.desc=Specify repository or single image to pull down to the host. ImagePull.title=Pull Image -ImagePull.name=Pull Image ImagePullName.label=Name: ImagePullName.toolTip=Enter either a REPOSITORY to load all its images or REPOSITORY:TAG to load a single image @@ -169,6 +168,7 @@ NewDockerConnectionPage.pingFailure=Ping failed ! NewDockerConnection.failure=Failure NewDockerConnection.failMessage=Failed to connect! +ImageSearch.title=Search and pull a Docker image ImageSearchPage.title=Search the Docker Registry for images ImageSearchPage.imageLabel=Image: ImageSearchPage.search=Search @@ -183,6 +183,16 @@ ImageSearchPage.noImageWarning=No image matched the specified term. ImageSearchPage.oneImageMatched=1 image matched the specified term. ImageSearchPage.imagesMatched={0} images matched the specified term. +ImageTagSelectionPage.title=Choose a tag for the selected image +ImageTagSelectionPage.column.tag=Tag +ImageTagSelectionPage.column.layer=Layer +ImageTagSelectionPage.column.localcopy=Pulled +ImageTagSelectionPage.searchTask=Searching tags... +ImageTagSelectionPage.noTagWarning=No tag found for the selected repository. +ImageTagSelectionPage.oneTagMatched=1 tag found for the selected repository. +ImageTagSelectionPage.tagsMatched={0} tag found for the selected repository. + + ImageSelectionPage.title=Docker Container settings ImageSelectionPage.runImage=Run a Docker Image ImageSelectionPage.exposedPortTitle=Image Selection and Exposed Port Publishing |