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)