More refactoring of the image module

Introducing new function _umount_all_partitions to reduce the size
of _install_grub2

Change-Id: I304468d57b10d677f2a9d58aec42a1bf414c6cba
(cherry picked from commit 80e11811f5)
This commit is contained in:
Riccardo Pittau 2020-07-15 15:27:19 +02:00 committed by Steve Baker
parent 8419c6d3f1
commit d9aa620368
1 changed files with 32 additions and 39 deletions

View File

@ -149,16 +149,13 @@ def _has_boot_sector(device):
stdout, stderr = utils.execute('file', '-s', device) stdout, stderr = utils.execute('file', '-s', device)
if 'boot sector' not in stdout: if 'boot sector' not in stdout:
return False return False
else: # Now lets check the signature
# Now lets check the signature ddout, dderr = utils.execute(
ddout, dderr = utils.execute( 'dd', 'if=%s' % device, 'bs=218', 'count=1', binary=True)
'dd', 'if=%s' % device, 'bs=218', 'count=1', binary=True) stdout, stderr = utils.execute('file', '-', process_input=ddout)
stdout, stderr = utils.execute('file', '-', process_input=ddout) # The bytes recovered by dd show as a "dos executable" when
# The bytes recovered by dd show as a "dos executable" when # examined with file. In other words, the bootloader is present.
# examined with file. In other words, the bootloader is present. return 'executable' in stdout
if 'executable' in stdout:
return True
return False
def _find_bootable_device(partitions, dev): def _find_bootable_device(partitions, dev):
@ -275,7 +272,6 @@ def _manage_uefi(device, efi_system_part_uuid=None):
using the efibootmgr. using the efibootmgr.
False - if no efi bootloader is found. False - if no efi bootloader is found.
""" """
efi_partition = None
efi_partition_mount_point = None efi_partition_mount_point = None
efi_mounted = False efi_mounted = False
@ -351,6 +347,29 @@ def _manage_uefi(device, efi_system_part_uuid=None):
shutil.rmtree(local_path) shutil.rmtree(local_path)
def _umount_all_partitions(path, path_variable, umount_warn_msg):
"""Umount all partitions we may have mounted"""
umount_binds_success = True
LOG.debug("Unmounting all vfat partitions inside the image ...")
try:
utils.execute('chroot %(path)s /bin/sh -c "umount -a -t vfat"' %
{'path': path}, shell=True,
env_variables={'PATH': path_variable})
except processutils.ProcessExecutionError as e:
LOG.warning("Unable to umount vfat partitions. Error: %(error)s",
{'error': e})
for fs in BIND_MOUNTS + ('/sys',):
try:
utils.execute('umount', path + fs, attempts=3,
delay_on_retry=True)
except processutils.ProcessExecutionError as e:
umount_binds_success = False
LOG.warning(umount_warn_msg, {'path': path + fs, 'error': e})
return umount_binds_success
def _install_grub2(device, root_uuid, efi_system_part_uuid=None, def _install_grub2(device, root_uuid, efi_system_part_uuid=None,
prep_boot_part_uuid=None): prep_boot_part_uuid=None):
"""Install GRUB2 bootloader on a given device.""" """Install GRUB2 bootloader on a given device."""
@ -490,9 +509,8 @@ def _install_grub2(device, root_uuid, efi_system_part_uuid=None,
raise errors.CommandExecutionError(error_msg) raise errors.CommandExecutionError(error_msg)
finally: finally:
umount_warn_msg = "Unable to umount %(path)s. Error: %(error)s"
# Umount binds and partition # Umount binds and partition
umount_binds_fail = False umount_warn_msg = "Unable to umount %(path)s. Error: %(error)s"
# If umount fails for efi partition, then we cannot be sure that all # If umount fails for efi partition, then we cannot be sure that all
# the changes were written back to the filesystem. # the changes were written back to the filesystem.
@ -506,33 +524,8 @@ def _install_grub2(device, root_uuid, efi_system_part_uuid=None,
LOG.error(error_msg) LOG.error(error_msg)
raise errors.CommandExecutionError(error_msg) raise errors.CommandExecutionError(error_msg)
# Umount the vfat partitions we may have mounted
LOG.debug("Unmounting all partitions inside the image ...")
try:
utils.execute('chroot %(path)s /bin/sh -c "umount -a -t vfat"' %
{'path': path}, shell=True,
env_variables={'PATH': path_variable})
except processutils.ProcessExecutionError as e:
LOG.warning("Unable to umount vfat partitions. Error: %(error)s",
{'error': e})
for fs in BIND_MOUNTS:
try:
utils.execute('umount', path + fs, attempts=3,
delay_on_retry=True)
except processutils.ProcessExecutionError as e:
umount_binds_fail = True
LOG.warning(umount_warn_msg, {'path': path + fs, 'error': e})
try:
utils.execute('umount', path + '/sys', attempts=3,
delay_on_retry=True)
except processutils.ProcessExecutionError as e:
umount_binds_fail = True
LOG.warning(umount_warn_msg, {'path': path + '/sys', 'error': e})
# If umounting the binds succeed then we can try to delete it # If umounting the binds succeed then we can try to delete it
if not umount_binds_fail: if _umount_all_partitions(path, path_variable, umount_warn_msg):
try: try:
utils.execute('umount', path, attempts=3, delay_on_retry=True) utils.execute('umount', path, attempts=3, delay_on_retry=True)
except processutils.ProcessExecutionError as e: except processutils.ProcessExecutionError as e: