Update ELevate patch

This commit is contained in:
Andrew Lukoshko 2023-02-13 13:44:13 +01:00
parent 3d5217f69d
commit 94fcffdb9c
2 changed files with 132 additions and 60 deletions

View File

@ -739,7 +739,7 @@ index da62c50..a8e7d76 100644
def check_version(version): def check_version(version):
diff --git a/commands/upgrade/__init__.py b/commands/upgrade/__init__.py 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 --- a/commands/upgrade/__init__.py
+++ b/commands/upgrade/__init__.py +++ b/commands/upgrade/__init__.py
@@ -86,7 +86,7 @@ def upgrade(args, breadcrumbs): @@ -86,7 +86,7 @@ def upgrade(args, breadcrumbs):
@ -751,16 +751,16 @@ index c9c2741..7646459 100644
logger.info("Using answerfile at %s", answerfile_path) logger.info("Using answerfile at %s", answerfile_path)
workflow.load_answers(answerfile_path, userchoices_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) logger.info("Answerfile will be created at %s", answerfile_path)
workflow.save_answers(answerfile_path, userchoices_path) workflow.save_answers(answerfile_path, userchoices_path)
report_errors(workflow.errors)
+ util.log_errors(workflow.errors, logger) + util.log_errors(workflow.errors, logger)
report_inhibitors(context)
+ util.log_inhibitors(context, logger) + util.log_inhibitors(context, logger)
report_errors(workflow.errors)
report_inhibitors(context)
util.generate_report_files(context, report_schema) util.generate_report_files(context, report_schema)
report_files = util.get_cfg_files('report', cfg) @@ -106,6 +108,7 @@ def upgrade(args, breadcrumbs):
log_files = util.get_cfg_files('logs', cfg)
report_info(report_files, log_files, answerfile_path, fail=workflow.failure) report_info(report_files, log_files, answerfile_path, fail=workflow.failure)
if workflow.failure: if workflow.failure:
@ -1266,25 +1266,29 @@ index 0000000..cd6801b
+ raise + raise
diff --git a/repos/system_upgrade/cloudlinux/actors/detectcontrolpanel/actor.py b/repos/system_upgrade/cloudlinux/actors/detectcontrolpanel/actor.py diff --git a/repos/system_upgrade/cloudlinux/actors/detectcontrolpanel/actor.py b/repos/system_upgrade/cloudlinux/actors/detectcontrolpanel/actor.py
new file mode 100644 new file mode 100644
index 0000000..7b947f9 index 0000000..e8ddc9a
--- /dev/null --- /dev/null
+++ b/repos/system_upgrade/cloudlinux/actors/detectcontrolpanel/actor.py +++ b/repos/system_upgrade/cloudlinux/actors/detectcontrolpanel/actor.py
@@ -0,0 +1,44 @@ @@ -0,0 +1,53 @@
+from leapp import reporting +from leapp import reporting
+from leapp.actors import Actor +from leapp.actors import Actor
+from leapp.reporting import Report +from leapp.reporting import Report
+from leapp.tags import ChecksPhaseTag, IPUWorkflowTag +from leapp.tags import ChecksPhaseTag, IPUWorkflowTag
+ +
+from leapp.libraries.common.cllaunch import run_on_cloudlinux +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): +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 = () + consumes = ()
+ produces = (Report,) + produces = (Report,)
+ tags = (ChecksPhaseTag, IPUWorkflowTag) + tags = (ChecksPhaseTag, IPUWorkflowTag)
@ -1293,27 +1297,32 @@ index 0000000..7b947f9
+ def process(self): + def process(self):
+ panel = detect_panel() + panel = detect_panel()
+ +
+ if panel: + if panel == CPANEL_NAME:
+ self.log.debug('cPanel detected, upgrade proceeding')
+ elif panel:
+ summary_info = "Detected panel: {}".format(panel) + summary_info = "Detected panel: {}".format(panel)
+ if panel == UNKNOWN_NAME: + 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. + # Block the upgrade on any systems with a panel detected.
+ reporting.create_report([ + reporting.create_report(
+ reporting.Title("The upgrade process should not be run on systems with a control panel present."), + [
+ reporting.Summary( + reporting.Title(
+ "Systems with a control panel present are not supported at the moment." + "The upgrade process should not be run on systems with a control panel present."
+ " No control panels are currently included in the Leapp database, which" + ),
+ " makes loss of functionality after the upgrade extremely likely." + reporting.Summary(
+ " {}.".format(summary_info)), + "Systems with a control panel present are not supported at the moment."
+ reporting.Severity(reporting.Severity.HIGH), + " No control panels are currently included in the Leapp database, which"
+ reporting.Tags([ + " makes loss of functionality after the upgrade extremely likely."
+ reporting.Tags.OS_FACTS + " {}.".format(summary_info)
+ ]), + ),
+ reporting.Flags([ + reporting.Severity(reporting.Severity.HIGH),
+ reporting.Flags.INHIBITOR + 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 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 new file mode 100644
index 0000000..15b797a index 0000000..15b797a
@ -1573,15 +1582,16 @@ index 0000000..0a059f1
+ api.produce(CustomTargetRepositoryFile(file=full_repo_path)) + 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 diff --git a/repos/system_upgrade/cloudlinux/actors/switchclnchannel/actor.py b/repos/system_upgrade/cloudlinux/actors/switchclnchannel/actor.py
new file mode 100644 new file mode 100644
index 0000000..ae01af1 index 0000000..784075a
--- /dev/null --- /dev/null
+++ b/repos/system_upgrade/cloudlinux/actors/switchclnchannel/actor.py +++ b/repos/system_upgrade/cloudlinux/actors/switchclnchannel/actor.py
@@ -0,0 +1,33 @@ @@ -0,0 +1,58 @@
+from leapp.actors import Actor +from leapp.actors import Actor
+from leapp.libraries.stdlib import api +from leapp.libraries.stdlib import api
+from leapp.tags import DownloadPhaseTag, IPUWorkflowTag +from leapp.tags import DownloadPhaseTag, IPUWorkflowTag
+from leapp.libraries.stdlib import CalledProcessError, run +from leapp.libraries.stdlib import CalledProcessError, run
+from leapp.libraries.common.cllaunch import run_on_cloudlinux +from leapp.libraries.common.cllaunch import run_on_cloudlinux
+from leapp import reporting
+ +
+ +
+class SwitchClnChannel(Actor): +class SwitchClnChannel(Actor):
@ -1589,18 +1599,18 @@ index 0000000..ae01af1
+ Switch CLN channel from 7 to 8 to be able to download upgrade packages + Switch CLN channel from 7 to 8 to be able to download upgrade packages
+ """ + """
+ +
+ name = 'switch_cln_channel' + name = "switch_cln_channel"
+ consumes = () + consumes = ()
+ produces = () + produces = ()
+ tags = (IPUWorkflowTag, DownloadPhaseTag.Before) + tags = (IPUWorkflowTag, DownloadPhaseTag.Before)
+ +
+ switch_bin = '/usr/sbin/cln-switch-channel' + switch_bin = "/usr/sbin/cln-switch-channel"
+ +
+ @run_on_cloudlinux + @run_on_cloudlinux
+ def process(self): + def process(self):
+ switch_cmd = [self.switch_bin, '-t', '8', '-o', '-f'] + switch_cmd = [self.switch_bin, "-t", "8", "-o", "-f"]
+ yum_clean_cmd = ['yum', 'clean', 'all'] + yum_clean_cmd = ["yum", "clean", "all"]
+ update_release_cmd = ['yum', 'update', '-y', 'cloudlinux-release'] + update_release_cmd = ["yum", "update", "-y", "cloudlinux-release"]
+ try: + try:
+ res = run(switch_cmd) + res = run(switch_cmd)
+ self.log.debug('Command "%s" result: %s', switch_cmd, res) + 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) + self.log.debug('Command "%s" result: %s', yum_clean_cmd, res)
+ res = run(update_release_cmd) + res = run(update_release_cmd)
+ self.log.debug('Command "%s" result: %s', update_release_cmd, res) + 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: + 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 diff --git a/repos/system_upgrade/cloudlinux/actors/updatecagefs/actor.py b/repos/system_upgrade/cloudlinux/actors/updatecagefs/actor.py
new file mode 100644 new file mode 100644
index 0000000..71e3c66 index 0000000..71e3c66
@ -3255,10 +3289,10 @@ index 0000000..1325647
+ scan_vendor_repomaps() + 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 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 new file mode 100644
index 0000000..ba27cbb index 0000000..32ccf58
--- /dev/null --- /dev/null
+++ b/repos/system_upgrade/common/actors/vendorrepositoriesmapping/libraries/vendorrepositoriesmapping.py +++ b/repos/system_upgrade/common/actors/vendorrepositoriesmapping/libraries/vendorrepositoriesmapping.py
@@ -0,0 +1,76 @@ @@ -0,0 +1,72 @@
+import os +import os
+ +
+from leapp.libraries.common.config.version import get_target_major_version, get_source_major_version +from leapp.libraries.common.config.version import get_target_major_version, get_source_major_version
@ -3277,22 +3311,17 @@ index 0000000..ba27cbb
+ try: + try:
+ repomap_data = RepoMapData.load_from_dict(json_data) + repomap_data = RepoMapData.load_from_dict(json_data)
+ +
+ # What repositories associated with the vendor are expected to be present + source_major = get_source_major_version()
+ # on a system with the current major version? + target_major = get_target_major_version()
+ # We need to know that to know what to look for in currently enabled +
+ # system repositories.
+ api.produce(VendorSourceRepos( + api.produce(VendorSourceRepos(
+ vendor=vendor_name, + 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()) + mapping = repomap_data.get_mappings(source_major, target_major)
+ valid_major_versions = [get_source_major_version(), get_target_major_version()] + 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( + api.produce(RepositoriesMapping(
+ mapping=mapping, + mapping=mapping,
+ repositories=repomap_data.get_repositories(valid_major_versions), + repositories=repomap_data.get_repositories(valid_major_versions),
@ -3301,8 +3330,9 @@ index 0000000..ba27cbb
+ except ModelViolationError as err: + except ModelViolationError as err:
+ err_message = ( + err_message = (
+ 'The repository mapping file is invalid: ' + 'The repository mapping file is invalid: '
+ 'the JSON does not match required schema (wrong field type/value): {}' + 'the JSON does not match required schema (wrong field type/value): {}. '
+ .format(err) + 'Ensure that the current upgrade path is correct and is present in the mappings: {} -> {}'
+ .format(err, source_major, target_major)
+ ) + )
+ inhibit_upgrade(err_message) + inhibit_upgrade(err_message)
+ except KeyError as err: + except KeyError as err:
@ -3424,6 +3454,44 @@ index 1c58148..37313b6 100644
return data return data
except EnvironmentError: except EnvironmentError:
_raise_error(local_path, "File {lp} exists but couldn't be read".format(lp=local_path)) _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 diff --git a/repos/system_upgrade/common/libraries/repomaputils.py b/repos/system_upgrade/common/libraries/repomaputils.py
new file mode 100644 new file mode 100644
index 0000000..5c41620 index 0000000..5c41620
@ -3685,7 +3753,7 @@ index 0000000..014b7af
+class VendorTopic(Topic): +class VendorTopic(Topic):
+ name = 'vendor_topic' + name = 'vendor_topic'
diff --git a/repos/system_upgrade/el7toel8/actors/networkmanagerupdateconnections/actor.py b/repos/system_upgrade/el7toel8/actors/networkmanagerupdateconnections/actor.py 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 --- a/repos/system_upgrade/el7toel8/actors/networkmanagerupdateconnections/actor.py
+++ b/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 @@ -2,6 +2,7 @@ from leapp.actors import Actor
@ -3696,14 +3764,22 @@ index 69ca0f0..c488eb0 100644
class NetworkManagerUpdateConnections(Actor): class NetworkManagerUpdateConnections(Actor):
@@ -26,8 +27,22 @@ class NetworkManagerUpdateConnections(Actor): @@ -26,9 +27,24 @@ class NetworkManagerUpdateConnections(Actor):
return return
try: try:
- r = run(['/usr/bin/python3', 'tools/nm-update-client-ids.py'])['stdout'] - r = run(['/usr/bin/python3', 'tools/nm-update-client-ids.py'])['stdout']
- self.log.info('Updated client-ids: {}'.format(r)) - 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']) + 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.' + 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 ' \ + 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 ' \ + '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.Severity(reporting.Severity.MEDIUM),
+ reporting.Tags([reporting.Tags.NETWORK]) + 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 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 index 923bf80..9972204 100755
--- a/repos/system_upgrade/el7toel8/actors/networkmanagerupdateconnections/tools/nm-update-client-ids.py --- a/repos/system_upgrade/el7toel8/actors/networkmanagerupdateconnections/tools/nm-update-client-ids.py

View File

@ -43,7 +43,7 @@ py2_byte_compile "%1" "%2"}
Epoch: 1 Epoch: 1
Name: leapp-repository Name: leapp-repository
Version: 0.16.0 Version: 0.16.0
Release: 6%{?dist}.elevate.6 Release: 6%{?dist}.elevate.7
Summary: Repositories for leapp Summary: Repositories for leapp
License: ASL 2.0 License: ASL 2.0