From 0f70dbf229c04b5374d767eeab25ad3fa32e0d8f Mon Sep 17 00:00:00 2001 From: Evgeni Golov Date: Mon, 19 Feb 2024 12:23:28 +0100 Subject: [PATCH 28/34] Add el8toel9 upgrade facts for Satellite This adds the el8toel9 specific fact scanner/generator for Satellite upgrades. The result of this actor is what drives the actual upgrade actions. --- .../actors/satellite_upgrade_facts/actor.py | 71 ++++++++ .../unit_test_satellite_upgrade_facts.py | 151 ++++++++++++++++++ 2 files changed, 222 insertions(+) create mode 100644 repos/system_upgrade/el8toel9/actors/satellite_upgrade_facts/actor.py create mode 100644 repos/system_upgrade/el8toel9/actors/satellite_upgrade_facts/tests/unit_test_satellite_upgrade_facts.py diff --git a/repos/system_upgrade/el8toel9/actors/satellite_upgrade_facts/actor.py b/repos/system_upgrade/el8toel9/actors/satellite_upgrade_facts/actor.py new file mode 100644 index 00000000..2dc78cce --- /dev/null +++ b/repos/system_upgrade/el8toel9/actors/satellite_upgrade_facts/actor.py @@ -0,0 +1,71 @@ +from leapp.actors import Actor +from leapp.libraries.common.config import architecture +from leapp.libraries.common.rpms import has_package +from leapp.models import ( + InstalledRPM, + RepositoriesSetupTasks, + RpmTransactionTasks, + SatelliteFacts, + SatellitePostgresqlFacts, + UsedRepositories +) +from leapp.tags import FactsPhaseTag, IPUWorkflowTag + +RELATED_PACKAGES = ('foreman', 'foreman-selinux', 'foreman-proxy', 'katello', 'katello-selinux', + 'candlepin', 'candlepin-selinux', 'pulpcore-selinux', 'satellite', 'satellite-capsule') +RELATED_PACKAGE_PREFIXES = ('rubygem-hammer', 'rubygem-foreman', 'rubygem-katello', + 'rubygem-smart_proxy', 'python3.11-pulp', 'foreman-installer', + 'satellite-installer') + + +class SatelliteUpgradeFacts(Actor): + """ + Report which Satellite packages require updates and how to handle PostgreSQL data + """ + + name = 'satellite_upgrade_facts' + consumes = (InstalledRPM, UsedRepositories) + produces = (RepositoriesSetupTasks, RpmTransactionTasks, SatelliteFacts) + tags = (IPUWorkflowTag, FactsPhaseTag) + + def process(self): + if not architecture.matches_architecture(architecture.ARCH_X86_64): + return + + has_foreman = has_package(InstalledRPM, 'foreman') or has_package(InstalledRPM, 'foreman-proxy') + if not has_foreman: + return + + local_postgresql = has_package(InstalledRPM, 'postgresql-server') + + to_install = ['rubygem-foreman_maintain'] + + for rpm_pkgs in self.consume(InstalledRPM): + for pkg in rpm_pkgs.items: + if pkg.name in RELATED_PACKAGES or pkg.name.startswith(RELATED_PACKAGE_PREFIXES): + to_install.append(pkg.name) + + if local_postgresql: + to_install.extend(['postgresql', 'postgresql-server']) + if has_package(InstalledRPM, 'postgresql-contrib'): + to_install.append('postgresql-contrib') + if has_package(InstalledRPM, 'postgresql-evr'): + to_install.append('postgresql-evr') + + self.produce(SatelliteFacts( + has_foreman=has_foreman, + has_katello_installer=False, + postgresql=SatellitePostgresqlFacts( + local_postgresql=local_postgresql, + ), + )) + + repositories_to_enable = [] + for used_repos in self.consume(UsedRepositories): + for used_repo in used_repos.repositories: + if used_repo.repository.startswith(('satellite-6', 'satellite-capsule-6', 'satellite-maintenance-6')): + repositories_to_enable.append(used_repo.repository.replace('for-rhel-8', 'for-rhel-9')) + if repositories_to_enable: + self.produce(RepositoriesSetupTasks(to_enable=repositories_to_enable)) + + self.produce(RpmTransactionTasks(to_install=to_install)) diff --git a/repos/system_upgrade/el8toel9/actors/satellite_upgrade_facts/tests/unit_test_satellite_upgrade_facts.py b/repos/system_upgrade/el8toel9/actors/satellite_upgrade_facts/tests/unit_test_satellite_upgrade_facts.py new file mode 100644 index 00000000..b0e44c46 --- /dev/null +++ b/repos/system_upgrade/el8toel9/actors/satellite_upgrade_facts/tests/unit_test_satellite_upgrade_facts.py @@ -0,0 +1,151 @@ +from leapp.libraries.common.config import mock_configs +from leapp.models import ( + InstalledRPM, + RepositoriesSetupTasks, + RPM, + RpmTransactionTasks, + SatelliteFacts, + UsedRepositories, + UsedRepository +) + +RH_PACKAGER = 'Red Hat, Inc. ' + + +def fake_package(pkg_name): + return RPM(name=pkg_name, version='0.1', release='1.sm01', epoch='1', packager=RH_PACKAGER, arch='noarch', + pgpsig='RSA/SHA256, Mon 01 Jan 1970 00:00:00 AM -03, Key ID 199e2f91fd431d51') + + +FOREMAN_RPM = fake_package('foreman') +FOREMAN_PROXY_RPM = fake_package('foreman-proxy') +KATELLO_INSTALLER_RPM = fake_package('foreman-installer-katello') +KATELLO_RPM = fake_package('katello') +RUBYGEM_KATELLO_RPM = fake_package('rubygem-katello') +RUBYGEM_FOREMAN_PUPPET_RPM = fake_package('rubygem-foreman_puppet') +POSTGRESQL_RPM = fake_package('postgresql-server') +SATELLITE_RPM = fake_package('satellite') +SATELLITE_CAPSULE_RPM = fake_package('satellite-capsule') + +SATELLITE_REPOSITORY = UsedRepository(repository='satellite-6.99-for-rhel-8-x86_64-rpms') +CAPSULE_REPOSITORY = UsedRepository(repository='satellite-capsule-6.99-for-rhel-8-x86_64-rpms') +MAINTENANCE_REPOSITORY = UsedRepository(repository='satellite-maintenance-6.99-for-rhel-8-x86_64-rpms') + + +def test_no_satellite_present(current_actor_context): + current_actor_context.feed(InstalledRPM(items=[])) + current_actor_context.run(config_model=mock_configs.CONFIG) + message = current_actor_context.consume(SatelliteFacts) + assert not message + + +def test_satellite_present(current_actor_context): + current_actor_context.feed(InstalledRPM(items=[FOREMAN_RPM])) + current_actor_context.run(config_model=mock_configs.CONFIG) + message = current_actor_context.consume(SatelliteFacts)[0] + assert message.has_foreman + + +def test_wrong_arch(current_actor_context): + current_actor_context.feed(InstalledRPM(items=[FOREMAN_RPM])) + current_actor_context.run(config_model=mock_configs.CONFIG_S390X) + message = current_actor_context.consume(SatelliteFacts) + assert not message + + +def test_satellite_capsule_present(current_actor_context): + current_actor_context.feed(InstalledRPM(items=[FOREMAN_PROXY_RPM])) + current_actor_context.run(config_model=mock_configs.CONFIG) + message = current_actor_context.consume(SatelliteFacts)[0] + assert message.has_foreman + + +def test_no_katello_installer_present(current_actor_context): + current_actor_context.feed(InstalledRPM(items=[FOREMAN_RPM])) + current_actor_context.run(config_model=mock_configs.CONFIG) + message = current_actor_context.consume(SatelliteFacts)[0] + assert not message.has_katello_installer + + +def test_katello_installer_present(current_actor_context): + current_actor_context.feed(InstalledRPM(items=[FOREMAN_RPM, KATELLO_INSTALLER_RPM])) + current_actor_context.run(config_model=mock_configs.CONFIG) + message = current_actor_context.consume(SatelliteFacts)[0] + # while the katello installer rpm is present, we do not want this to be true + # as the version in EL8 doesn't have the system checks we skip with this flag + assert not message.has_katello_installer + + +def test_installs_related_package(current_actor_context): + current_actor_context.feed(InstalledRPM(items=[FOREMAN_RPM, KATELLO_RPM, RUBYGEM_KATELLO_RPM, + RUBYGEM_FOREMAN_PUPPET_RPM])) + current_actor_context.run(config_model=mock_configs.CONFIG) + message = current_actor_context.consume(RpmTransactionTasks)[0] + assert 'katello' in message.to_install + assert 'rubygem-katello' in message.to_install + assert 'rubygem-foreman_puppet' in message.to_install + + +def test_installs_satellite_package(current_actor_context): + current_actor_context.feed(InstalledRPM(items=[FOREMAN_RPM, SATELLITE_RPM])) + current_actor_context.run(config_model=mock_configs.CONFIG) + message = current_actor_context.consume(RpmTransactionTasks)[0] + assert 'satellite' in message.to_install + assert 'satellite-capsule' not in message.to_install + + +def test_installs_satellite_capsule_package(current_actor_context): + current_actor_context.feed(InstalledRPM(items=[FOREMAN_PROXY_RPM, SATELLITE_CAPSULE_RPM])) + current_actor_context.run(config_model=mock_configs.CONFIG) + message = current_actor_context.consume(RpmTransactionTasks)[0] + assert 'satellite-capsule' in message.to_install + assert 'satellite' not in message.to_install + + +def test_detects_local_postgresql(current_actor_context): + current_actor_context.feed(InstalledRPM(items=[FOREMAN_RPM, POSTGRESQL_RPM])) + current_actor_context.run(config_model=mock_configs.CONFIG) + + satellitemsg = current_actor_context.consume(SatelliteFacts)[0] + assert satellitemsg.postgresql.local_postgresql + + +def test_detects_remote_postgresql(current_actor_context): + current_actor_context.feed(InstalledRPM(items=[FOREMAN_RPM])) + current_actor_context.run(config_model=mock_configs.CONFIG) + + satellitemsg = current_actor_context.consume(SatelliteFacts)[0] + assert not satellitemsg.postgresql.local_postgresql + + +def test_enables_right_repositories_on_satellite(current_actor_context): + current_actor_context.feed(InstalledRPM(items=[FOREMAN_RPM, SATELLITE_RPM])) + current_actor_context.feed(UsedRepositories(repositories=[SATELLITE_REPOSITORY, MAINTENANCE_REPOSITORY])) + current_actor_context.run(config_model=mock_configs.CONFIG) + + rpmmessage = current_actor_context.consume(RepositoriesSetupTasks)[0] + + assert 'satellite-maintenance-6.99-for-rhel-9-x86_64-rpms' in rpmmessage.to_enable + assert 'satellite-6.99-for-rhel-9-x86_64-rpms' in rpmmessage.to_enable + assert 'satellite-capsule-6.99-for-rhel-9-x86_64-rpms' not in rpmmessage.to_enable + + +def test_enables_right_repositories_on_capsule(current_actor_context): + current_actor_context.feed(InstalledRPM(items=[FOREMAN_PROXY_RPM, SATELLITE_CAPSULE_RPM])) + current_actor_context.feed(UsedRepositories(repositories=[CAPSULE_REPOSITORY, MAINTENANCE_REPOSITORY])) + current_actor_context.run(config_model=mock_configs.CONFIG) + + rpmmessage = current_actor_context.consume(RepositoriesSetupTasks)[0] + + assert 'satellite-maintenance-6.99-for-rhel-9-x86_64-rpms' in rpmmessage.to_enable + assert 'satellite-6.99-for-rhel-9-x86_64-rpms' not in rpmmessage.to_enable + assert 'satellite-capsule-6.99-for-rhel-9-x86_64-rpms' in rpmmessage.to_enable + + +def test_enables_right_repositories_on_upstream(current_actor_context): + current_actor_context.feed(InstalledRPM(items=[FOREMAN_RPM])) + current_actor_context.run(config_model=mock_configs.CONFIG) + + message = current_actor_context.consume(RepositoriesSetupTasks) + + assert not message -- 2.42.0