Merge lp:~newell-jensen/maas/fix-1685835 into lp:~maas-committers/maas/trunk

Proposed by Newell Jensen
Status: Merged
Approved by: Blake Rouse
Approved revision: no longer in the source branch.
Merged at revision: 6018
Proposed branch: lp:~newell-jensen/maas/fix-1685835
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 306 lines (+104/-33)
2 files modified
src/provisioningserver/drivers/pod/rsd.py (+55/-18)
src/provisioningserver/drivers/pod/tests/test_rsd.py (+49/-15)
To merge this branch: bzr merge lp:~newell-jensen/maas/fix-1685835
Reviewer Review Type Date Requested Status
Blake Rouse (community) Approve
Review via email: mp+323188@code.launchpad.net

Commit message

Ignore remote storage if the InitiatorIQN is non-empty in pre-composed nodes. This information is taken into account for calculating the total, available, and used iscsi storage on the RSD pod.

To post a comment you must log in.
Revision history for this message
Blake Rouse (blake-rouse) wrote :

Looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/provisioningserver/drivers/pod/rsd.py'
--- src/provisioningserver/drivers/pod/rsd.py 2017-04-24 20:10:24 +0000
+++ src/provisioningserver/drivers/pod/rsd.py 2017-04-25 23:06:27 +0000
@@ -519,17 +519,36 @@
519 discovered_machine_block_device)519 discovered_machine_block_device)
520520
521 def get_pod_machine_remote_storages(521 def get_pod_machine_remote_storages(
522 self, node_data, url, headers, logical_drives,522 self, node_data, url, headers, remote_drives, logical_drives,
523 targets, discovered_machine, request=None):523 targets, discovered_machine, request=None):
524 """Get pod machine remote storages."""524 """Get pod machine remote storages."""
525 remote_drives = node_data.get('Links', {}).get('RemoteDrives', [])525 node_remote_drives = node_data.get('Links', {}).get('RemoteDrives', [])
526 for remote_drive in remote_drives:526 remote_drives_to_delete = []
527 logical_drives_to_delete = []
528 for node_remote_drive in node_remote_drives:
529 target_data = targets[
530 node_remote_drive['@odata.id'].lstrip('/').encode('utf-8')]
531 initiator = target_data.get('Initiator')[0]
532 initiator_iqn = initiator.get('iSCSI', {}).get('InitiatorIQN')
533 if initiator_iqn:
534 # Since InitiatorIQN is not an empty string we will not be
535 # including this storage into MAAS.
536 # Remove this remote drive, target, and associated logical
537 # drives associated with this target.
538 for lv, lv_data in logical_drives.items():
539 lv_targets = lv_data.get('Links', {}).get('Targets', [])
540 for lv_target in lv_targets:
541 if (node_remote_drive['@odata.id'] ==
542 lv_target['@odata.id']):
543 remote_drives_to_delete.append(
544 node_remote_drive['@odata.id'])
545 logical_drives_to_delete.append(lv)
546 continue
547
527 discovered_machine_block_device = (548 discovered_machine_block_device = (
528 DiscoveredMachineBlockDevice(549 DiscoveredMachineBlockDevice(
529 model=None, serial=None, size=0,550 model=None, serial=None, size=0,
530 type=BlockDeviceType.ISCSI))551 type=BlockDeviceType.ISCSI))
531 target_data = targets[
532 remote_drive['@odata.id'].lstrip('/').encode('utf-8')]
533 addresses = target_data.get('Addresses')[0]552 addresses = target_data.get('Addresses')[0]
534 host = addresses.get('iSCSI', {}).get('TargetPortalIP')553 host = addresses.get('iSCSI', {}).get('TargetPortalIP')
535 proto = '6' # curtin currently only supports TCP.554 proto = '6' # curtin currently only supports TCP.
@@ -547,9 +566,11 @@
547 # find which one contains this remote drive.566 # find which one contains this remote drive.
548 for lv, lv_data in logical_drives.items():567 for lv, lv_data in logical_drives.items():
549 lv_targets = lv_data.get('Links', {}).get('Targets', [])568 lv_targets = lv_data.get('Links', {}).get('Targets', [])
550 if remote_drive in lv_targets:569 for lv_target in lv_targets:
551 discovered_machine_block_device.size = float(570 if (node_remote_drive['@odata.id'] ==
552 lv_data['CapacityGiB']) * (1024 ** 3)571 lv_target['@odata.id']):
572 discovered_machine_block_device.size = float(
573 lv_data['CapacityGiB']) * (1024 ** 3)
553574
554 # Map the tags from the request block devices to the discovered575 # Map the tags from the request block devices to the discovered
555 # block devices. This ensures that the composed machine has the576 # block devices. This ensures that the composed machine has the
@@ -570,6 +591,16 @@
570 discovered_machine.block_devices.append(591 discovered_machine.block_devices.append(
571 discovered_machine_block_device)592 discovered_machine_block_device)
572593
594 # Remove the remote drives, targests, and logical drives that
595 # are no longer needed. These will be used in later calculations
596 # for the total usable iscsi remote storage.
597 for remote_drive in set(remote_drives_to_delete):
598 del targets[
599 remote_drive.lstrip('/').encode('utf-8')]
600 remote_drives.remove(remote_drive)
601 for logical_drive in set(logical_drives_to_delete):
602 del logical_drives[logical_drive]
603
573 @inlineCallbacks604 @inlineCallbacks
574 def get_pod_machine_interfaces(605 def get_pod_machine_interfaces(
575 self, node_data, url, headers, discovered_machine):606 self, node_data, url, headers, discovered_machine):
@@ -627,7 +658,8 @@
627658
628 @inlineCallbacks659 @inlineCallbacks
629 def get_pod_machine(660 def get_pod_machine(
630 self, node, url, headers, logical_drives, targets, request=None):661 self, node, url, headers, remote_drives,
662 logical_drives, targets, request=None):
631 """Get pod composed machine.663 """Get pod composed machine.
632664
633 If required resources cannot be found, this665 If required resources cannot be found, this
@@ -661,7 +693,7 @@
661 node_data, url, headers, discovered_machine, request)693 node_data, url, headers, discovered_machine, request)
662 # Get remote storages.694 # Get remote storages.
663 self.get_pod_machine_remote_storages(695 self.get_pod_machine_remote_storages(
664 node_data, url, headers, logical_drives,696 node_data, url, headers, remote_drives, logical_drives,
665 targets, discovered_machine, request)697 targets, discovered_machine, request)
666 # Get interfaces.698 # Get interfaces.
667 yield self.get_pod_machine_interfaces(699 yield self.get_pod_machine_interfaces(
@@ -674,7 +706,8 @@
674706
675 @inlineCallbacks707 @inlineCallbacks
676 def get_pod_machines(708 def get_pod_machines(
677 self, url, headers, logical_drives, targets, request=None):709 self, url, headers, remote_drives,
710 logical_drives, targets, request=None):
678 """Get pod composed machines.711 """Get pod composed machines.
679712
680 If required resources cannot be found, these713 If required resources cannot be found, these
@@ -688,7 +721,8 @@
688 # Iterate over all composed nodes in the pod.721 # Iterate over all composed nodes in the pod.
689 for node in nodes:722 for node in nodes:
690 discovered_machine = yield self.get_pod_machine(723 discovered_machine = yield self.get_pod_machine(
691 node, url, headers, logical_drives, targets, request)724 node, url, headers, remote_drives,
725 logical_drives, targets, request)
692 discovered_machines.append(discovered_machine)726 discovered_machines.append(discovered_machine)
693 return discovered_machines727 return discovered_machines
694728
@@ -729,21 +763,24 @@
729 logical_drives, targets = yield self.scrape_logical_drives_and_targets(763 logical_drives, targets = yield self.scrape_logical_drives_and_targets(
730 url, headers)764 url, headers)
731 remote_drives = yield self.scrape_remote_drives(url, headers)765 remote_drives = yield self.scrape_remote_drives(url, headers)
766
767 # Discover composed machines.
768 pod_machines = yield self.get_pod_machines(
769 url, headers, remote_drives, logical_drives, targets)
770
771 # Discover pod resources.
732 pod_remote_storage, pod_hints_remote_storage = (772 pod_remote_storage, pod_hints_remote_storage = (
733 self.calculate_pod_remote_storage(773 self.calculate_pod_remote_storage(
734 remote_drives, logical_drives, targets))774 remote_drives, logical_drives, targets))
735
736 # Discover pod resources.
737 discovered_pod = yield self.get_pod_resources(url, headers)775 discovered_pod = yield self.get_pod_resources(url, headers)
738776
777 # Add machines to pod.
778 discovered_pod.machines = pod_machines
779
739 # Discover pod remote storage resources.780 # Discover pod remote storage resources.
740 discovered_pod.capabilities.append(Capabilities.ISCSI_STORAGE)781 discovered_pod.capabilities.append(Capabilities.ISCSI_STORAGE)
741 discovered_pod.iscsi_storage = pod_remote_storage782 discovered_pod.iscsi_storage = pod_remote_storage
742783
743 # Discover composed machines.
744 discovered_pod.machines = yield self.get_pod_machines(
745 url, headers, logical_drives, targets)
746
747 # Discover pod hints.784 # Discover pod hints.
748 discovered_pod.hints = self.get_pod_hints(discovered_pod)785 discovered_pod.hints = self.get_pod_hints(discovered_pod)
749 discovered_pod.hints.iscsi_storage = pod_hints_remote_storage786 discovered_pod.hints.iscsi_storage = pod_hints_remote_storage
750787
=== modified file 'src/provisioningserver/drivers/pod/tests/test_rsd.py'
--- src/provisioningserver/drivers/pod/tests/test_rsd.py 2017-04-24 20:10:24 +0000
+++ src/provisioningserver/drivers/pod/tests/test_rsd.py 2017-04-25 23:06:27 +0000
@@ -1013,7 +1013,7 @@
1013 b"redfish/v1/Services/1/Targets/3": SAMPLE_JSON_TARGET,1013 b"redfish/v1/Services/1/Targets/3": SAMPLE_JSON_TARGET,
1014 }1014 }
1015 remote_drives = set(1015 remote_drives = set(
1016 "redfish/v1/Services/1/Targets/1")1016 b"/redfish/v1/Services/1/Targets/1")
10171017
1018 remote_storage = driver.calculate_remote_storage(1018 remote_storage = driver.calculate_remote_storage(
1019 remote_drives, logical_drives, targets)1019 remote_drives, logical_drives, targets)
@@ -1313,23 +1313,51 @@
1313 context = make_context()1313 context = make_context()
1314 url = driver.get_url(context)1314 url = driver.get_url(context)
1315 headers = driver.make_auth_headers(**context)1315 headers = driver.make_auth_headers(**context)
1316 node_data = SAMPLE_JSON_NODE
1317 discovered_machine = make_discovered_machine(block_devices=[])1316 discovered_machine = make_discovered_machine(block_devices=[])
1318 TARGET_CHANGED = deepcopy(SAMPLE_JSON_TARGET)1317 node_data = deepcopy(SAMPLE_JSON_NODE)
1319 TARGET_CHANGED['Addresses'][0]['iSCSI']['TargetLUN'].append({'LUN': 3})1318 node_data['Links']['RemoteDrives'].append({
1319 "@odata.id": "/redfish/v1/Services/1/Targets/3"})
1320 LV_CHANGED = deepcopy(SAMPLE_JSON_LV)
1321 LV_CHANGED['Links']['Targets'].append({
1322 "@odata.id": "/redfish/v1/Services/1/Targets/3"})
1323 TARGET_CHANGED_1 = deepcopy(SAMPLE_JSON_TARGET)
1324 TARGET_CHANGED_2 = deepcopy(SAMPLE_JSON_TARGET)
1325 TARGET_CHANGED_1['Addresses'][0]['iSCSI']['TargetLUN'].append(
1326 {'LUN': 3})
1327 TARGET_CHANGED_2['Initiator'][0]['iSCSI']['InitiatorIQN'] = "ALL"
1328 remote_drives = set([
1329 "/redfish/v1/Services/1/Targets/1",
1330 "/redfish/v1/Services/1/Targets/2",
1331 "/redfish/v1/Services/1/Targets/3",
1332 ])
1320 logical_drives = {1333 logical_drives = {
1321 b"redfish/v1/Services/1/LogicalDrives/1": SAMPLE_JSON_LV,1334 b"redfish/v1/Services/1/LogicalDrives/1": SAMPLE_JSON_LV,
1322 b"redfish/v1/Services/1/LogicalDrives/2": SAMPLE_JSON_LVG,1335 b"redfish/v1/Services/1/LogicalDrives/2": SAMPLE_JSON_LVG,
1323 b"redfish/v1/Services/1/LogicalDrives/3": SAMPLE_JSON_LV1336 b"redfish/v1/Services/1/LogicalDrives/3": LV_CHANGED,
1324 }1337 }
1325 targets = {1338 targets = {
1326 b"redfish/v1/Services/1/Targets/1": SAMPLE_JSON_TARGET,1339 b"redfish/v1/Services/1/Targets/1": SAMPLE_JSON_TARGET,
1327 b"redfish/v1/Services/1/Targets/2": TARGET_CHANGED,1340 b"redfish/v1/Services/1/Targets/2": TARGET_CHANGED_1,
1341 b"redfish/v1/Services/1/Targets/3": TARGET_CHANGED_2,
1328 }1342 }
13291343
1330 driver.get_pod_machine_remote_storages(1344 driver.get_pod_machine_remote_storages(
1331 node_data, url, headers, logical_drives,1345 node_data, url, headers, remote_drives, logical_drives,
1332 targets, discovered_machine)1346 targets, discovered_machine)
1347 self.assertEquals(
1348 set([
1349 "/redfish/v1/Services/1/Targets/1",
1350 "/redfish/v1/Services/1/Targets/2"]), remote_drives)
1351 self.assertEquals(
1352 {
1353 b"redfish/v1/Services/1/LogicalDrives/1": SAMPLE_JSON_LV,
1354 b"redfish/v1/Services/1/LogicalDrives/2": SAMPLE_JSON_LVG
1355 }, logical_drives)
1356 self.assertEquals(
1357 {
1358 b"redfish/v1/Services/1/Targets/1": SAMPLE_JSON_TARGET,
1359 b"redfish/v1/Services/1/Targets/2": TARGET_CHANGED_1
1360 }, targets)
1333 self.assertThat(1361 self.assertThat(
1334 discovered_machine.block_devices, MatchesListwise([1362 discovered_machine.block_devices, MatchesListwise([
1335 MatchesStructure(1363 MatchesStructure(
@@ -1368,6 +1396,8 @@
1368 discovered_machine = make_discovered_machine(block_devices=[])1396 discovered_machine = make_discovered_machine(block_devices=[])
1369 TARGET_CHANGED = deepcopy(SAMPLE_JSON_TARGET)1397 TARGET_CHANGED = deepcopy(SAMPLE_JSON_TARGET)
1370 TARGET_CHANGED['Addresses'][0]['iSCSI']['TargetLUN'].append({'LUN': 3})1398 TARGET_CHANGED['Addresses'][0]['iSCSI']['TargetLUN'].append({'LUN': 3})
1399 remote_drives = set(
1400 b"/redfish/v1/Services/1/Targets/1")
1371 logical_drives = {1401 logical_drives = {
1372 b"redfish/v1/Services/1/LogicalDrives/1": SAMPLE_JSON_LV,1402 b"redfish/v1/Services/1/LogicalDrives/1": SAMPLE_JSON_LV,
1373 b"redfish/v1/Services/1/LogicalDrives/2": SAMPLE_JSON_LVG,1403 b"redfish/v1/Services/1/LogicalDrives/2": SAMPLE_JSON_LVG,
@@ -1379,7 +1409,7 @@
1379 }1409 }
13801410
1381 driver.get_pod_machine_remote_storages(1411 driver.get_pod_machine_remote_storages(
1382 node_data, url, headers, logical_drives,1412 node_data, url, headers, remote_drives, logical_drives,
1383 targets, discovered_machine, request)1413 targets, discovered_machine, request)
1384 self.assertThat(1414 self.assertThat(
1385 discovered_machine.block_devices, MatchesListwise([1415 discovered_machine.block_devices, MatchesListwise([
@@ -1481,6 +1511,8 @@
1481 node_data = SAMPLE_JSON_NODE1511 node_data = SAMPLE_JSON_NODE
1482 TARGET_CHANGED = deepcopy(SAMPLE_JSON_TARGET)1512 TARGET_CHANGED = deepcopy(SAMPLE_JSON_TARGET)
1483 TARGET_CHANGED['Addresses'][0]['iSCSI']['TargetLUN'].append({'LUN': 3})1513 TARGET_CHANGED['Addresses'][0]['iSCSI']['TargetLUN'].append({'LUN': 3})
1514 remote_drives = set(
1515 b"/redfish/v1/Services/1/Targets/1")
1484 logical_drives = {1516 logical_drives = {
1485 b"redfish/v1/Services/1/LogicalDrives/1": SAMPLE_JSON_LV,1517 b"redfish/v1/Services/1/LogicalDrives/1": SAMPLE_JSON_LV,
1486 b"redfish/v1/Services/1/LogicalDrives/2": SAMPLE_JSON_LVG,1518 b"redfish/v1/Services/1/LogicalDrives/2": SAMPLE_JSON_LVG,
@@ -1506,7 +1538,7 @@
1506 driver, 'get_pod_machine_interfaces')1538 driver, 'get_pod_machine_interfaces')
15071539
1508 machine = yield driver.get_pod_machine(1540 machine = yield driver.get_pod_machine(
1509 b"redfish/v1/Nodes/1", url, headers,1541 b"redfish/v1/Nodes/1", url, headers, remote_drives,
1510 logical_drives, targets, request)1542 logical_drives, targets, request)
1511 self.assertEquals(node_data['Name'], machine.hostname)1543 self.assertEquals(node_data['Name'], machine.hostname)
1512 self.assertEquals(1544 self.assertEquals(
@@ -1523,8 +1555,8 @@
1523 MockCalledOnceWith(node_data, url, headers, machine, request))1555 MockCalledOnceWith(node_data, url, headers, machine, request))
1524 self.assertThat(1556 self.assertThat(
1525 mock_get_pod_machine_remote_storages,1557 mock_get_pod_machine_remote_storages,
1526 MockCalledOnceWith(node_data, url, headers, logical_drives,1558 MockCalledOnceWith(node_data, url, headers, remote_drives,
1527 targets, machine, request))1559 logical_drives, targets, machine, request))
1528 self.assertThat(1560 self.assertThat(
1529 mock_get_pod_machine_interfaces,1561 mock_get_pod_machine_interfaces,
1530 MockCalledOnceWith(node_data, url, headers, machine))1562 MockCalledOnceWith(node_data, url, headers, machine))
@@ -1535,6 +1567,8 @@
1535 context = make_context()1567 context = make_context()
1536 url = driver.get_url(context)1568 url = driver.get_url(context)
1537 headers = driver.make_auth_headers(**context)1569 headers = driver.make_auth_headers(**context)
1570 remote_drives = set(
1571 b"redfish/v1/Services/1/Targets/1")
1538 logical_drives = {1572 logical_drives = {
1539 factory.make_name('lv_path'): factory.make_name('lv_data')1573 factory.make_name('lv_path'): factory.make_name('lv_data')
1540 for _ in range(3)1574 for _ in range(3)
@@ -1557,11 +1591,11 @@
1557 mock_get_pod_machine.return_value = expected_machines1591 mock_get_pod_machine.return_value = expected_machines
15581592
1559 discovered_machines = yield driver.get_pod_machines(1593 discovered_machines = yield driver.get_pod_machines(
1560 url, headers, logical_drives, targets)1594 url, headers, remote_drives, logical_drives, targets)
1561 self.assertEquals(1, len(discovered_machines))1595 self.assertEquals(1, len(discovered_machines))
1562 self.assertThat(mock_get_pod_machine, MockCalledOnceWith(1596 self.assertThat(mock_get_pod_machine, MockCalledOnceWith(
1563 b"redfish/v1/Nodes/1", url, headers,1597 b"redfish/v1/Nodes/1", url, headers,
1564 logical_drives, targets, None))1598 remote_drives, logical_drives, targets, None))
15651599
1566 def test__get_pod_hints(self):1600 def test__get_pod_hints(self):
1567 driver = RSDPodDriver()1601 driver = RSDPodDriver()
@@ -1638,7 +1672,7 @@
1638 mock_get_pod_resources, MockCalledOnceWith(url, headers))1672 mock_get_pod_resources, MockCalledOnceWith(url, headers))
1639 self.assertThat(1673 self.assertThat(
1640 mock_get_pod_machines, MockCalledOnceWith(1674 mock_get_pod_machines, MockCalledOnceWith(
1641 url, headers, logical_drives, targets))1675 url, headers, remote_drives, logical_drives, targets))
1642 self.assertThat(mock_get_pod_hints, MockCalledOnceWith(1676 self.assertThat(mock_get_pod_hints, MockCalledOnceWith(
1643 mock_get_pod_resources.return_value))1677 mock_get_pod_resources.return_value))
16441678
@@ -1815,7 +1849,7 @@
1815 for _ in range(3)1849 for _ in range(3)
1816 }1850 }
1817 remote_drives = set([1851 remote_drives = set([
1818 factory.make_name('target_path')1852 factory.make_name('target_path').encode('utf-8')
1819 for _ in range(3)1853 for _ in range(3)
1820 ])1854 ])
1821 mock_scrape_logical_drives_and_targets = self.patch(1855 mock_scrape_logical_drives_and_targets = self.patch(