Skip to content

Commit

Permalink
fix(arm,bootloaders): use correct blsdir when boot is not separate
Browse files Browse the repository at this point in the history
Currently, leapp does not distinguish between having and not having a
separate /boot partition. Since blsdir is relative to the device
on which /boot resides, ARM systems without a separate /boot could
not boot into our upgrade environment, and, instead, they booted
back into pre-upgrade RHEL8. This patch adds additional handling
for non-separate /boot to the process of specifying custom blsdir.

Resolves: RHEL-41193
  • Loading branch information
Michal Hecko committed Feb 6, 2025
1 parent c5accf4 commit 80a7d74
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,10 @@ def modify_our_grubenv_to_have_separate_blsdir(efi_info):
grubenv_vars = _list_grubenv_variables()
system_bls_dir = grubenv_vars.get('blsdir', '/loader/entries').lstrip('/')

grub_root_device_mountpoint = '/boot' if os.path.ismount('/boot') else '/'

# BLS dir is relative to /boot, prepend it so we can list its contents
system_bls_dir = os.path.join('/boot', system_bls_dir)
system_bls_dir = os.path.join(grub_root_device_mountpoint, system_bls_dir)

# Find our loader entry
try:
Expand Down Expand Up @@ -444,7 +446,12 @@ def modify_our_grubenv_to_have_separate_blsdir(efi_info):

shutil.move(leapp_bls_entry_fullpath, bls_entry_dst)

upgrade_bls_dir_rel_to_boot = efi_info.upgrade_bls_dir[len('/boot'):]
# BLSDIR must be relative to grub's root device. Therefore, if /boot is a separate mountpoint
# we need to convert blsdir=/boot/upgrade-loader into blsdir=/upgrade-loader. If there is no
# separate root, then root=/, so rstripping('/') produces an empty string.
# In such a case, the relative paths stays unchanged: blsdir=/boot/upgrade-loader
grub_root_device_mp_without_trail = grub_root_device_mountpoint.rstrip('/')
upgrade_bls_dir_rel_to_boot = efi_info.upgrade_bls_dir[len(grub_root_device_mp_without_trail):]

# Modify leapp's grubenv to define our own BLSDIR
try:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,8 @@ def readlink_mock(path):
assert uuid == 'MY_UUID1'


def test_modify_grubenv_to_have_separate_blsdir(monkeypatch):
@pytest.mark.parametrize('has_separate_boot', (True, False))
def test_modify_grubenv_to_have_separate_blsdir(monkeypatch, has_separate_boot):
efi_info = ArmWorkaroundEFIBootloaderInfo(
original_entry=EFIBootEntry(
boot_number='0001',
Expand All @@ -349,9 +350,14 @@ def test_modify_grubenv_to_have_separate_blsdir(monkeypatch):
upgrade_entry_efi_path='/boot/efi/EFI/leapp'
)

def is_mount_mocked(path):
assert path.rstrip('/') == '/boot'
return has_separate_boot

def list_grubenv_variables_mock():
blsdir = '/blsdir' if has_separate_boot else '/boot/blsdir'
return {
'blsdir': '/blsdir'
'blsdir': blsdir
}

def listdir_mock(dir_path):
Expand All @@ -369,11 +375,13 @@ def move_mocked(src, dst):
assert dst == '/boot/upgrade-loader/entries/4a9c76478b98444fb5e0fbf533950edf-upgrade.aarch64.conf'

def run_mocked(cmd, *arg, **kwargs):
assert cmd == ['grub2-editenv', '/boot/efi/EFI/leapp/grubenv', 'set', 'blsdir=/upgrade-loader/entries']
blsdir = '/upgrade-loader/entries' if has_separate_boot else '/boot/upgrade-loader/entries'
assert cmd == ['grub2-editenv', '/boot/efi/EFI/leapp/grubenv', 'set', 'blsdir={}'.format(blsdir)]

monkeypatch.setattr(addupgradebootentry, '_list_grubenv_variables', list_grubenv_variables_mock)
monkeypatch.setattr(os, 'listdir', listdir_mock)
monkeypatch.setattr(os.path, 'exists', assert_path_correct)
monkeypatch.setattr(os.path, 'ismount', is_mount_mocked)
monkeypatch.setattr(os, 'makedirs', assert_path_correct)
monkeypatch.setattr(shutil, 'move', move_mocked)
monkeypatch.setattr(addupgradebootentry, 'run', run_mocked)
Expand Down

0 comments on commit 80a7d74

Please sign in to comment.