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
36 changes: 36 additions & 0 deletions libcloud/compute/drivers/gce.py
Original file line number Diff line number Diff line change
Expand Up @@ -2346,6 +2346,42 @@ def ex_get_zone(self, name):
return None
return self._to_zone(response)

def ex_copy_image(self, name, url, description=None):
"""
Copy an image to your image collection.

:param name: The name of the image
:type name: ``str``

:param url: The URL to the image. The URL can start with `gs://`
:param url: ``str``

:param description: The description of the image
:type description: ``str``

:return: NodeImage object based on provided information or None if an
image with that name is not found.
:rtype: :class:`NodeImage` or ``None``
"""

# the URL for an image can start with gs://
if url.startswith('gs://'):
url = url.replace('gs://', 'https://storage.googleapis.com/', 1)

image_data = {
'name': name,
'description': description,
'sourceType': 'RAW',
'rawDisk': {
'source': url,
},
}

request = '/global/images'
self.connection.async_request(request, method='POST',
data=image_data)
return self.ex_get_image(name)

def _ex_connection_class_kwargs(self):
return {'auth_type': self.auth_type,
'project': self.project}
Expand Down
15 changes: 15 additions & 0 deletions libcloud/test/compute/fixtures/gce/global_images.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,21 @@
"selfLink": "https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/centos-6-v20131118",
"sourceType": "RAW",
"status": "READY"
},
{
"creationTimestamp": "2014-03-09T21:04:31.291-07:00",
"description": "CoreOS test image",
"id": "15196339658718959621",
"kind": "compute#image",
"name": "coreos",
"preferredKernel": "https://www.googleapis.com/compute/v1/projects/google/global/kernels/gce-v20130603",
"rawDisk": {
"containerType": "TAR",
"source": ""
},
"selfLink": "https://www.googleapis.com/compute/v1/projects/project_name/global/images/coreos",
"sourceType": "RAW",
"status": "READY"
}
],
"kind": "compute#imageList",
Expand Down
13 changes: 13 additions & 0 deletions libcloud/test/compute/fixtures/gce/global_images_post.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"id": "15196339658718959621",
"insertTime": "2014-03-09T21:04:31.228-07:00",
"kind": "compute#operation",
"name": "coreos",
"operationType": "insert",
"progress": 0,
"selfLink": "https://www.googleapis.com/compute/v1/projects/project_name/global/operations/operation-global_image_post",
"startTime": "2014-03-09T21:04:31.291-07:00",
"status": "PENDING",
"targetLink": "https://www.googleapis.com/compute/v1/projects/project_name/global/images/coreos",
"user": "897001307951@developer.gserviceaccount.com"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"endTime": "2014-03-09T21:04:33.291-07:00",
"id": "15196339658718959621",
"insertTime": "2014-03-09T21:04:31.228-07:00",
"kind": "compute#operation",
"name": "coreos",
"operationType": "insert",
"progress": 100,
"selfLink": "https://www.googleapis.com/compute/v1/projects/project_name/global/operations/operation-global_image_post",
"startTime": "2014-03-09T21:04:31.291-07:00",
"status": "DONE",
"targetId": "12551176716147327315",
"targetLink": "https://www.googleapis.com/compute/v1/projects/project_name/global/images/coreos",
"user": "897001307951@developer.gserviceaccount.com"
}
21 changes: 19 additions & 2 deletions libcloud/test/compute/test_gce.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def test_ex_list_forwarding_rules(self):
def test_list_images(self):
local_images = self.driver.list_images()
debian_images = self.driver.list_images(ex_project='debian-cloud')
self.assertEqual(len(local_images), 2)
self.assertEqual(len(local_images), 3)
self.assertEqual(len(debian_images), 19)
self.assertEqual(local_images[0].name, 'debian-7-wheezy-v20130617')
self.assertEqual(local_images[1].name, 'centos-6-v20131118')
Expand Down Expand Up @@ -501,6 +501,14 @@ def test_ex_get_image(self):
self.assertEqual(image.name, 'debian-6-squeeze-v20130926')
self.assertTrue(image.extra['description'].startswith('Debian'))

def test_ex_copy_image(self):
name = 'coreos'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your names don't seem to match here. The targetLink in the test fixtures references 'core-os' and this is 'coreos'. The tests don't currently care about that level of detail, but it would be nice to have it consistent.

url = 'gs://storage.core-os.net/coreos/amd64-generic/247.0.0/coreos_production_gce.tar.gz'
description = 'CoreOS test image'
image = self.driver.ex_copy_image(name, url, description)
self.assertEqual(image.name, name)
self.assertEqual(image.extra['description'], description)

def test_ex_get_network(self):
network_name = 'lcnetwork'
network = self.driver.ex_get_network(network_name)
Expand Down Expand Up @@ -669,7 +677,10 @@ def _global_firewalls_lcfirewall(self, method, url, body, headers):
return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK])

def _global_images(self, method, url, body, headers):
body = self.fixtures.load('global_images.json')
if method == 'POST':
body = self.fixtures.load('global_images_post.json')
else:
body = self.fixtures.load('global_images.json')
return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK])

def _global_networks(self, method, url, body, headers):
Expand Down Expand Up @@ -767,6 +778,12 @@ def _global_operations_operation_global_snapshots_lcsnapshot_delete(
'operations_operation_global_snapshots_lcsnapshot_delete.json')
return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK])

def _global_operations_operation_global_image_post(
self, method, url, body, headers):
body = self.fixtures.load(
'operations_operation_global_image_post.json')
return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK])

def _regions_us_central1_operations_operation_regions_us_central1_addresses_lcaddress_delete(
self, method, url, body, headers):
body = self.fixtures.load(
Expand Down