diff --git a/src/main/java/com/dubture/jenkins/digitalocean/DigitalOcean.java b/src/main/java/com/dubture/jenkins/digitalocean/DigitalOcean.java index e7ae17af..cb13c7c7 100644 --- a/src/main/java/com/dubture/jenkins/digitalocean/DigitalOcean.java +++ b/src/main/java/com/dubture/jenkins/digitalocean/DigitalOcean.java @@ -1,5 +1,14 @@ package com.dubture.jenkins.digitalocean; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.SortedMap; +import java.util.TreeMap; +import java.util.logging.Level; +import java.util.logging.Logger; + import com.myjeeva.digitalocean.common.ImageType; import com.myjeeva.digitalocean.exception.DigitalOceanException; import com.myjeeva.digitalocean.exception.RequestUnsuccessfulException; @@ -15,15 +24,6 @@ import com.myjeeva.digitalocean.pojo.Size; import com.myjeeva.digitalocean.pojo.Sizes; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.SortedMap; -import java.util.TreeMap; -import java.util.logging.Level; -import java.util.logging.Logger; - import static com.google.common.collect.Lists.newArrayList; /** @@ -85,7 +85,8 @@ public int compare(final Size s1, final Size s2) { static SortedMap getAvailableImages(String authToken) throws DigitalOceanException, RequestUnsuccessfulException { DigitalOceanClient client = new DigitalOceanClient(authToken); - SortedMap availableImages = new TreeMap(); + SortedMap availableImages = new TreeMap(ignoringCase()); + Images images; int page = 0; @@ -93,7 +94,7 @@ static SortedMap getAvailableImages(String authToken) throws Digit page += 1; images = client.getAvailableImages(page); for (Image image : images.getImages()) { - String prefix = image.getType() == ImageType.BACKUP ? "(Backup) " : ""; + String prefix = getPrefix(image); availableImages.put(prefix + image.getDistribution() + " " + image.getName(), image); } } @@ -102,7 +103,43 @@ static SortedMap getAvailableImages(String authToken) throws Digit return availableImages; } - /** + private static String getPrefix(Image image) { + + if (image.getType() == ImageType.BACKUP) { + return "(Backup) "; + } + + if (isUserSnapshot(image)) { + return "(Snapshot) "; + } + + return ""; + } + + /** + * Returns the appropriate identifier for creating droplets from this image. + * For non-snapshots, use the image ID instead of the slug (which isn't available + * anyway) so that we can build images based upon backups. + * + * @param image + * @return either a "slug" identifier e.g. "ubuntu-15-04-x64", or an integer ID. + */ + static String getImageIdentifier(Image image) { + return image.getType() == ImageType.SNAPSHOT && image.getSlug() != null + ? image.getSlug() + : image.getId().toString(); + } + + /** + * I'm told that if you manually take an image snapshot, then it + * has a snapshot type but no slug. Therefore, indicate that it is + * a user-snapshot + */ + private static boolean isUserSnapshot(Image image) { + return image.getType() == ImageType.SNAPSHOT && image.getSlug() == null; + } + + /** * Fetches all regions that are flagged as available. * @param authToken the API authorisation token to use * @return a list of {@link Region}s, sorted by name. @@ -232,4 +269,13 @@ static Image newImage(String idOrSlug) { return image; } + + private static Comparator ignoringCase() { + return new Comparator() { + @Override + public int compare(final String o1, final String o2) { + return o1.compareToIgnoreCase(o2); + } + }; + } } diff --git a/src/main/java/com/dubture/jenkins/digitalocean/SlaveTemplate.java b/src/main/java/com/dubture/jenkins/digitalocean/SlaveTemplate.java index 328e4408..ca7785f4 100644 --- a/src/main/java/com/dubture/jenkins/digitalocean/SlaveTemplate.java +++ b/src/main/java/com/dubture/jenkins/digitalocean/SlaveTemplate.java @@ -24,7 +24,17 @@ package com.dubture.jenkins.digitalocean; -import com.myjeeva.digitalocean.common.ImageType; +import java.io.IOException; +import java.io.PrintStream; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; +import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; + import com.myjeeva.digitalocean.exception.RequestUnsuccessfulException; import com.myjeeva.digitalocean.impl.DigitalOceanClient; import com.myjeeva.digitalocean.pojo.Droplet; @@ -47,17 +57,6 @@ import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; -import java.io.IOException; -import java.io.PrintStream; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; -import java.util.UUID; -import java.util.logging.Level; -import java.util.logging.Logger; - import static com.google.common.collect.Lists.newArrayList; /** @@ -257,7 +256,7 @@ public ListBoxModel doFillImageIdItems(@RelativePath("..") @QueryParameter Strin // For non-snapshots, use the image ID instead of the slug (which isn't available anyway) // so that we can build images based upon backups. - final String value = image.getType() == ImageType.SNAPSHOT ? image.getSlug() : image.getId().toString(); + final String value = DigitalOcean.getImageIdentifier(image); model.add(entry.getKey(), value); }