コード例 #1
0
    def _consume_data(self):
        """
        Wrapper function to consume majority input data.

        It doesn't consume TargetRepositories, which are consumed in the
        own function.
        """
        self.packages = {'dnf'}
        for message in api.consume(RequiredTargetUserspacePackages):
            self.packages.update(message.packages)

        # Get the RHSM information (available repos, attached SKUs, etc.) of the source (RHEL 7) system
        self.rhsm_info = next(api.consume(RHSMInfo), None)
        self.rhui_info = next(api.consume(RHUIInfo), None)
        if not self.rhsm_info and not rhsm.skip_rhsm():
            api.current_logger().warning(
                'Could not receive RHSM information - Is this system registered?'
            )
            raise StopActorExecution()
        if rhsm.skip_rhsm() and self.rhsm_info:
            # this should not happen. if so, raise an error as something in
            # other actors is wrong really
            raise StopActorExecutionError(
                "RHSM is not handled but the RHSMInfo message has been produced."
            )

        self.custom_repofiles = list(api.consume(CustomTargetRepositoryFile))
        self.xfs_info = next(api.consume(XFSPresence), XFSPresence())
        self.storage_info = next(api.consume(StorageInfo), None)
        if not self.storage_info:
            raise StopActorExecutionError(
                'No storage info available cannot proceed.')
コード例 #2
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)
コード例 #3
0
ファイル: actor.py プロジェクト: zdohnal/leapp-repository
    def process(self):
        leftover_packages = next(self.consume(LeftoverPackages), LeftoverPackages())
        if not leftover_packages.items:
            self.log.info('No leftover packages, skipping...')
            return

        installed_rpms = get_installed_rpms()

        to_remove = ['-'.join([pkg.name, pkg.version, pkg.release]) for pkg in leftover_packages.items]
        cmd = ['dnf', 'remove', '-y', '--noautoremove'] + to_remove
        if rhsm.skip_rhsm():
            # ensure we don't use suscription-manager when it should be skipped
            cmd += ['--disableplugin', 'subscription-manager']
        try:
            stdlib.run(cmd)
        except stdlib.CalledProcessError:
            error = 'Failed to remove packages: {}'.format(', '.join(to_remove))
            self.log.error(error)
            return

        removed_packages = RemovedPackages()
        removed = list(set(installed_rpms) - set(get_installed_rpms()))
        for pkg in removed:
            name, version, release, epoch, packager, arch, pgpsig = pkg.split('|')
            removed_packages.items.append(RPM(
                name=name,
                version=version,
                epoch=epoch,
                packager=packager,
                arch=arch,
                release=release,
                pgpsig=pgpsig
            ))
        self.produce(removed_packages)
コード例 #4
0
def gather_target_repositories(context):
    """
    Perform basic checks on requirements for RHSM repositories and return the list of target repository ids to use
    during the upgrade.

    :param context: An instance of a mounting.IsolatedActions class
    :type context: mounting.IsolatedActions class
    :return: List of target system repoids
    :rtype: List(string)
    """
    # Get the RHSM repos available in the RHEL 8 container
    available_repos = rhsm.get_available_repo_ids(
        context, releasever=api.current_actor().configuration.version.target)

    # FIXME: check that required repo IDs (baseos, appstream)
    # + or check that all required RHEL repo IDs are available.
    if not rhsm.skip_rhsm():
        if not available_repos or len(available_repos) < 2:
            raise StopActorExecutionError(
                message='Cannot find required basic RHEL 8 repositories.',
                details={
                    'hint':
                    ('It is required to have RHEL repositories on the system'
                     ' provided by the subscription-manager. 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 8 repositories.')
                })

    target_repoids = []
    for target_repo in api.consume(TargetRepositories):
        for rhel_repo in target_repo.rhel_repos:
            if rhel_repo.repoid in available_repos:
                target_repoids.append(rhel_repo.repoid)
            else:
                # TODO: We shall report that the RHEL repos that we deem necessary for the upgrade are not available.
                # The StopActorExecutionError called above might be moved here.
                pass
        for custom_repo in target_repo.custom_repos:
            # TODO: complete processing of custom repositories
            # HINT: now it will work only for custom repos that exist
            # + already on the system in a repo file
            # TODO: should check available_target_repoids + additional custom repos
            # + outside of rhsm..
            # #if custom_repo.repoid in available_target_repoids:
            target_repoids.append(custom_repo.repoid)
    api.current_logger().debug("Gathered target repositories: {}".format(
        ', '.join(target_repoids)))
    if not target_repoids:
        raise StopActorExecutionError(
            message=
            'There are no enabled target repositories for the upgrade process to proceed.',
            details={
                'hint':
                ('Ensure your system is correctly registered with the subscription manager and that'
                 ' your current subscription is entitled to install the requested target version {version}'
                 ).format(
                     version=api.current_actor().configuration.version.target)
            })
    return target_repoids
コード例 #5
0
def gather_target_repositories(target_rhsm_info):
    """
    Performs basic checks on requirements for RHSM repositories and returns the list of target repository ids to use
    during the upgrade.
    """
    # FIXME: check that required repo IDs (baseos, appstream)
    # + or check that all required RHEL repo IDs are available.
    if not rhsm.skip_rhsm():
        if not target_rhsm_info.available_repos or len(
                target_rhsm_info.available_repos) < 2:
            raise StopActorExecutionError(
                message='Cannot find required basic RHEL repositories.',
                details={
                    'hint':
                    ('It is required to have RHEL repository on the system'
                     ' provided by the subscription-manager. Possibly you'
                     ' are missing a valid SKU for the target system or network'
                     ' connection failed. Check whether your system is attached'
                     ' to the valid SKU providing target repositories.')
                })

    target_repoids = []
    for target_repo in api.consume(TargetRepositories):
        for rhel_repo in target_repo.rhel_repos:
            if rhel_repo.repoid in target_rhsm_info.available_repos:
                target_repoids.append(rhel_repo.repoid)
        for custom_repo in target_repo.custom_repos:
            # TODO: complete processing of custom repositories
            # HINT: now it will work only for custom repos that exist
            # + already on the system in a repo file
            # TODO: should check available_target_repoids + additional custom repos
            # + outside of rhsm..
            # #if custom_repo.repoid in available_target_repoids:
            target_repoids.append(custom_repo.repoid)
    return target_repoids
コード例 #6
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:
        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)
コード例 #7
0
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
                })
コード例 #8
0
    def _consume_data(self):
        """
        Wrapper function to consume majority input data.

        It doesn't consume TargetRepositories, which are consumed in the
        own function.
        """
        self.packages = {'dnf'}
        self.files = []
        _cftuples = set()

        def _update_files(copy_files):
            # add just uniq CopyFile objects to omit duplicate copying of files
            for cfile in copy_files:
                cftuple = (cfile.src, cfile.dst)
                if cftuple not in _cftuples:
                    _cftuples.add(cftuple)
                    self.files.append(cfile)

        for task in api.consume(TargetUserSpacePreupgradeTasks):
            self.packages.update(task.install_rpms)
            _update_files(task.copy_files)

        for message in api.consume(RequiredTargetUserspacePackages):
            self.packages.update(message.packages)

        # Get the RHSM information (available repos, attached SKUs, etc.) of the source system
        self.rhsm_info = next(api.consume(RHSMInfo), None)
        self.rhui_info = next(api.consume(RHUIInfo), None)
        if not self.rhsm_info and not rhsm.skip_rhsm():
            api.current_logger().warning(
                'Could not receive RHSM information - Is this system registered?'
            )
            raise StopActorExecution()
        if rhsm.skip_rhsm() and self.rhsm_info:
            # this should not happen. if so, raise an error as something in
            # other actors is wrong really
            raise StopActorExecutionError(
                "RHSM is not handled but the RHSMInfo message has been produced."
            )

        self.custom_repofiles = list(api.consume(CustomTargetRepositoryFile))
        self.xfs_info = next(api.consume(XFSPresence), XFSPresence())
        self.storage_info = next(api.consume(StorageInfo), None)
        if not self.storage_info:
            raise StopActorExecutionError(
                'No storage info available cannot proceed.')
コード例 #9
0
def perform():
    packages = {'dnf'}
    for message in api.consume(RequiredTargetUserspacePackages):
        packages.update(message.packages)

    rhsm_info = next(api.consume(SourceRHSMInfo), None)
    if not rhsm_info and not rhsm.skip_rhsm():
        api.current_logger().warn(
            'Could not receive RHSM information - Is this system registered?')
        return

    xfs_info = next(api.consume(XFSPresence), XFSPresence())
    storage_info = next(api.consume(StorageInfo), None)
    if not storage_info:
        api.current_logger.error('No storage info available cannot proceed.')

    prod_cert_path = _get_product_certificate_path()
    with overlaygen.create_source_overlay(mounts_dir=constants.MOUNTS_DIR,
                                          scratch_dir=constants.SCRATCH_DIR,
                                          storage_info=storage_info,
                                          xfs_info=xfs_info) as overlay:
        with overlay.nspawn() as context:
            target_version = api.current_actor().configuration.version.target
            with rhsm.switched_certificate(context, rhsm_info, prod_cert_path,
                                           target_version) as target_rhsm_info:
                api.current_logger().debug(
                    'Target RHSM Info: SKUs: {skus} Repositories: {repos}'.
                    format(repos=target_rhsm_info.enabled_repos,
                           skus=rhsm_info.attached_skus if rhsm_info else []))
                target_repoids = gather_target_repositories(target_rhsm_info)
                api.current_logger().debug(
                    "Gathered target repositories: {}".format(
                        ', '.join(target_repoids)))
                if not target_repoids:
                    raise StopActorExecutionError(
                        message=
                        'There are no enabled target repositories for the upgrade process to proceed.',
                        details={
                            'hint':
                            ('Ensure your system is correctly registered with the subscription manager and that'
                             ' your current subscription is entitled to install the requested target version {version}'
                             ).format(version=api.current_actor().
                                      configuration.version.target)
                        })
                prepare_target_userspace(context, constants.TARGET_USERSPACE,
                                         target_repoids, list(packages))
                _prep_repository_access(context, constants.TARGET_USERSPACE)
                dnfplugin.install(constants.TARGET_USERSPACE)
                api.produce(
                    UsedTargetRepositories(repos=[
                        UsedTargetRepository(repoid=repo)
                        for repo in target_repoids
                    ]))
                api.produce(target_rhsm_info)
                api.produce(
                    TargetUserSpaceInfo(path=constants.TARGET_USERSPACE,
                                        scratch=constants.SCRATCH_DIR,
                                        mounts=constants.MOUNTS_DIR))
コード例 #10
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)
コード例 #11
0
def _prep_repository_access(context, target_userspace):
    """
    Prepare repository access by copying all relevant certificates and configuration files to the userspace
    """
    target_etc = os.path.join(target_userspace, 'etc')
    target_yum_repos_d = os.path.join(target_etc, 'yum.repos.d')
    backup_yum_repos_d = os.path.join(target_etc, 'yum.repos.d.backup')
    if not rhsm.skip_rhsm():
        run(['rm', '-rf', os.path.join(target_etc, 'pki')])
        run(['rm', '-rf', os.path.join(target_etc, 'rhsm')])
        context.copytree_from('/etc/pki', os.path.join(target_etc, 'pki'))
        context.copytree_from('/etc/rhsm', os.path.join(target_etc, 'rhsm'))
    # NOTE: we cannot just remove the original target yum.repos.d dir
    # as e.g. in case of RHUI a special RHUI repofiles are installed by a pkg
    # when the target userspace container is created. Removing these files we loose
    # RHUI target repositories. So ...->
    # -> detect such a files...
    with mounting.NspawnActions(base_dir=target_userspace) as target_context:
        files_owned_by_rpms = _get_files_owned_by_rpms(target_context,
                                                       '/etc/yum.repos.d')

    # -> backup the orig dir & install the new one
    run(['mv', target_yum_repos_d, backup_yum_repos_d])
    context.copytree_from('/etc/yum.repos.d', target_yum_repos_d)

    # -> find old rhui repo files (we have to remove these as they cause duplicates)
    rhui_pkgs = _get_all_rhui_pkgs()
    old_files_owned_by_rhui_rpms = _get_files_owned_by_rpms(
        context, '/etc/yum.repos.d', rhui_pkgs)
    for fname in old_files_owned_by_rhui_rpms:
        api.current_logger().debug('Remove the old repofile: {}'.format(fname))
        run(['rm', '-f', os.path.join(target_yum_repos_d, fname)])
    # .. continue: remove our leapp rhui repo file (do not care if we are on rhui or not)
    for rhui_map in rhui.gen_rhui_files_map().values():
        for item in rhui_map:
            if item[1] != rhui.YUM_REPOS_PATH:
                continue
            target_leapp_repofile = os.path.join(target_yum_repos_d, item[0])
            if not os.path.isfile(target_leapp_repofile):
                continue
            # we found it!!
            run(['rm', '-f', target_leapp_repofile])
            break

    # -> copy expected files back
    for fname in files_owned_by_rpms:
        api.current_logger().debug(
            'Copy the backed up repo file: {}'.format(fname))
        run([
            'mv',
            os.path.join(backup_yum_repos_d, fname),
            os.path.join(target_yum_repos_d, fname)
        ])

    # -> remove the backed up dir
    run(['rm', '-rf', backup_yum_repos_d])
コード例 #12
0
ファイル: actor.py プロジェクト: winndows/leapp-repository
 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
コード例 #13
0
def _prep_repository_access(context, target_userspace):
    """
    Prepare repository access by copying all relevant certificates and configuration files to the userspace
    """
    if not rhsm.skip_rhsm():
        run(['rm', '-rf', os.path.join(target_userspace, 'etc', 'pki')])
        run(['rm', '-rf', os.path.join(target_userspace, 'etc', 'rhsm')])
        context.copytree_from('/etc/pki', os.path.join(target_userspace, 'etc', 'pki'))
        context.copytree_from('/etc/rhsm', os.path.join(target_userspace, 'etc', 'rhsm'))
    run(['rm', '-rf', os.path.join(target_userspace, 'etc', 'yum.repos.d')])
    context.copytree_from('/etc/yum.repos.d', os.path.join(target_userspace, 'etc', 'yum.repos.d'))
コード例 #14
0
def _get_all_available_repoids(context):
    repofiles = repofileutils.get_parsed_repofiles(context)
    # TODO: this is not good solution, but keep it as it is now
    # Issue: #486
    if rhsm.skip_rhsm():
        # only if rhsm is skipped, the duplicate repos are not detected
        # automatically and we need to do it extra
        _inhibit_on_duplicate_repos(repofiles)
    repoids = []
    for rfile in repofiles:
        if rfile.data:
            repoids += [repo.repoid for repo in rfile.data]
    return set(repoids)
コード例 #15
0
 def process(self):
     if not rhsm.skip_rhsm():
         for info in self.consume(SourceRHSMInfo):
             if not info.attached_skus:
                 report_with_remediation(
                     title='The system is not registered or subscribed.',
                     summary=
                     'The system has to be registered and subscribed to be able to proceed the upgrade.',
                     remediation=
                     ('Register your system with the subscription-manager tool and attach it to proper SKUs'
                      ' to be able to proceed the upgrade.'),
                     severity='high',
                     flags=['inhibitor'])
コード例 #16
0
def enable_rhsm_repos():
    """
    Try enabling all the RHEL 8 repositories that have been used for the upgrade transaction.

    In case of custom repositories, the subscription-manager reports an error that it doesn't know them, but it enables
    the known repositories.
    """
    if rhsm.skip_rhsm():
        api.current_logger().debug('Skipping enabling repositories through subscription-manager due to the use of'
                                   ' LEAPP_DEVEL_SKIP_RHSM.')
        return
    try:
        run(get_submgr_cmd(get_repos_to_enable()))
    except CalledProcessError as err:
        api.current_logger().warning('The subscription-manager could not enable some repositories.\n'
                                     'It is expected behavior in case of custom repositories unknown to'
                                     ' the subscription-manager - these need to be enabled manually.\n{0}'
                                     .format(str(err)))
コード例 #17
0
def _consume_data():
    """Wrapper function to consume all input data."""
    packages = {'dnf'}
    for message in api.consume(RequiredTargetUserspacePackages):
        packages.update(message.packages)

    # Get the RHSM information (available repos, attached SKUs, etc.) of the source (RHEL 7) system
    rhsm_info = next(api.consume(RHSMInfo), None)
    if not rhsm_info and not rhsm.skip_rhsm():
        api.current_logger().warn(
            'Could not receive RHSM information - Is this system registered?')
        raise StopActorExecution()

    xfs_info = next(api.consume(XFSPresence), XFSPresence())
    storage_info = next(api.consume(StorageInfo), None)
    if not storage_info:
        raise StopActorExecutionError(
            'No storage info available cannot proceed.')
    return packages, rhsm_info, xfs_info, storage_info
コード例 #18
0
ファイル: actor.py プロジェクト: yarda/leapp-repository
 def process(self):
     if not rhsm.skip_rhsm():
         for info in self.consume(SourceRHSMInfo):
             if not info.attached_skus:
                 create_report([
                     reporting.Title(
                         'The system is not registered or subscribed.'),
                     reporting.Summary(
                         'The system has to be registered and subscribed to be able to proceed the upgrade.'
                     ),
                     reporting.Severity(reporting.Severity.HIGH),
                     reporting.Tags([reporting.Tags.SANITY]),
                     reporting.Flags([reporting.Flags.INHIBITOR]),
                     reporting.Remediation(
                         hint=
                         'Register your system with the subscription-manager tool and attach it to proper SKUs'
                         ' to be able to proceed the upgrade.'),
                     reporting.RelatedResource('package',
                                               'subscription-manager')
                 ])
コード例 #19
0
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)))
コード例 #20
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)
コード例 #21
0
def process():
    if not rhsm.skip_rhsm():
        for info in api.consume(RHSMInfo):
            if not info.attached_skus:
                create_report([
                    reporting.Title(
                        'The system is not registered or subscribed.'),
                    reporting.Summary(
                        'The system has to be registered and subscribed to be able to proceed'
                        ' with the upgrade, unless the --no-rhsm option is specified when'
                        ' executing leapp.'),
                    reporting.Severity(reporting.Severity.HIGH),
                    reporting.Tags([reporting.Tags.SANITY]),
                    reporting.Flags([reporting.Flags.INHIBITOR]),
                    reporting.Remediation(
                        hint=
                        'Register your system with the subscription-manager tool and attach'
                        ' proper SKUs to be able to proceed the upgrade or use the --no-rhsm'
                        ' leapp option if you want to provide target repositories by yourself.'
                    ),
                    reporting.RelatedResource('package',
                                              'subscription-manager')
                ])
コード例 #22
0
ファイル: dnfplugin.py プロジェクト: vinzenz/leapp-repository
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):
        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:el8', '--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']
        context.call(cmd)
コード例 #23
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)
コード例 #24
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
コード例 #25
0
def process():
    if rhsm.skip_rhsm():
        _report_unhandled_release()
    else:
        _report_set_release()
コード例 #26
0
def process():

    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 8'),
            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 8'),
            reporting.RelatedResource('file', CUSTOM_REPO_PATH),
        ])