libcloud-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From to...@apache.org
Subject svn commit: r1351042 - in /libcloud/trunk: ./ libcloud/compute/ libcloud/compute/drivers/ test/compute/ test/compute/fixtures/cloudstack/ test/compute/fixtures/ec2/
Date Sun, 17 Jun 2012 03:35:59 GMT
Author: tomaz
Date: Sun Jun 17 03:35:58 2012
New Revision: 1351042

URL: http://svn.apache.org/viewvc?rev=1351042&view=rev
Log:
Add a standard API and methods for managing storage volumes to the
EC2 and CloudStack drivers.

Base API consistent of the following methods: create_volume,
destroy_volume, attach_volume, detach_volume. 

Also change ex_describe_tags, ex_create_tags and ex_delete_tags methods
signature in the EC2 driver. Argument is now called resource (previously
it was called node). This methods work with both Node and StorageVolume
objects.

Contributed by Gabriel Reid, part of LIBCLOUD-213.

Added:
    libcloud/trunk/test/compute/fixtures/cloudstack/deleteVolume_default.json
    libcloud/trunk/test/compute/fixtures/cloudstack/detachVolume_default.json
    libcloud/trunk/test/compute/fixtures/cloudstack/queryAsyncJobResult_detachvolumejob.json
    libcloud/trunk/test/compute/fixtures/ec2/attach_volume.xml
    libcloud/trunk/test/compute/fixtures/ec2/create_volume.xml
    libcloud/trunk/test/compute/fixtures/ec2/delete_volume.xml
    libcloud/trunk/test/compute/fixtures/ec2/detach_volume.xml
Modified:
    libcloud/trunk/CHANGES
    libcloud/trunk/libcloud/compute/base.py
    libcloud/trunk/libcloud/compute/drivers/cloudstack.py
    libcloud/trunk/libcloud/compute/drivers/ec2.py
    libcloud/trunk/test/compute/test_cloudstack.py
    libcloud/trunk/test/compute/test_ec2.py

Modified: libcloud/trunk/CHANGES
URL: http://svn.apache.org/viewvc/libcloud/trunk/CHANGES?rev=1351042&r1=1351041&r2=1351042&view=diff
==============================================================================
--- libcloud/trunk/CHANGES (original)
+++ libcloud/trunk/CHANGES Sun Jun 17 03:35:58 2012
@@ -46,6 +46,18 @@ Changes with Apache Libcloud in developm
       CloudStack driver.
       [DaeMyung Kang]
 
+    - Add a standard API and methods for managing storage volumes to the
+      EC2 and CloudStack drivers. Base API consistent of the following methods:
+      create_volume, destroy_volume, attach_volume, detach_volume. ;
+      LIBCLOUD-213
+      [Gabriel Reid]
+
+    - Change ex_describe_tags, ex_create_tags and ex_delete_tags methods
+      signature in the EC2 driver. Argument is now called resource (previously
+      it was called node). This methods work with both Node and StorageVolume
+      objects. ; LIBCLOUD-213
+      [Gabriel Reid, Tomaz Muraus]
+
   *) DNS
 
     - Add support for GEO RecordType to Zerigo driver. ; LIBCLOUD-203

Modified: libcloud/trunk/libcloud/compute/base.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/compute/base.py?rev=1351042&r1=1351041&r2=1351042&view=diff
==============================================================================
--- libcloud/trunk/libcloud/compute/base.py (original)
+++ libcloud/trunk/libcloud/compute/base.py Sun Jun 17 03:35:58 2012
@@ -98,7 +98,8 @@ class UuidMixin(object):
         same UUID!
         """
         if not self._uuid:
-            self._uuid = hashlib.sha1(b("%s:%d" % (self.id, self.driver.type))).hexdigest()
+            self._uuid = hashlib.sha1(b('%s:%d' % (self.id, self.driver.type))).hexdigest()
+
         return self._uuid
 
     @property
@@ -362,6 +363,56 @@ class NodeAuthPassword(object):
     def __repr__(self):
         return '<NodeAuthPassword>'
 
+class StorageVolume(UuidMixin):
+    """
+    A base StorageVolume class to derive from.
+    """
+
+    def __init__(self, id, name, size, driver, extra=None):
+        self.id = id
+        self.name = name
+        self.size = size
+        self.driver = driver
+        self.extra = extra
+        UuidMixin.__init__(self)
+
+    def attach(self, node, device=None):
+        """
+        Attach this volume to a node.
+
+        @param      node: Node to attach volume to
+        @type       node: L{Node}
+
+        @param      device: Where the device is exposed,
+                            e.g. '/dev/sdb (optional)
+        @type       device: C{str}
+
+        @returns C{bool}
+        """
+
+        return self.driver.attach_volume(node=node, volume=self, device=device)
+
+    def detach(self):
+        """
+        Detach this volume from its node
+
+        @returns C{bool}
+        """
+
+        return self.driver.detach_volume(volume=self)
+
+    def destroy(self):
+        """Destroy this storage volume.
+
+        @returns C{bool}
+        """
+
+        return self.driver.destroy_volume(volume=self)
+
+    def __repr__(self):
+        return '<StorageVolume id=%s size=%s driver=%s>' % (
+                        self.id, self.size, self.driver.name)
+
 
 class NodeDriver(BaseDriver):
     """
@@ -620,6 +671,72 @@ class NodeDriver(BaseDriver):
 
         return node
 
+    def create_volume(self, size, name, location=None, snapshot=None):
+        """
+        Create a new volume.
+
+        @param      size: Size of volume in gigabytes (required)
+        @type       size: C{int}
+
+        @keyword    name: Name of the volume to be created
+        @type       name: C{str}
+
+        @keyword    location: Which data center to create a volume in. If empty,
+                              undefined behavoir will be selected. (optional)
+        @type       location: L{NodeLocation}
+
+        @keyword    snapshot:  Name of snapshot from which to create the new
+                               volume.  (optional)
+        @type       snapshot:  C{str}
+
+        @return: The newly created L{StorageVolume}.
+        """
+        raise NotImplementedError(
+           'create_volume not implemented for this driver')
+
+    def destroy_volume(self, volume):
+        """
+        Destroys a storage volume.
+
+        @param      volume: Volume to be destroyed
+        @type       volume: L{StorageVolume}
+
+        @return: C{bool}
+        """
+
+        raise NotImplementedError(
+               'destroy_volume not implemented for this driver')
+
+    def attach_volume(self, node, volume, device=None):
+        """
+        Attaches volume to node.
+
+        @param      node: Node to attach volume to
+        @type       node: L{Node}
+
+        @param      volume: Volume to attach
+        @type       volume: L{StorageVolume}
+
+        @param      device: Where the device is exposed,
+                            e.g. '/dev/sdb (optional)
+        @type       device: C{str}
+
+        @return: C{bool}
+        """
+        raise NotImplementedError('attach not implemented for this driver')
+
+    def detach_volume(self, volume):
+        """
+        Detaches a volume from a node.
+
+        @param      volume: Volume to be detached
+        @type       volume: L{StorageVolume}
+
+        @returns C{bool}
+        """
+
+        raise NotImplementedError('detach not implemented for this driver')
+
     def _wait_until_running(self, node, wait_period=3, timeout=600,
                             ssh_interface='public_ips', force_ipv4=True):
         """

Modified: libcloud/trunk/libcloud/compute/drivers/cloudstack.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/compute/drivers/cloudstack.py?rev=1351042&r1=1351041&r2=1351042&view=diff
==============================================================================
--- libcloud/trunk/libcloud/compute/drivers/cloudstack.py (original)
+++ libcloud/trunk/libcloud/compute/drivers/cloudstack.py Sun Jun 17 03:35:58 2012
@@ -16,7 +16,7 @@
 from libcloud.compute.providers import Provider
 from libcloud.common.cloudstack import CloudStackDriverMixIn
 from libcloud.compute.base import Node, NodeDriver, NodeImage, NodeLocation, \
-                                  NodeSize
+                                  NodeSize, StorageVolume
 from libcloud.compute.types import NodeState, LibcloudError
 
 
@@ -90,18 +90,6 @@ class CloudStackDiskOffering(object):
     def __eq__(self, other):
         return self.__class__ is other.__class__ and self.id == other.id
 
-
-class CloudStackVolume(object):
-    """A storage volume within CloudStack."""
-
-    def __init__(self, id, name):
-        self.id = id
-        self.name = name
-
-    def __eq__(self, other):
-        return self.__class__ is other.__class__ and self.id == other.id
-
-
 class CloudStackNodeDriver(CloudStackDriverMixIn, NodeDriver):
     """Driver for the CloudStack API.
 
@@ -290,34 +278,20 @@ class CloudStackNodeDriver(CloudStackDri
 
         return diskOfferings
 
-    def ex_create_volume(self, name, location, size):
-        """
-        Create a new detached storage volume.
-
-        @type name: C{str}
-        @param name: Name to be given to the created volume
-
-        @type location: L{NodeLocation}
-        @param location: The location where the volume is to be created
-
-        @type size: C{int}
-        @param location: The size of the volume to be created, in GB
-
-        @returns: The newly-created detached volume
-        """
-
+    def create_volume(self, size, name, location, snapshot=None):
+        # TODO Add snapshot handling
         for diskOffering in self.ex_list_disk_offerings():
             if diskOffering.size == size or diskOffering.customizable:
                 break
         else:
             raise LibcloudError(
-                    "Disk offering with size=%s not found" % size)
+                    'Disk offering with size=%s not found' % size)
 
         extraParams = dict()
         if diskOffering.customizable:
             extraParams['size'] = size
 
-        requestResult = self._async_request('createVolume', 
+        requestResult = self._async_request('createVolume',
                                 name=name,
                                 diskOfferingId=diskOffering.id,
                                 zoneId=location.id,
@@ -325,25 +299,24 @@ class CloudStackNodeDriver(CloudStackDri
 
         volumeResponse = requestResult['volume']
 
-        return CloudStackVolume(
-                            id = volumeResponse['id'],
-                            name = volumeResponse['name'])
-
-
-    def ex_attach_volume(self, node, volume):
-        """
-        Attach a storage volume to a node.
-
-        @type node: L{CloudStackNode}
-        @param node: The node to which the volume is to be attached
+        return StorageVolume(id=volumeResponse['id'],
+                            name=name,
+                            size=size,
+                            driver=self,
+                            extra=dict(name=volumeResponse['name']))
+
+    def attach_volume(self, node, volume, device=None):
+        # TODO Add handling for device name
+        self._async_request('attachVolume', id=volume.id,
+                            virtualMachineId=node.id)
+        return True
 
-        @type volume: L{CloudStackVolume}
-        @param volume: The volume to be attached
-        """
+    def detach_volume(self, volume):
+        self._async_request('detachVolume', id=volume.id)
+        return True
 
-        self._async_request('attachVolume', 
-                                id=volume.id, 
-                                virtualMachineId=node.id)
+    def destroy_volume(self, volume):
+        self._sync_request('deleteVolume', id=volume.id)
         return True
 
     def ex_allocate_public_ip(self, node):

Modified: libcloud/trunk/libcloud/compute/drivers/ec2.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/compute/drivers/ec2.py?rev=1351042&r1=1351041&r2=1351042&view=diff
==============================================================================
--- libcloud/trunk/libcloud/compute/drivers/ec2.py (original)
+++ libcloud/trunk/libcloud/compute/drivers/ec2.py Sun Jun 17 03:35:58 2012
@@ -39,7 +39,7 @@ from libcloud.common.types import (Inval
 from libcloud.compute.providers import Provider
 from libcloud.compute.types import NodeState
 from libcloud.compute.base import Node, NodeDriver, NodeLocation, NodeSize
-from libcloud.compute.base import NodeImage
+from libcloud.compute.base import NodeImage, StorageVolume
 
 EC2_US_EAST_HOST = 'ec2.us-east-1.amazonaws.com'
 EC2_US_WEST_HOST = 'ec2.us-west-1.amazonaws.com'
@@ -460,6 +460,17 @@ class EC2NodeDriver(NodeDriver):
         )
         return n
 
+    def _to_volume(self, element, name):
+        volId = findtext(element=element, xpath='volumeId',
+                         namespace=NAMESPACE)
+        size = findtext(element=element, xpath='size', namespace=NAMESPACE)
+
+        return StorageVolume(
+                        id=volId,
+                        name=name,
+                        size=int(size),
+                        driver=self)
+
     def list_nodes(self, ex_node_ids=None):
         """
         @type node.id: C{list}
@@ -523,6 +534,45 @@ class EC2NodeDriver(NodeDriver):
                                              availability_zone))
         return locations
 
+    def create_volume(self, size, name, location=None, snapshot=None):
+        params = {
+                'Action': 'CreateVolume',
+                'Size': str(size) }
+
+        if location is not None:
+            params['AvailabilityZone'] = location.availability_zone.name
+
+        volume = self._to_volume(
+                   self.connection.request(self.path, params=params).object,
+                   name=name)
+        self.ex_create_tags(volume, {'Name': name})
+        return volume
+
+    def destroy_volume(self, volume):
+        params = {
+                'Action': 'DeleteVolume',
+                'VolumeId': volume.id }
+        response = self.connection.request(self.path, params=params).object
+        return self._get_boolean(response)
+
+    def attach_volume(self, node, volume, device):
+        params = {
+                'Action': 'AttachVolume',
+                'VolumeId': volume.id,
+                'InstanceId': node.id,
+                'Device': device }
+
+        self.connection.request(self.path, params=params)
+        return True
+
+    def detach_volume(self, volume):
+        params = {
+                'Action': 'DetachVolume',
+                'VolumeId': volume.id }
+
+        self.connection.request(self.path, params=params)
+        return True
+
     def ex_create_keypair(self, name):
         """Creates a new keypair
 
@@ -711,9 +761,9 @@ class EC2NodeDriver(NodeDriver):
 
         return availability_zones
 
-    def ex_describe_tags(self, node):
+    def ex_describe_tags(self, resource):
         """
-        Return a dictionary of tags for this instance.
+        Return a dictionary of tags for a resource (Node or StorageVolume).
 
         @type node: C{Node}
         @param node: Node instance
@@ -722,7 +772,7 @@ class EC2NodeDriver(NodeDriver):
         """
         params = {'Action': 'DescribeTags',
                   'Filter.0.Name': 'resource-id',
-                  'Filter.0.Value.0': node.id,
+                  'Filter.0.Value.0': resource.id,
                   'Filter.1.Name': 'resource-type',
                   'Filter.1.Value.0': 'instance',
                   }
@@ -740,12 +790,12 @@ class EC2NodeDriver(NodeDriver):
             tags[key] = value
         return tags
 
-    def ex_create_tags(self, node, tags):
+    def ex_create_tags(self, resource, tags):
         """
-        Create tags for an instance.
+        Create tags for a resource (Node or StorageVolume).
 
-        @type node: C{Node}
-        @param node: Node instance
+        @type resource: EC2 resource
+        @param resource: Resource to be tagged
         @param tags: A dictionary or other mapping of strings to strings,
                      associating tag names with tag values.
         """
@@ -753,7 +803,7 @@ class EC2NodeDriver(NodeDriver):
             return
 
         params = {'Action': 'CreateTags',
-                  'ResourceId.0': node.id}
+                  'ResourceId.0': resource.id}
         for i, key in enumerate(tags):
             params['Tag.%d.Key' % i] = key
             params['Tag.%d.Value' % i] = tags[key]
@@ -761,12 +811,12 @@ class EC2NodeDriver(NodeDriver):
         self.connection.request(self.path,
                                 params=params.copy()).object
 
-    def ex_delete_tags(self, node, tags):
+    def ex_delete_tags(self, resource, tags):
         """
-        Delete tags from an instance.
+        Delete tags from a resource.
 
-        @type node: C{Node}
-        @param node: Node instance
+        @type resource: EC2 resource
+        @param resource: Resource to be tagged
         @param tags: A dictionary or other mapping of strings to strings,
                      specifying the tag names and tag values to be deleted.
         """
@@ -774,7 +824,7 @@ class EC2NodeDriver(NodeDriver):
             return
 
         params = {'Action': 'DeleteTags',
-                  'ResourceId.0': node.id}
+                  'ResourceId.0': resource.id}
         for i, key in enumerate(tags):
             params['Tag.%d.Key' % i] = key
             params['Tag.%d.Value' % i] = tags[key]
@@ -1006,7 +1056,7 @@ class EC2NodeDriver(NodeDriver):
             tags = {'Name': kwargs['name']}
 
             try:
-                self.ex_create_tags(node=node, tags=tags)
+                self.ex_create_tags(resource=node, tags=tags)
             except Exception:
                 continue
 
@@ -1294,7 +1344,7 @@ class NimbusNodeDriver(EC2NodeDriver):
             nodes_elastic_ip_mappings[node.id] = []
         return nodes_elastic_ip_mappings
 
-    def ex_create_tags(self, node, tags):
+    def ex_create_tags(self, resource, tags):
         """
         Nimbus doesn't support creating tags, so this is a passthrough
         """

Added: libcloud/trunk/test/compute/fixtures/cloudstack/deleteVolume_default.json
URL: http://svn.apache.org/viewvc/libcloud/trunk/test/compute/fixtures/cloudstack/deleteVolume_default.json?rev=1351042&view=auto
==============================================================================
--- libcloud/trunk/test/compute/fixtures/cloudstack/deleteVolume_default.json (added)
+++ libcloud/trunk/test/compute/fixtures/cloudstack/deleteVolume_default.json Sun Jun 17 03:35:58
2012
@@ -0,0 +1 @@
+{ "deletevolumeresponse" : { "success" : "true"}  }

Added: libcloud/trunk/test/compute/fixtures/cloudstack/detachVolume_default.json
URL: http://svn.apache.org/viewvc/libcloud/trunk/test/compute/fixtures/cloudstack/detachVolume_default.json?rev=1351042&view=auto
==============================================================================
--- libcloud/trunk/test/compute/fixtures/cloudstack/detachVolume_default.json (added)
+++ libcloud/trunk/test/compute/fixtures/cloudstack/detachVolume_default.json Sun Jun 17 03:35:58
2012
@@ -0,0 +1 @@
+{ "detachvolumeresponse" : {"jobid":"detachvolumejob"} }

Added: libcloud/trunk/test/compute/fixtures/cloudstack/queryAsyncJobResult_detachvolumejob.json
URL: http://svn.apache.org/viewvc/libcloud/trunk/test/compute/fixtures/cloudstack/queryAsyncJobResult_detachvolumejob.json?rev=1351042&view=auto
==============================================================================
--- libcloud/trunk/test/compute/fixtures/cloudstack/queryAsyncJobResult_detachvolumejob.json
(added)
+++ libcloud/trunk/test/compute/fixtures/cloudstack/queryAsyncJobResult_detachvolumejob.json
Sun Jun 17 03:35:58 2012
@@ -0,0 +1 @@
+{ "queryasyncjobresultresponse" : {"accountid":"be7d76b3-8823-49c0-86e1-29efd9ea1eb0","userid":"a8bd3087-edc1-4e94-8470-6830404b7292","cmd":"com.cloud.api.commands.DetachVolumeCmd","jobstatus":1,"jobprocstatus":0,"jobresultcode":0,"jobresulttype":"object","jobresult":{"volume":{"id":"5931d2ca-4e90-4915-88a8-32b38b3991a3","name":"gre-test-volume","zoneid":"58624957-a150-46a3-acbf-4088776161e5","zonename":"EQ-AMS2-Z01","type":"DATADISK","size":10737418240,"created":"2012-06-15T14:56:40+0200","state":"Ready","account":"admin","domainid":"bfc35f83-8589-4e93-9150-d57e8479f772","domain":"ROOT","storagetype":"shared","hypervisor":"KVM","diskofferingid":"6345e3b7-227e-4209-8f8c-1f94219696e6","diskofferingname":"OS
disk for Windows","diskofferingdisplaytext":"OS disk for Windows","storage":"Shared Storage
CL01","destroyed":false,"isextractable":false}},"created":"2012-06-15T15:08:39+0200","jobid":"ca6c856d-1f36-4e27-989e-09cad2dad808"}
}

Added: libcloud/trunk/test/compute/fixtures/ec2/attach_volume.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/test/compute/fixtures/ec2/attach_volume.xml?rev=1351042&view=auto
==============================================================================
--- libcloud/trunk/test/compute/fixtures/ec2/attach_volume.xml (added)
+++ libcloud/trunk/test/compute/fixtures/ec2/attach_volume.xml Sun Jun 17 03:35:58 2012
@@ -0,0 +1,8 @@
+<AttachVolumeResponse xmlns="http://ec2.amazonaws.com/doc/2010-08-31/">
+  <requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
+  <volumeId>vol-4d826724</volumeId>
+  <instanceId>i-6058a509</instanceId>
+  <device>/dev/sdh</device>
+  <status>attaching</status>
+  <attachTime>2008-05-07T11:51:50.000Z</attachTime>
+</AttachVolumeResponse>

Added: libcloud/trunk/test/compute/fixtures/ec2/create_volume.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/test/compute/fixtures/ec2/create_volume.xml?rev=1351042&view=auto
==============================================================================
--- libcloud/trunk/test/compute/fixtures/ec2/create_volume.xml (added)
+++ libcloud/trunk/test/compute/fixtures/ec2/create_volume.xml Sun Jun 17 03:35:58 2012
@@ -0,0 +1,9 @@
+<CreateVolumeResponse xmlns="http://ec2.amazonaws.com/doc/2010-08-31/">
+  <requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId> 
+  <volumeId>vol-4d826724</volumeId>
+  <size>10</size>
+  <snapshotId/>
+  <availabilityZone>us-east-1a</availabilityZone>
+  <status>creating</status>
+  <createTime>2008-05-07T11:51:50.000Z</createTime>
+</CreateVolumeResponse>

Added: libcloud/trunk/test/compute/fixtures/ec2/delete_volume.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/test/compute/fixtures/ec2/delete_volume.xml?rev=1351042&view=auto
==============================================================================
--- libcloud/trunk/test/compute/fixtures/ec2/delete_volume.xml (added)
+++ libcloud/trunk/test/compute/fixtures/ec2/delete_volume.xml Sun Jun 17 03:35:58 2012
@@ -0,0 +1,4 @@
+<DeleteVolumeResponse xmlns="http://ec2.amazonaws.com/doc/2010-08-31/">
+  <requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId> 
+  <return>true</return>
+</DeleteVolumeResponse>

Added: libcloud/trunk/test/compute/fixtures/ec2/detach_volume.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/test/compute/fixtures/ec2/detach_volume.xml?rev=1351042&view=auto
==============================================================================
--- libcloud/trunk/test/compute/fixtures/ec2/detach_volume.xml (added)
+++ libcloud/trunk/test/compute/fixtures/ec2/detach_volume.xml Sun Jun 17 03:35:58 2012
@@ -0,0 +1,8 @@
+<DetachVolumeResponse xmlns="http://ec2.amazonaws.com/doc/2010-08-31/">
+  <requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId> 
+  <volumeId>vol-4d826724</volumeId>
+  <instanceId>i-6058a509</instanceId>
+  <device>/dev/sdh</device>
+  <status>detaching</status>
+  <attachTime>2008-05-08T11:51:50.000Z</attachTime>
+</DetachVolumeResponse>

Modified: libcloud/trunk/test/compute/test_cloudstack.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/test/compute/test_cloudstack.py?rev=1351042&r1=1351041&r2=1351042&view=diff
==============================================================================
--- libcloud/trunk/test/compute/test_cloudstack.py (original)
+++ libcloud/trunk/test/compute/test_cloudstack.py Sun Jun 17 03:35:58 2012
@@ -73,16 +73,16 @@ class CloudStackNodeDriverTest(unittest.
         self.assertEquals('Disk offer 1', diskOffering.name)
         self.assertEquals(10, diskOffering.size)
 
-    def test_ex_create_volume(self):
+    def test_create_volume(self):
         volumeName = 'vol-0'
         location = self.driver.list_locations()[0]
 
-        volume = self.driver.ex_create_volume(
-                                volumeName, location, size=10)
+        volume = self.driver.create_volume(10, volumeName, location)
 
         self.assertEquals(volumeName, volume.name)
+        self.assertEquals(10, volume.size)
 
-    def test_ex_create_volume_no_noncustomized_offering_with_size(self):
+    def test_create_volume_no_noncustomized_offering_with_size(self):
         """If the sizes of disk offerings are not configurable and there
         are no disk offerings with the requested size, an exception should
         be thrown."""
@@ -91,30 +91,26 @@ class CloudStackNodeDriverTest(unittest.
 
         self.assertRaises(
                 LibcloudError,
-                self.driver.ex_create_volume,
+                self.driver.create_volume,
                     'vol-0', location, 11)
 
-    def test_ex_create_volume_with_custom_disk_size_offering(self):
-
+    def test_create_volume_with_custom_disk_size_offering(self):
         CloudStackMockHttp.fixture_tag = 'withcustomdisksize'
 
         volumeName = 'vol-0'
         location = self.driver.list_locations()[0]
 
-        volume = self.driver.ex_create_volume(
-                                volumeName, location, size=11)
+        volume = self.driver.create_volume(10, volumeName, location)
 
         self.assertEquals(volumeName, volume.name)
 
-    def test_ex_attach_volume(self):
+    def test_attach_volume(self):
         node = self.driver.list_nodes()[0]
         volumeName = 'vol-0'
         location = self.driver.list_locations()[0]
 
-        volume = self.driver.ex_create_volume(
-                                volumeName, location, 10)
-
-        attachReturnVal = self.driver.ex_attach_volume(volume, node)
+        volume = self.driver.create_volume(10, volumeName, location)
+        attachReturnVal = self.driver.attach_volume(volume, node)
 
         self.assertTrue(attachReturnVal)
 

Modified: libcloud/trunk/test/compute/test_ec2.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/test/compute/test_ec2.py?rev=1351042&r1=1351041&r2=1351042&view=diff
==============================================================================
--- libcloud/trunk/test/compute/test_ec2.py (original)
+++ libcloud/trunk/test/compute/test_ec2.py Sun Jun 17 03:35:58 2012
@@ -22,6 +22,7 @@ from libcloud.compute.drivers.ec2 import
 from libcloud.compute.drivers.ec2 import EC2APNENodeDriver
 from libcloud.compute.drivers.ec2 import IdempotentParamError
 from libcloud.compute.base import Node, NodeImage, NodeSize, NodeLocation
+from libcloud.compute.base import StorageVolume
 
 from test import MockHttp, LibcloudTestCase
 from test.compute import TestCaseMixin
@@ -211,7 +212,7 @@ class EC2Tests(LibcloudTestCase, TestCas
 
     def test_ex_describe_tags(self):
         node = Node('i-4382922a', None, None, None, None, self.driver)
-        tags = self.driver.ex_describe_tags(node)
+        tags = self.driver.ex_describe_tags(resource=node)
 
         self.assertEqual(len(tags), 3)
         self.assertTrue('tag' in tags)
@@ -293,6 +294,39 @@ class EC2Tests(LibcloudTestCase, TestCas
         result = self.driver.ex_change_node_size(node=node, new_size=size)
         self.assertTrue(result)
 
+    def test_create_volume(self):
+        location = self.driver.list_locations()[0]
+        vol = self.driver.create_volume(10, 'vol', location)
+
+        self.assertEquals(10, vol.size)
+        self.assertEquals('vol', vol.name)
+
+    def test_destroy_volume(self):
+        vol = StorageVolume(
+                    id='vol-4282672b', name='test',
+                    size=10, driver=self.driver)
+
+        retValue = self.driver.destroy_volume(vol)
+        self.assertTrue(retValue)
+
+    def test_attach(self):
+        vol = StorageVolume(
+                    id='vol-4282672b', name='test',
+                    size=10, driver=self.driver)
+
+        node = Node('i-4382922a', None, None, None, None, self.driver)
+        retValue = self.driver.attach_volume(node, vol, '/dev/sdh')
+
+        self.assertTrue(retValue)
+
+    def test_detach(self):
+        vol = StorageVolume(
+                    id='vol-4282672b', name='test',
+                    size=10, driver=self.driver)
+
+        retValue = self.driver.detach_volume(vol)
+        self.assertTrue(retValue)
+
 
 class EC2MockHttp(MockHttp):
 
@@ -378,6 +412,22 @@ class EC2MockHttp(MockHttp):
         body = self.fixtures.load('create_tags.xml')
         return (httplib.OK, body, {}, httplib.responses[httplib.OK])
 
+    def _CreateVolume(self, method, url, body, headers):
+        body = self.fixtures.load('create_volume.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _DeleteVolume(self, method, url, body, headers):
+        body = self.fixtures.load('delete_volume.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _AttachVolume(self, method, url, body, headers):
+        body = self.fixtures.load('attach_volume.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _DetachVolume(self, method, url, body, headers):
+        body = self.fixtures.load('detach_volume.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
 
 class EucMockHttp(EC2MockHttp):
     fixtures = ComputeFileFixtures('ec2')
@@ -479,7 +529,7 @@ class NimbusTests(EC2Tests):
         # Nimbus doesn't support creating tags so this one should be a
         # passthrough
         node = self.driver.list_nodes()[0]
-        self.driver.ex_create_tags(node=node, tags={'foo': 'bar'})
+        self.driver.ex_create_tags(resource=node, tags={'foo': 'bar'})
         self.assertExecutedMethodCount(0)
 
 



Mime
View raw message