예제 #1
0
 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}
예제 #3
0
    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))
예제 #4
0
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]
예제 #5
0
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)))
예제 #6
0
    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))
예제 #7
0
    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)))
예제 #8
0
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))
예제 #9
0
 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))
예제 #10
0
 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']
예제 #13
0
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
예제 #14
0
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))
예제 #15
0
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']
예제 #16
0
    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
예제 #17
0
 def process(self):
     for sctpconfig in self.consume(SCTPConfig):
         if sctpconfig.wanted:
             self.produce(RpmTransactionTasks(to_install=['kernel-modules-extra']))
             break