diff --git a/repos/system_upgrade/cloudlinux/actors/backupmysqldata/actor.py b/repos/system_upgrade/cloudlinux/actors/backupmysqldata/actor.py index 8e0f0e2cb7..5948889db4 100644 --- a/repos/system_upgrade/cloudlinux/actors/backupmysqldata/actor.py +++ b/repos/system_upgrade/cloudlinux/actors/backupmysqldata/actor.py @@ -1,6 +1,6 @@ import os from leapp.actors import Actor -from leapp.tags import InterimPreparationPhaseTag, IPUWorkflowTag +from leapp.tags import DownloadPhaseTag, IPUWorkflowTag from leapp.libraries.common.cllaunch import run_on_cloudlinux from leapp.libraries.common.backup import backup_file, CLSQL_BACKUP_FILES @@ -13,7 +13,7 @@ class BackupMySqlData(Actor): name = 'backup_my_sql_data' consumes = () produces = () - tags = (InterimPreparationPhaseTag.Before, IPUWorkflowTag) + tags = (DownloadPhaseTag.Before, IPUWorkflowTag) @run_on_cloudlinux def process(self): diff --git a/repos/system_upgrade/cloudlinux/actors/checkcllicense/actor.py b/repos/system_upgrade/cloudlinux/actors/checkcllicense/actor.py index d88c831660..a7a80e422b 100644 --- a/repos/system_upgrade/cloudlinux/actors/checkcllicense/actor.py +++ b/repos/system_upgrade/cloudlinux/actors/checkcllicense/actor.py @@ -6,7 +6,7 @@ from leapp.libraries.common.cllaunch import run_on_cloudlinux from leapp.models import ( - RequiredUpgradeInitramPackages, # deprecated + TargetUserSpacePreupgradeTasks, TargetUserSpaceUpgradeTasks, CopyFile ) @@ -28,7 +28,7 @@ def rhn_to_target_userspace(): if os.path.isfile(src_path): files_to_copy.append(CopyFile(src=src_path)) - api.produce(RequiredUpgradeInitramPackages(packages=REQUIRED_PKGS)) + api.produce(TargetUserSpacePreupgradeTasks(install_rpms=REQUIRED_PKGS, copy_files=files_to_copy)) api.produce(TargetUserSpaceUpgradeTasks(install_rpms=REQUIRED_PKGS, copy_files=files_to_copy)) @@ -39,7 +39,7 @@ class CheckClLicense(Actor): name = 'check_cl_license' consumes = () - produces = (Report, RequiredUpgradeInitramPackages, TargetUserSpaceUpgradeTasks) + produces = (Report, TargetUserSpacePreupgradeTasks, TargetUserSpaceUpgradeTasks) tags = (ChecksPhaseTag, IPUWorkflowTag) system_id_path = '/etc/sysconfig/rhn/systemid' diff --git a/repos/system_upgrade/cloudlinux/actors/setclncacheonlyflag/actor.py b/repos/system_upgrade/cloudlinux/actors/setclncacheonlyflag/actor.py new file mode 100644 index 0000000000..7d915d343c --- /dev/null +++ b/repos/system_upgrade/cloudlinux/actors/setclncacheonlyflag/actor.py @@ -0,0 +1,25 @@ +from leapp.actors import Actor +from leapp.tags import PreparationPhaseTag, IPUWorkflowTag +from leapp.libraries.common.cllaunch import run_on_cloudlinux + + +class SetClnCacheOnlyFlag(Actor): + """ + Set a flag for the dnf-spacewalk-plugin to not attempt to contact the CLN server during transaction, + as it will fail and remove CLN-based package repos from the list. + + When this flag exists, the plugin will act as if there's no network connection, + only using the local cache. + """ + + name = 'set_cln_cache_only_flag' + consumes = () + produces = () + tags = (IPUWorkflowTag, PreparationPhaseTag) + + @run_on_cloudlinux + def process(self): + # TODO: Use a more reliable method to detect if we're running from the isolated userspace + # TODO: Replace hardcoded path with a constant (from target_userspace_creator.constants?) + with open('/var/lib/leapp/el8userspace/etc/cln_leapp_in_progress', 'w') as file: + file.write('1') diff --git a/repos/system_upgrade/cloudlinux/actors/unsetclncacheonlyflag/actor.py b/repos/system_upgrade/cloudlinux/actors/unsetclncacheonlyflag/actor.py new file mode 100644 index 0000000000..08428b3427 --- /dev/null +++ b/repos/system_upgrade/cloudlinux/actors/unsetclncacheonlyflag/actor.py @@ -0,0 +1,19 @@ +from leapp.actors import Actor +from leapp.tags import PreparationPhaseTag, IPUWorkflowTag +from leapp.libraries.common.cllaunch import run_on_cloudlinux + +import os + +class UnsetClnCacheOnlyFlag(Actor): + """ + Remove the flag for the dnf-spacewalk-plugin to not attempt to contact the CLN server during transaction. + """ + + name = 'unset_cln_cache_only_flag' + consumes = () + produces = () + tags = (IPUWorkflowTag, PreparationPhaseTag) + + @run_on_cloudlinux + def process(self): + os.remove('/var/lib/leapp/el8userspace/etc/cln_leapp_in_progress', 'w') diff --git a/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py b/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py index 56caef52e3..0606bfbadc 100644 --- a/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py +++ b/repos/system_upgrade/common/actors/targetuserspacecreator/libraries/userspacegen.py @@ -133,6 +133,35 @@ def _backup_to_persistent_package_cache(userspace_dir): target_context.copytree_from('/var/cache/dnf', PERSISTENT_PACKAGE_CACHE_DIR) +def enable_spacewalk_module(context): + enabled_repos = ["cloudlinux8-baseos"] + target_major_version = get_target_major_version() + repos_opt = [['--enablerepo', repo] for repo in enabled_repos] + repos_opt = list(itertools.chain(*repos_opt)) + + api.current_logger().debug('Enabling module for target userspace: satellite-5-client') + + cmd = ['dnf', + 'module', + 'enable', + 'satellite-5-client', + '-y', + '--nogpgcheck', + '--setopt=module_platform_id=platform:el{}'.format(target_major_version), + '--setopt=keepcache=1', + '--releasever', api.current_actor().configuration.version.target, + '--installroot', '/el{}target'.format(target_major_version), + '--disablerepo', '*' + ] + repos_opt + try: + context.call(cmd, callback_raw=utils.logging_handler) + except CalledProcessError as exc: + raise StopActorExecutionError( + message='Unable to activate spacewalk module.', + details={'details': str(exc), 'stderr': exc.stderr} + ) + + def prepare_target_userspace(context, userspace_dir, enabled_repos, packages): """ Implement the creation of the target userspace. @@ -147,6 +176,14 @@ def prepare_target_userspace(context, userspace_dir, enabled_repos, packages): ): _restore_persistent_package_cache(userspace_dir) + api.current_logger().debug('Installing cloudlinux-release') + context.call(['rpm', '--import', 'https://repo.cloudlinux.com/cloudlinux/security/RPM-GPG-KEY-CloudLinux'], callback_raw=utils.logging_handler) + context.call(['dnf', '-y', 'localinstall', 'https://repo.cloudlinux.com/cloudlinux/migrate/release-files/cloudlinux/8/x86_64/cloudlinux8-release-current.x86_64.rpm'], callback_raw=utils.logging_handler) + + enable_spacewalk_module(context) + + api.current_logger().debug('Installing packages into target userspace: {}'.format(packages)) + repos_opt = [['--enablerepo', repo] for repo in enabled_repos] repos_opt = list(itertools.chain(*repos_opt)) cmd = ['dnf', @@ -171,6 +208,26 @@ def prepare_target_userspace(context, userspace_dir, enabled_repos, packages): details={'details': str(exc), 'stderr': exc.stderr} ) + api.current_logger().debug('Checking the CLN registration status') + context.call(['rhn_check'], callback_raw=utils.logging_handler) + switch_bin = "/usr/sbin/cln-switch-channel" + switch_cmd = [switch_bin, "-t", "8", "-o", "-f"] + context.call(switch_cmd, callback_raw=utils.logging_handler) + + reporting.create_report([ + reporting.Title('CLN channel switched to CL8.'), + reporting.Summary( + 'The CLN channel for this system has been switched from CL7 to CL8.' + 'This is required to pull the correct packages for the upgrade.' + 'However, if the upgrade stops at a later stage, you may want to switch back to the original channel.' + ), + reporting.Tags([reporting.Tags.UPGRADE_PROCESS, reporting.Tags.AUTHENTICATION]), + reporting.Severity(reporting.Severity.MEDIUM), + reporting.Remediation(hint=( + 'Set the channel back to CL7 using the command: cln-switch-channel -t 7 -o -f' + )), + ]) + def _get_all_rhui_pkgs(): """ @@ -231,6 +288,23 @@ def _prep_repository_access(context, target_userspace): run(['rm', '-rf', os.path.join(target_etc, 'rhsm')]) context.copytree_from('/etc/pki', os.path.join(target_etc, 'pki')) context.copytree_from('/etc/rhsm', os.path.join(target_etc, 'rhsm')) + + # Copy RHN data independent from RHSM config + if os.path.isdir('/etc/sysconfig/rhn'): + context.call(['/usr/sbin/rhn_check'], callback_raw=utils.logging_handler) + run(['rm', '-rf', os.path.join(target_etc, 'sysconfig/rhn')]) + context.copytree_from('/etc/sysconfig/rhn', os.path.join(target_etc, 'sysconfig/rhn')) + # Set up spacewalk plugin config + with open(os.path.join(target_etc, 'dnf/plugins/spacewalk.conf'), 'r') as f: + lines = f.readlines() + new_lines = [] + for line in lines: + if 'enabled' in line: + line = 'enabled = 1\n' + new_lines.append(line) + with open(os.path.join(target_etc, 'dnf/plugins/spacewalk.conf'), 'w') as f: + f.writelines(new_lines) + # NOTE: we cannot just remove the original target yum.repos.d dir # as e.g. in case of RHUI a special RHUI repofiles are installed by a pkg # when the target userspace container is created. Removing these files we loose diff --git a/repos/system_upgrade/common/files/rhel_upgrade.py b/repos/system_upgrade/common/files/rhel_upgrade.py index f5b4c706b5..8043e18805 100644 --- a/repos/system_upgrade/common/files/rhel_upgrade.py +++ b/repos/system_upgrade/common/files/rhel_upgrade.py @@ -124,11 +124,16 @@ def configure(self): self.base.conf.tsflags.append("test") enabled_repos = self.plugin_data['dnf_conf']['enable_repos'] + print("All DNF repos: {}".format(self.base.repos.all())) self.base.repos.all().disable() aws_region = None for repo in self.base.repos.all(): + # we always want to have CLN repos enabled + if type(repo).__name__ == "SpacewalkRepo": + repo.enable() + if repo.id in enabled_repos: repo.skip_if_unavailable = False if not self.base.conf.gpgcheck: diff --git a/repos/system_upgrade/common/libraries/dnfplugin.py b/repos/system_upgrade/common/libraries/dnfplugin.py index f09557588b..0e0e90f878 100644 --- a/repos/system_upgrade/common/libraries/dnfplugin.py +++ b/repos/system_upgrade/common/libraries/dnfplugin.py @@ -60,6 +60,7 @@ def install(target_basedir): shutil.copy2( api.get_file_path(DNF_PLUGIN_NAME), os.path.join(target_basedir, DNF_PLUGIN_PATH.lstrip('/'))) + api.current_logger().debug('Installing DNF plugin to {}'.format(DNF_PLUGIN_PATH)) except EnvironmentError as e: api.current_logger().debug('Failed to install DNF plugin', exc_info=True) raise StopActorExecutionError( @@ -375,6 +376,7 @@ def perform_transaction_check(target_userspace_info, used_repos, tasks, xfs_info """ with _prepare_perform(used_repos=used_repos, target_userspace_info=target_userspace_info, xfs_info=xfs_info, storage_info=storage_info) as (context, overlay, target_repoids): + api.current_logger().debug('DNF plugin target repoids: {}'.format(target_repoids)) apply_workarounds(overlay.nspawn()) dnfconfig.exclude_leapp_rpms(context) _transaction(