def process(self): arch = self.configuration.architecture for provider, info in rhui.RHUI_CLOUD_MAP[arch].items(): if has_package(InstalledRPM, info['el7_pkg']): if not rhsm.skip_rhsm(): create_report([ reporting.Title( 'Upgrade initiated with RHSM on public cloud with RHUI infrastructure' ), reporting.Summary( 'Leapp detected this system is on public cloud with RHUI infrastructure ' 'but the process was initiated without "--no-rhsm" command line option ' 'which implies RHSM usage (valid subscription is needed).' ), reporting.Severity(reporting.Severity.INFO), reporting.Tags([reporting.Tags.PUBLIC_CLOUD]), ]) return # AWS RHUI package is provided and signed by RH but the Azure one not if not has_package(InstalledRPM, info['leapp_pkg']): create_report([ reporting.Title('Package "{}" is missing'.format( info['leapp_pkg'])), reporting.Summary( 'On {} using RHUI infrastructure, a package "{}" is needed for' 'in-place upgrade'.format(provider.upper(), info['leapp_pkg'])), reporting.Severity(reporting.Severity.HIGH), reporting.RelatedResource('package', info['leapp_pkg']), reporting.Flags([reporting.Flags.INHIBITOR]), reporting.Tags( [reporting.Tags.PUBLIC_CLOUD, reporting.Tags.RHUI]), reporting.Remediation(commands=[[ 'yum', 'install', '-y', info['leapp_pkg'] ]]) ]) return if provider == 'aws': # We have to disable Amazon-id plugin in the initramdisk phase as the network # is down at the time self.produce( DNFPluginTask(name='amazon-id', disable_in=['upgrade'])) # if RHEL7 and RHEL8 packages differ, we cannot rely on simply updating them if info['el7_pkg'] != info['el8_pkg']: self.produce( RpmTransactionTasks(to_install=[info['el8_pkg']])) self.produce( RpmTransactionTasks(to_remove=[info['el7_pkg']])) self.produce(RHUIInfo(provider=provider)) self.produce( RequiredTargetUserspacePackages( packages=[info['el8_pkg']])) return
def test_actor_execution_with_sample_data(current_actor_context): installed_rpm = [ RPM(name='sample01', version='0.1', release='1.sm01', epoch='1', packager=RH_PACKAGER, arch='noarch', pgpsig='SOME_PGP_SIG'), RPM(name='sample02', version='0.1', release='1.sm01', epoch='1', packager=RH_PACKAGER, arch='noarch', pgpsig='SOME_PGP_SIG') ] modules_to_enable = [ Module(name='enable', stream='1'), Module(name='enable', stream='2') ] modules_to_reset = [ Module(name='reset', stream='1'), Module(name='reset', stream='2') ] current_actor_context.feed(InstalledRedHatSignedRPM(items=installed_rpm)) current_actor_context.feed( RpmTransactionTasks( to_remove=[rpm.name for rpm in installed_rpm], to_keep=[installed_rpm[0].name], modules_to_enable=modules_to_enable, modules_to_reset=modules_to_reset, )) current_actor_context.feed( RpmTransactionTasks( modules_to_enable=modules_to_enable, modules_to_reset=modules_to_reset, )) current_actor_context.run() result = current_actor_context.consume(FilteredRpmTransactionTasks) assert len(result) == 1 assert result[0].to_keep == [installed_rpm[0].name] assert result[0].to_remove == [installed_rpm[1].name] assert len(result[0].modules_to_enable) == 2 assert all(m.name == 'enable' for m in result[0].modules_to_enable) assert '1' in {m.stream for m in result[0].modules_to_enable} assert '2' in {m.stream for m in result[0].modules_to_enable} assert len(result[0].modules_to_reset) == 2 assert all(m.name == 'reset' for m in result[0].modules_to_reset) assert '1' in {m.stream for m in result[0].modules_to_reset} assert '2' in {m.stream for m in result[0].modules_to_reset}
def process(self): # exit if SELinux is disabled for fact in self.consume(SELinuxFacts): if not fact.enabled: return ( semodule_list, template_list, rpms_to_install, ) = selinuxcontentscanner.get_selinux_modules() self.produce( SELinuxModules(modules=semodule_list, templates=template_list)) self.produce(RpmTransactionTasks(to_install=rpms_to_install)) # this is produced so that we can later verify that the RPMs are present after upgrade self.produce(SELinuxRequestRPMs(to_install=rpms_to_install)) ( semanage_valid, semanage_removed, ) = selinuxcontentscanner.get_selinux_customizations() self.produce( SELinuxCustom(commands=semanage_valid, removed=semanage_removed))
def test_actor_execution_with_sample_data(current_actor_context): installed_rpm = [ RPM(name='sample01', version='0.1', release='1.sm01', epoch='1', packager=RH_PACKAGER, arch='noarch', pgpsig='SOME_PGP_SIG'), RPM(name='sample02', version='0.1', release='1.sm01', epoch='1', packager=RH_PACKAGER, arch='noarch', pgpsig='SOME_PGP_SIG') ] current_actor_context.feed(InstalledRedHatSignedRPM(items=installed_rpm)) current_actor_context.feed( RpmTransactionTasks(to_remove=[rpm.name for rpm in installed_rpm], to_keep=[installed_rpm[0].name])) current_actor_context.run() result = current_actor_context.consume(FilteredRpmTransactionTasks) assert len(result) == 1 assert result[0].to_keep == [installed_rpm[0].name] assert result[0].to_remove == [installed_rpm[1].name]
def process_events(events): """ Process PES Events and generate Leapp messages """ to_install = {} to_remove = {} for event in events: to_install.update(event.out_pkgs) if event.action not in ('Present', 'Deprecated', 'Moved') and event.in_pkgs: to_remove.update(event.in_pkgs) filter_by_repositories(to_install) map_repositories(to_install) to_install_pkgs = set(to_install.keys()) to_remove_pkgs = set(to_remove.keys()) common = to_install_pkgs.intersection(to_remove_pkgs) to_install_pkgs.difference_update(common) to_remove_pkgs.difference_update(common) if to_install_pkgs or to_remove_pkgs: api.produce( RpmTransactionTasks(to_install=list(to_install_pkgs), to_remove=list(to_remove_pkgs))) to_enable_repos = set(to_install.values()) if to_enable_repos: api.produce(RepositoriesSetupTasks(to_enable=list(to_enable_repos)))
def process(self): # exit if SELinux is disabled for fact in self.consume(SELinuxFacts): if not fact.enabled: return ( semodule_list, rpms_to_keep, rpms_to_install, ) = selinuxcontentscanner.get_selinux_modules() self.produce(SELinuxModules(modules=semodule_list)) self.produce( RpmTransactionTasks( to_install=rpms_to_install, # possibly not necessary - dnf should not remove RPMs (that exist in both RHEL 7 and 8) durign update to_keep=rpms_to_keep)) # this is produced so that we can later verify that the RPMs are present after upgrade self.produce( SELinuxRequestRPMs(to_install=rpms_to_install, to_keep=rpms_to_keep)) ( semanage_valid, semanage_removed, ) = selinuxcontentscanner.get_selinux_customizations() self.produce( SELinuxCustom(commands=semanage_valid, removed=semanage_removed))
def process(self): installed_pkgs = set() for rpm_pkgs in self.consume(InstalledRedHatSignedRPM): installed_pkgs.update([pkg.name for pkg in rpm_pkgs.items]) to_install = set() to_remove = set() with open(self.get_file_path('pes-events.json')) as f: data = json.load(f)['packageinfo'] for event in data: action = EVENTS[event['action']] in_packages = self.get_packages(event, 'in_packageset') out_packages = self.get_packages(event, 'out_packageset') if not installed_pkgs.intersection(in_packages): continue if action not in ('Present', 'Deprecated', 'Moved') and in_packages: to_remove.update(in_packages) if out_packages: to_install.update(out_packages) common = to_install.intersection(to_remove) to_install.difference_update(common) to_remove.difference_update(common) if to_install or to_remove: self.produce( RpmTransactionTasks(to_install=list(to_install), to_remove=list(to_remove)))
def load_tasks(base_dir, logger): # Loads configuration files to_install, to_keep, and to_remove from the given base directory return RpmTransactionTasks( to_install=load_tasks_file(os.path.join(base_dir, 'to_install'), logger), to_keep=load_tasks_file(os.path.join(base_dir, 'to_keep'), logger), to_remove=load_tasks_file(os.path.join(base_dir, 'to_remove'), logger))
def process(self): location = self.get_folder_path('bundled-rpms') local_rpms = [] for name in os.listdir(location): if name.endswith('.rpm'): local_rpms.append(os.path.join(location, name)) if local_rpms: self.produce(RpmTransactionTasks(local_rpms=local_rpms))
def process(self): location = self.get_folder_path('bundled-rpms') to_install = [] for name in os.listdir(location): if name.endswith('.rpm'): to_install.append(os.path.join(location, name)) if to_install: self.produce(RpmTransactionTasks(to_install=to_install))
def process(): location = api.get_folder_path('bundled-rpms') local_rpms = [] for name in os.listdir(location): if name.endswith('.rpm'): # It is important to put here the realpath to the files here, because # symlinks cannot be resolved properly inside of the target userspace since they use the /installroot # mount target local_rpms.append(os.path.realpath(os.path.join(location, name))) if local_rpms: api.produce(RpmTransactionTasks(local_rpms=local_rpms))
def test_add_output_pkgs_to_transaction_conf(): """ Verifies that the add_output_pkgs_to_transaction_conf correctly modifies to_remove field based on the supplied events. """ events = [ Event(1, Action.SPLIT, {'split_in': 'repo'}, {'split_out1': 'repo', 'split_out2': 'repo'}, (7, 6), (8, 0), []), Event(2, Action.MERGED, {'merge_in1': 'repo', 'merge_in2': 'repo'}, {'merge_out': 'repo'}, (7, 6), (8, 0), []), Event(3, Action.RENAMED, {'renamed_in': 'repo'}, {'renamed_out': 'repo'}, (7, 6), (8, 0), []), Event(4, Action.REPLACED, {'replaced_in': 'repo'}, {'replaced_out': 'repo'}, (7, 6), (8, 0), []), ] conf_empty = RpmTransactionTasks() add_output_pkgs_to_transaction_conf(conf_empty, events) assert conf_empty.to_remove == [] conf_split = RpmTransactionTasks(to_remove=['split_in']) add_output_pkgs_to_transaction_conf(conf_split, events) assert sorted(conf_split.to_remove) == ['split_in', 'split_out1', 'split_out2'] conf_merged_incomplete = RpmTransactionTasks(to_remove=['merge_in1']) add_output_pkgs_to_transaction_conf(conf_merged_incomplete, events) assert conf_merged_incomplete.to_remove == ['merge_in1'] conf_merged = RpmTransactionTasks(to_remove=['merge_in1', 'merge_in2']) add_output_pkgs_to_transaction_conf(conf_merged, events) assert sorted(conf_merged.to_remove) == ['merge_in1', 'merge_in2', 'merge_out'] conf_renamed = RpmTransactionTasks(to_remove=['renamed_in']) add_output_pkgs_to_transaction_conf(conf_renamed, events) assert sorted(conf_renamed.to_remove) == ['renamed_in', 'renamed_out'] conf_replaced = RpmTransactionTasks(to_remove=['replaced_in']) add_output_pkgs_to_transaction_conf(conf_replaced, events) assert sorted(conf_replaced.to_remove) == ['replaced_in', 'replaced_out']
def get_transaction_configuration(): """ Get pkgs to install, keep and remove from the user configuration files in /etc/leapp/transaction/. These configuration files have higher priority than PES data. :return: RpmTransactionTasks model instance """ transaction_configuration = RpmTransactionTasks() for tasks in api.consume(RpmTransactionTasks): transaction_configuration.to_install.extend(tasks.to_install) transaction_configuration.to_remove.extend(tasks.to_remove) transaction_configuration.to_keep.extend(tasks.to_keep) return transaction_configuration
def load_tasks(base_dir, logger): # Loads configuration files to_install, to_keep, and to_remove from the given base directory rpms = next(api.consume(InstalledRedHatSignedRPM)) rpm_names = [rpm.name for rpm in rpms.items] to_install = load_tasks_file(os.path.join(base_dir, 'to_install'), logger) # we do not want to put into rpm transaction what is already installed (it will go to "to_upgrade" bucket) to_install_filtered = [pkg for pkg in to_install if pkg not in rpm_names] filtered = set(to_install) - set(to_install_filtered) if filtered: api.current_logger().debug( 'The following packages from "to_install" file will be ignored as they are already installed:' '\n- ' + '\n- '.join(filtered)) return RpmTransactionTasks( to_install=to_install_filtered, to_keep=load_tasks_file(os.path.join(base_dir, 'to_keep'), logger), to_remove=load_tasks_file(os.path.join(base_dir, 'to_remove'), logger))
def test_add_output_pkgs_to_transaction_conf(): events = [ Event('Split', {'split_in': 'repo'}, { 'split_out1': 'repo', 'split_out2': 'repo' }, (7, 6), (8, 0), []), Event('Merged', { 'merged_in1': 'repo', 'merged_in2': 'repo' }, {'merged_out': 'repo'}, (7, 6), (8, 0), []), Event('Renamed', {'renamed_in': 'repo'}, {'renamed_out': 'repo'}, (7, 6), (8, 0), []), Event('Replaced', {'replaced_in': 'repo'}, {'replaced_out': 'repo'}, (7, 6), (8, 0), []), ] conf_empty = RpmTransactionTasks() add_output_pkgs_to_transaction_conf(conf_empty, events) assert conf_empty.to_remove == [] conf_split = RpmTransactionTasks(to_remove=['split_in']) add_output_pkgs_to_transaction_conf(conf_split, events) assert sorted( conf_split.to_remove) == ['split_in', 'split_out1', 'split_out2'] conf_merged_incomplete = RpmTransactionTasks(to_remove=['merged_in1']) add_output_pkgs_to_transaction_conf(conf_merged_incomplete, events) assert conf_merged_incomplete.to_remove == ['merged_in1'] conf_merged = RpmTransactionTasks(to_remove=['merged_in1', 'merged_in2']) add_output_pkgs_to_transaction_conf(conf_merged, events) assert sorted( conf_merged.to_remove) == ['merged_in1', 'merged_in2', 'merged_out'] conf_renamed = RpmTransactionTasks(to_remove=['renamed_in']) add_output_pkgs_to_transaction_conf(conf_renamed, events) assert sorted(conf_renamed.to_remove) == ['renamed_in', 'renamed_out'] conf_replaced = RpmTransactionTasks(to_remove=['replaced_in']) add_output_pkgs_to_transaction_conf(conf_replaced, events) assert sorted(conf_replaced.to_remove) == ['replaced_in', 'replaced_out']
def process(self): upg_path = rhui.get_upg_path() for provider, info in rhui.RHUI_CLOUD_MAP[upg_path].items(): if has_package(InstalledRPM, info['src_pkg']): is_azure_sap = False azure_sap_pkg = rhui.RHUI_CLOUD_MAP[upg_path]['azure-sap'][ 'src_pkg'] azure_nonsap_pkg = rhui.RHUI_CLOUD_MAP[upg_path]['azure'][ 'src_pkg'] # we need to do this workaround in order to overcome our RHUI handling limitation # in case there are more client packages on the source system if 'azure' in info['src_pkg'] and has_package( InstalledRPM, azure_sap_pkg): is_azure_sap = True provider = 'azure-sap' info = rhui.RHUI_CLOUD_MAP[upg_path]['azure-sap'] if not rhsm.skip_rhsm(): create_report([ reporting.Title( 'Upgrade initiated with RHSM on public cloud with RHUI infrastructure' ), reporting.Summary( 'Leapp detected this system is on public cloud with RHUI infrastructure ' 'but the process was initiated without "--no-rhsm" command line option ' 'which implies RHSM usage (valid subscription is needed).' ), reporting.Severity(reporting.Severity.INFO), reporting.Tags([reporting.Tags.PUBLIC_CLOUD]), ]) return # AWS RHUI package is provided and signed by RH but the Azure one not if not has_package(InstalledRPM, info['leapp_pkg']): create_report([ reporting.Title('Package "{}" is missing'.format( info['leapp_pkg'])), reporting.Summary( 'On {} using RHUI infrastructure, a package "{}" is needed for' 'in-place upgrade'.format(provider.upper(), info['leapp_pkg'])), reporting.Severity(reporting.Severity.HIGH), reporting.RelatedResource('package', info['leapp_pkg']), reporting.Flags([reporting.Flags.INHIBITOR]), reporting.Tags( [reporting.Tags.PUBLIC_CLOUD, reporting.Tags.RHUI]), reporting.Remediation(commands=[[ 'yum', 'install', '-y', info['leapp_pkg'] ]]) ]) return # there are several "variants" related to the *AWS* provider (aws, aws-sap) if provider.startswith('aws'): # We have to disable Amazon-id plugin in the initramdisk phase as the network # is down at the time self.produce( DNFPluginTask(name='amazon-id', disable_in=['upgrade'])) # if RHEL7 and RHEL8 packages differ, we cannot rely on simply updating them if info['src_pkg'] != info['target_pkg']: self.produce( RpmTransactionTasks(to_install=[info['target_pkg']])) self.produce( RpmTransactionTasks(to_remove=[info['src_pkg']])) if is_azure_sap: self.produce( RpmTransactionTasks(to_remove=[azure_nonsap_pkg])) self.produce(RHUIInfo(provider=provider)) self.produce( RequiredTargetUserspacePackages( packages=[info['target_pkg']])) return
def process(self): for sctpconfig in self.consume(SCTPConfig): if sctpconfig.wanted: self.produce(RpmTransactionTasks(to_install=['kernel-modules-extra'])) break