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/01/13 00:10:35 UTC
[1/3] git commit: Issue LIBCLOUD-494: Add extension methods to
support additional EC2 image calls. The first is ex_copy_image which is used
to copy Amazon Machine Images between regions and the second is
ex_create_image which can be used to create an AMI
Updated Branches:
refs/heads/trunk edaff3f8d -> c3c90ac53
Issue LIBCLOUD-494: Add extension methods to support additional EC2 image
calls. The first is ex_copy_image which is used to copy Amazon Machine
Images between regions and the second is ex_create_image which can be
used to create an AMI from an EBS backed instance.
Closes #222.
Signed-off-by: Tomaz Muraus <to...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/b81a63a8
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/b81a63a8
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/b81a63a8
Branch: refs/heads/trunk
Commit: b81a63a88f11bd0fe1105be3868c915c69faba45
Parents: edaff3f
Author: Chris DeRamus <ch...@divvycloud.com>
Authored: Sun Jan 12 14:55:16 2014 -0500
Committer: Tomaz Muraus <to...@apache.org>
Committed: Sun Jan 12 23:53:23 2014 +0100
----------------------------------------------------------------------
libcloud/compute/drivers/ec2.py | 132 +++++++++++++++++--
.../test/compute/fixtures/ec2/copy_image.xml | 4 +
.../test/compute/fixtures/ec2/create_image.xml | 4 +
libcloud/test/compute/test_ec2.py | 30 +++++
4 files changed, 158 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/b81a63a8/libcloud/compute/drivers/ec2.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/ec2.py b/libcloud/compute/drivers/ec2.py
index a226f88..176d450 100644
--- a/libcloud/compute/drivers/ec2.py
+++ b/libcloud/compute/drivers/ec2.py
@@ -1339,18 +1339,8 @@ class BaseEC2NodeDriver(NodeDriver):
params['ClientToken'] = kwargs['ex_clienttoken']
if 'ex_blockdevicemappings' in kwargs:
- if not isinstance(kwargs['ex_blockdevicemappings'], (list, tuple)):
- raise AttributeError(
- 'ex_blockdevicemappings not list or tuple')
-
- for idx, mapping in enumerate(kwargs['ex_blockdevicemappings']):
- idx += 1 # we want 1-based indexes
- if not isinstance(mapping, dict):
- raise AttributeError(
- 'mapping %s in ex_blockdevicemappings '
- 'not a dict' % mapping)
- for k, v in mapping.items():
- params['BlockDeviceMapping.%d.%s' % (idx, k)] = str(v)
+ params.update(self._get_block_device_mapping_params(
+ kwargs['ex_blockdevicemappings']))
if 'ex_iamprofile' in kwargs:
if not isinstance(kwargs['ex_iamprofile'], basestring):
@@ -1566,6 +1556,91 @@ class BaseEC2NodeDriver(NodeDriver):
namespace=NAMESPACE)
return element == 'true'
+ def ex_copy_image(self, source_region, image, name=None, description=None):
+ """
+ Copy an Amazon Machine Image from the specified source region
+ to the current region.
+
+ :param source_region: The region where the image resides
+ :type source_region: ``str``
+
+ :param image: Instance of class NodeImage
+ :type image: :class:`NodeImage`
+
+ :param name: The name of the new image
+ :type name: ``str``
+
+ :param description: The description of the new image
+ :type description: ``str``
+
+ :return: Instance of class ``NodeImage``
+ :rtype: :class:`NodeImage`
+ """
+ params = {'Action': 'CopyImage',
+ 'SourceRegion': source_region,
+ 'SourceImageId': image.id}
+
+ if name is not None:
+ params['Name'] = name
+
+ if description is not None:
+ params['Description'] = description
+
+ image = self._to_image(
+ self.connection.request(self.path, params=params).object)
+
+ return image
+
+ def ex_create_image_from_node(self, node, name, block_device_mapping,
+ reboot=False, description=None):
+ """
+ Create an Amazon Machine Image based off of an EBS-backed instance.
+
+ :param node: Instance of ``Node``
+ :type node: :class: `Node`
+
+ :param name: The name for the new image
+ :type name: ``str``
+
+ :param block_device_mapping: A dictionary of the disk layout
+ An example of this dict is included
+ below.
+ :type block_device_mapping: ``list`` of ``dict``
+
+ :param reboot: Whether or not to shutdown the instance before
+ creation. By default Amazon sets this to false
+ to ensure a clean image.
+ :type reboot: ``bool``
+
+ :param description: An optional description for the new image
+ :type description: ``str``
+
+ @note An example block device mapping dictionary is included:
+ mapping = [{'VirtualName': None,
+ 'Ebs': {'VolumeSize': 10,
+ 'VolumeType': 'standard',
+ 'DeleteOnTermination': 'true'},
+ 'DeviceName': '/dev/sda1'}]
+
+ :return: Instance of class ``NodeImage``
+ :rtype: :class:`NodeImage`
+ """
+ params = {'Action': 'CreateImage',
+ 'InstanceId': node.id,
+ 'Name': name,
+ 'Reboot': reboot}
+
+ if description is not None:
+ params['Description'] = description
+
+ params.update(self._get_block_device_mapping_params(
+ block_device_mapping))
+
+ image = self._to_image(
+ self.connection.request(self.path, params=params).object)
+
+ return image
+
def ex_destroy_image(self, image):
params = {
'Action': 'DeregisterImage',
@@ -3447,6 +3522,39 @@ class BaseEC2NodeDriver(NodeDriver):
return tags
+ def _get_block_device_mapping_params(self, block_device_mapping):
+ """
+ Return a list of dictionaries with query parameters for
+ a valid block device mapping.
+
+ :param mapping: List of dictionaries with the drive layout
+ :type mapping: ``list`` or ``dict``
+
+ :return: Dictionary representation of the drive mapping
+ :rtype: ``dict``
+ """
+
+ if not isinstance(block_device_mapping, (list, tuple)):
+ raise AttributeError(
+ 'block_device_mapping not list or tuple')
+
+ params = {}
+
+ for idx, mapping in enumerate(block_device_mapping):
+ idx += 1 # We want 1-based indexes
+ if not isinstance(mapping, dict):
+ raise AttributeError(
+ 'mapping %s in block_device_mapping '
+ 'not a dict' % mapping)
+ for k, v in mapping.items():
+ if not isinstance(v, dict):
+ params['BlockDeviceMapping.%d.%s' % (idx, k)] = str(v)
+ else:
+ for key, value in v.items():
+ params['BlockDeviceMapping.%d.%s.%s'
+ % (idx, k, key)] = str(value)
+ return params
+
def _get_common_security_group_params(self, group_id, protocol,
from_port, to_port, cidr_ips,
group_pairs):
http://git-wip-us.apache.org/repos/asf/libcloud/blob/b81a63a8/libcloud/test/compute/fixtures/ec2/copy_image.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/ec2/copy_image.xml b/libcloud/test/compute/fixtures/ec2/copy_image.xml
new file mode 100644
index 0000000..f2e76b0
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ec2/copy_image.xml
@@ -0,0 +1,4 @@
+<CopyImageResponse xmlns="http://ec2.amazonaws.com/doc/2013-10-15/">
+ <requestId>7b7d87d5-c045-4c2c-a2c4-b538debe14b2</requestId>
+ <imageId>ami-4db38224</imageId>
+</CopyImageResponse>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/b81a63a8/libcloud/test/compute/fixtures/ec2/create_image.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/ec2/create_image.xml b/libcloud/test/compute/fixtures/ec2/create_image.xml
new file mode 100644
index 0000000..1213f0a
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ec2/create_image.xml
@@ -0,0 +1,4 @@
+<CreateImageResponse xmlns="http://ec2.amazonaws.com/doc/2013-10-15/">
+ <requestId>3629ec66-c1f8-4b66-aac5-a8ad1cdf6c15</requestId>
+ <imageId>ami-e9b38280</imageId>
+</CreateImageResponse>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/b81a63a8/libcloud/test/compute/test_ec2.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_ec2.py b/libcloud/test/compute/test_ec2.py
index d86af68..e0af93d 100644
--- a/libcloud/test/compute/test_ec2.py
+++ b/libcloud/test/compute/test_ec2.py
@@ -442,6 +442,28 @@ class EC2Tests(LibcloudTestCase, TestCaseMixin):
self.assertEqual(len(images), 2)
+ def test_ex_copy_image(self):
+ image = self.driver.list_images()[0]
+ resp = self.driver.ex_copy_image('us-east-1', image,
+ name='Faux Image',
+ description='Test Image Copy')
+ self.assertEqual(resp.id, 'ami-4db38224')
+
+ def test_ex_create_image_from_node(self):
+ node = self.driver.list_nodes()[0]
+
+ mapping = [{'VirtualName': None,
+ 'Ebs': {'VolumeSize': 10,
+ 'VolumeType': 'standard',
+ 'DeleteOnTermination': 'true'},
+ 'DeviceName': '/dev/sda1'}]
+
+ resp = self.driver.ex_create_image_from_node(node,
+ 'New Image',
+ mapping,
+ description='New EBS Image')
+ self.assertEqual(resp.id, 'ami-e9b38280')
+
def ex_destroy_image(self):
images = self.driver.list_images()
image = images[0]
@@ -1222,6 +1244,14 @@ class EC2MockHttp(MockHttpTestCase):
body = self.fixtures.load('delete_snapshot.xml')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+ def _CopyImage(self, method, url, body, headers):
+ body = self.fixtures.load('copy_image.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+ def _CreateImage(self, method, url, body, headers):
+ body = self.fixtures.load('create_image.xml')
+ return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
def _DeregisterImage(self, method, url, body, headers):
body = self.fixtures.load('deregister_image.xml')
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
[3/3] git commit: Update CHANGES.
Posted by to...@apache.org.
Update CHANGES.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/c3c90ac5
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/c3c90ac5
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/c3c90ac5
Branch: refs/heads/trunk
Commit: c3c90ac534ea22418d82abeb825caaeaee111a8f
Parents: 457da9f
Author: Tomaz Muraus <to...@apache.org>
Authored: Mon Jan 13 00:06:51 2014 +0100
Committer: Tomaz Muraus <to...@apache.org>
Committed: Mon Jan 13 00:06:51 2014 +0100
----------------------------------------------------------------------
CHANGES | 4 ++++
1 file changed, 4 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/c3c90ac5/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 9a22b3f..df07e91 100644
--- a/CHANGES
+++ b/CHANGES
@@ -192,6 +192,10 @@ Changes with Apache Libcloud in development
the Node object in the EC2 driver. (LIBCLOUD-493, GITHUB-221)
[Chris DeRamus]
+ - Add ex_copy_image and ex_create_image_from_node method to the EC2 driver.
+ (LIBCLOUD-494, GITHUB-222)
+ [Chris DeRamus]
+
*) Storage
- Allow user to specify 'Content-Disposition' header in the CloudFiles
[2/3] git commit: Fix docstring issue which caused failed
documentation build.
Posted by to...@apache.org.
Fix docstring issue which caused failed documentation build.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/457da9fb
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/457da9fb
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/457da9fb
Branch: refs/heads/trunk
Commit: 457da9fb75f03431c6993b2c6270abcbbe9e42f9
Parents: b81a63a
Author: Tomaz Muraus <to...@apache.org>
Authored: Mon Jan 13 00:01:58 2014 +0100
Committer: Tomaz Muraus <to...@apache.org>
Committed: Mon Jan 13 00:01:58 2014 +0100
----------------------------------------------------------------------
libcloud/compute/drivers/ec2.py | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/457da9fb/libcloud/compute/drivers/ec2.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/ec2.py b/libcloud/compute/drivers/ec2.py
index 176d450..164fd88 100644
--- a/libcloud/compute/drivers/ec2.py
+++ b/libcloud/compute/drivers/ec2.py
@@ -1615,12 +1615,13 @@ class BaseEC2NodeDriver(NodeDriver):
:param description: An optional description for the new image
:type description: ``str``
- @note An example block device mapping dictionary is included:
- mapping = [{'VirtualName': None,
- 'Ebs': {'VolumeSize': 10,
- 'VolumeType': 'standard',
- 'DeleteOnTermination': 'true'},
- 'DeviceName': '/dev/sda1'}]
+ An example block device mapping dictionary is included:
+
+ mapping = [{'VirtualName': None,
+ 'Ebs': {'VolumeSize': 10,
+ 'VolumeType': 'standard',
+ 'DeleteOnTermination': 'true'},
+ 'DeviceName': '/dev/sda1'}]
:return: Instance of class ``NodeImage``
:rtype: :class:`NodeImage`