Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions libcloud/compute/drivers/gce.py
Original file line number Diff line number Diff line change
Expand Up @@ -1133,6 +1133,67 @@ def ex_create_forwarding_rule(self, name, targetpool, region=None,

return self.ex_get_forwarding_rule(name)

def ex_create_image(self, name, volume, description=None,
use_existing=True, wait_for_completion=True):
"""
Create an image from the provided volume.

:param name: The name of the image to create.
:type name: ``str``

:param volume: The volume to use to create the image, or the
Google Cloud Storage URI
:type volume: ``str`` or :class:`StorageVolume`

:keyword description: Description of the new Image
:type description: ``str``

:keyword use_existing: If True and an image with the given name
already exists, return an object for that
image instead of attempting to create
a new image.
:type use_existing: ``bool``

:keyword wait_for_completion: If True, wait until the new image is
created before returning a new NodeImage
Otherwise, return a new NodeImage
instance, and let the user track the
creation progress
:type wait_for_completion: ``bool``

:return: A GCENodeImage object for the new image
:rtype: :class:`GCENodeImage`

"""
image_data = {}
image_data['name'] = name
image_data['description'] = description
if isinstance(volume, StorageVolume):
image_data['sourceDisk'] = volume.extra['selfLink']
image_data['zone'] = volume.extra['zone'].name
elif isinstance(volume, str) and \
volume.startswith('https://') and volume.endswith('tar.gz'):
image_data['rawDisk'] = {'source': volume, 'containerType': 'TAR'}
else:
raise ValueError('Source must be instance of StorageVolume or URI')

request = '/global/images'

try:
if wait_for_completion:
self.connection.async_request(request, method='POST',
data=image_data)
else:
self.connection.request(request, method='POST',
data=image_data)

except ResourceExistsError:
e = sys.exc_info()[1]
if not use_existing:
raise e

return self.ex_get_image(name)

def ex_create_network(self, name, cidr):
"""
Create a network.
Expand Down Expand Up @@ -3225,6 +3286,7 @@ def _to_node_image(self, image):
extra['creationTimestamp'] = image.get('creationTimestamp')
extra['selfLink'] = image.get('selfLink')
extra['deprecated'] = image.get('deprecated', None)
extra['status'] = image.get('status')

return GCENodeImage(id=image['id'], name=image['name'], driver=self,
extra=extra)
Expand Down
11 changes: 9 additions & 2 deletions libcloud/test/compute/test_gce.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
timestamp_to_datetime,
GCEAddress, GCEHealthCheck,
GCEFirewall, GCEForwardingRule,
GCENetwork,
GCEZone)
GCENetwork, GCEZone,
GCENodeImage)
from libcloud.common.google import (GoogleBaseAuthConnection,
GoogleInstalledAppAuthConnection,
GoogleBaseConnection,
Expand Down Expand Up @@ -242,6 +242,13 @@ def test_ex_create_healthcheck(self):
self.assertEqual(hc.extra['host'], 'lchost')
self.assertEqual(hc.extra['description'], 'test healthcheck')

def test_ex_create_image(self):
volume = self.driver.ex_get_volume('lcdisk')
image = self.driver.ex_create_image('coreos', volume)
self.assertTrue(isinstance(image, GCENodeImage))
self.assertEquals(image.name, 'coreos')
self.assertEquals(image.extra['description'], 'CoreOS test image')

def test_ex_create_firewall(self):
firewall_name = 'lcfirewall'
allowed = [{'IPProtocol': 'tcp', 'ports': ['4567']}]
Expand Down