You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@jclouds.apache.org by Bhathiya <no...@github.com> on 2014/12/19 08:29:22 UTC
[jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function (#117)
implement OSImageToImage Function
chahnge locations list to location
Address test failiures
You can merge this Pull Request by running:
git pull https://github.com/hsbhathiya/jclouds-labs azure_m1_OSImageStream
Or you can view, comment on it, or merge it online at:
https://github.com/jclouds/jclouds-labs/pull/117
-- Commit Summary --
* implement OSImageToImage Function
-- File Changes --
M azurecompute/src/main/java/org/jclouds/azurecompute/compute/functions/OSImageToImage.java (45)
M azurecompute/src/main/java/org/jclouds/azurecompute/domain/Disk.java (6)
M azurecompute/src/main/java/org/jclouds/azurecompute/domain/OSImage.java (12)
M azurecompute/src/main/java/org/jclouds/azurecompute/xml/DiskHandler.java (2)
M azurecompute/src/main/java/org/jclouds/azurecompute/xml/OSImageHandler.java (18)
A azurecompute/src/test/java/org/jclouds/azurecompute/compute/functions/OSImageToImageTest.java (49)
M azurecompute/src/test/java/org/jclouds/azurecompute/features/DiskApiLiveTest.java (6)
M azurecompute/src/test/java/org/jclouds/azurecompute/features/OSImageApiLiveTest.java (2)
M azurecompute/src/test/java/org/jclouds/azurecompute/xml/ListOSImagesHandlerTest.java (31)
M azurecompute/src/test/resources/images.xml (11)
-- Patch Links --
https://github.com/jclouds/jclouds-labs/pull/117.patch
https://github.com/jclouds/jclouds-labs/pull/117.diff
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Andrea Turli <no...@github.com>.
> @@ -68,7 +68,7 @@ private void checkOSImage(OSImage OSImage) {
> "MediaLink should be an http(s) url" + OSImage);
> }
>
> - assertTrue(locations.containsAll(OSImage.locations()), "Locations not in " + locations + " :" + OSImage);
> + assertTrue(locations.contains(OSImage.location()), "Locations not in " + locations + " :" + OSImage);
check indentation
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22148175
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Bhathiya <no...@github.com>.
@andreaturli @andreaturli
Can you review this?
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117#issuecomment-67607141
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Bhathiya <no...@github.com>.
@andreaturli , @nacx
I've addressed most of the review suggestions.
@nacx
Not clear about how Image.Status is used
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117#issuecomment-68826892
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Andrea Turli <no...@github.com>.
> URI mediaLink, Integer logicalSizeInGB, Attachment attachedTo, String sourceImage) {
> - return new AutoValue_Disk(name, location, affinityGroup, description, os, mediaLink, logicalSizeInGB, attachedTo,
> + return new AutoValue_Disk(name, location, affinityGroup, description, OS, mediaLink, logicalSizeInGB, attachedTo,
no need to change from `os` to `OS`
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22093937
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Ignasi Barrera <no...@github.com>.
> + return OperatingSystem.builder().family(OsFamily.WINDOWS).version(version)
> + .description(image.description());
> + }
> + return OperatingSystem.builder().family(OsFamily.LINUX).version(version).description(image.description());
> + }
> +
> + private Location createLocation(String input) {
> + return new LocationBuilder().id(input).scope(LocationScope.REGION).description(input).parent(
> + Iterables.getOnlyElement(provider.get())).metadata(ImmutableMap.<String, Object>of("name", input)).build();
> + }
> +
> + public static Function<String, OsFamily> osFamily() {
> + return new Function<String, OsFamily>() {
> + @Override
> + public OsFamily apply(final String label) {
> + if (label != null) {
Instead of using this conditional use `checkNotNull` to fail on a null input value.
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22192061
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Bhathiya <no...@github.com>.
@andreaturli , @nacx
Shall we get this merged?
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117#issuecomment-69695591
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Ignasi Barrera <no...@github.com>.
Just a couple comments. If @andreaturli does not say the opposite this lgtm. Thanks!
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117#issuecomment-69412109
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Ignasi Barrera <no...@github.com>.
>
> @Override
> - public Image apply(OSImage input) {
> - return null;
> + public Image apply(OSImage image) {
> +
> + ImageBuilder builder = new ImageBuilder()
> + .id(image.label())
This must be unique, as it is the ID jclouds will try to find when calling the `computeService.getImage(id)` method. Is this label unique?
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22191941
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Ignasi Barrera <no...@github.com>.
> + private static final String UNRECOGNIZED = "UNRECOGNIZED";
> +
> + private static final String UBUNTU = "Ubuntu";
> + private static final String WINDOWS = "Windows";
> + private static final String OPENLOGIC = "openLogic";
> + private static final String CENTOS = "CentOS";
> + private static final String COREOS = "CoreOS";
> + private static final String OPENSUSE = "openSUSE";
> + private static final String SUSE = "SUSE";
> + private static final String SQL_SERVER = "SQL Server";
> + private static final String ORACLE_lINUX = "Orcale Linux";
> +
> + private final JustProvider provider;
> +
> + @Inject
> + protected OSImageToImage(JustProvider provider) {
Make it package private by removing the `protected` modifier.
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22748154
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Andrea Turli <no...@github.com>.
> + .status(Image.Status.AVAILABLE)
> + .uri(image.mediaLink())
> + .providerId(image.publisherName())
> + .location(createLocation(image.location()));
> +
> + OperatingSystem.Builder osBuilder = setOperatingSystem(image);
> + return builder.operatingSystem(osBuilder.build()).build();
> + }
> +
> + private OperatingSystem.Builder setOperatingSystem(OSImage image) {
> + OsFamily family = osFamily().apply(image.label());
> + String version = version().apply(image.label());
> + if (family != OsFamily.UNRECOGNIZED) {
> + return OperatingSystem.builder().family(family).version(version)
> + .description(image.description());
> + } else if (family == OsFamily.UNRECOGNIZED && image.os() == OSImage.Type.WINDOWS) {
I really think this logic should be part of `osFamily().apply()` maybe changing it into `osFamily().apply(osImage)` ?
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22148131
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Andrea Turli <no...@github.com>.
> +
> + ImageBuilder builder = new ImageBuilder()
> + .id(image.label())
> + .name(image.name())
> + .description(image.description())
> + .status(Image.Status.AVAILABLE)
> + .uri(image.mediaLink())
> + .providerId(image.publisherName())
> + .location(createLocation(image.location()));
> +
> + OperatingSystem.Builder osBuilder = setOperatingSystem(image);
> + return builder.operatingSystem(osBuilder.build()).build();
> + }
> +
> + private OperatingSystem.Builder setOperatingSystem(OSImage image) {
> + if (image.os() == OSImage.Type.WINDOWS) {
good start, but looking at `images.xml` you should be able to retrieve more information out of it.
It is really important for portability that the list of images returned by a jclouds provider contain as much details as possible.
For example, `osFamily` and `osVersion` could be generated using something like
```
OsFamily osFamily = OperatingSystems.osFamily().apply(osImage.label());
String osVersion = OperatingSystems.version().apply(osImage);
```
where `OperatingSystems` util class will make things like
```
public static Function<String, OsFamily> osFamily() {
return new Function<String, OsFamily>() {
@Override
public OsFamily apply(final String label) {
if (label != null) {
if (label.contains(CENTOS)) return OsFamily.CENTOS;
else if (label.contains(SUSE)) return OsFamily.SUSE;
else if (label.contains(UBUNTU)) return OsFamily.UBUNTU;
else if (label.contains(WINDOWS)) return OsFamily.WINDOWS;
}
return OsFamily.UNRECOGNIZED;
}
};
}
```
and similarly for `osVersion`. Make sense?
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22094212
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Andrea Turli <no...@github.com>.
Thanks @hsbhathiya for your PR, very good start!
There are some comments from my side, please try to address them and if you have troubles, feel free to reach out to us on IRC #jclouds.
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117#issuecomment-67610737
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Ignasi Barrera <no...@github.com>.
> + return OsFamily.WINDOWS;
> + else if (label.toUpperCase().contains("ORACLE LINUX"))
> + return OsFamily.OEL;
> + }
> + return OsFamily.UNRECOGNIZED;
> + }
> + };
> + }
> +
> + public static Function<String, String> version() {
> + return new Function<String, String>() {
> + @Override
> + public String apply(final String label) {
> + if (label != null) {
> + //ex: CoreOS Alpha -> Alpha
> + if (label.toUpperCase().contains("COREOS"))
These checks don't seem to be consistent. You perform a "case insensitive" check , but then a "case sensitive" replacement. This doesn't seem to be properly handled.
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22192182
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Andrea Turli <no...@github.com>.
> @@ -68,7 +68,7 @@ private void checkOSImage(OSImage OSImage) {
> "MediaLink should be an http(s) url" + OSImage);
> }
>
> - assertTrue(locations.containsAll(OSImage.locations()), "Locations not in " + locations + " :" + OSImage);
> + // assertTrue(locations.containsAll(OSImage.locations()), "Locations not in " + locations + " :" + OSImage);
same here. Fix the test and/or remove this assertion if no more meaningful
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22094055
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Ignasi Barrera <no...@github.com>.
> + assertEquals(transformed.getOperatingSystem().getFamily(), OsFamily.SUSE);
> + assertEquals(transformed.getOperatingSystem().getVersion(), "13.1");
> + assertEquals(transformed.getId(), OSImage.label());
> + assertEquals(transformed.getProviderId(), OSImage.publisherName());
> + assertEquals(transformed.getLocation().getId(), OSImage.location());
> + }
> +
> + private static OSImage createOSImage(String name) {
> + return OSImage.create(name, "Central US", null, "openSUSE 13.1",
> + "openSUSE 13.1 brings updated desktop environments and software, lot of polishing, a brand new KDE theme, "
> + + "complete systemd integration and many other features.",
> + "MSDN", OSImage.Type.WINDOWS, "SUSE",
> + URI.create("http://example.blob.core.windows.net/disks/myimage.vhd"), 30,
> + Arrays.asList("http://www.ubuntu.com/project/about-ubuntu/licensing"));
> + }
> +}
Add also tests for each Operating system case: unrecognized and others, and also for the other OS versions. You are doing custom parsing of every os version, and that should be properly unit tested.
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22192331
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Ignasi Barrera <no...@github.com>.
>
> public class OSImageToImage implements Function<OSImage, Image> {
> + private static final String UNRECOGNIZED = "UNRECOGNIZED";
> + private final JustProvider provider;
> +
> + @Inject
> + public OSImageToImage(JustProvider provider) {
It is OK. It is used to set the parent root location.
BTW, make the constructor package private.
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22191856
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Andrea Turli <no...@github.com>.
> + //openSUSE 13.1 -> 13.1
> + if (label.toUpperCase().contains("OPENSUSE"))
> + return label.replace("openSUSE ", "");
> + //SUSE Linux Enterprise Server 11 SP3 (Premium Image) -> 11 SP3(Premium Image)
> + else if (label.toUpperCase().contains("SUSE"))
> + return label.replace("SUSE Linux Enterprise Server ", "");
> + //Ubuntu Server 12.04 LTS -> 12.04 LTS
> + else if (label.toUpperCase().contains("UBUNTU"))
> + return label.replace("Ubuntu Server ", "");
> + // return label
> + else if (label.toUpperCase().contains("WINDOWS"))
> + return label;
> + else if (label.toUpperCase().equals("ORACLE LINUX"))
> + return label;
> +
> + return UNRECOGNIZED + ":" + label;
remove that, just UNRECOGNIZED would be ok.
you could log (debug level?) that this UNRECOGNIZED was for `label`
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22148170
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Andrea Turli <no...@github.com>.
> @@ -67,7 +67,7 @@ public static Attachment create(String hostedService, String deployment, String
> @Nullable public abstract String description();
>
> /** The operating system type of the OS image, or null if a data disk. */
> - @Nullable public abstract OSImage.Type os();
> + @Nullable public abstract OSImage.Type OS();
any particular reason to do that? I think the implementation should work with lowerCase
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22093918
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Ignasi Barrera <no...@github.com>.
>
> @Override
> - public Image apply(OSImage input) {
> - return null;
> + public Image apply(OSImage image) {
> +
> + ImageBuilder builder = new ImageBuilder()
> + .id(image.label())
> + .name(image.name())
> + .description(image.description())
> + .status(Image.Status.AVAILABLE)
Out of curiosity: are all existing images available?
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22192011
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Andrea Turli <no...@github.com>.
> + .description(image.description());
> + }
> + return OperatingSystem.builder().family(OsFamily.LINUX).version(version).description(image.description());
> + }
> +
> + private Location createLocation(String input) {
> + return new LocationBuilder().id(input).scope(LocationScope.REGION).description(input).parent(
> + Iterables.getOnlyElement(provider.get())).metadata(ImmutableMap.<String, Object>of("name", input)).build();
> + }
> +
> + public static Function<String, OsFamily> osFamily() {
> + return new Function<String, OsFamily>() {
> + @Override
> + public OsFamily apply(final String label) {
> + if (label != null) {
> + if (label.toUpperCase().contains("CENTOS"))
worth to use constant, like UNRECOGNIZE, and use them also in `setOperatingSystem` to infer more OSFamily.
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22148109
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Ignasi Barrera <no...@github.com>.
>
> @Override
> - public Image apply(OSImage input) {
> - return null;
> + public Image apply(OSImage image) {
> +
> + ImageBuilder builder = new ImageBuilder()
> + .id(image.label())
> + .name(image.name())
> + .description(image.description())
> + .status(Image.Status.AVAILABLE)
> + .uri(image.mediaLink())
> + .providerId(image.publisherName())
This should be the "real" ID of the image in the provider (usually the same as the *id* field, but sometimes in jclouds we encode the region as part of the id). Is this publisher name the *real* and *unique* id of the image in the provider?
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22191970
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Andrea Turli <no...@github.com>.
> + .id(image.label())
> + .name(image.name())
> + .description(image.description())
> + .status(Image.Status.AVAILABLE)
> + .uri(image.mediaLink())
> + .providerId(image.publisherName())
> + .location(createLocation(image.location()));
> +
> + OperatingSystem.Builder osBuilder = setOperatingSystem(image);
> + return builder.operatingSystem(osBuilder.build()).build();
> + }
> +
> + private OperatingSystem.Builder setOperatingSystem(OSImage image) {
> + OsFamily family = osFamily().apply(image.label());
> + String version = version().apply(image.label());
> + if (family != OsFamily.UNRECOGNIZED) {
could you try to enhance this method to detect more os families ?
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22148111
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Ignasi Barrera <no...@github.com>.
> + return null;
> + }
> + }
> +
> + public static Function<OSImage, OperatingSystem.Builder> osFamily() {
> + return new Function<OSImage, OperatingSystem.Builder>() {
> + @Override
> + public OperatingSystem.Builder apply(final OSImage image) {
> +
> + final String label = image.label();
> + checkNotNull(label, "label");
> + OsFamily family = OsFamily.UNRECOGNIZED;
> +
> + if (label.contains(CENTOS))
> + family = OsFamily.CENTOS;
> + else if (label.toUpperCase().contains(OPENLOGIC))
I'm a bit confused. Why the label is compared upper case in some cases and not everywhere?
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22748335
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Ignasi Barrera <no...@github.com>.
> +
> + private Location createLocation(String input) {
> + return new LocationBuilder().id(input).scope(LocationScope.REGION).description(input).parent(
> + Iterables.getOnlyElement(provider.get())).metadata(ImmutableMap.<String, Object>of("name", input)).build();
> + }
> +
> + public static Function<String, OsFamily> osFamily() {
> + return new Function<String, OsFamily>() {
> + @Override
> + public OsFamily apply(final String label) {
> + if (label != null) {
> + if (label.toUpperCase().contains("CENTOS"))
> + return OsFamily.CENTOS;
> + if (label.toUpperCase().contains("OPENLOGIC"))
> + return OsFamily.CENTOS;
> + else if (label.contains("SUSE"))
No need to call `toUpperCase()` here?
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22192100
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Ignasi Barrera <no...@github.com>.
> + return OsFamily.UBUNTU;
> + else if (label.toUpperCase().contains("WINDOWS"))
> + return OsFamily.WINDOWS;
> + else if (label.toUpperCase().contains("ORACLE LINUX"))
> + return OsFamily.OEL;
> + }
> + return OsFamily.UNRECOGNIZED;
> + }
> + };
> + }
> +
> + public static Function<String, String> version() {
> + return new Function<String, String>() {
> + @Override
> + public String apply(final String label) {
> + if (label != null) {
Same about the conditional. Remove it and add a proper null precondition check.
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22192119
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Andrea Turli <no...@github.com>.
> @@ -37,7 +37,7 @@
> public abstract String name();
>
> /** The geo-locations of the image, if the image is not associated with an affinity group. */
> - public abstract List<String> locations();
> + @Nullable public abstract String location();
Good spot!
Please make sure that all the fields in OSImage match Response Body at http://msdn.microsoft.com/en-us/library/jj157191.aspx
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22094009
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Andrea Turli <no...@github.com>.
> @@ -95,9 +95,9 @@ public static Attachment create(String hostedService, String deployment, String
> */
> @Nullable public abstract String sourceImage();
>
> - public static Disk create(String name, String location, String affinityGroup, String description, OSImage.Type os,
> + public static Disk create(String name, String location, String affinityGroup, String description, OSImage.Type OS,
no need to change from `os` to `OS`
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22093935
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Andrea Turli <no...@github.com>.
> @@ -60,8 +60,8 @@ public void testList() {
> }
>
> private void checkDisk(Disk disk) {
> - assertNull(disk.name(), "Name cannot be null for: " + disk);
> - assertNull(disk.os(), "OS cannot be null for: " + disk);
> + assertNotNull(disk.name(), "Name cannot be null for: " + disk);
> + //assertNotNull(disk.OS(), "OS cannot be null for: " + disk);
revert to `os()` and don't comment assertion: test need to pass with that enabled
In general, we never commit commented code!
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22094046
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Andrea Turli <no...@github.com>.
>
> public class OSImageToImage implements Function<OSImage, Image> {
> + private static final String UNRECOGNIZED = "UNRECOGNIZED";
> + private final JustProvider provider;
> +
> + @Inject
> + public OSImageToImage(JustProvider provider) {
not sure we will need this parameter here, as we'd probably use the real locations, but let address that later.
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117/files#r22148151
Re: [jclouds-labs] JCLOUDS-664:Implement OSImageToImage Function
(#117)
Posted by Ignasi Barrera <no...@github.com>.
Thanks @hsbhathiya! This is a good start.
---
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/117#issuecomment-67893977