adding external volume configuring support for IaaSes
Project: http://git-wip-us.apache.org/repos/asf/incubator-stratos/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-stratos/commit/6b561b21 Tree: http://git-wip-us.apache.org/repos/asf/incubator-stratos/tree/6b561b21 Diff: http://git-wip-us.apache.org/repos/asf/incubator-stratos/diff/6b561b21 Branch: refs/heads/master Commit: 6b561b213e23302cf356e5b56664dff7181de8bc Parents: 2e89631 Author: Nirmal Fernando <[email protected]> Authored: Tue Feb 11 15:20:49 2014 +0530 Committer: Nirmal Fernando <[email protected]> Committed: Tue Feb 11 15:20:49 2014 +0530 ---------------------------------------------------------------------- .../cloud/controller/iaases/AWSEC2Iaas.java | 114 ++++++++++++++++ .../controller/iaases/OpenstackNovaIaas.java | 132 +++++++++++++++++-- .../cloud/controller/iaases/VCloudIaas.java | 24 ++++ .../cloud/controller/interfaces/Iaas.java | 28 ++++ 4 files changed, 290 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/6b561b21/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/AWSEC2Iaas.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/AWSEC2Iaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/AWSEC2Iaas.java index 203017e..5796ed5 100644 --- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/AWSEC2Iaas.java +++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/AWSEC2Iaas.java @@ -43,12 +43,16 @@ import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.ec2.domain.Attachment; import org.jclouds.ec2.domain.AvailabilityZoneInfo; import org.jclouds.ec2.domain.KeyPair; import org.jclouds.ec2.domain.PublicIpInstanceIdPair; +import org.jclouds.ec2.domain.Volume; import org.jclouds.ec2.features.AvailabilityZoneAndRegionApi; +import org.jclouds.ec2.features.ElasticBlockStoreApi; import org.jclouds.ec2.features.ElasticIPAddressApi; import org.jclouds.ec2.options.DescribeAvailabilityZonesOptions; +import org.jclouds.ec2.options.DetachVolumeOptions; import java.util.ArrayList; import java.util.Collections; @@ -382,5 +386,115 @@ public class AWSEC2Iaas extends Iaas { return new AWSEC2PartitionValidator(); } + @Override + public String createVolume(int sizeGB) { + IaasProvider iaasInfo = getIaasProvider(); + + ComputeServiceContext context = iaasInfo.getComputeService() + .getContext(); + + String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo); + String zone = ComputeServiceBuilderUtil.extractZone(iaasInfo); + + if(region == null || zone == null) { + log.fatal("Cannot create a new volume in the [region] : "+region + +", [zone] : "+zone+" of Iaas : "+iaasInfo); + return null; + } + + ElasticBlockStoreApi blockStoreApi = context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get(); + + Volume volume = blockStoreApi.createVolumeInAvailabilityZone(zone, sizeGB); + + if (volume == null) { + log.fatal("Volume creation was unsuccessful. [region] : " + region + + ", [zone] : " + zone + " of Iaas : " + iaasInfo); + return null; + } + + log.info("Successfully created a new volume [id]: "+volume.getId() + +" in [region] : "+region+", [zone] : "+zone+" of Iaas : "+iaasInfo); + return volume.getId(); + } + + @Override + public String attachVolume(String instanceId, String volumeId) { + IaasProvider iaasInfo = getIaasProvider(); + + ComputeServiceContext context = iaasInfo.getComputeService() + .getContext(); + + String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo); + String zone = ComputeServiceBuilderUtil.extractZone(iaasInfo); + String device = ComputeServiceBuilderUtil.extractDevice(iaasInfo, "/dev/sdh"); + + if(region == null || zone == null) { + log.fatal("Cannot attach the volume [id]: "+volumeId+" in the [region] : "+region + +", [zone] : "+zone+" of Iaas : "+iaasInfo); + return null; + } + + ElasticBlockStoreApi blockStoreApi = context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get(); + Attachment attachment = blockStoreApi.attachVolumeInRegion(region, volumeId, instanceId, device); + + if (attachment == null) { + log.fatal("Volume [id]: "+volumeId+" attachment for instance [id]: "+instanceId + +" was unsuccessful. [region] : " + region + + ", [zone] : " + zone + " of Iaas : " + iaasInfo); + return null; + } + + log.info("Volume [id]: "+volumeId+" attachment for instance [id]: "+instanceId + +" was successful [status]: "+attachment.getStatus().value()+". [region] : " + region + + ", [zone] : " + zone + " of Iaas : " + iaasInfo); + return attachment.getStatus().value(); + } + + @Override + public void detachVolume(String instanceId, String volumeId) { + IaasProvider iaasInfo = getIaasProvider(); + + ComputeServiceContext context = iaasInfo.getComputeService() + .getContext(); + + String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo); + + if(region == null) { + log.fatal("Cannot detach the volume [id]: "+volumeId+" from the instance [id]: "+instanceId + +" of the [region] : "+region + +" of Iaas : "+iaasInfo); + return; + } + + ElasticBlockStoreApi blockStoreApi = context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get(); + blockStoreApi.detachVolumeInRegion(region, volumeId, true, DetachVolumeOptions.Builder.fromInstance(instanceId)); + + log.info("Detachment of Volume [id]: "+volumeId+" from instance [id]: "+instanceId + +" was successful. [region] : " + region + + " of Iaas : " + iaasInfo); + } + + @Override + public void deleteVolume(String volumeId) { + IaasProvider iaasInfo = getIaasProvider(); + + ComputeServiceContext context = iaasInfo.getComputeService() + .getContext(); + + String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo); + + if(region == null) { + log.fatal("Cannot delete the volume [id]: "+volumeId+" of the [region] : "+region + +" of Iaas : "+iaasInfo); + return; + } + + ElasticBlockStoreApi blockStoreApi = context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get(); + blockStoreApi.deleteVolumeInRegion(region, volumeId); + + log.info("Deletion of Volume [id]: "+volumeId+" was successful. [region] : " + region + + " of Iaas : " + iaasInfo); + } + } http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/6b561b21/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/OpenstackNovaIaas.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/OpenstackNovaIaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/OpenstackNovaIaas.java index b654696..de1b258 100644 --- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/OpenstackNovaIaas.java +++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/OpenstackNovaIaas.java @@ -44,13 +44,20 @@ import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.options.TemplateOptions; import org.jclouds.openstack.nova.v2_0.NovaApi; import org.jclouds.openstack.nova.v2_0.NovaApiMetadata; +import org.jclouds.openstack.nova.v2_0.NovaAsyncApi; import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions; import org.jclouds.openstack.nova.v2_0.domain.FloatingIP; import org.jclouds.openstack.nova.v2_0.domain.HostAggregate; import org.jclouds.openstack.nova.v2_0.domain.KeyPair; +import org.jclouds.openstack.nova.v2_0.domain.Volume; +import org.jclouds.openstack.nova.v2_0.domain.VolumeAttachment; import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPApi; import org.jclouds.openstack.nova.v2_0.extensions.HostAggregateApi; import org.jclouds.openstack.nova.v2_0.extensions.KeyPairApi; +import org.jclouds.openstack.nova.v2_0.extensions.VolumeApi; +import org.jclouds.openstack.nova.v2_0.extensions.VolumeAttachmentApi; +import org.jclouds.openstack.nova.v2_0.options.CreateVolumeOptions; +import org.jclouds.rest.RestContext; import java.util.ArrayList; import java.util.Collections; @@ -58,7 +65,6 @@ import java.util.Set; public class OpenstackNovaIaas extends Iaas { - private static final Log log = LogFactory.getLog(OpenstackNovaIaas.class); private static final String SUCCESSFUL_LOG_LINE = "A key-pair is created successfully in "; private static final String FAILED_LOG_LINE = "Key-pair is unable to create in "; @@ -170,8 +176,8 @@ public class OpenstackNovaIaas extends Iaas { ComputeServiceContext context = iaasInfo.getComputeService() .getContext(); - - KeyPairApi api = context.unwrapApi(NovaApi.class).getKeyPairExtensionForZone(region).get(); + RestContext<NovaApi, NovaAsyncApi> nova = context.unwrap(); + KeyPairApi api = nova.getApi().getKeyPairExtensionForZone(region).get(); KeyPair keyPair = api.createWithPublicKey(keyPairName, publicKey); @@ -199,7 +205,8 @@ public class OpenstackNovaIaas extends Iaas { String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo); - FloatingIPApi floatingIp = context.unwrapApi(NovaApi.class).getFloatingIPExtensionForZone( + RestContext<NovaApi, NovaAsyncApi> nova = context.unwrap(); + FloatingIPApi floatingIp = nova.getApi().getFloatingIPExtensionForZone( region).get(); String ip = null; @@ -278,7 +285,8 @@ public class OpenstackNovaIaas extends Iaas { String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo); - FloatingIPApi floatingIPApi = context.unwrapApi(NovaApi.class) + RestContext<NovaApi, NovaAsyncApi> nova = context.unwrap(); + FloatingIPApi floatingIPApi = nova.getApi() .getFloatingIPExtensionForZone(region).get(); for (FloatingIP floatingIP : floatingIPApi.list()) { @@ -313,8 +321,8 @@ public class OpenstackNovaIaas extends Iaas { } ComputeServiceContext context = iaasInfo.getComputeService().getContext(); - - Set<String> zones = context.unwrapApi(NovaApi.class).getConfiguredZones(); + RestContext<NovaApi, NovaAsyncApi> nova = context.unwrap(); + Set<String> zones = nova.getApi().getConfiguredZones(); for (String configuredZone : zones) { if (region.equalsIgnoreCase(configuredZone)) { if (log.isDebugEnabled()) { @@ -351,7 +359,8 @@ public class OpenstackNovaIaas extends Iaas { throw new InvalidHostException(msg); } ComputeServiceContext context = iaasInfo.getComputeService().getContext(); - HostAggregateApi hostApi = context.unwrapApi(NovaApi.class).getHostAggregateExtensionForZone(zone).get(); + RestContext<NovaApi, NovaAsyncApi> nova = context.unwrap(); + HostAggregateApi hostApi = nova.getApi().getHostAggregateExtensionForZone(zone).get(); for (HostAggregate hostAggregate : hostApi.list()) { for (String configuredHost : hostAggregate.getHosts()) { if (host.equalsIgnoreCase(configuredHost)) { @@ -373,4 +382,111 @@ public class OpenstackNovaIaas extends Iaas { return new OpenstackNovaPartitionValidator(); } + @Override + public String createVolume(int sizeGB) { + IaasProvider iaasInfo = getIaasProvider(); + String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo); + if (region == null || iaasInfo == null) { + log.fatal("Cannot create a new volume in the [region] : "+region + +" of Iaas : "+iaasInfo); + return null; + } + ComputeServiceContext context = iaasInfo.getComputeService().getContext(); + + RestContext<NovaApi, NovaAsyncApi> nova = context.unwrap(); + VolumeApi api = nova.getApi().getVolumeExtensionForZone(region).get(); + Volume volume = api.create(sizeGB, CreateVolumeOptions.Builder.availabilityZone(region)); + if (volume == null) { + log.fatal("Volume creation was unsuccessful. [region] : " + region + + " of Iaas : " + iaasInfo); + return null; + } + + log.info("Successfully created a new volume [id]: "+volume.getId() + +" in [region] : "+region+" of Iaas : "+iaasInfo); + return volume.getId(); + } + + @Override + public String attachVolume(String instanceId, String volumeId) { + IaasProvider iaasInfo = getIaasProvider(); + + ComputeServiceContext context = iaasInfo.getComputeService() + .getContext(); + + String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo); + String device = ComputeServiceBuilderUtil.extractDevice(iaasInfo, "/dev/vdc"); + + if(region == null) { + log.fatal("Cannot attach the volume [id]: "+volumeId+" in the [region] : "+region + +" of Iaas : "+iaasInfo); + return null; + } + + RestContext<NovaApi, NovaAsyncApi> nova = context.unwrap(); + VolumeAttachmentApi api = nova.getApi().getVolumeAttachmentExtensionForZone(region).get(); + VolumeAttachment attachment = api.attachVolumeToServerAsDevice(volumeId, instanceId, device); + + if (attachment == null) { + log.fatal("Volume [id]: "+volumeId+" attachment for instance [id]: "+instanceId + +" was unsuccessful. [region] : " + region + + " of Iaas : " + iaasInfo); + return null; + } + + log.info("Volume [id]: "+volumeId+" attachment for instance [id]: "+instanceId + +" was successful [status]: "+"Attaching"+". [region] : " + region + + " of Iaas : " + iaasInfo); + return "Attaching"; + } + + @Override + public void detachVolume(String instanceId, String volumeId) { + IaasProvider iaasInfo = getIaasProvider(); + + ComputeServiceContext context = iaasInfo.getComputeService() + .getContext(); + + String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo); + + if(region == null) { + log.fatal("Cannot detach the volume [id]: "+volumeId+" from the instance [id]: "+instanceId + +" of the [region] : "+region + +" of Iaas : "+iaasInfo); + return; + } + + RestContext<NovaApi, NovaAsyncApi> nova = context.unwrap(); + VolumeAttachmentApi api = nova.getApi().getVolumeAttachmentExtensionForZone(region).get(); + if (api.detachVolumeFromServer(volumeId, instanceId)) { + log.info("Detachment of Volume [id]: "+volumeId+" from instance [id]: "+instanceId + +" was successful. [region] : " + region + + " of Iaas : " + iaasInfo); + } + + } + + @Override + public void deleteVolume(String volumeId) { + IaasProvider iaasInfo = getIaasProvider(); + + ComputeServiceContext context = iaasInfo.getComputeService() + .getContext(); + + String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo); + + if(region == null) { + log.fatal("Cannot delete the volume [id]: "+volumeId+" of the [region] : "+region + +" of Iaas : "+iaasInfo); + return; + } + + RestContext<NovaApi, NovaAsyncApi> nova = context.unwrap(); + VolumeApi api = nova.getApi().getVolumeExtensionForZone(region).get(); + if (api.delete(volumeId)) { + log.info("Deletion of Volume [id]: "+volumeId+" was successful. [region] : " + region + + " of Iaas : " + iaasInfo); + } + } + } http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/6b561b21/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/VCloudIaas.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/VCloudIaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/VCloudIaas.java index b49f2c8..852bc30 100644 --- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/VCloudIaas.java +++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/VCloudIaas.java @@ -211,4 +211,28 @@ public class VCloudIaas extends Iaas { return null; } + @Override + public String createVolume(int sizeGB) { + // TODO Auto-generated method stub + return null; + } + + @Override + public String attachVolume(String instanceId, String volumeId) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void detachVolume(String instanceId, String volumeId) { + // TODO Auto-generated method stub + + } + + @Override + public void deleteVolume(String volumeId) { + // TODO Auto-generated method stub + + } + } http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/6b561b21/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/interfaces/Iaas.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/interfaces/Iaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/interfaces/Iaas.java index d6303c2..c66844f 100644 --- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/interfaces/Iaas.java +++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/interfaces/Iaas.java @@ -127,4 +127,32 @@ public abstract class Iaas { */ public abstract void buildTemplate(); + /** + * Create a new volume in the respective Iaas. + * @param sizeGB size of the volume in Giga Bytes. + * @return Id of the created volume. + */ + public abstract String createVolume(int sizeGB); + + /** + * Attach a given volume to an instance at the specified device path. + * @param instanceId of the instance. + * @param volumeId volume id of the volume to be attached. + * @return the status of the attachment. + */ + public abstract String attachVolume(String instanceId, String volumeId); + + /** + * Detach a given volume from the given instance. + * @param instanceId of the instance. + * @param volumeId volume id of the volume to be detached. + */ + public abstract void detachVolume(String instanceId, String volumeId); + + /** + * Delete a given volume. + * @param volumeId volume id of the volume to be detached. + */ + public abstract void deleteVolume(String volumeId); + }
