Search for efi partition

This patch adds a function that will be responsible to identify
the efi partition on a give device, this is necessary on the Software
Raid scenario and when installing bootloader.

Conflicts:
        ironic_python_agent/tests/unit/test_utils.py
        ironic_python_agent/utils.py

Change-Id: I5f326db2d37b2a15090ec84e477e63f7d92e7447
Co-Authored-By: Raphael Glon <raphael.glon@corp.ovh.com>
(cherry picked from commit 966356e58c)
This commit is contained in:
Iury Gregory Melo Ferreira 2019-12-04 19:55:27 +01:00
parent 61128de52b
commit 6a777e8587
2 changed files with 70 additions and 0 deletions

View File

@ -34,6 +34,30 @@ from ironic_python_agent import hardware
from ironic_python_agent.tests.unit import base as ironic_agent_base from ironic_python_agent.tests.unit import base as ironic_agent_base
from ironic_python_agent import utils 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
'''
PARTED_OUTPUT_NO_EFI = '''Model: whatever
Disk /dev/sda: 450GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
14 1049kB 5243kB 4194kB bios_grub
1 116MB 2361MB 2245MB ext4
'''
class ExecuteTestCase(ironic_agent_base.IronicAgentTest): class ExecuteTestCase(ironic_agent_base.IronicAgentTest):
# This test case does call utils.execute(), so don't block access to the # This test case does call utils.execute(), so don't block access to the
@ -556,3 +580,25 @@ class TestUtils(testtools.TestCase):
keyfile='spam', certfile='ham') keyfile='spam', certfile='ham')
self.assertEqual((True, ('ham', 'spam')), self.assertEqual((True, ('ham', 'spam')),
utils.get_ssl_client_options(conf)) utils.get_ssl_client_options(conf))
@mock.patch.object(utils, 'execute', autospec=True)
def test_get_efi_part_on_device(self, mocked_execute):
parted_ret = PARTED_OUTPUT_UNFORMATTED.format('gpt')
mocked_execute.side_effect = [
(parted_ret, None)
]
ret = utils.get_efi_part_on_device('/dev/sda')
mocked_execute.assert_has_calls(
[mock.call('parted', '-s', '/dev/sda', '--', 'print')]
)
self.assertEqual('15', ret)
@mock.patch.object(utils, 'execute', autospec=True)
def test_get_efi_part_on_device_not_found(self, mocked_execute):
mocked_execute.side_effect = [
(PARTED_OUTPUT_NO_EFI, None)
]
self.assertIsNone(utils.get_efi_part_on_device('/dev/sda'))
mocked_execute.assert_has_calls(
[mock.call('parted', '-s', '/dev/sda', '--', 'print')]
)

View File

@ -17,6 +17,7 @@ import errno
import glob import glob
import io import io
import os import os
import re
import shutil import shutil
import subprocess import subprocess
import tarfile import tarfile
@ -60,6 +61,9 @@ COLLECT_LOGS_COMMANDS = {
} }
PARTED_ESP_PATTERN = re.compile(r'^\s*(\d+)\s.*\sfat\d*\s.*esp(,|\s|$).*$')
def execute(*cmd, **kwargs): def execute(*cmd, **kwargs):
"""Convenience wrapper around ironic_lib's execute() method. """Convenience wrapper around ironic_lib's execute() method.
@ -437,3 +441,23 @@ def get_ssl_client_options(conf):
else: else:
cert = None cert = None
return verify, cert return verify, cert
def get_efi_part_on_device(device):
"""Looks for the efi partition on a given device
:param device: lock device upon which to check for the efi partition
:return: the efi partition or None
"""
efi_part = None
out, _u = execute('parted', '-s', device, '--', 'print')
for line in out.splitlines():
m = PARTED_ESP_PATTERN.match(line)
if m:
efi_part = m.group(1)
LOG.debug("Found efi partition %s on device %s.", efi_part, device)
break
else:
LOG.debug("No efi partition found on device %s", device)
return efi_part