You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by to...@apache.org on 2014/02/06 21:14:04 UTC
[3/6] git commit: LIBCLOUD-512: Added snapshot lifecycle support and
fixture tests to support snapshot listing, creation and deletion.
LIBCLOUD-512: Added snapshot lifecycle support and fixture tests to support snapshot listing, creation and deletion.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/b064453d
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/b064453d
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/b064453d
Branch: refs/heads/trunk
Commit: b064453d8eb7db5fe673288c0d5dab62fe27e8cf
Parents: 8e36cb5
Author: Chris DeRamus <ch...@divvycloud.com>
Authored: Tue Feb 4 08:59:44 2014 -0500
Committer: Chris DeRamus <ch...@divvycloud.com>
Committed: Thu Feb 6 07:51:43 2014 -0500
----------------------------------------------------------------------
libcloud/compute/drivers/openstack.py | 81 +++++++++++++++++++-
.../fixtures/openstack_v1.1/_os_snapshots.json | 22 ++++++
.../openstack_v1.1/_os_snapshots_create.json | 11 +++
libcloud/test/compute/test_openstack.py | 38 +++++++++
4 files changed, 151 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/b064453d/libcloud/compute/drivers/openstack.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/openstack.py b/libcloud/compute/drivers/openstack.py
index db5c7f1..8e28759 100644
--- a/libcloud/compute/drivers/openstack.py
+++ b/libcloud/compute/drivers/openstack.py
@@ -35,7 +35,8 @@ from libcloud.common.openstack import OpenStackBaseConnection
from libcloud.common.openstack import OpenStackDriverMixin
from libcloud.common.types import MalformedResponseError, ProviderError
from libcloud.compute.base import NodeSize, NodeImage
-from libcloud.compute.base import NodeDriver, Node, NodeLocation, StorageVolume
+from libcloud.compute.base import (NodeDriver, Node, NodeLocation,
+ StorageVolume, VolumeSnapshot)
from libcloud.compute.base import KeyPair
from libcloud.compute.types import NodeState, Provider
from libcloud.compute.types import KeyPairDoesNotExistError
@@ -1275,6 +1276,10 @@ class OpenStack_1_1_NodeDriver(OpenStackNodeDriver):
volumes = obj['volumes']
return [self._to_volume(volume) for volume in volumes]
+ def _to_snapshots(self, obj):
+ snapshots = obj['snapshots']
+ return [self._to_snapshot(snapshot) for snapshot in snapshots]
+
def _to_sizes(self, obj):
flavors = obj['flavors']
return [self._to_size(flavor) for flavor in flavors]
@@ -1597,6 +1602,49 @@ class OpenStack_1_1_NodeDriver(OpenStackNodeDriver):
method='POST', data=data).object
return resp
+ def ex_list_snapshots(self):
+ return self._to_snapshots(
+ self.connection.request('/os-snapshots').object)
+
+ def ex_create_snapshot(self, volume, name, description=None, force=False):
+ """
+ Create a snapshot based off of a volume.
+
+ :param node: volume
+ :type node: :class:`StorageVolume`
+
+ :keyword name: New name for the volume snapshot
+ :type name: ``str``
+
+ :keyword description: Description of the snapshot (optional)
+ :type description: ``str``
+
+ :keyword force: Whether to force creation (optional)
+ :type force: ``bool``
+
+ :rtype: :class:`VolumeSnapshot`
+ """
+ data = {'snapshot': {'display_name': name,
+ 'display_description': description,
+ 'volume_id': volume.id,
+ 'force': force}}
+
+ return self._to_snapshot(self.connection.request('/os-snapshots',
+ method='POST',
+ data=data).object)
+
+ def ex_delete_snapshot(self, snapshot):
+ """
+ Delete a VolumeSnapshot
+
+ :param node: snapshot
+ :type node: :class:`VolumeSnapshot`
+
+ :rtype: ``bool``
+ """
+ return self.connection.request('/os-snapshots/%s' % snapshot.id,
+ method='DELETE').success()
+
def _to_security_group_rules(self, obj):
return [self._to_security_group_rule(security_group_rule) for
security_group_rule in obj]
@@ -1983,6 +2031,37 @@ class OpenStack_1_1_NodeDriver(OpenStackNodeDriver):
}
)
+ def _to_snapshot(self, api_node):
+ if 'snapshot' in api_node:
+ api_node = api_node['snapshot']
+
+ # RackSpace vs. OpenStack
+ if 'displayName' in api_node:
+ return VolumeSnapshot(
+ id=api_node['id'],
+ driver=self,
+ size=api_node['size'],
+ extra={
+ 'volume_id': api_node['volumeId'],
+ 'name': api_node['displayName'],
+ 'created': api_node['createdAt'],
+ 'description': api_node['displayDescription'],
+ 'status': api_node['status'],
+ })
+
+ else:
+ return VolumeSnapshot(
+ id=api_node['id'],
+ driver=self,
+ size=api_node['size'],
+ extra={
+ 'volume_id': api_node['volume_id'],
+ 'name': api_node['display_name'],
+ 'created': api_node['created_at'],
+ 'description': api_node['display_description'],
+ 'status': api_node['status'],
+ })
+
def _to_size(self, api_flavor, price=None, bandwidth=None):
# if provider-specific subclasses can get better values for
# price/bandwidth, then can pass them in when they super().
http://git-wip-us.apache.org/repos/asf/libcloud/blob/b064453d/libcloud/test/compute/fixtures/openstack_v1.1/_os_snapshots.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/openstack_v1.1/_os_snapshots.json b/libcloud/test/compute/fixtures/openstack_v1.1/_os_snapshots.json
new file mode 100644
index 0000000..032b553
--- /dev/null
+++ b/libcloud/test/compute/fixtures/openstack_v1.1/_os_snapshots.json
@@ -0,0 +1,22 @@
+{
+ "snapshots": [
+ {
+ "id": "3fbbcccf-d058-4502-8844-6feeffdf4cb5",
+ "display_name": "snap-001",
+ "display_description": "Daily backup",
+ "volume_id": "521752a6-acf6-4b2d-bc7a-119f9148cd8c",
+ "status": "available",
+ "size": 30,
+ "created_at": "2012-02-29T03:50:07Z"
+ },
+ {
+ "id": "e479997c-650b-40a4-9dfe-77655818b0d2",
+ "display_name": "snap-002",
+ "display_description": "Weekly backup",
+ "volume_id": "76b8950a-8594-4e5b-8dce-0dfa9c696358",
+ "status": "available",
+ "size": 25,
+ "created_at": "2012-03-19T01:52:47Z"
+ }
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/b064453d/libcloud/test/compute/fixtures/openstack_v1.1/_os_snapshots_create.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/openstack_v1.1/_os_snapshots_create.json b/libcloud/test/compute/fixtures/openstack_v1.1/_os_snapshots_create.json
new file mode 100644
index 0000000..e1059b5
--- /dev/null
+++ b/libcloud/test/compute/fixtures/openstack_v1.1/_os_snapshots_create.json
@@ -0,0 +1,11 @@
+{
+ "snapshot": {
+ "id": "3fbbcccf-d058-4502-8844-6feeffdf4cb5",
+ "display_name": "snap-001",
+ "display_description": "Daily backup",
+ "volume_id": "521752a6-acf6-4b2d-bc7a-119f9148cd8c",
+ "status": "available",
+ "size": 30,
+ "created_at": "2012-02-29T03:50:07Z"
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/b064453d/libcloud/test/compute/test_openstack.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_openstack.py b/libcloud/test/compute/test_openstack.py
index a249dfc..3b6c65f 100644
--- a/libcloud/test/compute/test_openstack.py
+++ b/libcloud/test/compute/test_openstack.py
@@ -1533,6 +1533,23 @@ class OpenStack_1_1_Tests(unittest.TestCase, TestCaseMixin):
expected_output = 'FAKE CONSOLE OUTPUT\nANOTHER\nLAST LINE'
self.assertEqual(resp['output'], expected_output)
+ def test_ex_list_snapshots(self):
+ snapshots = self.driver.ex_list_snapshots()
+ self.assertEqual(len(snapshots), 2)
+ self.assertEqual(snapshots[0].extra['name'], 'snap-001')
+
+ def test_ex_create_snapshot(self):
+ volume = self.driver.list_volumes()[0]
+ ret = self.driver.ex_create_snapshot(volume,
+ 'Test Volume',
+ 'This is a test')
+ self.assertEqual(ret.id, '3fbbcccf-d058-4502-8844-6feeffdf4cb5')
+
+ def test_ex_delete_snapshot(self):
+ snapshot = self.driver.ex_list_snapshots()[0]
+ ret = self.driver.ex_delete_snapshot(snapshot)
+ self.assertTrue(ret is True)
+
class OpenStack_1_1_FactoryMethodTests(OpenStack_1_1_Tests):
should_list_locations = False
@@ -1871,6 +1888,7 @@ class OpenStack_1_1_MockHttp(MockHttpTestCase):
return (httplib.OK, body, self.json_content_headers, httplib.responses[httplib.OK])
+<<<<<<< HEAD
def _v1_1_slug_servers_12086_action(self, method, url, body, headers):
if method == "POST":
body = self.fixtures.load('_servers_12086_console_output.json')
@@ -1878,6 +1896,26 @@ class OpenStack_1_1_MockHttp(MockHttpTestCase):
else:
raise NotImplementedError()
+=======
+ def _v1_1_slug_os_snapshots(self, method, url, body, headers):
+ if method == "GET":
+ body = self.fixtures.load('_os_snapshots.json')
+ elif method == "POST":
+ body = self.fixtures.load('_os_snapshots_create.json')
+ else:
+ raise NotImplementedError()
+
+ return (httplib.OK, body, self.json_content_headers, httplib.responses[httplib.OK])
+
+ def _v1_1_slug_os_snapshots_3fbbcccf_d058_4502_8844_6feeffdf4cb5(self, method, url, body, headers):
+ if method == "DELETE":
+ body = ''
+ else:
+ raise NotImplementedError()
+
+ return (httplib.OK, body, self.json_content_headers, httplib.responses[httplib.OK])
+
+>>>>>>> LIBCLOUD-512: Added snapshot lifecycle support and fixture tests to support snapshot listing, creation and deletion.
# This exists because the nova compute url in devstack has v2 in there but the v1.1 fixtures
# work fine.