Skip to content

Commit c74b9e4

Browse files
committed
Improve Linode create_image
1 parent b828f5a commit c74b9e4

3 files changed

Lines changed: 77 additions & 11 deletions

File tree

libcloud/compute/drivers/linode.py

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,43 @@ def ex_list_disks(self, node):
409409

410410
return [self._to_disk(obj) for obj in data]
411411

412+
def ex_get_primary_disk(self, node):
413+
"""
414+
Return the disk configured as the node's root device.
415+
416+
The first configuration profile is used, matching the configuration
417+
selected by default by Linode when none is explicitly specified.
418+
419+
:param node: Node whose primary disk should be returned. (required)
420+
:type node: :class:`Node`
421+
422+
:rtype: :class:`LinodeDisk`
423+
"""
424+
if not isinstance(node, Node):
425+
raise LinodeExceptionV4("Invalid node instance")
426+
427+
configs = self._paginated_request(
428+
"/v4/linode/instances/%s/configs" % node.id, "data"
429+
)
430+
if not configs:
431+
raise LinodeExceptionV4("Node has no configuration profiles")
432+
433+
config = configs[0]
434+
root_device = config.get("root_device") or "/dev/sda"
435+
device_name = root_device.rsplit("/", 1)[-1]
436+
device = config.get("devices", {}).get(device_name) or {}
437+
disk_id = device.get("disk")
438+
439+
if disk_id is None:
440+
raise LinodeExceptionV4("Node root device is not backed by a disk")
441+
442+
disks = self.ex_list_disks(node)
443+
for disk in disks:
444+
if str(disk.id) == str(disk_id):
445+
return disk
446+
447+
raise LinodeExceptionV4("Node root disk was not found")
448+
412449
def ex_create_disk(
413450
self,
414451
size,
@@ -748,11 +785,10 @@ def create_image(
748785
name,
749786
description=None,
750787
):
751-
"""Creates a private image from a LinodeDisk.
752-
Images are limited to three per account.
788+
"""Creates a private image from a Node's primary disk.
753789
754-
:param node: LinodeDisk to create the image from (required)
755-
:type node: :class:`LinodeDisk`
790+
:param node: Node to create the image from (required)
791+
:type node: :class:`Node`
756792
757793
:keyword name: A name for the image.\
758794
Defaults to the name of the disk \
@@ -766,10 +802,10 @@ def create_image(
766802
:rtype: :class:`NodeImage`
767803
"""
768804

769-
disk = node
770-
if not isinstance(disk, LinodeDisk):
771-
raise LinodeExceptionV4("Invalid disk instance")
805+
if not isinstance(node, Node):
806+
raise LinodeExceptionV4("Invalid node instance")
772807

808+
disk = self.ex_get_primary_disk(node)
773809
attr = {"disk_id": int(disk.id), "label": name, "description": description}
774810

775811
response = self.connection.request(
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"data": [
3+
{
4+
"id": 123456,
5+
"label": "My CentOS 7 Disk Profile",
6+
"root_device": "/dev/sda",
7+
"devices": {
8+
"sda": {
9+
"disk": 23517413,
10+
"volume": null
11+
},
12+
"sdb": {
13+
"disk": 66517499,
14+
"volume": null
15+
}
16+
}
17+
}
18+
],
19+
"page": 1,
20+
"pages": 1,
21+
"results": 1
22+
}

libcloud/test/compute/test_linode_v4.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -412,16 +412,20 @@ def test_ex_get_volume(self):
412412

413413
def test_create_image(self):
414414
node = Node("22344420", None, None, None, None, driver=self.driver)
415-
disk = self.driver.ex_list_disks(node)[0]
416-
image = self.driver.create_image(disk, name="Test", description="Test Image")
415+
image = self.driver.create_image(node, name="Test", description="Test Image")
417416
self.assertIsInstance(image, NodeImage)
418417
self.assertEqual(image.name, "Test")
419418
self.assertEqual(image.extra["description"], "Test Image")
420419

420+
def test_ex_get_primary_disk(self):
421+
node = Node("22344420", None, None, None, None, driver=self.driver)
422+
disk = self.driver.ex_get_primary_disk(node)
423+
self.assertIsInstance(disk, LinodeDisk)
424+
self.assertEqual(disk.id, "23517413")
425+
421426
def test_delete_image(self):
422427
node = Node("22344420", None, None, None, None, driver=self.driver)
423-
disk = self.driver.ex_list_disks(node)[0]
424-
image = self.driver.create_image(disk, name="Test", description="Test Image")
428+
image = self.driver.create_image(node, name="Test", description="Test Image")
425429
result = self.driver.delete_image(image)
426430
self.assertTrue(result)
427431

@@ -561,6 +565,10 @@ def _v4_linode_instances_22344420_disks(self, method, url, body, headers):
561565
body = self.fixtures.load("create_disk.json")
562566
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
563567

568+
def _v4_linode_instances_22344420_configs(self, method, url, body, headers):
569+
body = self.fixtures.load("list_configs.json")
570+
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
571+
564572
def _v4_linode_instances_22344420_disks_23517413(self, method, url, body, headers):
565573
return (httplib.OK, body, {}, httplib.responses[httplib.OK])
566574

0 commit comments

Comments
 (0)