You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
4.0 KiB
119 lines
4.0 KiB
10 months ago
|
import os
|
||
|
|
||
|
from leapp.exceptions import StopActorExecution
|
||
|
from leapp.libraries.common import mdraid
|
||
|
from leapp.libraries.stdlib import api, CalledProcessError, run
|
||
|
from leapp.utils.deprecation import deprecated
|
||
|
|
||
|
|
||
|
def has_grub(blk_dev):
|
||
|
"""
|
||
|
Check whether GRUB is present on block device
|
||
|
"""
|
||
|
try:
|
||
|
blk = os.open(blk_dev, os.O_RDONLY)
|
||
|
mbr = os.read(blk, 512)
|
||
|
except OSError:
|
||
|
api.current_logger().warning(
|
||
|
'Could not read first sector of {} in order to identify the bootloader'.format(blk_dev)
|
||
|
)
|
||
|
raise StopActorExecution()
|
||
|
os.close(blk)
|
||
|
test = 'GRUB'
|
||
|
if not isinstance(mbr, str):
|
||
|
test = test.encode('utf-8')
|
||
|
|
||
|
return test in mbr
|
||
|
|
||
|
|
||
|
def blk_dev_from_partition(partition):
|
||
|
"""
|
||
|
Find parent device of /boot partition
|
||
|
"""
|
||
|
try:
|
||
|
result = run(['lsblk', '-spnlo', 'name', partition])
|
||
|
except CalledProcessError:
|
||
|
api.current_logger().warning(
|
||
|
'Could not get parent device of {} partition'.format(partition)
|
||
|
)
|
||
|
raise StopActorExecution()
|
||
|
# lsblk "-s" option prints dependencies in inverse order, so the parent device will always
|
||
|
# be the last or the only device.
|
||
|
# Command result example:
|
||
|
# 'result', {'signal': 0, 'pid': 3872, 'exit_code': 0, 'stderr': u'', 'stdout': u'/dev/vda1\n/dev/vda\n'}
|
||
|
return result['stdout'].strip().split()[-1]
|
||
|
|
||
|
|
||
|
def get_boot_partition():
|
||
|
"""
|
||
|
Get /boot partition name.
|
||
|
"""
|
||
|
try:
|
||
|
# call grub2-probe to identify /boot partition
|
||
|
result = run(['grub2-probe', '--target=device', '/boot'])
|
||
|
except CalledProcessError:
|
||
|
api.current_logger().warning(
|
||
|
'Could not get name of underlying /boot partition'
|
||
|
)
|
||
|
raise StopActorExecution()
|
||
|
except OSError:
|
||
|
api.current_logger().warning(
|
||
|
'Could not get name of underlying /boot partition:'
|
||
|
' grub2-probe is missing.'
|
||
|
' Possibly called on system that does not use GRUB2?'
|
||
|
)
|
||
|
raise StopActorExecution()
|
||
|
boot_partition = result['stdout'].strip()
|
||
|
api.current_logger().info('/boot is on {}'.format(boot_partition))
|
||
|
return boot_partition
|
||
|
|
||
|
|
||
|
def get_grub_devices():
|
||
|
"""
|
||
|
Get block devices where GRUB is located. We assume GRUB is on the same device
|
||
|
as /boot partition is. In case that device is an md (Multiple Device) device, all
|
||
|
of the component devices of such a device are considered.
|
||
|
|
||
|
:return: Devices where GRUB is located
|
||
|
:rtype: list
|
||
|
"""
|
||
|
boot_device = get_boot_partition()
|
||
|
devices = []
|
||
|
if mdraid.is_mdraid_dev(boot_device):
|
||
|
component_devs = mdraid.get_component_devices(boot_device)
|
||
|
blk_devs = [blk_dev_from_partition(dev) for dev in component_devs]
|
||
|
# remove duplicates as there might be raid on partitions on the same drive
|
||
|
# even if that's very unusual
|
||
|
devices = sorted(list(set(blk_devs)))
|
||
|
else:
|
||
|
devices.append(blk_dev_from_partition(boot_device))
|
||
|
|
||
|
have_grub = [dev for dev in devices if has_grub(dev)]
|
||
|
api.current_logger().info('GRUB is installed on {}'.format(",".join(have_grub)))
|
||
|
return have_grub
|
||
|
|
||
|
|
||
|
@deprecated(since='2023-06-23', message='This function has been replaced by get_grub_devices')
|
||
|
def get_grub_device():
|
||
|
"""
|
||
|
Get block device where GRUB is located. We assume GRUB is on the same device
|
||
|
as /boot partition is.
|
||
|
|
||
|
"""
|
||
|
boot_partition = get_boot_partition()
|
||
|
grub_dev = blk_dev_from_partition(boot_partition)
|
||
|
api.current_logger().info('GRUB is installed on {}'.format(grub_dev))
|
||
|
# if has_grub(grub_dev):
|
||
|
return grub_dev if has_grub(grub_dev) else None
|
||
|
|
||
|
|
||
|
def is_blscfg_enabled_in_defaultgrub(default_grub_msg):
|
||
|
"""
|
||
|
Check if GRUB_ENABLE_BLSCFG is true in /etc/default/grub file
|
||
|
"""
|
||
|
grub_options_lst = default_grub_msg.default_grub_info
|
||
|
default_grub_options = {
|
||
|
option.name: option.value.strip('"') for option in grub_options_lst
|
||
|
}
|
||
|
return bool(default_grub_options.get('GRUB_ENABLE_BLSCFG', '') == 'true')
|