From 1126e8215df2e72c606ec8565a45e085c4143085 Mon Sep 17 00:00:00 2001 From: wangzhe Date: Thu, 10 Aug 2023 16:28:20 +0800 Subject: [PATCH 1/8] install efibootmgr Signed-off-by: wangzhe --- .../el7toel8/actors/efibootorderfix/actor.py | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/repos/system_upgrade/el7toel8/actors/efibootorderfix/actor.py b/repos/system_upgrade/el7toel8/actors/efibootorderfix/actor.py index 41cf6901..d30f3347 100644 --- a/repos/system_upgrade/el7toel8/actors/efibootorderfix/actor.py +++ b/repos/system_upgrade/el7toel8/actors/efibootorderfix/actor.py @@ -1,10 +1,13 @@ import os +import subprocess from leapp.actors import Actor from leapp import reporting from leapp.tags import ChecksPhaseTag, IPUWorkflowTag from leapp.models import FirmwareFacts - +from leapp.libraries.stdlib import api +from leapp.dialogs import Dialog +from leapp.dialogs.components import BooleanComponent class EfiCheckBoot(Actor): """ @@ -16,6 +19,23 @@ class EfiCheckBoot(Actor): produces = (reporting.Report,) tags = (ChecksPhaseTag, IPUWorkflowTag) + dialogs = ( + Dialog( + scope='install_efibootmgr', + reason='Confirmation', + components=( + BooleanComponent( + key='confirm', + label='Install efibootmgr? ' + 'If no, the upgrade process will be interrupted.', + description='efibootmgr package is required on EFI systems.', + default=True, + reason='efibootmgr is required so that we can set proper boot options in between restarts. ' + ), + ) + ), + ) + def process(self): is_system_efi = False has_efibootmgr = os.path.exists('/sbin/efibootmgr') @@ -25,12 +45,23 @@ class EfiCheckBoot(Actor): break if is_system_efi and not has_efibootmgr: + command = "yum install -y efibootmgr" + answer = self.get_answers(self.dialogs[0]) + if answer.get('confirm') == True: + try: + subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as e: + api.current_logger().error('install efibootmgr failed: {}'.format(e)) + else: + api.current_logger().info('install efibootmgr succeeded: {}'.format(command)) + return + reporting.create_report([ reporting.Title('efibootmgr package is required on EFI systems'), reporting.Summary( 'efibootmgr is required so that we can can set proper boot options in between restarts' ), - reporting.Remediation(commands=[['yum', '-y', 'install', 'efibootmgr']]), + reporting.Remediation(commands=[[command]]), reporting.RelatedResource('package', 'efibootmgr'), reporting.Flags([reporting.Flags.INHIBITOR]), reporting.Severity(reporting.Severity.HIGH), -- Gitee From 01ff859edd098bf257cc40c9f48c1f73fd96a98b Mon Sep 17 00:00:00 2001 From: wangzhe Date: Thu, 10 Aug 2023 17:44:39 +0800 Subject: [PATCH 2/8] Upgrade symlinks in root directory to be relative Signed-off-by: wangzhe --- .../actors/checkrootsymlinks/actor.py | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/repos/system_upgrade/el7toel8/actors/checkrootsymlinks/actor.py b/repos/system_upgrade/el7toel8/actors/checkrootsymlinks/actor.py index ab7c5ca0..0666559e 100644 --- a/repos/system_upgrade/el7toel8/actors/checkrootsymlinks/actor.py +++ b/repos/system_upgrade/el7toel8/actors/checkrootsymlinks/actor.py @@ -1,11 +1,14 @@ import os +import subprocess from leapp import reporting from leapp.actors import Actor from leapp.exceptions import StopActorExecutionError from leapp.models import Report, RootDirectory from leapp.tags import IPUWorkflowTag, ChecksPhaseTag - +from leapp.libraries.stdlib import api +from leapp.dialogs import Dialog +from leapp.dialogs.components import BooleanComponent class CheckRootSymlinks(Actor): """ @@ -18,6 +21,23 @@ class CheckRootSymlinks(Actor): consumes = (RootDirectory,) produces = (Report,) tags = (IPUWorkflowTag, ChecksPhaseTag) + + dialogs = ( + Dialog( + scope='change_root_symlinks', + reason='Confirmation', + components=( + BooleanComponent( + key='confirm', + label='Change symlinks in root directory? ' + 'If no, the upgrade process will be interrupted.', + description='Upgrade requires links in root directory to be relative.', + default=True, + reason='After rebooting, parts of the upgrade process can fail if symbolic links in / point to absolute paths. ' + ), + ) + ), + ) def process(self): rootdir = next(self.consume(RootDirectory), None) @@ -32,6 +52,16 @@ class CheckRootSymlinks(Actor): os.path.relpath(item.target, '/'), os.path.join('/', item.name)]) for item in absolute_links] remediation = [['sh', '-c', ' && '.join(commands)]] + answer = self.get_answers(self.dialogs[0]) + if answer.get('confirm') == True: + try: + subprocess.check_output(commands, shell=True, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as e: + api.current_logger().error('change symlinks to relative paths failed: {}'.format(e)) + else: + api.current_logger().info('change symlinks to relative paths succeeded: {}'.format(commands)) + return + reporting.create_report([ reporting.Title('Upgrade requires links in root directory to be relative'), reporting.Summary( -- Gitee From 43795398a57a7c741e63d73ec4e768632e4918e7 Mon Sep 17 00:00:00 2001 From: wangzhe Date: Thu, 10 Aug 2023 19:03:04 +0800 Subject: [PATCH 3/8] remove btrfs module Signed-off-by: wangzhe --- .../el7toel8/actors/checkbtrfs/actor.py | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/repos/system_upgrade/el7toel8/actors/checkbtrfs/actor.py b/repos/system_upgrade/el7toel8/actors/checkbtrfs/actor.py index 74e431f0..a9c530f7 100644 --- a/repos/system_upgrade/el7toel8/actors/checkbtrfs/actor.py +++ b/repos/system_upgrade/el7toel8/actors/checkbtrfs/actor.py @@ -1,8 +1,13 @@ +import subprocess + from leapp.actors import Actor from leapp.models import ActiveKernelModulesFacts from leapp.tags import ChecksPhaseTag, IPUWorkflowTag from leapp import reporting from leapp.reporting import Report, create_report +from leapp.libraries.stdlib import api +from leapp.dialogs import Dialog +from leapp.dialogs.components import BooleanComponent class CheckBtrfs(Actor): @@ -18,16 +23,44 @@ class CheckBtrfs(Actor): produces = (Report,) tags = (ChecksPhaseTag, IPUWorkflowTag) + dialogs = ( + Dialog( + scope='remove_btrfs_module', + reason='Confirmation', + components=( + BooleanComponent( + key='confirm', + label='Remove btrfs module? ' + 'If no, the upgrade process will be interrupted.', + description='Btrfs has been removed from Anolis 8.', + default=True, + reason='Btrfs filesystem was deprecated on versions 6.6 and 7.4 and will not be present in Anolis 8. ' + ), + ) + ), + ) + def process(self): for fact in self.consume(ActiveKernelModulesFacts): for active_module in fact.kernel_modules: if active_module.filename == 'btrfs': + command = "rmmod btrfs" + answer = self.get_answers(self.dialogs[0]) + if answer.get('confirm') == True: + try: + subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as e: + api.current_logger().error('remove btrfs module failed: {}'.format(e)) + else: + api.current_logger().info('remove btrfs module succeeded: {}'.format(command)) + return + create_report([ - reporting.Title('Btrfs has been removed from Anolis8'), + reporting.Title('Btrfs has been removed from Anolis 8'), reporting.Summary( 'The Btrfs file system was introduced as Technology Preview with the ' 'initial release of Red Hat Enterprise Linux 6 and Red Hat Enterprise Linux 7. As of ' - 'versions 6.6 and 7.4 this technology has been deprecated and removed in Anolis8.' + 'versions 6.6 and 7.4 this technology has been deprecated and removed in Anolis 8.' ), reporting.Severity(reporting.Severity.HIGH), reporting.Flags([reporting.Flags.INHIBITOR]), -- Gitee From 21300581a68deb4980c83a84cd873290f214904d Mon Sep 17 00:00:00 2001 From: wangzhe Date: Thu, 10 Aug 2023 21:17:02 +0800 Subject: [PATCH 4/8] cancle nfs mount in fstab Signed-off-by: wangzhe --- .../el7toel8/actors/checknfs/actor.py | 58 ++++++++++++++----- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/repos/system_upgrade/el7toel8/actors/checknfs/actor.py b/repos/system_upgrade/el7toel8/actors/checknfs/actor.py index 47626f74..d322d8e3 100644 --- a/repos/system_upgrade/el7toel8/actors/checknfs/actor.py +++ b/repos/system_upgrade/el7toel8/actors/checknfs/actor.py @@ -1,9 +1,13 @@ +import subprocess + from leapp.actors import Actor from leapp.models import StorageInfo from leapp.reporting import Report, create_report from leapp import reporting from leapp.tags import ChecksPhaseTag, IPUWorkflowTag - +from leapp.libraries.stdlib import api +from leapp.dialogs import Dialog +from leapp.dialogs.components import BooleanComponent class CheckNfs(Actor): """ @@ -16,6 +20,23 @@ class CheckNfs(Actor): consumes = (StorageInfo,) produces = (Report,) tags = (ChecksPhaseTag, IPUWorkflowTag,) + + dialogs = ( + Dialog( + scope='cancle_nfs_mount_in_fstab', + reason='Confirmation', + components=( + BooleanComponent( + key='confirm', + label='Cancle nfs mount in fstab? ' + 'If no, the upgrade process will be interrupted.', + description='Deprecated NFS mount present in /etc/fstab.', + default=True, + reason='NFS is currently not supported by the inplace upgrade.' + ), + ) + ), + ) def process(self): details = "NFS is currently not supported by the inplace upgrade.\n" \ @@ -44,18 +65,29 @@ class CheckNfs(Actor): # mountpoint is not available in the model systemd_nfs_mounts.append(" - {}\n".format(systemdmount.node)) - if any((fstab_nfs_mounts, nfs_mounts, systemd_nfs_mounts)): - if fstab_nfs_mounts: - details += "- NFS shares found in /etc/fstab:\n" - details += ''.join(fstab_nfs_mounts) + if nfs_mounts: + details += "- NFS shares currently mounted:\n" + details += ''.join(nfs_mounts) - if nfs_mounts: - details += "- NFS shares currently mounted:\n" - details += ''.join(nfs_mounts) + if systemd_nfs_mounts: + details += "- NFS mounts configured with systemd-mount:\n" + details += ''.join(systemd_nfs_mounts) - if systemd_nfs_mounts: - details += "- NFS mounts configured with systemd-mount:\n" - details += ''.join(systemd_nfs_mounts) + if fstab_nfs_mounts: + details += "- NFS shares found in /etc/fstab:\n" + details += ''.join(fstab_nfs_mounts) + api.current_logger().info(details) + + command = "sed -i '/nfs/ s/^/#/' /etc/fstab" + answer = self.get_answers(self.dialogs[0]) + if answer.get('confirm') == True: + try: + subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as e: + api.current_logger().error('comment out NFS mount failed: {}'.format(e)) + else: + api.current_logger().info('comment out NFS mount succeeded: {}'.format(command)) + return fstab_related_resource = [reporting.RelatedResource('file', '/etc/fstab')] if fstab_nfs_mounts else [] @@ -64,8 +96,8 @@ class CheckNfs(Actor): reporting.Summary(details), reporting.Severity(reporting.Severity.HIGH), reporting.Tags([ - reporting.Tags.FILESYSTEM, - reporting.Tags.NETWORK + reporting.Tags.FILESYSTEM, + reporting.Tags.NETWORK ]), reporting.Remediation(hint='Disable NFS temporarily for the upgrade if possible.'), reporting.Flags([reporting.Flags.INHIBITOR]), -- Gitee From 5d23fea64cdbb2dc9786ba2f33dd9dd74bce974a Mon Sep 17 00:00:00 2001 From: wangzhe Date: Fri, 11 Aug 2023 10:21:35 +0800 Subject: [PATCH 5/8] Deprecated XFS mount options present in fstab cancle xfs mount in fstab Signed-off-by: wangzhe --- .../actors/checkfstabxfsoptions/actor.py | 26 +++++++++++++++++-- .../libraries/checkfstabxfsoptions.py | 14 +++++++++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/repos/system_upgrade/el7toel8/actors/checkfstabxfsoptions/actor.py b/repos/system_upgrade/el7toel8/actors/checkfstabxfsoptions/actor.py index 06c5f325..1e449430 100644 --- a/repos/system_upgrade/el7toel8/actors/checkfstabxfsoptions/actor.py +++ b/repos/system_upgrade/el7toel8/actors/checkfstabxfsoptions/actor.py @@ -3,7 +3,8 @@ from leapp.libraries.actor import checkfstabxfsoptions from leapp.models import StorageInfo from leapp.reporting import Report from leapp.tags import ChecksPhaseTag, IPUWorkflowTag - +from leapp.dialogs import Dialog +from leapp.dialogs.components import BooleanComponent class CheckFstabXFSOptions(Actor): """ @@ -22,6 +23,27 @@ class CheckFstabXFSOptions(Actor): consumes = (StorageInfo,) produces = (Report,) tags = (ChecksPhaseTag, IPUWorkflowTag) + + dialogs = ( + Dialog( + scope='change_fstab_xfs_options', + reason='Confirmation', + components=( + BooleanComponent( + key='confirm', + label='Change fstab xfs options? ' + 'If no, the upgrade process will be interrupted.', + description='Deprecated XFS mount options present in fstab.', + default=True, + reason='Some XFS mount options are not supported.' + ), + ) + ), + ) + + def is_confirm(self): + answer = self.get_answers(self.dialogs[0]) + return answer.get('confirm') def process(self): - checkfstabxfsoptions.process() + checkfstabxfsoptions.process(self.is_confirm) diff --git a/repos/system_upgrade/el7toel8/actors/checkfstabxfsoptions/libraries/checkfstabxfsoptions.py b/repos/system_upgrade/el7toel8/actors/checkfstabxfsoptions/libraries/checkfstabxfsoptions.py index c74772fb..b10eb7ce 100644 --- a/repos/system_upgrade/el7toel8/actors/checkfstabxfsoptions/libraries/checkfstabxfsoptions.py +++ b/repos/system_upgrade/el7toel8/actors/checkfstabxfsoptions/libraries/checkfstabxfsoptions.py @@ -1,3 +1,5 @@ +import subprocess + from leapp import reporting from leapp.exceptions import StopActorExecutionError from leapp.libraries.stdlib import api @@ -27,7 +29,7 @@ def _get_storage_data(): return storage -def process(): +def process(is_confirm): storage = _get_storage_data() used_removed_options = set() for entry in storage.fstab: @@ -40,6 +42,16 @@ def process(): if not used_removed_options: return + command = "sed -i '/xfs/ s/^/#/' /etc/fstab" + if is_confirm() == True: + try: + subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as e: + api.current_logger().error('comment out XFS mount failed: {}'.format(e)) + else: + api.current_logger().info('comment out XFS mount succeeded: {}'.format(command)) + return + list_separator_fmt = '\n - ' reporting.create_report([ reporting.Title('Deprecated XFS mount options present in FSTAB.'), -- Gitee From 3eaf1c2a3ab200c0383d40e6da8c7ea83d101326 Mon Sep 17 00:00:00 2001 From: wangzhe Date: Fri, 11 Aug 2023 12:45:00 +0800 Subject: [PATCH 6/8] cancle baota inhibitor Signed-off-by: wangzhe --- repos/system_upgrade/el7toel8/actors/checkbaota/actor.py | 1 - 1 file changed, 1 deletion(-) diff --git a/repos/system_upgrade/el7toel8/actors/checkbaota/actor.py b/repos/system_upgrade/el7toel8/actors/checkbaota/actor.py index af256b2d..0c6d8119 100644 --- a/repos/system_upgrade/el7toel8/actors/checkbaota/actor.py +++ b/repos/system_upgrade/el7toel8/actors/checkbaota/actor.py @@ -29,7 +29,6 @@ class Checkbaota(Actor): 'You should first backup your application files and data when baota requires openssl-libs. Secondly, install new version for baota after migration and recover the data.'), reporting.Severity(reporting.Severity.HIGH), reporting.Remediation(hint='Please uninstall baota, and then preupgrade again.'), - reporting.Flags([reporting.Flags.INHIBITOR]) ]) except: pass -- Gitee From 986d2e4639fd9cd4ab80674aee8e8bda5bbf7223 Mon Sep 17 00:00:00 2001 From: wangzhe Date: Mon, 14 Aug 2023 19:56:07 +0800 Subject: [PATCH 7/8] Fix the error that the kernel is not signed by Red Hat Signed-off-by: wangzhe --- .../kernel/checkinstalledkernels/actor.py | 2 +- .../libraries/checkinstalledkernels.py | 31 +++++++++++++++---- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/repos/system_upgrade/el7toel8/actors/kernel/checkinstalledkernels/actor.py b/repos/system_upgrade/el7toel8/actors/kernel/checkinstalledkernels/actor.py index 1c78b529..78f1e5ad 100644 --- a/repos/system_upgrade/el7toel8/actors/kernel/checkinstalledkernels/actor.py +++ b/repos/system_upgrade/el7toel8/actors/kernel/checkinstalledkernels/actor.py @@ -45,7 +45,7 @@ class CheckInstalledKernels(Actor): label='Remove extra kernel? ' 'If no, the upgrade process will be interrupted.', description='Newest installed kernel not in use.', - default=False, + default=True, reason='To ensure a stable upgrade, the machine needs to be ' 'booted into the latest installed kernel.' ), diff --git a/repos/system_upgrade/el7toel8/actors/kernel/checkinstalledkernels/libraries/checkinstalledkernels.py b/repos/system_upgrade/el7toel8/actors/kernel/checkinstalledkernels/libraries/checkinstalledkernels.py index 3c0ccfa8..dee39db9 100644 --- a/repos/system_upgrade/el7toel8/actors/kernel/checkinstalledkernels/libraries/checkinstalledkernels.py +++ b/repos/system_upgrade/el7toel8/actors/kernel/checkinstalledkernels/libraries/checkinstalledkernels.py @@ -77,7 +77,7 @@ def get_newest_evr(pkgs): packages have same name. """ if not pkgs: - return None + return () rpms_evr = _get_pkgs_evr(pkgs) newest_evr = rpms_evr.pop() @@ -89,15 +89,14 @@ def get_newest_evr(pkgs): def get_newer_evr(pkgs, current_evr): if not pkgs: - return None + return () newer_evr = [] rpms_evr = _get_pkgs_evr(pkgs) for pkg in rpms_evr: if labelCompare(current_evr, pkg) < 0: newer_evr.append(pkg) - print(newer_evr) - return newer_evr + return tuple(newer_evr) def process(is_confirm): @@ -111,8 +110,28 @@ def process(is_confirm): # Hypothatical, user is not allowed to install any kernel that is not signed by RH # In case we would like to be cautious, we could check whether there are no other # kernels installed as well. - api.current_logger().error('Cannot find any installed kernel signed by Red Hat.') - raise StopActorExecutionError('Cannot find any installed kernel signed by Red Hat.') + command = "yum install -y kernel" + try: + subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as e: + api.current_logger().error('install kernel failed: {}'.format(e)) + title = 'Cannot find any installed kernel signed by Red Hat' + summary = ('The upgrade process does not handle well the case when kernel that is not signed by Red Hat. ' + 'Please install the RPM package named kernel.') + reporting.create_report([ + reporting.Title(title), + reporting.Summary(summary), + reporting.Severity(reporting.Severity.HIGH), + reporting.Tags([reporting.Tags.KERNEL, reporting.Tags.BOOT]), + reporting.Flags([reporting.Flags.INHIBITOR]), + reporting.Remediation( + hint="Install kernel package", + commands=[[command]], + ), + reporting.RelatedResource('package', 'kernel') + ]) + else: + api.current_logger().info('install kernel succeeded: {}'.format(command)) if len(all_kernel_pkgs) > 1 and architecture.matches_architecture(architecture.ARCH_S390X): # It's temporary solution, so no need to try automatize everything. -- Gitee From e6772cbff697caf917859681bbe8c20367c8e463 Mon Sep 17 00:00:00 2001 From: wangzhe Date: Tue, 15 Aug 2023 16:40:00 +0800 Subject: [PATCH 8/8] Change fstab xfs mount options Signed-off-by: wangzhe --- .../checkfstabxfsoptions/libraries/checkfstabxfsoptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repos/system_upgrade/el7toel8/actors/checkfstabxfsoptions/libraries/checkfstabxfsoptions.py b/repos/system_upgrade/el7toel8/actors/checkfstabxfsoptions/libraries/checkfstabxfsoptions.py index b10eb7ce..8d84939e 100644 --- a/repos/system_upgrade/el7toel8/actors/checkfstabxfsoptions/libraries/checkfstabxfsoptions.py +++ b/repos/system_upgrade/el7toel8/actors/checkfstabxfsoptions/libraries/checkfstabxfsoptions.py @@ -42,7 +42,7 @@ def process(is_confirm): if not used_removed_options: return - command = "sed -i '/xfs/ s/^/#/' /etc/fstab" + command = "sed -i 's/\(\S\+\s\+\S\+\s\+xfs\s\+\)\S\+/\\1defaults/' /etc/fstab" if is_confirm() == True: try: subprocess.check_output(command, shell=True, stderr=subprocess.STDOUT) -- Gitee