diff --git a/SOURCES/leapp-repository-0.16.0-elevate.patch b/SOURCES/leapp-repository-0.16.0-elevate.patch index f3bd54a..7a80324 100644 --- a/SOURCES/leapp-repository-0.16.0-elevate.patch +++ b/SOURCES/leapp-repository-0.16.0-elevate.patch @@ -739,7 +739,7 @@ index da62c50..a8e7d76 100644 def check_version(version): diff --git a/commands/upgrade/__init__.py b/commands/upgrade/__init__.py -index c9c2741..7646459 100644 +index c9c2741..f4f27dd 100644 --- a/commands/upgrade/__init__.py +++ b/commands/upgrade/__init__.py @@ -86,7 +86,7 @@ def upgrade(args, breadcrumbs): @@ -751,16 +751,16 @@ index c9c2741..7646459 100644 logger.info("Using answerfile at %s", answerfile_path) workflow.load_answers(answerfile_path, userchoices_path) -@@ -99,13 +99,16 @@ def upgrade(args, breadcrumbs): +@@ -98,6 +98,8 @@ def upgrade(args, breadcrumbs): + logger.info("Answerfile will be created at %s", answerfile_path) workflow.save_answers(answerfile_path, userchoices_path) - report_errors(workflow.errors) + util.log_errors(workflow.errors, logger) - report_inhibitors(context) + util.log_inhibitors(context, logger) + report_errors(workflow.errors) + report_inhibitors(context) util.generate_report_files(context, report_schema) - report_files = util.get_cfg_files('report', cfg) - log_files = util.get_cfg_files('logs', cfg) +@@ -106,6 +108,7 @@ def upgrade(args, breadcrumbs): report_info(report_files, log_files, answerfile_path, fail=workflow.failure) if workflow.failure: @@ -1266,25 +1266,29 @@ index 0000000..cd6801b + raise diff --git a/repos/system_upgrade/cloudlinux/actors/detectcontrolpanel/actor.py b/repos/system_upgrade/cloudlinux/actors/detectcontrolpanel/actor.py new file mode 100644 -index 0000000..7b947f9 +index 0000000..e8ddc9a --- /dev/null +++ b/repos/system_upgrade/cloudlinux/actors/detectcontrolpanel/actor.py -@@ -0,0 +1,44 @@ +@@ -0,0 +1,53 @@ +from leapp import reporting +from leapp.actors import Actor +from leapp.reporting import Report +from leapp.tags import ChecksPhaseTag, IPUWorkflowTag + +from leapp.libraries.common.cllaunch import run_on_cloudlinux -+from leapp.libraries.actor.detectcontrolpanel import detect_panel, UNKNOWN_NAME ++from leapp.libraries.actor.detectcontrolpanel import ( ++ detect_panel, ++ UNKNOWN_NAME, ++ CPANEL_NAME, ++) + + +class DetectControlPanel(Actor): + """ -+ Check for a presence of a control panel, and inhibit the upgrade if one is found. ++ Check for a presence of a control panel, and inhibit the upgrade if an unsupported one is found. + """ + -+ name = 'detect_control_panel' ++ name = "detect_control_panel" + consumes = () + produces = (Report,) + tags = (ChecksPhaseTag, IPUWorkflowTag) @@ -1293,27 +1297,32 @@ index 0000000..7b947f9 + def process(self): + panel = detect_panel() + -+ if panel: ++ if panel == CPANEL_NAME: ++ self.log.debug('cPanel detected, upgrade proceeding') ++ elif panel: + summary_info = "Detected panel: {}".format(panel) + if panel == UNKNOWN_NAME: -+ summary_info = "Legacy custom panel script detected in CloudLinux configuration" ++ summary_info = ( ++ "Legacy custom panel script detected in CloudLinux configuration" ++ ) + + # Block the upgrade on any systems with a panel detected. -+ reporting.create_report([ -+ reporting.Title("The upgrade process should not be run on systems with a control panel present."), -+ reporting.Summary( -+ "Systems with a control panel present are not supported at the moment." -+ " No control panels are currently included in the Leapp database, which" -+ " makes loss of functionality after the upgrade extremely likely." -+ " {}.".format(summary_info)), -+ reporting.Severity(reporting.Severity.HIGH), -+ reporting.Tags([ -+ reporting.Tags.OS_FACTS -+ ]), -+ reporting.Flags([ -+ reporting.Flags.INHIBITOR -+ ]) -+ ]) ++ reporting.create_report( ++ [ ++ reporting.Title( ++ "The upgrade process should not be run on systems with a control panel present." ++ ), ++ reporting.Summary( ++ "Systems with a control panel present are not supported at the moment." ++ " No control panels are currently included in the Leapp database, which" ++ " makes loss of functionality after the upgrade extremely likely." ++ " {}.".format(summary_info) ++ ), ++ reporting.Severity(reporting.Severity.HIGH), ++ reporting.Tags([reporting.Tags.OS_FACTS]), ++ reporting.Flags([reporting.Flags.INHIBITOR]), ++ ] ++ ) diff --git a/repos/system_upgrade/cloudlinux/actors/detectcontrolpanel/libraries/detectcontrolpanel.py b/repos/system_upgrade/cloudlinux/actors/detectcontrolpanel/libraries/detectcontrolpanel.py new file mode 100644 index 0000000..15b797a @@ -1573,15 +1582,16 @@ index 0000000..0a059f1 + api.produce(CustomTargetRepositoryFile(file=full_repo_path)) diff --git a/repos/system_upgrade/cloudlinux/actors/switchclnchannel/actor.py b/repos/system_upgrade/cloudlinux/actors/switchclnchannel/actor.py new file mode 100644 -index 0000000..ae01af1 +index 0000000..784075a --- /dev/null +++ b/repos/system_upgrade/cloudlinux/actors/switchclnchannel/actor.py -@@ -0,0 +1,33 @@ +@@ -0,0 +1,58 @@ +from leapp.actors import Actor +from leapp.libraries.stdlib import api +from leapp.tags import DownloadPhaseTag, IPUWorkflowTag +from leapp.libraries.stdlib import CalledProcessError, run +from leapp.libraries.common.cllaunch import run_on_cloudlinux ++from leapp import reporting + + +class SwitchClnChannel(Actor): @@ -1589,18 +1599,18 @@ index 0000000..ae01af1 + Switch CLN channel from 7 to 8 to be able to download upgrade packages + """ + -+ name = 'switch_cln_channel' ++ name = "switch_cln_channel" + consumes = () + produces = () + tags = (IPUWorkflowTag, DownloadPhaseTag.Before) + -+ switch_bin = '/usr/sbin/cln-switch-channel' ++ switch_bin = "/usr/sbin/cln-switch-channel" + + @run_on_cloudlinux + def process(self): -+ switch_cmd = [self.switch_bin, '-t', '8', '-o', '-f'] -+ yum_clean_cmd = ['yum', 'clean', 'all'] -+ update_release_cmd = ['yum', 'update', '-y', 'cloudlinux-release'] ++ switch_cmd = [self.switch_bin, "-t", "8", "-o", "-f"] ++ yum_clean_cmd = ["yum", "clean", "all"] ++ update_release_cmd = ["yum", "update", "-y", "cloudlinux-release"] + try: + res = run(switch_cmd) + self.log.debug('Command "%s" result: %s', switch_cmd, res) @@ -1608,8 +1618,32 @@ index 0000000..ae01af1 + self.log.debug('Command "%s" result: %s', yum_clean_cmd, res) + res = run(update_release_cmd) + self.log.debug('Command "%s" result: %s', update_release_cmd, res) ++ except CalledProcessError as e: ++ reporting.create_report( ++ [ ++ reporting.Title( ++ "Failed to switch CloudLinux Network channel from 7 to 8." ++ ), ++ reporting.Summary( ++ "Command {} failed with exit code {}." ++ " The most probable cause of that is a problem with this system's" ++ " CloudLinux Network registration.".format(e.command, e.exit_code) ++ ), ++ reporting.Remediation( ++ hint="Check the state of this system's registration with \'rhn_check\'." ++ " Attempt to re-register the system with \'rhnreg_ks --force\'." ++ ), ++ reporting.Severity(reporting.Severity.HIGH), ++ reporting.Tags( ++ [reporting.Tags.OS_FACTS, reporting.Tags.AUTHENTICATION] ++ ), ++ reporting.Flags([reporting.Flags.INHIBITOR]), ++ ] ++ ) + except OSError as e: -+ api.current_logger().error('Could not call RHN command: Message: %s', str(e), exc_info=True) ++ api.current_logger().error( ++ "Could not call RHN command: Message: %s", str(e), exc_info=True ++ ) diff --git a/repos/system_upgrade/cloudlinux/actors/updatecagefs/actor.py b/repos/system_upgrade/cloudlinux/actors/updatecagefs/actor.py new file mode 100644 index 0000000..71e3c66 @@ -3255,10 +3289,10 @@ index 0000000..1325647 + scan_vendor_repomaps() diff --git a/repos/system_upgrade/common/actors/vendorrepositoriesmapping/libraries/vendorrepositoriesmapping.py b/repos/system_upgrade/common/actors/vendorrepositoriesmapping/libraries/vendorrepositoriesmapping.py new file mode 100644 -index 0000000..ba27cbb +index 0000000..32ccf58 --- /dev/null +++ b/repos/system_upgrade/common/actors/vendorrepositoriesmapping/libraries/vendorrepositoriesmapping.py -@@ -0,0 +1,76 @@ +@@ -0,0 +1,72 @@ +import os + +from leapp.libraries.common.config.version import get_target_major_version, get_source_major_version @@ -3277,22 +3311,17 @@ index 0000000..ba27cbb + try: + repomap_data = RepoMapData.load_from_dict(json_data) + -+ # What repositories associated with the vendor are expected to be present -+ # on a system with the current major version? -+ # We need to know that to know what to look for in currently enabled -+ # system repositories. ++ source_major = get_source_major_version() ++ target_major = get_target_major_version() ++ + api.produce(VendorSourceRepos( + vendor=vendor_name, -+ source_repoids=repomap_data.get_version_repoids(get_source_major_version()) ++ source_repoids=repomap_data.get_version_repoids(source_major) + )) + -+ mapping = repomap_data.get_mappings(get_source_major_version(), get_target_major_version()) -+ valid_major_versions = [get_source_major_version(), get_target_major_version()] ++ mapping = repomap_data.get_mappings(source_major, target_major) ++ valid_major_versions = [source_major, target_major] + -+ # This RepositoriesMapping message is different from the one produced by the -+ # builtin actor because of the vendor field. -+ # It can be used later to distinguish the messages provided from vendors and the one -+ # from the OS upgrade data. + api.produce(RepositoriesMapping( + mapping=mapping, + repositories=repomap_data.get_repositories(valid_major_versions), @@ -3301,8 +3330,9 @@ index 0000000..ba27cbb + except ModelViolationError as err: + err_message = ( + 'The repository mapping file is invalid: ' -+ 'the JSON does not match required schema (wrong field type/value): {}' -+ .format(err) ++ 'the JSON does not match required schema (wrong field type/value): {}. ' ++ 'Ensure that the current upgrade path is correct and is present in the mappings: {} -> {}' ++ .format(err, source_major, target_major) + ) + inhibit_upgrade(err_message) + except KeyError as err: @@ -3424,6 +3454,44 @@ index 1c58148..37313b6 100644 return data except EnvironmentError: _raise_error(local_path, "File {lp} exists but couldn't be read".format(lp=local_path)) +diff --git a/repos/system_upgrade/common/libraries/overlaygen.py b/repos/system_upgrade/common/libraries/overlaygen.py +index 6a2f5aa..51030fd 100644 +--- a/repos/system_upgrade/common/libraries/overlaygen.py ++++ b/repos/system_upgrade/common/libraries/overlaygen.py +@@ -14,11 +14,15 @@ OVERLAY_DO_NOT_MOUNT = ('tmpfs', 'devpts', 'sysfs', 'proc', 'cramfs', 'sysv', 'v + MountPoints = namedtuple('MountPoints', ['fs_file', 'fs_vfstype']) + + +-def _ensure_enough_diskimage_space(space_needed, directory): ++def _ensure_enough_diskimage_space(space_needed, directory, xfs_mountpoint_count): + stat = os.statvfs(directory) + if (stat.f_frsize * stat.f_bavail) < (space_needed * 1024 * 1024): + message = ('Not enough space available for creating required disk images in {directory}. ' + + 'Needed: {space_needed} MiB').format(space_needed=space_needed, directory=directory) ++ # An arbitrary cutoff, but "how many XFS mountpoints is too much" is subjective. ++ if xfs_mountpoint_count > 10: ++ message += (". Hint: there are {} XFS mountpoints with ftype=0 on the system. Space " ++ "required is calculated according to that amount".format(xfs_mountpoint_count)) + api.current_logger().error(message) + raise StopActorExecutionError(message) + +@@ -53,13 +57,14 @@ def _prepare_required_mounts(scratch_dir, mounts_dir, mount_points, xfs_info): + if not xfs_info.mountpoints_without_ftype: + return result + +- space_needed = _overlay_disk_size() * len(xfs_info.mountpoints_without_ftype) ++ xfs_noftype_mounts = len(xfs_info.mountpoints_without_ftype) ++ space_needed = _overlay_disk_size() * xfs_noftype_mounts + disk_images_directory = os.path.join(scratch_dir, 'diskimages') + + # Ensure we cleanup old disk images before we check for space contraints. + run(['rm', '-rf', disk_images_directory]) + _create_diskimages_dir(scratch_dir, disk_images_directory) +- _ensure_enough_diskimage_space(space_needed, scratch_dir) ++ _ensure_enough_diskimage_space(space_needed, scratch_dir, xfs_noftype_mounts) + + mount_names = [mount_point.fs_file for mount_point in mount_points] + diff --git a/repos/system_upgrade/common/libraries/repomaputils.py b/repos/system_upgrade/common/libraries/repomaputils.py new file mode 100644 index 0000000..5c41620 @@ -3685,7 +3753,7 @@ index 0000000..014b7af +class VendorTopic(Topic): + name = 'vendor_topic' diff --git a/repos/system_upgrade/el7toel8/actors/networkmanagerupdateconnections/actor.py b/repos/system_upgrade/el7toel8/actors/networkmanagerupdateconnections/actor.py -index 69ca0f0..c488eb0 100644 +index 69ca0f0..a7d7db1 100644 --- a/repos/system_upgrade/el7toel8/actors/networkmanagerupdateconnections/actor.py +++ b/repos/system_upgrade/el7toel8/actors/networkmanagerupdateconnections/actor.py @@ -2,6 +2,7 @@ from leapp.actors import Actor @@ -3696,14 +3764,22 @@ index 69ca0f0..c488eb0 100644 class NetworkManagerUpdateConnections(Actor): -@@ -26,8 +27,22 @@ class NetworkManagerUpdateConnections(Actor): +@@ -26,9 +27,24 @@ class NetworkManagerUpdateConnections(Actor): return try: - r = run(['/usr/bin/python3', 'tools/nm-update-client-ids.py'])['stdout'] - self.log.info('Updated client-ids: {}'.format(r)) +- except (OSError, CalledProcessError) as e: +- self.log.warning('Error calling nm-update-client-ids script: {}'.format(e)) + r = run(['/usr/bin/python3', 'tools/nm-update-client-ids.py']) -+ if r['exit_code'] == 79: ++ ++ self.log.info('Updated client-ids: {}'.format(r['stdout'])) ++ except OSError as e: ++ self.log.warning('OSError calling nm-update-client-ids script: {}'.format(e)) ++ except CalledProcessError as e: ++ self.log.warning('CalledProcessError calling nm-update-client-ids script: {}'.format(e)) ++ if e.exit_code == 79: + title = 'NetworkManager connection update failed - PyGObject bindings for NetworkManager not found.' + summary = 'When using dhcp=dhclient on Red Hat Enterprise Linux 7, a non-hexadecimal ' \ + 'client-id (a string) is sent on the wire as is. On Red Hat Enterprise Linux 8, a zero ' \ @@ -3715,12 +3791,8 @@ index 69ca0f0..c488eb0 100644 + reporting.Severity(reporting.Severity.MEDIUM), + reporting.Tags([reporting.Tags.NETWORK]) + ]) -+ continue -+ -+ self.log.info('Updated client-ids: {}'.format(r['stdout'])) - except (OSError, CalledProcessError) as e: - self.log.warning('Error calling nm-update-client-ids script: {}'.format(e)) + break diff --git a/repos/system_upgrade/el7toel8/actors/networkmanagerupdateconnections/tools/nm-update-client-ids.py b/repos/system_upgrade/el7toel8/actors/networkmanagerupdateconnections/tools/nm-update-client-ids.py index 923bf80..9972204 100755 --- a/repos/system_upgrade/el7toel8/actors/networkmanagerupdateconnections/tools/nm-update-client-ids.py diff --git a/SPECS/leapp-repository.spec b/SPECS/leapp-repository.spec index 9bd9a9c..d3a1e7e 100644 --- a/SPECS/leapp-repository.spec +++ b/SPECS/leapp-repository.spec @@ -43,7 +43,7 @@ py2_byte_compile "%1" "%2"} Epoch: 1 Name: leapp-repository Version: 0.16.0 -Release: 6%{?dist}.elevate.6 +Release: 6%{?dist}.elevate.7 Summary: Repositories for leapp License: ASL 2.0