Author: tomaz
Date: Fri Jun 8 21:31:25 2012
New Revision: 1348250
URL: http://svn.apache.org/viewvc?rev=1348250&view=rev
Log:
Add docstrings to Joyent driver. Contributed by Ben Rockwood part of GH-66.
Modified:
libcloud/trunk/libcloud/compute/drivers/cloudstack.py
libcloud/trunk/libcloud/compute/drivers/joyent.py
libcloud/trunk/test/compute/test_cloudstack.py
Modified: libcloud/trunk/libcloud/compute/drivers/cloudstack.py
URL:
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/compute/drivers/cloudstack.py?rev=1348250&r1=1348249&r2=1348250&view=diff
==============================================================================
--- libcloud/trunk/libcloud/compute/drivers/cloudstack.py (original)
+++ libcloud/trunk/libcloud/compute/drivers/cloudstack.py Fri Jun 8 21:31:25
2012
@@ -78,6 +78,31 @@ class CloudStackForwardingRule(object):
return self.__class__ is other.__class__ and self.id == other.id
+class CloudStackDiskOffering(object):
+ """A disk offering within CloudStack."""
+
+ def __init__(self, id, name, size, customizable):
+ self.id = id
+ self.name = name
+ self.size = size
+ self.customizable = customizable
+
+ 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.
@@ -200,6 +225,7 @@ class CloudStackNodeDriver(CloudStackDri
0, self))
return sizes
+
def create_node(self, name, size, image, location=None, **kwargs):
extra_args = {}
if location is None:
@@ -247,6 +273,58 @@ class CloudStackNodeDriver(CloudStackDri
self._async_request('rebootVirtualMachine', id=node.id)
return True
+ def ex_list_disk_offerings(self):
+ """Fetch a list of all available disk offerings."""
+
+ diskOfferings = []
+
+ diskOfferResponse = self._sync_request('listDiskOfferings')
+ for diskOfferDict in diskOfferResponse.get('diskoffering', ()):
+ diskOfferings.append(
+ CloudStackDiskOffering(
+ id=diskOfferDict['id'],
+ name=diskOfferDict['name'],
+ size=diskOfferDict['disksize'],
+ customizable=diskOfferDict['iscustomized']))
+
+ return diskOfferings
+
+ def ex_create_volume(self, name, location, size):
+ """Create a new detached storage volume."""
+
+ 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)
+
+ extraParams = dict()
+ if diskOffering.customizable:
+ extraParams['size'] = size
+
+ requestResult = self._async_request('createVolume',
+ name=name,
+ diskOfferingId=diskOffering.id,
+ zoneId=location.id,
+ **extraParams)
+
+ 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"""
+
+ self._async_request('attachVolume',
+ id=volume.id,
+ virtualMachineId=node.id)
+ return True
+
+
def ex_allocate_public_ip(self, node):
"Allocate a public IP and bind it to a node."
Modified: libcloud/trunk/libcloud/compute/drivers/joyent.py
URL:
http://svn.apache.org/viewvc/libcloud/trunk/libcloud/compute/drivers/joyent.py?rev=1348250&r1=1348249&r2=1348250&view=diff
==============================================================================
--- libcloud/trunk/libcloud/compute/drivers/joyent.py (original)
+++ libcloud/trunk/libcloud/compute/drivers/joyent.py Fri Jun 8 21:31:25 2012
@@ -13,6 +13,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+"""
+Joyent Cloud (http://www.joyentcloud.com) driver.
+"""
+
import base64
try:
@@ -47,6 +51,10 @@ DEFAULT_LOCATION = LOCATIONS[0]
class JoyentResponse(JsonResponse):
+ """
+ Joyent response class.
+ """
+
valid_response_codes = [httplib.OK, httplib.ACCEPTED, httplib.CREATED,
httplib.NO_CONTENT]
@@ -61,6 +69,10 @@ class JoyentResponse(JsonResponse):
class JoyentConnection(ConnectionUserAndKey):
+ """
+ Joyent connection class.
+ """
+
responseCls = JoyentResponse
def add_default_headers(self, headers):
@@ -74,6 +86,10 @@ class JoyentConnection(ConnectionUserAnd
class JoyentNodeDriver(NodeDriver):
+ """
+ Joyent node driver class.
+ """
+
type = Provider.JOYENT
name = 'Joyent'
connectionCls = JoyentConnection
Modified: libcloud/trunk/test/compute/test_cloudstack.py
URL:
http://svn.apache.org/viewvc/libcloud/trunk/test/compute/test_cloudstack.py?rev=1348250&r1=1348249&r2=1348250&view=diff
==============================================================================
--- libcloud/trunk/test/compute/test_cloudstack.py (original)
+++ libcloud/trunk/test/compute/test_cloudstack.py Fri Jun 8 21:31:25 2012
@@ -16,7 +16,7 @@ except AttributeError:
parse_qsl = cgi.parse_qsl
from libcloud.compute.drivers.cloudstack import CloudStackNodeDriver
-from libcloud.compute.types import DeploymentError
+from libcloud.compute.types import DeploymentError, LibcloudError
from test import MockHttpTestCase
from test.compute import TestCaseMixin
@@ -64,6 +64,63 @@ class CloudStackNodeDriverTest(unittest.
images = self.driver.list_images()
self.assertEquals(0, len(images))
+
+ def test_ex_list_disk_offerings(self):
+ diskOfferings = self.driver.ex_list_disk_offerings()
+ self.assertEquals(1, len(diskOfferings))
+
+ diskOffering, = diskOfferings
+
+ self.assertEquals('Disk offer 1', diskOffering.name)
+ self.assertEquals(10, diskOffering.size)
+
+
+ def test_ex_create_volume(self):
+ volumeName = 'vol-0'
+ location = self.driver.list_locations()[0]
+
+ volume = self.driver.ex_create_volume(
+ volumeName, location, size=10)
+
+ self.assertEquals(volumeName, volume.name)
+
+ def test_ex_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."""
+
+ location = self.driver.list_locations()[0]
+
+ self.assertRaises(
+ LibcloudError,
+ self.driver.ex_create_volume,
+ 'vol-0', location, 11)
+
+ def test_ex_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)
+
+ self.assertEquals(volumeName, volume.name)
+
+ def test_ex_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)
+
+ self.assertTrue(attachReturnVal)
+
+
class CloudStackMockHttp(MockHttpTestCase):
fixtures = ComputeFileFixtures('cloudstack')
fixture_tag = 'default'