예제 #1
0
def check_ntp(installed_packages):
    service_data = [('ntpd', 'ntp', '/etc/ntp.conf'),
                    ('ntpdate', 'ntpdate', '/etc/ntp/step-tickers'),
                    ('ntp-wait', 'ntp-perl', None)]

    migrate_services = []
    migrate_configs = []
    for service, package, main_config in service_data:
        if package in installed_packages and \
                check_service('{}.service'.format(service)) and \
                (not main_config or is_file(main_config)):
            migrate_services.append(service)
            if main_config:
                migrate_configs.append(service)

    if migrate_configs:
        reporting.create_report([
            reporting.Title('{} configuration will be migrated'.format(' and '.join(migrate_configs))),
            reporting.Summary('{} service(s) detected to be enabled and active'.format(', '.join(migrate_services))),
            reporting.Severity(reporting.Severity.LOW),
            reporting.Tags([reporting.Tags.SERVICES, reporting.Tags.TIME_MANAGEMENT]),
        ] + related)

        # Save configuration files that will be renamed in the upgrade
        config_tgz64 = get_tgz64(files)
    else:
        api.current_logger().info('ntpd/ntpdate configuration will not be migrated')
        migrate_services = []
        config_tgz64 = ''

    return NtpMigrationDecision(migrate_services=migrate_services, config_tgz64=config_tgz64)
예제 #2
0
def version2_check(info):
    """ Performs all checks for SAP HANA 2 and creates a report if anything unsupported has been detected """
    found = {}
    for instance in info.instances:
        if _manifest_get(instance.manifest, 'release', None) == '1.00':
            continue
        if not _fullfills_hana_min_version(instance):
            _add_hana_details(found, instance)

    if found:
        detected = _create_detected_instances_list(found)
        reporting.create_report([
            reporting.Title('SAP HANA needs to be updated before upgrade'),
            reporting.Summary((
                'A newer version of SAP HANA is required in order continue with the upgrade.'
                ' {min_hana_version} is required for the target version of RHEL.\n\n'
                'The following SAP HANA instances have been detected to be running with a lower version'
                ' than required on the target system:\n'
                '{detected}').format(
                    detected=detected,
                    min_hana_version=SAP_HANA_MINIMAL_VERSION_STRING)),
            reporting.RemediationHint('Update SAP HANA at least to {}'.format(
                SAP_HANA_MINIMAL_VERSION_STRING)),
            reporting.ExternalLink(
                url='https://launchpad.support.sap.com/#/notes/2235581',
                title='SAP HANA: Supported Operating Systems'),
            reporting.Severity(reporting.Severity.HIGH),
            reporting.Tags([reporting.Tags.SANITY]),
            reporting.Flags([reporting.Flags.INHIBITOR]),
            reporting.Audience('sysadmin')
        ])
예제 #3
0
def process():
    if not architecture.matches_architecture(architecture.ARCH_S390X):
        return

    pkgs = _get_kernel_rpms()
    if not pkgs:
        # Hypothatical, user is not allowed to install any kernel that is not signed by RH
        # In case we would like to be cautious, we could check whether there are no other
        # kernels installed as well.
        api.current_logger().log.error(
            'Cannot find any installed kernel signed by Red Hat.')
        raise StopActorExecutionError(
            'Cannot find any installed kernel signed by Red Hat.')
    if len(pkgs) > 1:
        # It's temporary solution, so no need to try automatize everything.
        title = 'Multiple kernels installed'
        summary = (
            'The upgrade process does not handle well the case when multiple kernels'
            ' are installed on s390x. There is a severe risk of the bootloader configuration'
            ' getting corrupted during the upgrade.')
        remediation = (
            'Boot into the most up-to-date kernel and remove all older'
            ' kernels installed on the machine before running Leapp again.')
        reporting.create_report([
            reporting.Title(title),
            reporting.Summary(summary),
            reporting.Severity(reporting.Severity.HIGH),
            reporting.Tags([reporting.Tags.KERNEL, reporting.Tags.BOOT]),
            reporting.Flags([reporting.Flags.INHIBITOR]),
            reporting.Remediation(hint=remediation),
            reporting.RelatedResource('package', 'kernel')
        ])
예제 #4
0
def _check_default_path_checker(options):
    if not options['default_path_checker']:
        return
    value, pathname = options['default_path_checker']
    if value == 'tur':
        return
    create_report([
        reporting.Title('Unsupported device-mapper-multipath configuration'),
        reporting.Summary(
            'device-mapper-multipath has changed the default path_checker '
            'from "directio" to "tur" in RHEL-8. Further, changing the '
            'default path_checker can cause issues with built-in device '
            'configurations in RHEL-8. Please remove the "path_checker" '
            'option from the defaults section of {}, and add it to the '
            'device configuration of any devices that need it.'.format(
                pathname)),
        reporting.Severity(reporting.Severity.HIGH),
        reporting.Tags([reporting.Tags.SERVICES]),
        reporting.Flags([reporting.Flags.INHIBITOR]),
        reporting.RelatedResource('package', 'device-mapper-multipath'),
        reporting.RelatedResource('file', pathname),
        reporting.Remediation(
            hint='Please remove the "path_checker {}" option from the '
            'defaults section of {}, and add it to the device configuration '
            'of any devices that need it.'.format(value, pathname))
    ])
예제 #5
0
    def produce_current_configuration(self, model):
        self.produce(
            AuthselectDecision(
                confirmed=False
            )
        )

        create_report([
            reporting.Title(
                'Current PAM and nsswitch.conf configuration will be kept.'
            ),
            reporting.Summary(
                'There is a new tool called authselect in RHEL8 that '
                'replaced authconfig. The upgrade process was unable '
                'to find an authselect profile that would be equivalent '
                'to your current configuration. Therefore your '
                'configuration will be left intact.'
            ),
            reporting.Tags([
                reporting.Tags.AUTHENTICATION,
                reporting.Tags.SECURITY,
                reporting.Tags.TOOLS
            ]),
            reporting.Severity(reporting.Severity.INFO)
        ] + resources)
예제 #6
0
def report_skipped_packages(title,
                            message,
                            package_repo_pairs,
                            remediation=None):
    """Generate report message about skipped packages"""
    package_repo_pairs = sorted(package_repo_pairs)
    summary = '{} {}\n{}'.format(
        len(package_repo_pairs), message, '\n'.join([
            '- {pkg} (repoid: {repo})'.format(pkg=pkg, repo=repo)
            for pkg, repo in package_repo_pairs
        ]))
    report_content = [
        reporting.Title(title),
        reporting.Summary(summary),
        reporting.Severity(reporting.Severity.HIGH),
        reporting.Tags([reporting.Tags.REPOSITORY]),
    ]
    if remediation:
        report_content += [reporting.Remediation(hint=remediation)]
    report_content += [
        reporting.RelatedResource('package', p) for p, _ in package_repo_pairs
    ]
    reporting.create_report(report_content)
    if is_verbose():
        api.current_logger().info(summary)
예제 #7
0
def get_os_release(path):
    """Retrieve data about System OS release from provided file."""
    try:
        with open(path) as f:
            data = dict(l.strip().split('=', 1) for l in f.readlines()
                        if '=' in l)
            return OSRelease(release_id=data.get('ID', '').strip('"'),
                             name=data.get('NAME', '').strip('"'),
                             pretty_name=data.get('PRETTY_NAME',
                                                  '').strip('"'),
                             version=data.get('VERSION', '').strip('"'),
                             version_id=data.get('VERSION_ID', '').strip('"'),
                             variant=data.get('VARIANT', '').strip('"')
                             or None,
                             variant_id=data.get('VARIANT_ID', '').strip('"')
                             or None)
    except IOError as e:
        reporting.create_report([
            reporting.Title('Error while collecting system OS facts'),
            reporting.Summary(str(e)),
            reporting.Severity(reporting.Severity.HIGH),
            reporting.Tags([reporting.Tags.OS_FACTS, reporting.Tags.SANITY]),
            reporting.Flags([reporting.Flags.INHIBITOR]),
            reporting.RelatedResource('file', path)
        ])
        return None
예제 #8
0
def update_grub_core(grub_dev):
    """
    Update GRUB core after upgrade from RHEL7 to RHEL8

    On legacy systems, GRUB core does not get automatically updated when GRUB packages
    are updated.
    """
    cmd = ['grub2-install', grub_dev]
    if config.is_debug():
        cmd += ['-v']
    try:
        run(cmd)
    except CalledProcessError as err:
        reporting.create_report([
            reporting.Title('GRUB core update failed'),
            reporting.Summary(str(err)),
            reporting.Tags([reporting.Tags.BOOT]),
            reporting.Severity(reporting.Severity.HIGH),
            reporting.Remediation(
                hint=
                'Please run "grub2-install <GRUB_DEVICE>" manually after upgrade'
            )
        ])
        api.current_logger().warning(
            'GRUB core update on {} failed'.format(grub_dev))
        raise StopActorExecution()
    reporting.create_report([
        reporting.Title('GRUB core successfully updated'),
        reporting.Summary(
            'GRUB core on {} was successfully updated'.format(grub_dev)),
        reporting.Tags([reporting.Tags.BOOT]),
        reporting.Severity(reporting.Severity.INFO)
    ])
def test_render_report(
    monkeypatch,
    restricted_driver_names_on_host,
    restricted_pci_ids_on_host,
    restricted_devices_drivers,
    restricted_devices_pcis,
    inhibit_upgrade,
    exp_line_length,
    caplog,
):
    """Check report appearance."""
    monkeypatch.setattr(
        reporting,
        "create_report",
        create_report_mocked(),
    )
    reporting.create_report(
        render_report(
            restricted_driver_names_on_host=restricted_driver_names_on_host,
            restricted_pci_ids_on_host=restricted_pci_ids_on_host,
            restricted_devices_drivers=restricted_devices_drivers,
            restricted_devices_pcis=restricted_devices_pcis,
            inhibit_upgrade=inhibit_upgrade,
        ))
    logger.info(reporting.create_report.report_fields["summary"])
    assert sum(len(m.split("\n")) for m in caplog.messages) == exp_line_length
예제 #10
0
    def process(self):
        interfaces = next(self.consume(PersistentNetNamesFacts)).interfaces

        if self.single_eth0(interfaces):
            self.disable_persistent_naming()
        elif len(interfaces) > 1 and self.ethX_count(interfaces) > 0:
            create_report([
                reporting.Title('Unsupported network configuration'),
                reporting.Summary(
                    'Detected multiple physical network interfaces where one or more use kernel naming (e.g. eth0). '
                    'Upgrade process can not continue because stability of names can not be guaranteed. '
                    'Please read the article at https://access.redhat.com/solutions/4067471 for more information.'
                ),
                reporting.ExternalLink(
                    title=
                    'How to perform an in-place upgrade to RHEL 8 when using kernel NIC names on RHEL 7',
                    url='https://access.redhat.com/solutions/4067471'),
                reporting.Remediation(
                    hint=
                    'Rename all ethX network interfaces following the attached KB solution article.'
                ),
                reporting.Severity(reporting.Severity.HIGH),
                reporting.Tags([reporting.Tags.NETWORK]),
                reporting.Flags([reporting.Flags.INHIBITOR])
            ])
예제 #11
0
    def process(self):
        if architecture.matches_architecture(architecture.ARCH_S390X):
            # s390x archs use ZIPL instead of GRUB
            return

        ff = next(self.consume(FirmwareFacts), None)
        if ff and ff.firmware == 'bios':
            dev = next(self.consume(GrubDevice), None)
            if dev:
                self.produce(UpdateGrub(grub_device=dev.grub_device))
                create_report([
                    reporting.Title(
                        'GRUB core will be updated during upgrade'),
                    reporting.Summary(GRUB_SUMMARY),
                    reporting.Severity(reporting.Severity.HIGH),
                    reporting.Tags([reporting.Tags.BOOT]),
                ])
            else:
                create_report([
                    reporting.Title(
                        'Leapp could not identify where GRUB core is located'),
                    reporting.Summary(
                        'We assume GRUB core is located on the same device as /boot. Leapp needs to '
                        'update GRUB core as it is not done automatically on legacy (BIOS) systems. '
                    ),
                    reporting.Severity(reporting.Severity.HIGH),
                    reporting.Tags([reporting.Tags.BOOT]),
                    reporting.Remediation(
                        hint=
                        'Please run "grub2-install <GRUB_DEVICE> command manually after upgrade'
                    ),
                ])
예제 #12
0
def _report_excluded_repos(repos):
    api.current_logger().info(
        "The optional repository is not enabled. Excluding %r "
        "from the upgrade",
        repos,
    )

    report = [
        reporting.Title("Excluded RHEL 8 repositories"),
        reporting.Summary(
            "The following repositories are not supported by "
            "Red Hat and are excluded from the list of repositories "
            "used during the upgrade.\n- {}".format("\n- ".join(repos))
        ),
        reporting.Severity(reporting.Severity.INFO),
        reporting.Tags([reporting.Tags.REPOSITORY]),
        reporting.Flags([reporting.Flags.FAILURE]),
        reporting.Remediation(
            hint=(
                "If you still require to use the excluded repositories "
                "during the upgrade, execute leapp with the following options: {}."
            ).format(" ".join(["--enablerepo {}".format(repo) for repo in repos])),
        ),
    ]
    reporting.create_report(report)
예제 #13
0
    def process(self):
        tftp_client_service = 'tftp-client'
        send_report = False

        for facts in self.consume(FirewalldUsedObjectNames):
            if tftp_client_service in facts.services:
                send_report = True

        if send_report:
            create_report([
                reporting.Title('Unsupported Firewalld Configuration In Use'),
                reporting.Summary(
                    'Firewalld has service "{service}" enabled. '
                    'Service "{service}" has been removed in RHEL-9.'.format(
                        service=tftp_client_service)),
                reporting.Severity(reporting.Severity.HIGH),
                reporting.Tags(
                    [reporting.Tags.SANITY, reporting.Tags.FIREWALL]),
                reporting.Flags([reporting.Flags.INHIBITOR]),
                reporting.Remediation(hint=(
                    'Remove all usage of service "{service}" from '
                    'firewalld\'s permanent configuration. '
                    'It may be in use by: zones, policies, or rich rules.\n'
                    'Usage can be found by listing zone and policy '
                    'configuration:\n'
                    '  # firewall-cmd --permanent --list-all-zones\n'
                    '  # firewall-cmd --permanent --list-all-policies\n'
                    'Example to remove usage from a zone:\n'
                    '  # firewall-cmd --permanent --zone public '
                    ' --remove-service {service}\n'.format(
                        service=tftp_client_service))),
            ])
예제 #14
0
def process(openssh_messages):
    config = next(openssh_messages, None)
    if list(openssh_messages):
        api.current_logger().warning('Unexpectedly received more than one OpenSshConfig message.')
    if not config:
        raise StopActorExecutionError(
            'Could not check openssh configuration', details={'details': 'No OpenSshConfig facts found.'}
        )

    if config.protocol:
        reporting.create_report([
            reporting.Title('OpenSSH configured with removed configuration Protocol'),
            reporting.Summary(
                'OpenSSH is configured with removed configuration '
                'option Protocol. If this used to be for enabling '
                'SSHv1, this is no longer supported in RHEL 8. '
                'Otherwise this option can be simply removed.'
            ),
            reporting.Severity(reporting.Severity.LOW),
            reporting.Tags([
                    reporting.Tags.AUTHENTICATION,
                    reporting.Tags.SECURITY,
                    reporting.Tags.NETWORK,
                    reporting.Tags.SERVICES
            ]),
        ])
예제 #15
0
    def process(self):
        removed_file = 'files/removed_drivers.txt'
        conflicting = check_drivers(get_removed_drivers(removed_file),
                                    get_present_drivers())

        if conflicting:
            title = ('Detected loaded kernel drivers which have been removed '
                     'in RHEL 8. Upgrade cannot proceed.')
            URL = (
                'https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html-single/'
                'considerations_in_adopting_rhel_8/index#removed-device-drivers_hardware-enablement'
            )
            summary = ('Support for the following RHEL 7 '
                       'device drivers has been removed in RHEL 8: \n     - {}'
                       '\nPlease see {} for details.'.format(
                           '\n     - '.join(conflicting), URL))
            remediation = (
                'Please disable detected kernel drivers in '
                'order to proceed with the upgrade process using the rmmod or modprobe -r.'
            )
            create_report([
                reporting.Title(title),
                reporting.Summary(summary),
                reporting.Severity(reporting.Severity.HIGH),
                reporting.Tags([reporting.Tags.KERNEL, reporting.Tags.DRIVERS
                                ]),
                reporting.Flags([reporting.Flags.INHIBITOR]),
                reporting.Remediation(hint=remediation)
            ] + [
                reporting.RelatedResource('kernel-driver', kd)
                for kd in conflicting
            ])
예제 #16
0
    def process(self):
        rootdir = next(self.consume(RootDirectory), None)
        if not rootdir:
            raise StopActorExecutionError('Cannot check root symlinks',
                                          details={
                                              'Problem':
                                              'Did not receive a message with '
                                              'root subdirectories'
                                          })
        absolute_links = [
            item for item in rootdir.items
            if item.target and os.path.isabs(item.target)
        ]

        if absolute_links:
            commands = [
                ' '.join([
                    'ln', '-snf',
                    os.path.relpath(item.target, '/'),
                    os.path.join('/', item.name)
                ]) for item in absolute_links
            ]
            remediation = [['sh', '-c', ' && '.join(commands)]]
            reporting.create_report([
                reporting.Title(
                    'Upgrade requires links in root directory to be relative'),
                reporting.Summary(
                    'After rebooting, parts of the upgrade process can fail if symbolic links in / '
                    'point to absolute paths.\n'
                    'Please change these links to relative ones.'),
                reporting.Severity(reporting.Severity.HIGH),
                reporting.Flags([reporting.Flags.INHIBITOR]),
                reporting.Remediation(commands=remediation)
            ])
예제 #17
0
def get_events(pes_json_directory, pes_json_filename):
    """
    Get all the events from the source JSON file exported from PES.

    :return: List of Event tuples, where each event contains event type and input/output pkgs
    """
    try:
        return parse_pes_events(
            fetch.read_or_fetch(pes_json_filename,
                                directory=pes_json_directory,
                                allow_empty=True))
    except (ValueError, KeyError):
        title = 'Missing/Invalid PES data file ({}/{})'.format(
            pes_json_directory, pes_json_filename)
        summary = 'Read documentation at: https://access.redhat.com/articles/3664871 for more information ' \
            'about how to retrieve the files'
        reporting.create_report([
            reporting.Title(title),
            reporting.Summary(summary),
            reporting.Severity(reporting.Severity.HIGH),
            reporting.Tags([reporting.Tags.SANITY]),
            reporting.Flags([reporting.Flags.INHIBITOR]),
            reporting.RelatedResource(
                'file', os.path.join(pes_json_directory, pes_json_filename))
        ])
        raise StopActorExecution()
예제 #18
0
def _inhibit_on_duplicate_repos(repofiles):
    """
    Inhibit the upgrade if any repoid is defined multiple times.

    When that happens, it not only shows misconfigured system, but then
    we can't get details of all the available repos as well.
    """
    duplicates = repofileutils.get_duplicate_repositories(repofiles).keys()

    if not duplicates:
        return
    list_separator_fmt = '\n    - '
    api.current_logger().warning(
        'The following repoids are defined multiple times:{0}{1}'.format(
            list_separator_fmt, list_separator_fmt.join(duplicates)))

    reporting.create_report([
        reporting.Title('A YUM/DNF repository defined multiple times'),
        reporting.Summary(
            'The following repositories are defined multiple times:{0}{1}'.
            format(list_separator_fmt, list_separator_fmt.join(duplicates))),
        reporting.Severity(reporting.Severity.MEDIUM),
        reporting.Tags([reporting.Tags.REPOSITORY]),
        reporting.Flags([reporting.Flags.INHIBITOR]),
        reporting.Remediation(
            hint='Remove the duplicate repository definitions.')
    ])
예제 #19
0
    def process(self):
        for decision in self.consume(SelinuxRelabelDecision):
            if decision.set_relabel:
                try:
                    with open('/.autorelabel', 'w'):
                        pass
                    create_report([
                        reporting.Title('SElinux scheduled for relabelling'),
                        reporting.Summary(
                            '/.autorelabel file touched on root in order to schedule SElinux relabelling.'
                        ),
                        reporting.Severity(reporting.Severity.INFO),
                        reporting.Tags(COMMON_REPORT_TAGS),
                    ] + related)

                except EnvironmentError as e:
                    # FIXME: add an "action required" flag later
                    create_report([
                        reporting.Title(
                            'Could not schedule SElinux for relabelling'),
                        reporting.Summary(
                            '/.autorelabel file could not be created: {}.'.
                            format(e)),
                        reporting.Severity(reporting.Severity.HIGH),
                        reporting.Tags(COMMON_REPORT_TAGS),
                        reporting.Remediation(
                            hint=
                            'Please set autorelabelling manually after the upgrade.'
                        ),
                        reporting.Flags([reporting.Flags.FAILURE])
                    ] + related)
                    self.log.critical(
                        'Could not schedule SElinux for relabelling: %s.' % e)
예제 #20
0
def check_chrony(chrony_installed):
    """Report potential issues in chrony configuration."""
    if not chrony_installed:
        api.current_logger().info('chrony package is not installed')
        return

    if is_config_default():
        reporting.create_report([
            reporting.Title('chrony using default configuration'),
            reporting.Summary(
                'default chrony configuration in RHEL8 uses leapsectz directive, which cannot be used with '
                'leap smearing NTP servers, and uses a single pool directive instead of four server directives'
            ),
            reporting.Severity(reporting.Severity.MEDIUM),
            reporting.Tags(
                [reporting.Tags.SERVICES, reporting.Tags.TIME_MANAGEMENT])
        ] + related)

    else:
        reporting.create_report([
            reporting.Title('chrony using non-default configuration'),
            reporting.Summary('chrony behavior will not change in RHEL8'),
            reporting.Severity(reporting.Severity.LOW),
            reporting.Tags(
                [reporting.Tags.SERVICES, reporting.Tags.TIME_MANAGEMENT])
        ] + related)
예제 #21
0
def process():
    conflicts = _detect_dracut_modules_conflicts(UpgradeInitramfsTasks)
    if conflicts:
        report = [
            reporting.Title(
                'Conflicting requirements of dracut modules for the upgrade initramfs'
            ),
            reporting.Summary(
                SUMMARY_DRACUT_FMT.format(_printable_modules(conflicts))),
            reporting.Severity(reporting.Severity.HIGH),
            reporting.Tags([reporting.Tags.SANITY]),
            reporting.Flags([reporting.Flags.INHIBITOR]),
        ]
        reporting.create_report(report)

    conflicts = _detect_dracut_modules_conflicts(TargetInitramfsTasks)
    if conflicts:
        report = [
            reporting.Title(
                'Conflicting requirements of dracut modules for the target initramfs'
            ),
            reporting.Summary(
                SUMMARY_DRACUT_FMT.format(_printable_modules(conflicts))),
            reporting.Severity(reporting.Severity.HIGH),
            reporting.Tags([reporting.Tags.SANITY]),
            reporting.Flags([reporting.Flags.INHIBITOR]),
        ]
        reporting.create_report(report)
예제 #22
0
    def process(self):
        model = next(self.consume(SSSDConfig8to9), None)
        if not model:
            return

        # enable_files_domain is set explicitly, change of default has no effect
        if model.enable_files_domain_set:
            return

        # there is explicit files domain, implicit files domain has no effect
        if model.explicit_files_domain:
            return

        # smartcard authentication is disabled, implicit files domain has no effect
        if not model.pam_cert_auth:
            return

        create_report([
            reporting.Title('SSSD implicit files domain is now disabled by default.'),
            reporting.Summary('Default value of [sssd]/enable_files_domain has '
                              'changed from true to false.'),
            reporting.Tags(COMMON_REPORT_TAGS),
            reporting.Remediation(
                hint='If you use smartcard authentication for local users, '
                     'set this option to true explicitly and call '
                     '"authselect enable-feature with-files-domain".'
            ),
            reporting.Severity(reporting.Severity.MEDIUM)
        ] + related)
예제 #23
0
def _check_default_detection(options):
    bad = []
    for keyword in ('detect_path_checker', 'detect_prio',
                    'retain_attached_hw_handler'):
        if options[keyword] and not options[keyword][0] and \
                options[keyword][1] not in bad:
            bad.append(options[keyword][1])
    if bad == []:
        return
    paths = _create_paths_str(bad)
    create_report([
        reporting.Title(
            'device-mapper-multipath now defaults to detecting settings'),
        reporting.Summary(
            'In RHEL-8, the default value for the "detect_path_checker", '
            '"detect_prio" and "retain_attached_hw_handler" options has '
            'changed to "yes". Further, changing these default values can '
            'cause issues with the built-in device configurations in RHEL-8. '
            'They will be commented out in the defaults section of all '
            'multipath config files. This is unlikely to cause any issues '
            'with existing configurations. If it does, please move these '
            'options from the defaults sections of {} to the device '
            'configuration sections of any devices that need them.'.format(
                paths)),
        reporting.Severity(reporting.Severity.MEDIUM),
        reporting.Tags([reporting.Tags.SERVICES]),
        reporting.RelatedResource('package', 'device-mapper-multipath')
    ])
예제 #24
0
def check_dialogs(inhibit_if_no_userchoice=True):
    results = list(api.consume(DialogModel))
    for dialog in results:
        sections = dialog.answerfile_sections
        summary = (
            'One or more sections in answerfile are missing user choices: {}\n'
            'For more information consult https://leapp.readthedocs.io/en/latest/dialogs.html'
        )
        dialog_resources = [
            reporting.RelatedResource('dialog', s) for s in sections
        ]
        dialogs_remediation = (
            'Please register user choices with leapp answer cli command or by manually editing '
            'the answerfile.')
        # FIXME: Enable more choices once we can do multi-command remediations
        cmd_remediation = [[
            'leapp', 'answer', '--section', "{}={}".format(s, choice)
        ] for s, choices in dialog.answerfile_sections.items()
                           for choice in choices[:1]]
        report_data = [
            reporting.Title('Missing required answers in the answer file'),
            reporting.Severity(reporting.Severity.HIGH),
            reporting.Summary(summary.format('\n'.join(sections))),
            reporting.Flags([reporting.Flags.
                             INHIBITOR] if inhibit_if_no_userchoice else []),
            reporting.Remediation(hint=dialogs_remediation,
                                  commands=cmd_remediation),
            reporting.Key(dialog.key)
        ]
        reporting.create_report(report_data + dialog_resources)
예제 #25
0
    def produce_authconfig_configuration(self, model, command):
        self.produce(
            AuthselectDecision(
                confirmed=True
            )
        )

        create_report([
            reporting.Title(
                'Authselect will be used to configure PAM and nsswitch.conf.'
            ),
            reporting.Summary(
                'There is a new tool called authselect in RHEL8 that '
                'replaced authconfig. The upgrade process detected '
                'that authconfig was used to generate current '
                'configuration and it will automatically convert it '
                'to authselect. Authselect call is: {}. The process will '
                'also enable "oddjobd" systemd service on startup'.format(command)
            ),
            reporting.Tags([
                reporting.Tags.AUTHENTICATION,
                reporting.Tags.SECURITY,
                reporting.Tags.TOOLS
            ])
        ] + resources)
예제 #26
0
    def process(self):
        if not architecture.matches_architecture(architecture.ARCH_S390X):
            return

        cmdline = library.get_kernel_cmdline()
        if library.znet_is_set(cmdline):
            _report = [
                reporting.Title(
                    'Detected the rd.znet parameter in kernel cmdline'),
                reporting.Severity(reporting.Severity.HIGH),
                reporting.Tags(([reporting.Tags.SANITY])),
                reporting.Flags(([reporting.Flags.INHIBITOR])),
                reporting.Summary(
                    'Upgrade on s390x machines with the rd.znet kernel'
                    ' parameter is not supported and the upgrade has been'
                    ' inhibited.')
            ]

            if not library.vlan_is_used():
                hint = (
                    'If you want to continue, remove the rd.znet parameter from'
                    ' the kernel cmdline using grubby and zipl tools and reboot.'
                    ' But only in case you are sure you do not the parameter'
                    ' specified to have working network. E.g. in case you are'
                    ' using VLAN, you should not do that.')
                _report.append(reporting.Remediation(hint=hint))
            reporting.create_report(_report)
예제 #27
0
def version1_check(info):
    """ Creates a report for SAP HANA instances running on version 1 """
    found = {}
    for instance in info.instances:
        if _manifest_get(instance.manifest, 'release') == '1.00':
            _add_hana_details(found, instance)

    if found:
        detected = _create_detected_instances_list(found)
        reporting.create_report([
            reporting.Title(
                'Found SAP HANA 1 which is not supported with the target version of RHEL'
            ),
            reporting.Summary((
                'SAP HANA 1.00 is not supported with the version of RHEL you are upgrading to.\n\n'
                'The following instances have been detected to be version 1.00:\n'
                '{}'.format(detected))),
            reporting.Severity(reporting.Severity.HIGH),
            reporting.RemediationHint((
                'In order to upgrade RHEL, you will have to upgrade your SAP HANA 1.0 software to '
                '{supported}.'.format(
                    supported=SAP_HANA_MINIMAL_VERSION_STRING))),
            reporting.ExternalLink(
                url='https://launchpad.support.sap.com/#/notes/2235581',
                title='SAP HANA: Supported Operating Systems'),
            reporting.Tags([reporting.Tags.SANITY]),
            reporting.Flags([reporting.Flags.INHIBITOR]),
            reporting.Audience('sysadmin')
        ])
예제 #28
0
    def process(self):

        hint = 'In order to unload the module from the running system, check the accompanied command.'
        command = ['modprobe', '-r', 'btrfs']

        for fact in self.consume(ActiveKernelModulesFacts):
            for active_module in fact.kernel_modules:
                if active_module.filename == 'btrfs':
                    create_report([
                        reporting.Title('Btrfs has been removed from RHEL8'),
                        reporting.Summary(
                            'The Btrfs file system was introduced as Technology Preview with the '
                            'initial release of Red Hat Enterprise Linux 6 and Red Hat Enterprise Linux 7. As of '
                            'versions 6.6 and 7.4 this technology has been deprecated and removed in RHEL8.'
                        ),
                        reporting.ExternalLink(
                            title='Considerations in adopting RHEL 8 - btrfs has been removed.',
                            url='https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/considerations_in_adopting_rhel_8/file-systems-and-storage_considerations-in-adopting-rhel-8#btrfs-has-been-removed_file-systems-and-storage'  # noqa: E501; pylint: disable=line-too-long
                        ),
                        reporting.ExternalLink(
                            title='How do I prevent a kernel module from loading automatically?',
                            url='https://access.redhat.com/solutions/41278'
                        ),
                        reporting.Severity(reporting.Severity.HIGH),
                        reporting.Flags([reporting.Flags.INHIBITOR]),
                        reporting.Tags([reporting.Tags.FILESYSTEM]),
                        reporting.Remediation(hint=hint, commands=[command]),
                        reporting.RelatedResource('kernel-driver', 'btrfs')
                    ])
                    break
예제 #29
0
def inhibit(node_type):
    create_report([
        reporting.Title("Use of HA cluster detected. Upgrade can't proceed."),
        reporting.Summary(
            "HA cluster is not supported by the inplace upgrade.\n"
            "HA cluster configuration file(s) found."
            " It seems to be a cluster {0}.".format(node_type)),
        reporting.Severity(reporting.Severity.HIGH),
        reporting.Tags([reporting.Tags.HIGH_AVAILABILITY]),
        reporting.Flags([reporting.Flags.INHIBITOR]),
        reporting.ExternalLink(
            url="https://access.redhat.com/articles/2059253",
            title=(
                "Recommended Practices for Applying Software Updates"
                " to a RHEL High Availability or Resilient Storage Cluster"),
        ),
        reporting.Remediation(
            hint=(
                "Destroy the existing HA cluster"
                " or (if you have already removed HA cluster packages) remove"
                " configuration files {0} and {1}".format(
                    CIB_LOCATION,
                    COROSYNC_CONF_LOCATION,
                )),
            commands=[[
                "sh", "-c",
                "pcs cluster stop --all --wait && pcs cluster destroy --all"
            ]]),
        reporting.RelatedResource('file', COROSYNC_CONF_LOCATION),
        reporting.RelatedResource('file', CIB_LOCATION)
    ])
예제 #30
0
def _inhibit_on_duplicate_repos(repos_raw_stderr):
    """
    Inhibit the upgrade if any repoid is defined multiple times.

    When that happens, it not only shows misconfigured system, but then we can't get details of all the available
    repos as well.
    """
    duplicates = []
    for duplicate in re.findall(
            r'Repository ([^\s]+) is listed more than once', repos_raw_stderr,
            re.DOTALL | re.MULTILINE):
        duplicates.append(duplicate)

    if not duplicates:
        return
    list_separator_fmt = '\n    - '
    api.current_logger().warn(
        'The following repoids are defined multiple times:{0}{1}'.format(
            list_separator_fmt, list_separator_fmt.join(duplicates)))

    reporting.create_report([
        reporting.Title('A YUM/DNF repository defined multiple times'),
        reporting.Summary(
            'The `yum repoinfo` command reports that the following repositories are defined multiple times:{0}{1}'
            .format(list_separator_fmt, list_separator_fmt.join(duplicates))),
        reporting.Severity(reporting.Severity.MEDIUM),
        reporting.Tags([reporting.Tags.REPOSITORY]),
        reporting.Flags([reporting.Flags.INHIBITOR]),
        reporting.Remediation(
            hint='Remove the duplicit repository definitions.')
    ])