- Fix the calculation of the required free space on each partitions/volume for the upgrade transactions - Create source overlay images with dynamic sizes to optimize disk space consumption - Update GRUB2 when /boot resides on multiple devices aggregated in RAID - Use new leapp CLI API which provides better report summary output - Introduce possibility to add (custom) kernel drivers to initramfs - Detect and report use of deprecated Xorg drivers - Fix the generation of the report about hybrid images - Inhibit the upgrade when unsupported x86-64 microarchitecture is detected - Minor improvements and fixes of various reports - Requires leapp-framework 4.0 - Update leapp data files - Resolves: rhbz#2140011, rhbz#2144304, rhbz#2174095, rhbz#2219544, rhbz#2215997
162 lines
7.5 KiB
Diff
162 lines
7.5 KiB
Diff
From 591cdb865befff8035d53b861d9ff95b5704ed64 Mon Sep 17 00:00:00 2001
|
|
From: Petr Stodulka <pstodulk@redhat.com>
|
|
Date: Fri, 14 Jul 2023 17:32:46 +0200
|
|
Subject: [PATCH 41/42] upgradeinitramfsgenerator: Check the free space prior
|
|
the initeramfs generation
|
|
|
|
Under rare conditions it's possible the last piece free space
|
|
is consumed when the upgrade initramfs is generated. It's hard
|
|
to hit this problems right now without additional customisations
|
|
that consume more space than we expect. However, when it happens,
|
|
it not good situation. From this point, check the remaining free
|
|
space on the FS hosting the container. In case we have less than
|
|
500MB, do not even try. Possibly we will increase the value in future,
|
|
but consider it good enough for now.
|
|
---
|
|
.../libraries/upgradeinitramfsgenerator.py | 73 +++++++++++++++++++
|
|
.../unit_test_upgradeinitramfsgenerator.py | 14 ++++
|
|
2 files changed, 87 insertions(+)
|
|
|
|
diff --git a/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/libraries/upgradeinitramfsgenerator.py b/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/libraries/upgradeinitramfsgenerator.py
|
|
index f141d9e3..5a686a47 100644
|
|
--- a/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/libraries/upgradeinitramfsgenerator.py
|
|
+++ b/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/libraries/upgradeinitramfsgenerator.py
|
|
@@ -20,6 +20,7 @@ from leapp.utils.deprecation import suppress_deprecation
|
|
|
|
INITRAM_GEN_SCRIPT_NAME = 'generate-initram.sh'
|
|
DRACUT_DIR = '/dracut'
|
|
+DEDICATED_LEAPP_PART_URL = 'https://access.redhat.com/solutions/7011704'
|
|
|
|
|
|
def _get_target_kernel_version(context):
|
|
@@ -231,6 +232,77 @@ def prepare_userspace_for_initram(context):
|
|
_copy_files(context, files)
|
|
|
|
|
|
+def _get_fspace(path, convert_to_mibs=False, coefficient=1):
|
|
+ """
|
|
+ Return the free disk space on given path.
|
|
+
|
|
+ The default is in bytes, but if convert_to_mibs is True, return MiBs instead.
|
|
+
|
|
+ Raises OSError if nothing exists on the given `path`.
|
|
+
|
|
+ :param path: Path to an existing file or directory
|
|
+ :type path: str
|
|
+ :param convert_to_mibs: If True, convert the value to MiBs
|
|
+ :type convert_to_mibs: bool
|
|
+ :param coefficient: Coefficient to multiply the free space (e.g. 0.9 to have it 10% lower). Max: 1
|
|
+ :type coefficient: float
|
|
+ :rtype: int
|
|
+ """
|
|
+ # TODO(pstodulk): discuss the function params
|
|
+ # NOTE(pstodulk): This func is copied from the overlaygen.py lib
|
|
+ # probably it would make sense to make it public in the utils.py lib,
|
|
+ # but for now, let's keep it private
|
|
+ stat = os.statvfs(path)
|
|
+
|
|
+ coefficient = min(coefficient, 1)
|
|
+ fspace_bytes = int(stat.f_frsize * stat.f_bavail * coefficient)
|
|
+ if convert_to_mibs:
|
|
+ return int(fspace_bytes / 1024 / 1024) # noqa: W1619; pylint: disable=old-division
|
|
+ return fspace_bytes
|
|
+
|
|
+
|
|
+def _check_free_space(context):
|
|
+ """
|
|
+ Raise StopActorExecutionError if there is less than 500MB of free space available.
|
|
+
|
|
+ If there is not enough free space in the context, the initramfs will not be
|
|
+ generated successfully and it's hard to discover what was the issue. Also
|
|
+ the missing space is able to kill the leapp itself - trying to write to the
|
|
+ leapp.db when the FS hosting /var/lib/leapp is full, kills the framework
|
|
+ and the actor execution too - so there is no gentle way to handle such
|
|
+ exceptions when it happens. From this point, let's rather check the available
|
|
+ space in advance and stop the execution when it happens.
|
|
+
|
|
+ It is not expected to hit this issue, but I was successful and I know
|
|
+ it's still possible even with all other changes (just it's much harder
|
|
+ now to hit it). So adding this seatbelt, that is not 100% bulletproof,
|
|
+ but I call it good enough.
|
|
+
|
|
+ Currently protecting last 500MB. In case of problems, we can increase
|
|
+ the value.
|
|
+ """
|
|
+ message = 'There is not enough space on the file system hosting /var/lib/leapp.'
|
|
+ hint = (
|
|
+ 'Increase the free space on the filesystem hosting'
|
|
+ ' /var/lib/leapp by 500MB at minimum (suggested 1500MB).\n\n'
|
|
+ 'It is also a good practice to create dedicated partition'
|
|
+ ' for /var/lib/leapp when more space is needed, which can be'
|
|
+ ' dropped after the system upgrade is fully completed.'
|
|
+ ' For more info, see: {}'
|
|
+ .format(DEDICATED_LEAPP_PART_URL)
|
|
+ )
|
|
+ detail = (
|
|
+ 'Remaining free space is lower than 500MB which is not enough to'
|
|
+ ' be able to generate the upgrade initramfs. '
|
|
+ )
|
|
+
|
|
+ if _get_fspace(context.base_dir, convert_to_mibs=True) < 500:
|
|
+ raise StopActorExecutionError(
|
|
+ message=message,
|
|
+ details={'hint': hint, 'detail': detail}
|
|
+ )
|
|
+
|
|
+
|
|
def generate_initram_disk(context):
|
|
"""
|
|
Function to actually execute the init ramdisk creation.
|
|
@@ -238,6 +310,7 @@ def generate_initram_disk(context):
|
|
Includes handling of specified dracut and kernel modules from the host when
|
|
needed. The check for the 'conflicting' modules is in a separate actor.
|
|
"""
|
|
+ _check_free_space(context)
|
|
env = {}
|
|
if get_target_major_version() == '9':
|
|
env = {'SYSTEMD_SECCOMP': '0'}
|
|
diff --git a/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/tests/unit_test_upgradeinitramfsgenerator.py b/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/tests/unit_test_upgradeinitramfsgenerator.py
|
|
index a2f1c837..8068e177 100644
|
|
--- a/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/tests/unit_test_upgradeinitramfsgenerator.py
|
|
+++ b/repos/system_upgrade/common/actors/initramfs/upgradeinitramfsgenerator/tests/unit_test_upgradeinitramfsgenerator.py
|
|
@@ -10,6 +10,7 @@ from leapp.libraries.common.testutils import CurrentActorMocked, logger_mocked,
|
|
from leapp.utils.deprecation import suppress_deprecation
|
|
|
|
from leapp.models import ( # isort:skip
|
|
+ FIPSInfo,
|
|
RequiredUpgradeInitramPackages, # deprecated
|
|
UpgradeDracutModule, # deprecated
|
|
BootContent,
|
|
@@ -250,6 +251,16 @@ def test_prepare_userspace_for_initram(monkeypatch, adjust_cwd, input_msgs, pkgs
|
|
assert _sort_files(upgradeinitramfsgenerator._copy_files.args[1]) == _files
|
|
|
|
|
|
+class MockedGetFspace(object):
|
|
+ def __init__(self, space):
|
|
+ self.space = space
|
|
+
|
|
+ def __call__(self, dummy_path, convert_to_mibs=False):
|
|
+ if not convert_to_mibs:
|
|
+ return self.space
|
|
+ return int(self.space / 1024 / 1024) # noqa: W1619; pylint: disable=old-division
|
|
+
|
|
+
|
|
@pytest.mark.parametrize('input_msgs,dracut_modules,kernel_modules', [
|
|
# test dracut modules with UpgradeDracutModule(s) - orig functionality
|
|
(gen_UDM_list(MODULES[0]), MODULES[0], []),
|
|
@@ -275,8 +286,11 @@ def test_generate_initram_disk(monkeypatch, input_msgs, dracut_modules, kernel_m
|
|
monkeypatch.setattr(upgradeinitramfsgenerator, '_get_target_kernel_version', lambda _: '')
|
|
monkeypatch.setattr(upgradeinitramfsgenerator, 'copy_kernel_modules', MockedCopyArgs())
|
|
monkeypatch.setattr(upgradeinitramfsgenerator, 'copy_boot_files', lambda dummy: None)
|
|
+ monkeypatch.setattr(upgradeinitramfsgenerator, '_get_fspace', MockedGetFspace(2*2**30))
|
|
upgradeinitramfsgenerator.generate_initram_disk(context)
|
|
|
|
+ # TODO(pstodulk): add tests for the check of the free space (sep. from this func)
|
|
+
|
|
# test now just that all modules have been passed for copying - so we know
|
|
# all modules have been consumed
|
|
detected_dracut_modules = set()
|
|
--
|
|
2.41.0
|
|
|