Use two more functions from disk_utils

Change-Id: If01c9cd7f95b4495509369786360741b731161db
This commit is contained in:
Dmitry Tantsur 2021-08-27 13:28:41 +02:00
parent 36d4a18fbc
commit 89bc73aa01
6 changed files with 18 additions and 140 deletions

View File

@ -15,6 +15,7 @@ import re
import shutil
import tempfile
from ironic_lib import disk_utils
from oslo_concurrency import processutils
from oslo_log import log
@ -48,7 +49,7 @@ def manage_uefi(device, efi_system_part_uuid=None):
local_path = tempfile.mkdtemp()
# Trust the contents on the disk in the event of a whole disk image.
efi_partition = utils.get_efi_part_on_device(device)
efi_partition = disk_utils.find_efi_partition(device)
if not efi_partition and efi_system_part_uuid:
# _get_partition returns <device>+<partition> and we only need the
# partition number

View File

@ -18,6 +18,7 @@ import re
import shutil
import tempfile
from ironic_lib import disk_utils
from ironic_lib import utils as ilib_utils
from oslo_concurrency import processutils
from oslo_config import cfg
@ -136,7 +137,7 @@ def _prepare_boot_partitions_for_softraid(device, holders, efi_part,
# Let's try to scan for esp on the root softraid device. If not
# found, it's fine in most cases to just create an empty esp and
# let grub handle the magic.
efi_part = utils.get_efi_part_on_device(device)
efi_part = disk_utils.find_efi_partition(device)
if efi_part:
efi_part = '{}p{}'.format(device, efi_part)
@ -198,7 +199,7 @@ def _prepare_boot_partitions_for_softraid(device, holders, efi_part,
elif target_boot_mode == 'bios':
partlabel_prefix = 'bios-boot-part-'
for number, holder in enumerate(holders):
label = utils.scan_partition_table_type(holder)
label = disk_utils.get_partition_table_type(holder)
if label == 'gpt':
LOG.debug("Creating bios boot partition on disk holder %s",
holder)

View File

@ -18,6 +18,7 @@ import shutil
import tempfile
from unittest import mock
from ironic_lib import disk_utils
from ironic_lib import utils as ilib_utils
from oslo_concurrency import processutils
@ -27,7 +28,6 @@ from ironic_python_agent.extensions import image
from ironic_python_agent import hardware
from ironic_python_agent import partition_utils
from ironic_python_agent.tests.unit import base
from ironic_python_agent import utils
@mock.patch.object(hardware, 'dispatch_to_managers', autospec=True)
@ -215,7 +215,7 @@ class TestImageExtension(base.IronicAgentTest):
@mock.patch.object(os.path, 'exists', lambda *_: False)
@mock.patch.object(efi_utils, '_get_efi_bootloaders', autospec=True)
@mock.patch.object(partition_utils, 'get_partition', autospec=True)
@mock.patch.object(utils, 'get_efi_part_on_device', autospec=False)
@mock.patch.object(disk_utils, 'find_efi_partition', autospec=False)
@mock.patch.object(os, 'makedirs', autospec=True)
def test__uefi_bootloader_given_partition(
self, mkdir_mock, mock_utils_efi_part, mock_partition,
@ -263,7 +263,7 @@ class TestImageExtension(base.IronicAgentTest):
@mock.patch.object(os.path, 'exists', lambda *_: False)
@mock.patch.object(efi_utils, '_get_efi_bootloaders', autospec=True)
@mock.patch.object(partition_utils, 'get_partition', autospec=True)
@mock.patch.object(utils, 'get_efi_part_on_device', autospec=True)
@mock.patch.object(disk_utils, 'find_efi_partition', autospec=True)
@mock.patch.object(os, 'makedirs', autospec=True)
def test__uefi_bootloader_find_partition(
self, mkdir_mock, mock_utils_efi_part, mock_partition,
@ -310,7 +310,7 @@ class TestImageExtension(base.IronicAgentTest):
@mock.patch.object(os.path, 'exists', lambda *_: False)
@mock.patch.object(efi_utils, '_get_efi_bootloaders', autospec=True)
@mock.patch.object(partition_utils, 'get_partition', autospec=True)
@mock.patch.object(utils, 'get_efi_part_on_device', autospec=True)
@mock.patch.object(disk_utils, 'find_efi_partition', autospec=True)
@mock.patch.object(os, 'makedirs', autospec=True)
def test__uefi_bootloader_with_entry_removal(
self, mkdir_mock, mock_utils_efi_part, mock_partition,
@ -367,7 +367,7 @@ Boot0002 VENDMAGIC FvFile(9f3c6294-bf9b-4208-9808-be45dfc34b51)
@mock.patch.object(os.path, 'exists', lambda *_: False)
@mock.patch.object(efi_utils, '_get_efi_bootloaders', autospec=True)
@mock.patch.object(partition_utils, 'get_partition', autospec=True)
@mock.patch.object(utils, 'get_efi_part_on_device', autospec=True)
@mock.patch.object(disk_utils, 'find_efi_partition', autospec=True)
@mock.patch.object(os, 'makedirs', autospec=True)
def test__uefi_bootloader_with_entry_removal_lenovo(
self, mkdir_mock, mock_utils_efi_part, mock_partition,
@ -429,7 +429,7 @@ Boot0004* ironic1 HD(1,GPT,55db8d03-c8f6-4a5b-9155-790dddc348fa,0x800,0x640
@mock.patch.object(os.path, 'exists', lambda *_: False)
@mock.patch.object(efi_utils, '_get_efi_bootloaders', autospec=True)
@mock.patch.object(partition_utils, 'get_partition', autospec=True)
@mock.patch.object(utils, 'get_efi_part_on_device', autospec=True)
@mock.patch.object(disk_utils, 'find_efi_partition', autospec=True)
@mock.patch.object(os, 'makedirs', autospec=True)
def test__add_multi_bootloaders(
self, mkdir_mock, mock_utils_efi_part, mock_partition,
@ -1653,7 +1653,7 @@ Boot0004* ironic1 HD(1,GPT,55db8d03-c8f6-4a5b-9155-790dddc348fa,0x800,0x640
uuid=self.fake_root_uuid)
self.assertFalse(mock_dispatch.called)
@mock.patch.object(utils, 'get_efi_part_on_device', autospec=True)
@mock.patch.object(disk_utils, 'find_efi_partition', autospec=True)
def test__prepare_boot_partitions_for_softraid_uefi_gpt(
self, mock_efi_part, mock_execute, mock_dispatch):
mock_efi_part.return_value = '12'
@ -1702,7 +1702,7 @@ Boot0004* ironic1 HD(1,GPT,55db8d03-c8f6-4a5b-9155-790dddc348fa,0x800,0x640
mock_execute.assert_has_calls(expected, any_order=False)
self.assertEqual(efi_part, '/dev/md/esp')
@mock.patch.object(utils, 'get_efi_part_on_device', autospec=True)
@mock.patch.object(disk_utils, 'find_efi_partition', autospec=True)
@mock.patch.object(ilib_utils, 'mkfs', autospec=True)
def test__prepare_boot_partitions_for_softraid_uefi_gpt_esp_not_found(
self, mock_mkfs, mock_efi_part, mock_execute, mock_dispatch):
@ -1794,7 +1794,7 @@ Boot0004* ironic1 HD(1,GPT,55db8d03-c8f6-4a5b-9155-790dddc348fa,0x800,0x640
mock_execute.assert_has_calls(expected, any_order=False)
self.assertEqual(efi_part, '/dev/md/esp')
@mock.patch.object(utils, 'scan_partition_table_type', autospec=True,
@mock.patch.object(disk_utils, 'get_partition_table_type', autospec=True,
return_value='msdos')
def test__prepare_boot_partitions_for_softraid_bios_msdos(
self, mock_label_scan, mock_execute, mock_dispatch):
@ -1810,7 +1810,7 @@ Boot0004* ironic1 HD(1,GPT,55db8d03-c8f6-4a5b-9155-790dddc348fa,0x800,0x640
mock_label_scan.assert_has_calls(expected, any_order=False)
self.assertIsNone(efi_part)
@mock.patch.object(utils, 'scan_partition_table_type', autospec=True,
@mock.patch.object(disk_utils, 'get_partition_table_type', autospec=True,
return_value='gpt')
def test__prepare_boot_partitions_for_softraid_bios_gpt(
self, mock_label_scan, mock_execute, mock_dispatch):

View File

@ -15,6 +15,8 @@ import shutil
import tempfile
from unittest import mock
from ironic_lib import disk_utils
from ironic_python_agent import efi_utils
from ironic_python_agent import errors
from ironic_python_agent import partition_utils
@ -128,7 +130,7 @@ class TestRunEfiBootmgr(base.IronicAgentTest):
@mock.patch.object(utils, 'rescan_device', autospec=True)
@mock.patch.object(utils, 'execute', autospec=True)
@mock.patch.object(partition_utils, 'get_partition', autospec=True)
@mock.patch.object(utils, 'get_efi_part_on_device', autospec=True)
@mock.patch.object(disk_utils, 'find_efi_partition', autospec=True)
class TestManageUefi(base.IronicAgentTest):
fake_dev = '/dev/fake'

View File

@ -23,7 +23,6 @@ import tarfile
import tempfile
from unittest import mock
from ironic_lib import disk_utils
from ironic_lib import utils as ironic_utils
from oslo_concurrency import processutils
from oslo_serialization import base64
@ -35,18 +34,6 @@ from ironic_python_agent import hardware
from ironic_python_agent.tests.unit import base as ironic_agent_base
from ironic_python_agent import utils
PARTED_OUTPUT_UNFORMATTED = '''Model: whatever
Disk /dev/sda: 450GB
Sector size (logical/physical): 512B/512B
Partition Table: {}
Disk Flags:
Number Start End Size File system Name Flags
14 1049kB 5243kB 4194kB bios_grub
15 5243kB 116MB 111MB fat32 boot, esp
1 116MB 2361MB 2245MB ext4
'''
class ExecuteTestCase(ironic_agent_base.IronicAgentTest):
# This test case does call utils.execute(), so don't block access to the
@ -818,36 +805,6 @@ class TestUtils(ironic_agent_base.IronicAgentTest):
self.assertEqual('gpt', label)
mock_boot_mode.assert_has_calls([])
@mock.patch.object(utils, 'execute', autospec=True)
def test_scan_partition_table_type_gpt(self, mocked_execute):
self._test_scan_partition_table_by_type(mocked_execute, 'gpt', 'gpt')
@mock.patch.object(utils, 'execute', autospec=True)
def test_scan_partition_table_type_msdos(self, mocked_execute):
self._test_scan_partition_table_by_type(mocked_execute, 'msdos',
'msdos')
@mock.patch.object(utils, 'execute', autospec=True)
def test_scan_partition_table_type_unknown(self, mocked_execute):
self._test_scan_partition_table_by_type(mocked_execute, 'whatever',
'unknown')
def _test_scan_partition_table_by_type(self, mocked_execute,
table_type_output,
expected_table_type):
parted_ret = PARTED_OUTPUT_UNFORMATTED.format(table_type_output)
mocked_execute.side_effect = [
(parted_ret, None),
]
ret = utils.scan_partition_table_type('hello')
mocked_execute.assert_has_calls(
[mock.call('parted', '-s', 'hello', '--', 'print')]
)
self.assertEqual(expected_table_type, ret)
class TestRemoveKeys(testtools.TestCase):
def test_remove_keys(self):
@ -942,48 +899,6 @@ class TestClockSyncUtils(ironic_agent_base.IronicAgentTest):
self.assertEqual(0, mock_execute.call_count)
@mock.patch.object(disk_utils, 'list_partitions', autospec=True)
@mock.patch.object(utils, 'scan_partition_table_type', autospec=True)
class TestGetEfiPart(testtools.TestCase):
def test_get_efi_part_on_device(self, mocked_type, mocked_parts):
mocked_parts.return_value = [
{'number': '1', 'flags': ''},
{'number': '14', 'flags': 'bios_grub'},
{'number': '15', 'flags': 'esp, boot'},
]
ret = utils.get_efi_part_on_device('/dev/sda')
self.assertEqual('15', ret)
def test_get_efi_part_on_device_only_boot_flag_gpt(self, mocked_type,
mocked_parts):
mocked_type.return_value = 'gpt'
mocked_parts.return_value = [
{'number': '1', 'flags': ''},
{'number': '14', 'flags': 'bios_grub'},
{'number': '15', 'flags': 'boot'},
]
ret = utils.get_efi_part_on_device('/dev/sda')
self.assertEqual('15', ret)
def test_get_efi_part_on_device_only_boot_flag_mbr(self, mocked_type,
mocked_parts):
mocked_type.return_value = 'msdos'
mocked_parts.return_value = [
{'number': '1', 'flags': ''},
{'number': '14', 'flags': 'bios_grub'},
{'number': '15', 'flags': 'boot'},
]
self.assertIsNone(utils.get_efi_part_on_device('/dev/sda'))
def test_get_efi_part_on_device_not_found(self, mocked_type, mocked_parts):
mocked_parts.return_value = [
{'number': '1', 'flags': ''},
{'number': '14', 'flags': 'bios_grub'},
]
self.assertIsNone(utils.get_efi_part_on_device('/dev/sda'))
@mock.patch.object(utils, '_booted_from_vmedia', autospec=True)
@mock.patch.object(utils, '_check_vmedia_device', autospec=True)
@mock.patch.object(utils, '_find_vmedia_device_by_labels', autospec=True)

View File

@ -26,7 +26,6 @@ import sys
import tarfile
import time
from ironic_lib import disk_utils
from ironic_lib import utils as ironic_utils
from oslo_concurrency import processutils
from oslo_config import cfg
@ -75,8 +74,6 @@ COLLECT_LOGS_COMMANDS = {
DEVICE_EXTRACTOR = re.compile(r'^(?:(.*\d)p|(.*\D))(?:\d+)$')
PARTED_TABLE_TYPE_REGEX = re.compile(r'^.*partition\s+table\s*:\s*(gpt|msdos)',
re.IGNORECASE)
_EARLY_LOG_BUFFER = []
@ -733,44 +730,6 @@ def get_partition_table_type_from_specs(node):
return 'gpt' if disk_label == 'gpt' else 'msdos'
def scan_partition_table_type(device):
"""Get partition table type, msdos or gpt.
:param device_name: the name of the device
:return: msdos, gpt or unknown
"""
out, _u = execute('parted', '-s', device, '--', 'print')
out = out.splitlines()
for line in out:
m = PARTED_TABLE_TYPE_REGEX.match(line)
if m:
return m.group(1)
LOG.warning("Unable to get partition table type for device %s.",
device)
return 'unknown'
def get_efi_part_on_device(device):
"""Looks for the efi partition on a given device.
A boot partition on a GPT disk is assumed to be an EFI partition as well.
:param device: lock device upon which to check for the efi partition
:return: the efi partition or None
"""
is_gpt = scan_partition_table_type(device) == 'gpt'
for part in disk_utils.list_partitions(device):
flags = {x.strip() for x in part['flags'].split(',')}
if 'esp' in flags or ('boot' in flags and is_gpt):
LOG.debug("Found EFI partition %s on device %s.", part, device)
return part['number']
else:
LOG.debug("No efi partition found on device %s", device)
_LARGE_KEYS = frozenset(['configdrive', 'system_logs'])