Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Coulon2016-01-22 10:45:46 +0000
committerJeff Johnston2016-01-22 22:27:33 +0000
commit9e40d478d6ba65c4da23b16b6994a1feec44b8b3 (patch)
tree2226ffd7433c6881d938e053641c4cf66d5bc829 /containers/org.eclipse.linuxtools.docker.core/src/org/eclipse
parentc898d6287508ef68fcb78f8a633f1e2fb7154f66 (diff)
downloadorg.eclipse.linuxtools-9e40d478d6ba65c4da23b16b6994a1feec44b8b3.tar.gz
org.eclipse.linuxtools-9e40d478d6ba65c4da23b16b6994a1feec44b8b3.tar.xz
org.eclipse.linuxtools-9e40d478d6ba65c4da23b16b6994a1feec44b8b3.zip
Bug 481218 - DockerImages view shows same repo name instead of all variants
Using the 'repo()' instead of 'repoTags()' method to retrieve the actual repo name for the Docker Images. Making sure that there's one DockerImage for all repo/tags in the Docker Images view, but one Docker Image *per repo/tags* in the Docker Explorer view Changing the equals/hashcode implementations in DockerImage to distinguish 2 images with the same id but with different names (otherwise, a single tree item was displayed in the Docker Explorer view). Also preventing exception if image id is less than 12 characters. Added SWTBot tests to verify the number of items in the Docker Images view and in the Docker Explorer view. Change-Id: I3c2df8d6b8e8620cc9c46a81e06a2c4d163ac527 Signed-off-by: Xavier Coulon <xcoulon@redhat.com> Reviewed-on: https://git.eclipse.org/r/65029 Tested-by: Hudson CI Reviewed-by: Jeff Johnston <jjohnstn@redhat.com>
Diffstat (limited to 'containers/org.eclipse.linuxtools.docker.core/src/org/eclipse')
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerImage.java6
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerConnection.java34
-rw-r--r--containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/internal/docker/core/DockerImage.java154
3 files changed, 134 insertions, 60 deletions
diff --git a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerImage.java b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerImage.java
index 066fea7e5a..6bc89505cd 100644
--- a/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerImage.java
+++ b/containers/org.eclipse.linuxtools.docker.core/src/org/eclipse/linuxtools/docker/core/IDockerImage.java
@@ -24,8 +24,14 @@ public interface IDockerImage {
public List<String> repoTags();
+ /**
+ * @return the first repo/name of the Image.
+ */
public String repo();
+ /**
+ * @return all tags associated with the first repo/name of this image
+ */
public List<String> tags();
public Long size();
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 0baa460dfb..9bd6dbe463 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
@@ -759,7 +759,7 @@ public class DockerConnection implements IDockerConnection, Closeable {
@Override
public List<IDockerImage> listImages() throws DockerException {
- final List<IDockerImage> dilist = new ArrayList<>();
+ final List<IDockerImage> tempImages = new ArrayList<>();
synchronized (imageLock) {
List<Image> rawImages = null;
try {
@@ -768,7 +768,7 @@ public class DockerConnection implements IDockerConnection, Closeable {
// been closed but there is an async request to update the
// images list left in the queue
if (client == null)
- return dilist;
+ return tempImages;
rawImages = client.listImages(
DockerClient.ListImagesParam.allImages());
}
@@ -795,25 +795,25 @@ public class DockerConnection implements IDockerConnection, Closeable {
&& imageParentIds.contains(rawImage.id());
final boolean danglingImage = !taggedImage
&& !intermediateImage;
- // FIXME: if an image with a unique ID belongs to multiple repos, we should
- // probably have multiple instances of IDockerImage
- final Map<String, List<String>> repoTags = DockerImage.extractTagsByRepo(rawImage.repoTags());
- for(Entry<String, List<String>> entry : repoTags.entrySet()) {
- final String repo = entry.getKey();
- final List<String> tags = entry.getValue();
- dilist.add(new DockerImage(this, rawImage
- .repoTags(), repo, tags, rawImage.id(), rawImage.parentId(),
- rawImage.created(), rawImage.size(), rawImage
- .virtualSize(), intermediateImage,
- danglingImage));
- }
+ // return one IDockerImage per raw image
+ final List<String> repoTags = new ArrayList<>(
+ rawImage.repoTags());
+ Collections.sort(repoTags);
+ final String repo = DockerImage.extractRepo(repoTags.get(0));
+ final List<String> tags = Arrays
+ .asList(DockerImage.extractTag(repoTags.get(0)));
+ tempImages.add(new DockerImage(this, repoTags, repo,
+ tags, rawImage.id(), rawImage.parentId(),
+ rawImage.created(), rawImage.size(),
+ rawImage.virtualSize(), intermediateImage,
+ danglingImage));
}
- images = dilist;
+ images = tempImages;
}
// Perform notification outside of lock so that listener doesn't cause a
// deadlock to occur
- notifyImageListeners(dilist);
- return dilist;
+ notifyImageListeners(tempImages);
+ return tempImages;
}
@Override
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 63e56522fe..388b479fdf 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,6 +17,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.regex.Pattern;
import org.eclipse.linuxtools.docker.core.IDockerImage;
@@ -37,14 +38,13 @@ public class DockerImage implements IDockerImage {
+ "(\\:(?<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()
- {
+ private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>() {
+ @Override
+ protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd"); //$NON-NLS-1$
- }
- };
-
+ }
+ };
+
private final DockerConnection parent;
private final String created;
private final String createdDate;
@@ -61,9 +61,11 @@ public class DockerImage implements IDockerImage {
/** the literal value for the 'latest' tag on Docker images. */
public static final String TAG_LATEST = "latest"; //$NON-NLS-1$
- public DockerImage(final DockerConnection parent, @Deprecated final List<String> repoTags, final String repo, final List<String> tags,
- final String id, final String parentId, final String created, final Long size,
- final Long virtualSize, final boolean intermediateImage, final boolean danglingImage) {
+ public DockerImage(final DockerConnection parent,
+ @Deprecated final List<String> repoTags, final String repo,
+ final List<String> tags, final String id, final String parentId,
+ final String created, final Long size, final Long virtualSize,
+ final boolean intermediateImage, final boolean danglingImage) {
this.parent = parent;
this.repoTags = repoTags;
this.repo = repo;
@@ -71,7 +73,8 @@ public class DockerImage implements IDockerImage {
this.id = id;
this.parentId = parentId;
this.created = created;
- this.createdDate = formatter.get().format(new Date(Long.valueOf(created).longValue() * 1000));
+ this.createdDate = formatter.get()
+ .format(new Date(Long.valueOf(created).longValue() * 1000));
this.size = size;
this.virtualSize = virtualSize;
this.intermediateImage = intermediateImage;
@@ -79,47 +82,98 @@ public class DockerImage implements IDockerImage {
}
/**
- * Extracts the org/repo and all the associated tags from the given {@code repoTags}, assuming that the given repoTags elements have the following format:
- * <pre>org/repo:tag</pre> or <pre>repo:tag</pre>.
- * @param repoTags the list of repo/tags to analyze
+ * Extracts the org/repo and all the associated tags from the given
+ * {@code repoTags}, assuming that the given repoTags elements have the
+ * following format: {@code [org/]repo[:tag]}. Tags are sorted by their
+ * natural order.
+ *
+ * @param repoTags
+ * the list of repo/tags to analyze
* @return the tags indexed by org/repo
*/
- public static Map<String, List<String>> extractTagsByRepo(final List<String> repoTags) {
+ public static Map<String, List<String>> extractTagsByRepo(
+ final List<String> repoTags) {
final Map<String, List<String>> results = new HashMap<>();
- for(String entry : repoTags) {
+ for (String entry : repoTags) {
final int indexOfColonChar = entry.lastIndexOf(':');
- final String repo = (indexOfColonChar > -1) ? entry.substring(0, indexOfColonChar) : entry;
- if(!results.containsKey(repo)) {
+ final String repo = (indexOfColonChar > -1)
+ ? entry.substring(0, indexOfColonChar) : entry;
+ if (!results.containsKey(repo)) {
results.put(repo, new ArrayList<String>());
}
- if(indexOfColonChar > -1) {
- results.get(repo).add(entry.substring(indexOfColonChar+1));
+ if (indexOfColonChar > -1) {
+ results.get(repo).add(entry.substring(indexOfColonChar + 1));
}
}
+ // now sort the tags
+ for (Entry<String, List<String>> entry : results.entrySet()) {
+ Collections.sort(entry.getValue());
+ }
return results;
}
/**
- * Extracts the list of tags in the give repo/tags, assuming that the given repoTags elements have the following format:
- * <pre>org/repo:tag</pre> or <pre>repo:tag</pre>.
- * @param repoTags the repo/tags list to analyze
+ * Extracts the list of tags in the given repo/tags, assuming that the given
+ * repoTags elements have the following format: {@code [org/]repo[:tag]}.
+ *
+ * @param repoTags
+ * the repo/tags list to analyze
* @return the list of tags or empty list if none was found.
*/
public static List<String> extractTags(final List<String> repoTags) {
- if(repoTags.isEmpty()) {
+ if (repoTags.isEmpty()) {
return Collections.emptyList();
- }
+ }
final List<String> tags = new ArrayList<>();
- for(String repoTag : repoTags) {
+ for (String repoTag : repoTags) {
final int indexOfColonChar = repoTag.lastIndexOf(':');
- if(indexOfColonChar == -1) {
+ if (indexOfColonChar == -1) {
continue;
}
- tags.add(repoTag.substring(indexOfColonChar+1));
+ final String tag = repoTag.substring(indexOfColonChar + 1);
+ tags.add(tag);
}
return tags;
}
-
+
+ /**
+ * Extracts the tag in the given repo/tag, assuming that the given repoTag
+ * element has the following format: {@code [org/]repo[:tag]}.
+ *
+ * @param repoTag
+ * the repo/tag to analyze
+ * @return the tag or null if none was found.
+ */
+ public static String extractRepo(final String repoTag) {
+ if (repoTag == null) {
+ return null;
+ }
+ final int indexOfColonChar = repoTag.lastIndexOf(':');
+ if (indexOfColonChar == -1) {
+ return repoTag;
+ }
+ return repoTag.substring(0, indexOfColonChar);
+ }
+
+ /**
+ * Extracts the tag in the given repo/tag, assuming that the given repoTag
+ * element has the following format: {@code [org/]repo[:tag]}
+ *
+ * @param repoTag
+ * the repo/tag to analyze
+ * @return the tag or null if none was found.
+ */
+ public static String extractTag(final String repoTag) {
+ if (repoTag == null) {
+ return null;
+ }
+ final int indexOfColonChar = repoTag.lastIndexOf(':');
+ if (indexOfColonChar == -1) {
+ return null;
+ }
+ return repoTag.substring(indexOfColonChar + 1);
+ }
+
@Override
public DockerConnection getConnection() {
return parent;
@@ -134,12 +188,12 @@ public class DockerImage implements IDockerImage {
public String repo() {
return repo;
}
-
+
@Override
public List<String> tags() {
return tags;
}
-
+
@Override
public String id() {
return id;
@@ -169,12 +223,12 @@ public class DockerImage implements IDockerImage {
public Long virtualSize() {
return virtualSize;
}
-
+
@Override
public boolean isDangling() {
return danglingImage;
}
-
+
@Override
public boolean isIntermediateImage() {
return intermediateImage;
@@ -182,10 +236,10 @@ public class DockerImage implements IDockerImage {
@Override
public String toString() {
- return "Image: id=" + id() + "\n" + " parentId=" + parentId() + "\n"
- + " created=" + created() + "\n" + " repoTags="
- + repoTags().toString() + "\n" + " size=" + size() + "\n"
- + " virtualSize=" + virtualSize() + "\n";
+ return "Image: id=" + id() + "\n parentId=" + parentId()
+ + "\n created=" + created() + "\n repo=" + repo()
+ + "\n tags=" + tags() + "\n size=" + size()
+ + "\n virtualSize=" + virtualSize();
}
@Override
@@ -193,23 +247,37 @@ public class DockerImage implements IDockerImage {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
+ result = prime * result + ((repo == null) ? 0 : repo.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
- if (this == obj)
+ if (this == obj) {
return true;
- if (obj == null)
+ }
+ if (obj == null) {
return false;
- if (getClass() != obj.getClass())
+ }
+ if (getClass() != obj.getClass()) {
return false;
- DockerImage other = (DockerImage) obj;
+ }
+ final DockerImage other = (DockerImage) obj;
if (id == null) {
- if (other.id != null)
+ if (other.id != null) {
return false;
- } else if (!id.equals(other.id))
+ }
+ } else if (!id.equals(other.id)) {
return false;
+ }
+ if (repo == null) {
+ if (other.repo != null) {
+ return false;
+ }
+ } else if (!repo.equals(other.repo)) {
+ return false;
+ }
+
return true;
}

Back to the top