示例#1
0
def install_initramdisk_requirements(packages, target_userspace_info, used_repos):
    """
    Performs the installation of packages into the initram disk
    """
    with _prepare_transaction(used_repos=used_repos,
                              target_userspace_info=target_userspace_info) as (context, target_repoids, _unused):
        if get_target_major_version() == '9':
            _rebuild_rpm_db(context)
        repos_opt = [['--enablerepo', repo] for repo in target_repoids]
        repos_opt = list(itertools.chain(*repos_opt))
        cmd = [
            'dnf',
            'install',
            '-y',
            '--nogpgcheck',
            '--setopt=module_platform_id=platform:el{}'.format(get_target_major_version()),
            '--setopt=keepcache=1',
            '--releasever', api.current_actor().configuration.version.target,
            '--disablerepo', '*'
        ] + repos_opt + list(packages)
        if config.is_verbose():
            cmd.append('-v')
        if rhsm.skip_rhsm():
            cmd += ['--disableplugin', 'subscription-manager']
        env = {}
        if get_target_major_version() == '9':
            # allow handling new RHEL 9 syscalls by systemd-nspawn
            env = {'SYSTEMD_SECCOMP': '0'}
        context.call(cmd, env=env)
示例#2
0
def perform_transaction_install(target_userspace_info, storage_info, used_repos, tasks, plugin_info):
    """
    Performs the actual installation with the DNF rhel-upgrade plugin using the target userspace
    """

    # These bind mounts are performed by systemd-nspawn --bind parameters
    bind_mounts = [
        '/:/installroot',
        '/dev:/installroot/dev',
        '/proc:/installroot/proc',
        '/run/udev:/installroot/run/udev',
    ]

    if get_target_major_version() == '8':
        bind_mounts.append('/sys:/installroot/sys')
    else:
        # the target major version is RHEL 9+
        # we are bindmounting host's "/sys" to the intermediate "/hostsys"
        # in the upgrade initramdisk to avoid cgroups tree layout clash
        bind_mounts.append('/hostsys:/installroot/sys')

    already_mounted = {entry.split(':')[0] for entry in bind_mounts}
    for entry in storage_info.fstab:
        mp = entry.fs_file
        if not os.path.isdir(mp):
            continue
        if mp not in already_mounted:
            bind_mounts.append('{}:{}'.format(mp, os.path.join('/installroot', mp.lstrip('/'))))

    if os.path.ismount('/boot'):
        bind_mounts.append('/boot:/installroot/boot')

    if os.path.ismount('/boot/efi'):
        bind_mounts.append('/boot/efi:/installroot/boot/efi')

    with _prepare_transaction(used_repos=used_repos,
                              target_userspace_info=target_userspace_info,
                              binds=bind_mounts
                              ) as (context, target_repoids, _unused):
        # the below nsenter command is important as we need to enter sysvipc namespace on the host so we can
        # communicate with udev
        cmd_prefix = ['nsenter', '--ipc=/installroot/proc/1/ns/ipc']

        # we have to ensure the leapp packages will stay untouched
        # Note: this is the most probably duplicate action - it should be already
        # set like that, however seatbelt is a good thing.
        dnfconfig.exclude_leapp_rpms(context)

        if get_target_major_version() == '9':
            _rebuild_rpm_db(context, root='/installroot')
        _transaction(
            context=context, stage='upgrade', target_repoids=target_repoids, plugin_info=plugin_info, tasks=tasks,
            cmd_prefix=cmd_prefix
        )

        # we have to ensure the leapp packages will stay untouched even after the
        # upgrade is fully finished (it cannot be done before the upgarde
        # on the host as the config-manager plugin is available since rhel-8)
        dnfconfig.exclude_leapp_rpms(mounting.NotIsolatedActions(base_dir='/'))
示例#3
0
def _get_repoids_to_exclude(repo_mapping):
    """
    Returns a set of repoids that should be blacklisted on the target system.

    :param RepositoriesMapping repo_mapping: Repository mapping data.
    :returns: A set of repoids to blacklist on the target system.
    :rtype: Set[str]
    """
    pesid_repos_to_exclude = _get_pesid_repos(
        repo_mapping, UNSUPPORTED_PESIDS[get_target_major_version()],
        get_target_major_version())
    return {pesid_repo.repoid for pesid_repo in pesid_repos_to_exclude}
示例#4
0
def perform_transaction_install(target_userspace_info, storage_info,
                                used_repos, tasks, plugin_info):
    """
    Performs the actual installation with the DNF rhel-upgrade plugin using the target userspace
    """

    # These bind mounts are performed by systemd-nspawn --bind parameters
    bind_mounts = [
        '/:/installroot',
        '/dev:/installroot/dev',
        '/proc:/installroot/proc',
        '/run/udev:/installroot/run/udev',
    ]

    if get_target_major_version() == '8':
        bind_mounts.append('/sys:/installroot/sys')
    else:
        # the target major version is RHEL 9+
        # we are bindmounting host's "/sys" to the intermediate "/hostsys"
        # in the upgrade initramdisk to avoid cgroups tree layout clash
        bind_mounts.append('/hostsys:/installroot/sys')

    already_mounted = {entry.split(':')[0] for entry in bind_mounts}
    for entry in storage_info.fstab:
        mp = entry.fs_file
        if not os.path.isdir(mp):
            continue
        if mp not in already_mounted:
            bind_mounts.append('{}:{}'.format(
                mp, os.path.join('/installroot', mp.lstrip('/'))))

    if os.path.ismount('/boot'):
        bind_mounts.append('/boot:/installroot/boot')

    if os.path.ismount('/boot/efi'):
        bind_mounts.append('/boot/efi:/installroot/boot/efi')

    with _prepare_transaction(used_repos=used_repos,
                              target_userspace_info=target_userspace_info,
                              binds=bind_mounts) as (context, target_repoids,
                                                     _unused):
        # the below nsenter command is important as we need to enter sysvipc namespace on the host so we can
        # communicate with udev
        cmd_prefix = ['nsenter', '--ipc=/installroot/proc/1/ns/ipc']

        if get_target_major_version() == '9':
            _rebuild_rpm_db(context, root='/installroot')
        _transaction(context=context,
                     stage='upgrade',
                     target_repoids=target_repoids,
                     plugin_info=plugin_info,
                     tasks=tasks,
                     cmd_prefix=cmd_prefix)
def prepare_target_userspace(context, userspace_dir, enabled_repos, packages):
    """
    Implement the creation of the target userspace.
    """
    target_major_version = get_target_major_version()
    run(['rm', '-rf', userspace_dir])
    _create_target_userspace_directories(userspace_dir)
    with mounting.BindMount(source=userspace_dir,
                            target=os.path.join(
                                context.base_dir,
                                'el{}target'.format(target_major_version))):
        repos_opt = [['--enablerepo', repo] for repo in enabled_repos]
        repos_opt = list(itertools.chain(*repos_opt))
        cmd = [
            'dnf', 'install', '-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 + packages
        if config.is_verbose():
            cmd.append('-v')
        if rhsm.skip_rhsm():
            cmd += ['--disableplugin', 'subscription-manager']
        try:
            context.call(cmd, callback_raw=utils.logging_handler)
        except CalledProcessError as exc:
            raise StopActorExecutionError(
                message='Unable to install RHEL {} userspace packages.'.format(
                    target_major_version),
                details={
                    'details': str(exc),
                    'stderr': exc.stderr
                })
示例#6
0
def generate_initram_disk(context):
    """
    Function to actually execute the init ramdisk creation.

    Includes handling of specified dracut modules from the host when needed.
    The check for the 'conflicting' dracut modules is in a separate actor.
    """
    env = {}
    if get_target_major_version() == '9':
        env = {'SYSTEMD_SECCOMP': '0'}
    # TODO(pstodulk): Add possibility to add particular drivers
    # Issue #645
    modules = _get_dracut_modules()  # deprecated
    files = set()
    for task in api.consume(UpgradeInitramfsTasks):
        modules.extend(task.include_dracut_modules)
        files.update(task.include_files)
    copy_dracut_modules(context, modules)
    # FIXME: issue #376
    context.call([
        '/bin/sh', '-c',
        'LEAPP_ADD_DRACUT_MODULES="{modules}" LEAPP_KERNEL_ARCH={arch} '
        'LEAPP_DRACUT_INSTALL_FILES="{files}" {cmd}'.format(
            modules=','.join([mod.name for mod in modules]),
            arch=api.current_actor().configuration.architecture,
            files=' '.join(files),
            cmd=os.path.join('/', INITRAM_GEN_SCRIPT_NAME))
    ],
                 env=env)
    copy_boot_files(context)
def _get_rhsm_available_repoids(context):
    target_major_version = get_target_major_version()
    # FIXME: check that required repo IDs (baseos, appstream)
    # + or check that all required RHEL repo IDs are available.
    if rhsm.skip_rhsm():
        return set()
    # Get the RHSM repos available in the target RHEL container
    # TODO: very similar thing should happens for all other repofiles in container
    #
    repoids = rhsm.get_available_repo_ids(context)
    if not repoids or len(repoids) < 2:
        raise StopActorExecutionError(
            message='Cannot find required basic RHEL {} repositories.'.format(
                target_major_version),
            details={
                'hint':
                ('It is required to have RHEL repositories on the system'
                 ' provided by the subscription-manager unless the --no-rhsm'
                 ' options is specified. Possibly you'
                 ' are missing a valid SKU for the target system or network'
                 ' connection failed. Check whether your system is attached'
                 ' to a valid SKU providing RHEL {} repositories.'
                 ' In case the Satellite is used, read the upgrade documentation'
                 ' to setup the satellite and the system properly.'.format(
                     target_major_version))
            })
    return set(repoids)
示例#8
0
def build_plugin_data(target_repoids, debug, test, tasks, on_aws):
    """
    Generates a dictionary with the DNF plugin data.
    """
    # get list of repo IDs of target repositories that should be used for upgrade
    data = {
        'pkgs_info': {
            'local_rpms': [os.path.join('/installroot', pkg.lstrip('/')) for pkg in tasks.local_rpms],
            'to_install': tasks.to_install,
            'to_remove': tasks.to_remove,
            'to_upgrade': tasks.to_upgrade
        },
        'dnf_conf': {
            'allow_erasing': True,
            'best': True,
            'debugsolver': debug,
            'disable_repos': True,
            'enable_repos': target_repoids,
            'gpgcheck': False,
            'platform_id': 'platform:el{}'.format(get_target_major_version()),
            'releasever': api.current_actor().configuration.version.target,
            'installroot': '/installroot',
            'test_flag': test
        },
        'rhui': {
            'aws': {
              'on_aws': on_aws,
              'region': None,
            }
        }
    }
    return data
示例#9
0
def _transaction(context, stage, target_repoids, tasks, plugin_info, test=False, cmd_prefix=None, on_aws=False):
    """
    Perform the actual DNF rpm download via our DNF plugin
    """

    # we do not want
    if stage != 'upgrade':
        create_config(
            context=context,
            target_repoids=target_repoids,
            debug=config.is_debug(),
            test=test, tasks=tasks,
            on_aws=on_aws
        )
    backup_config(context=context)

    # FIXME: rhsm
    with guards.guarded_execution(guards.connection_guard(), guards.space_guard()):
        cmd = [
            '/usr/bin/dnf',
            'rhel-upgrade',
            stage,
            DNF_PLUGIN_DATA_PATH
        ]
        if config.is_verbose():
            cmd.append('-v')
        if rhsm.skip_rhsm():
            cmd += ['--disableplugin', 'subscription-manager']
        if plugin_info:
            for info in plugin_info:
                if stage in info.disable_in:
                    cmd += ['--disableplugin', info.name]
        if cmd_prefix:
            cmd = cmd_prefix + cmd
        env = {}
        if get_target_major_version() == '9':
            # allow handling new RHEL 9 syscalls by systemd-nspawn
            env = {'SYSTEMD_SECCOMP': '0'}
        try:
            context.call(
                cmd=cmd,
                callback_raw=utils.logging_handler,
                env=env
            )
        except OSError as e:
            api.current_logger().error('Could not call dnf command: Message: %s', str(e), exc_info=True)
            raise StopActorExecutionError(
                message='Failed to execute dnf. Reason: {}'.format(str(e))
            )
        except CalledProcessError as e:
            api.current_logger().error('DNF execution failed: ')
            raise StopActorExecutionError(
                message='DNF execution failed with non zero exit code.\nSTDOUT:\n{stdout}\nSTDERR:\n{stderr}'.format(
                    stdout=e.stdout, stderr=e.stderr)
            )
        finally:
            if stage == 'check':
                backup_debug_data(context=context)
def scan_repositories(read_repofile_func=_read_repofile):
    """
    Scan the repository mapping file and produce RepositoriesMap msg.

    See the description of the actor for more details.
    """
    # TODO: add filter based on the current arch
    # TODO: deprecate the product type and introduce the "channels" ?.. more or less
    # NOTE: product type is changed, now it's channel: eus,e4s,aus,tus,ga,beta

    if os.path.exists(os.path.join('/etc/leapp/files', OLD_REPOMAP_FILE)):
        # NOTE: what about creating the report (instead of warning)
        api.current_logger().warning(
            'The old repomap file /etc/leapp/files/repomap.csv is present.'
            ' The file has been replaced by the repomap.json file and it is'
            ' not used anymore.')

    json_data = read_repofile_func(REPOMAP_FILE)
    try:
        repomap_data = RepoMapData.load_from_dict(json_data)
        mapping = repomap_data.get_mappings(get_source_major_version(),
                                            get_target_major_version())

        valid_major_versions = [
            get_source_major_version(),
            get_target_major_version()
        ]
        api.produce(
            RepositoriesMapping(mapping=mapping,
                                repositories=repomap_data.get_repositories(
                                    valid_major_versions)))
    except ModelViolationError as err:
        err_message = (
            'The repository mapping file is invalid: '
            'the JSON does not match required schema (wrong field type/value): {}'
            .format(err))
        _inhibit_upgrade(err_message)
    except KeyError as err:
        _inhibit_upgrade(
            'The repository mapping file is invalid: the JSON is missing a required field: {}'
            .format(err))
    except ValueError as err:
        # The error should contain enough information, so we do not need to clarify it further
        _inhibit_upgrade(
            'The repository mapping file is invalid: {}'.format(err))
示例#11
0
def _create_initram_packages():
    # copy the list as we do not want to affect the constant because of tests
    required_pkgs = _REQUIRED_PACKAGES[:]
    if architecture.matches_architecture(architecture.ARCH_X86_64):
        required_pkgs.append('biosdevname')
    if version.get_target_major_version() == '9':
        required_pkgs += ['policycoreutils', 'rng-tools']
    return (RequiredUpgradeInitramPackages(packages=required_pkgs),
            TargetUserSpaceUpgradeTasks(install_rpms=required_pkgs))
示例#12
0
    def get_target_pesid_repos(self, pesid):
        """
        Return the list of PESIDRepositoryEntry objects for a specified PES ID
        mathing the target OS major version.

        :param pesid: The PES ID for which to retrieve PESIDRepositoryEntries.
        :type pesid: str
        :return: A list of PESIDRepositoryEntries that match the provided PES ID and have
                 the OS Major version same as the target OS.
        :rtype: List[PESIDRepositoryEntry]
        """
        return self.get_pesid_repos(pesid, get_target_major_version())
示例#13
0
def _get_kernel_version(kernel_name):
    try:
        kernels = run(['rpm', '-q', kernel_name], split=True)['stdout']
    except CalledProcessError:
        return ''

    for kernel in kernels:
        # name-version-release - we want the last two fields only
        version = '-'.join(kernel.split('-')[-2:])
        if 'el{}'.format(get_target_major_version()) in version:
            return version
    return ''
def set_rhsm_release():
    """Set the RHSM release to the target RHEL minor version."""
    if rhsm.skip_rhsm():
        api.current_logger().debug(
            'Skipping setting the RHSM release due to --no-rhsm or environment variables.'
        )
        return

    if config.get_product_type('target') != 'ga':
        api.current_logger().debug(
            'Skipping setting the RHSM release as target product is set to beta/htb'
        )
        return
    target_version = api.current_actor().configuration.version.target
    try:
        rhsm.set_release(mounting.NotIsolatedActions(base_dir='/'),
                         target_version)
    except CalledProcessError as err:
        api.current_logger().warning(
            'Unable to set the {0} release through subscription-manager. When using dnf,'
            ' content of the latest RHEL {1} minor version will be downloaded.\n{2}'
            .format(target_version, get_target_major_version(), str(err)))
示例#15
0
def _get_rhsm_available_repoids(context):
    target_major_version = get_target_major_version()
    # FIXME: check that required repo IDs (baseos, appstream)
    # + or check that all required RHEL repo IDs are available.
    if rhsm.skip_rhsm():
        return set()
    # Get the RHSM repos available in the target RHEL container
    # TODO: very similar thing should happens for all other repofiles in container
    #
    repoids = rhsm.get_available_repo_ids(context)
    if not repoids or len(repoids) < 2:
        reporting.create_report([
            reporting.Title(
                'Cannot find required basic RHEL target repositories.'),
            reporting.Summary(
                'This can happen when a repository ID was entered incorrectly either while using the --enablerepo'
                ' option of leapp or in a third party actor that produces a CustomTargetRepositoryMessage.'
            ),
            reporting.Tags([reporting.Tags.REPOSITORY]),
            reporting.Severity(reporting.Severity.HIGH),
            reporting.Flags([reporting.Flags.INHIBITOR]),
            reporting.Remediation(hint=(
                'It is required to have RHEL repositories on the system'
                ' provided by the subscription-manager unless the --no-rhsm'
                ' option is specified. You might be missing a valid SKU for'
                ' the target system or have a failed network connection.'
                ' Check whether your system is attached to a valid SKU that is'
                ' providing RHEL {} repositories.'
                ' If you are using Red Hat Satellite, read the upgrade documentation'
                ' to set up Satellite and the system properly.'
            ).format(target_major_version)),
            reporting.ExternalLink(
                # TODO: How to handle different documentation links for each version?
                url='https://red.ht/preparing-for-upgrade-to-rhel8',
                title='Preparing for the upgrade')
        ])
        raise StopActorExecution()
    return set(repoids)
示例#16
0
def process():
    target_major_version = get_target_major_version()

    if target_major_version == '8':
        ipu_doc_url = (
            'https://access.redhat.com/documentation/en-us/'
            'red_hat_enterprise_linux/8/html-single/upgrading_to_rhel_8/index')
    elif target_major_version == '9':
        ipu_doc_url = ('TBA')

    rhui_info = next(api.consume(RHUIInfo), None)

    if not rhsm.skip_rhsm() or rhui_info:
        # getting RH repositories through RHSM or RHUI; resolved by seatbelts
        # implemented in other actors
        return

    # rhsm skipped; take your seatbelts please
    is_ctr = _any_custom_repo_defined()
    is_ctrf = _the_custom_repofile_defined()
    is_re = _the_enablerepo_option_used()
    if not is_ctr:
        # no rhsm, no custom repositories.. this will really not work :)
        # TODO: add link to the RH article about use of custom repositories!!
        # NOTE: we can put here now the link to the main document, as this
        # will be described there or at least the link to the right document
        # will be delivered here.
        if is_ctrf:
            summary_ctrf = '\n\nThe custom repository file has been detected. Maybe it is empty?'
        else:
            summary_ctrf = ''
        reporting.create_report([
            reporting.Title(
                'Using RHSM has been skipped but no custom or RHUI repositories have been delivered.'
            ),
            reporting.Summary(
                'Leapp is run in the mode when the Red Hat Subscription Manager'
                ' is not used (the --no-rhsm option or the LEAPP_NO_RHSM=1'
                ' environment variable has been set) so leapp is not able to'
                ' obtain YUM/DNF repositories with the content for the target'
                ' system in the standard way. The content has to be delivered'
                ' either by user manually or, in case of public clouds, by a'
                ' special Leapp package for RHUI environments.'),
            reporting.Remediation(hint=(
                'Create the repository file according to instructions in the'
                ' referred document on the following path with all'
                ' repositories that should be used during the upgrade: "{}".'
                '\n\n{}'.format(CUSTOM_REPO_PATH, summary_ctrf))),
            reporting.Severity(reporting.Severity.HIGH),
            reporting.Tags([reporting.Tags.SANITY]),
            reporting.Flags([reporting.Flags.INHIBITOR]),
            reporting.ExternalLink(
                url=ipu_doc_url,
                title='UPGRADING TO RHEL {}'.format(target_major_version)),
            reporting.RelatedResource('file', CUSTOM_REPO_PATH),
        ])
    elif not (is_ctrf or is_re):
        # Some custom repositories have been discovered, but the custom repo
        # file not - neither the --enablerepo option is used. Inform about
        # the official recommended way.
        reporting.create_report([
            reporting.Title(
                'Detected "CustomTargetRepositories" without using new provided mechanisms used.'
            ),
            reporting.Summary(
                'Red Hat now provides an official way for using custom'
                ' repositories during the in-place upgrade through'
                ' the referred custom repository file or through the'
                ' --enablerepo option for leapp. The CustomTargetRepositories'
                ' have been produced from custom (own) actors?'),
            reporting.Remediation(hint=(
                'Follow the new simple way to enable custom repositories'
                ' during the upgrade (see the referred document) or create'
                ' the empty custom repository file to acknowledge this report'
                ' message.')),
            reporting.Severity(reporting.Severity.INFO),
            reporting.ExternalLink(
                url=ipu_doc_url,
                title='UPGRADING TO RHEL {}'.format(target_major_version)),
            reporting.RelatedResource('file', CUSTOM_REPO_PATH),
        ])
示例#17
0
 def _feed(self):
     major = get_target_major_version()
     if major not in _DnfPluginPathStr._PATHS.keys():  # pylint: disable=W1655
         raise KeyError('{} is not a supported target version of RHEL'.format(major))
     self.data = _DnfPluginPathStr._PATHS[major]
示例#18
0
def _transaction(context, stage, target_repoids, tasks, plugin_info, test=False, cmd_prefix=None, on_aws=False):
    """
    Perform the actual DNF rpm download via our DNF plugin
    """

    # we do not want
    if stage not in ['dry-run', 'upgrade']:
        create_config(
            context=context,
            target_repoids=target_repoids,
            debug=config.is_debug(),
            test=test, tasks=tasks,
            on_aws=on_aws
        )
    backup_config(context=context)

    # FIXME: rhsm
    with guards.guarded_execution(guards.connection_guard(), guards.space_guard()):
        cmd_prefix = cmd_prefix or []
        common_params = []
        if config.is_verbose():
            common_params.append('-v')
        if rhsm.skip_rhsm():
            common_params += ['--disableplugin', 'subscription-manager']
        if plugin_info:
            for info in plugin_info:
                if stage in info.disable_in:
                    common_params += ['--disableplugin', info.name]
        env = {}
        if get_target_major_version() == '9':
            # allow handling new RHEL 9 syscalls by systemd-nspawn
            env = {'SYSTEMD_SECCOMP': '0'}

            # We need to reset modules twice, once before we check, and the second time before we actually perform
            # the upgrade. Not more often as the modules will be reset already.
            if stage in ('check', 'upgrade') and tasks.modules_to_reset:
                # We shall only reset modules that are not going to be enabled
                # This will make sure it is so
                modules_to_reset = {(module.name, module.stream) for module in tasks.modules_to_reset}
                modules_to_enable = {(module.name, module.stream) for module in tasks.modules_to_enable}
                module_reset_list = [module[0] for module in modules_to_reset - modules_to_enable]
                # Perform module reset
                cmd = ['/usr/bin/dnf', 'module', 'reset', '--enabled', ] + module_reset_list
                cmd += ['--disablerepo', '*', '-y', '--installroot', '/installroot']
                try:
                    context.call(
                        cmd=cmd_prefix + cmd + common_params,
                        callback_raw=utils.logging_handler,
                        env=env
                    )
                except (CalledProcessError, OSError):
                    api.current_logger().debug('Failed to reset modules via dnf with an error. Ignoring.',
                                               exc_info=True)

        cmd = [
            '/usr/bin/dnf',
            'rhel-upgrade',
            stage,
            DNF_PLUGIN_DATA_PATH
        ]
        try:
            context.call(
                cmd=cmd_prefix + cmd + common_params,
                callback_raw=utils.logging_handler,
                env=env
            )
        except OSError as e:
            api.current_logger().error('Could not call dnf command: Message: %s', str(e), exc_info=True)
            raise StopActorExecutionError(
                message='Failed to execute dnf. Reason: {}'.format(str(e))
            )
        except CalledProcessError as e:
            api.current_logger().error('DNF execution failed: ')
            raise StopActorExecutionError(
                message='DNF execution failed with non zero exit code.\nSTDOUT:\n{stdout}\nSTDERR:\n{stderr}'.format(
                    stdout=e.stdout, stderr=e.stderr)
            )
        finally:
            if stage == 'check':
                backup_debug_data(context=context)
def _get_repositories_mapping(target_pesids):
    """
    Get all repositories mapped from repomap file and map repositories id with respective names.

    :param target_pesids: The set of expected needed target PES IDs
    :return: Dictionary with all repositories mapped.
    """

    repositories_map_msgs = api.consume(RepositoriesMapping)
    repositories_map_msg = next(repositories_map_msgs, None)
    if list(repositories_map_msgs):
        api.current_logger().warning(
            'Unexpectedly received more than one RepositoriesMapping message.')
    if not repositories_map_msg:
        raise StopActorExecutionError(
            'Cannot parse RepositoriesMapping data properly',
            details={
                'Problem': 'Did not receive a message with mapped repositories'
            })

    repomap = peseventsscanner_repomap.RepoMapDataHandler(repositories_map_msg)
    # NOTE: We have to calculate expected target repositories
    # like in the setuptargetrepos actor. It's planned to handle this in different
    # way in future...
    enabled_repoids = _get_enabled_repoids()
    default_channels = peseventsscanner_repomap.get_default_repository_channels(
        repomap, enabled_repoids)
    repomap.set_default_channels(default_channels)

    exp_pesid_repos = repomap.get_expected_target_pesid_repos(enabled_repoids)
    # FIXME: this is hack now. In case some packages will need a repository
    # with pesid that is not mapped by default regarding the enabled repos,
    # let's use this one representative repository (baseos/appstream) to get
    # data for a guess of the best repository from the requires target pesid..
    # FIXME: this could now fail in case all repos are disabled...
    representative_repo = exp_pesid_repos.get(
        peseventsscanner_repomap.DEFAULT_PESID[get_target_major_version()],
        None)
    if not representative_repo:
        api.current_logger().warning(
            'Cannot determine the representative target base repository.')
        api.current_logger().info(
            'Fallback: Create an artificial representative PESIDRepositoryEntry for the repository mapping'
        )
        representative_repo = PESIDRepositoryEntry(
            pesid=peseventsscanner_repomap.DEFAULT_PESID[
                get_target_major_version()],
            arch=api.current_actor().configuration.architecture,
            major_version=get_target_major_version(),
            repoid='artificial-repoid',
            repo_type='rpm',
            channel='ga',
            rhui='',
        )

    for pesid in target_pesids:
        if pesid in exp_pesid_repos:
            continue
        # some packages are moved to repos outside of default repomapping
        # try to find the best possible repo for them..
        # FIXME: HACK NOW
        # good way is to modify class to search repo with specific criteria..
        if not representative_repo:
            api.current_logger().warning(
                'Cannot find suitable repository for PES ID: {}'.format(pesid))
            continue
        pesid_repo = repomap._find_repository_target_equivalent(
            representative_repo, pesid)

        if not pesid_repo:
            api.current_logger().warning(
                'Cannot find suitable repository for PES ID: {}'.format(pesid))
            continue
        exp_pesid_repos[pesid] = pesid_repo

    # map just pesids with found repoids
    # {to_pesid: repoid}
    repositories_mapping = {}
    for pesid, repository in exp_pesid_repos.items():
        if pesid not in target_pesids:
            # We can skip this repo as it was not identified as needed during the processing of PES events
            continue
        if not repository:
            # TODO
            continue
        repositories_mapping[pesid] = repository.repoid

    return repositories_mapping
def _get_target_userspace():
    return constants.TARGET_USERSPACE.format(get_target_major_version())
示例#21
0
def process():
    facts = next(api.consume(SELinuxFacts), None)
    if not facts:
        return

    enabled = facts.enabled
    conf_status = facts.static_mode

    if conf_status == 'disabled':
        if get_target_major_version() == '9':
            api.produce(KernelCmdlineArg(key='selinux', value='0'))
            reporting.create_report([
                reporting.Title('LEAPP detected SELinux disabled in "/etc/selinux/config"'),
                reporting.Summary(
                    'On RHEL 9, disabling SELinux in "/etc/selinux/config" is no longer possible. '
                    'This way, the system starts with SELinux enabled but with no policy loaded. LEAPP '
                    'will automatically disable SELinux using "SELINUX=0" kernel command line parameter. '
                    'However, Red Hat strongly recommends to have SELinux enabled'
                ),
                reporting.Severity(reporting.Severity.INFO),
                reporting.Tags([reporting.Tags.SELINUX]),
                reporting.RelatedResource('file', '/etc/selinux/config'),
                reporting.ExternalLink(url=DOC_URL, title='Disabling SELinux'),
            ])

        if enabled:
            reporting.create_report([
                reporting.Title('SElinux should be disabled based on the configuration file but it is enabled'),
                reporting.Summary(
                    'This message is to inform user about non-standard SElinux configuration. Please check '
                    '"/etc/selinux/config" to see whether the configuration is set as expected.'
                ),
                reporting.Severity(reporting.Severity.LOW),
                reporting.Tags([reporting.Tags.SELINUX, reporting.Tags.SECURITY])
            ])
        reporting.create_report([
            reporting.Title('SElinux disabled'),
            reporting.Summary('SElinux disabled, continuing...'),
            reporting.Tags([reporting.Tags.SELINUX, reporting.Tags.SECURITY])
        ])
        return

    if conf_status in ('enforcing', 'permissive'):
        api.produce(SelinuxRelabelDecision(set_relabel=True))
        reporting.create_report([
            reporting.Title('SElinux relabeling will be scheduled'),
            reporting.Summary('SElinux relabeling will be scheduled as the status is permissive/enforcing.'),
            reporting.Severity(reporting.Severity.INFO),
            reporting.Tags([reporting.Tags.SELINUX, reporting.Tags.SECURITY])
        ])

    if conf_status == 'enforcing':
        api.produce(SelinuxPermissiveDecision(
            set_permissive=True))
        reporting.create_report([
            reporting.Title('SElinux will be set to permissive mode'),
            reporting.Summary(
                'SElinux will be set to permissive mode. Current mode: enforcing. This action is '
                'required by the upgrade process to make sure the upgraded system can boot without '
                'beinig blocked by SElinux rules.'
            ),
            reporting.Severity(reporting.Severity.LOW),
            reporting.Remediation(hint=(
                'Make sure there are no SElinux related warnings after the upgrade and enable SElinux '
                'manually afterwards. Notice: You can ignore the "/root/tmp_leapp_py3" SElinux warnings.'
                )
            ),
            reporting.Tags([reporting.Tags.SELINUX, reporting.Tags.SECURITY])
        ])
示例#22
0
def get_upg_path():
    """
    Get upgrade path in specific string format
    """
    return '7to8' if get_target_major_version() == '8' else '8to9'