예제 #1
0
def get_default_repository_channels(repomap, src_repoids):
    """
    Returns the default repository channels. The 'ga' channel is always included and is the last
    one in the list, so it is the lowest priority when checking for channels.

    :param repomap: A RepoMapDataHandler instance containing the RepositoriesMapping data.
    :type repomap: RepoMapDataHandler
    :param src_repoids: Repositories present on the source system.
    :type src_repoids: List[str]
    :rtype: List[str]
    """
    default_pesid = DEFAULT_PESID[get_source_major_version()]
    top_prio_pesid_repo = None
    for repoid in src_repoids:
        pesid_repo = repomap.get_pesid_repo_entry(repoid, get_source_major_version())
        if not pesid_repo or pesid_repo.pesid != default_pesid:
            continue
        if not top_prio_pesid_repo or _get_channel_prio(pesid_repo) > _get_channel_prio(top_prio_pesid_repo):
            top_prio_pesid_repo = pesid_repo

    # always return at least 'ga'
    if not top_prio_pesid_repo or top_prio_pesid_repo.channel == 'ga':
        return ['ga']

    # keep this order to prefer higher prio to check first
    return [top_prio_pesid_repo.channel, 'ga']
예제 #2
0
def _are_optional_repos_disabled(repo_mapping, repos_on_system):
    """
    Checks whether all optional repositories are disabled.

    :param RepositoriesMapping repo_mapping: Repository mapping data.
    :param RepositoriesFacts repos_on_system: Installed repositories on the source system.
    :returns: True if there are any optional repositories enabled on the source system.
    """

    # Get a set of all repo_ids that are optional
    optional_pesid_repos = _get_pesid_repos(
        repo_mapping, UNSUPPORTED_PESIDS[get_source_major_version()],
        get_source_major_version())

    optional_repoids = [
        optional_pesid_repo.repoid
        for optional_pesid_repo in optional_pesid_repos
    ]

    # Gather all optional repositories on the source system that are not enabled
    for repofile in repos_on_system.repositories:
        for repository in repofile.data:
            if repository.repoid in optional_repoids and repository.enabled:
                return False
    return True
예제 #3
0
def _get_mapped_repoids(repomap, src_repoids):
    mapped_repoids = set()
    src_maj_ver = get_source_major_version()
    for repoid in src_repoids:
        if repomap.get_pesid_repo_entry(repoid, src_maj_ver):
            mapped_repoids.add(repoid)
    return mapped_repoids
def get_selinux_customizations():
    """
    Extract local SELinux customizations introduced by semanage command

    Returns tuple (semanage_valid, semanage_removed)
    where "semanage_valid" is a list of semanage commands
    which should be safe to re-apply on RHEL 8 system
    and "semanage_removed" is a list of commands that
    will no longer be valid after system upgrade
    """
    removed_types = REMOVED_TYPES_EL7 if version.get_source_major_version(
    ) == "7" else REMOVED_TYPES_EL8

    semanage_removed = []
    semanage_valid = []
    try:
        # Collect SELinux customizations and select the ones that
        # can be reapplied after the upgrade
        semanage = run(["semanage", "export"], split=True)
        for line in semanage.get("stdout", []):
            for setype in removed_types:
                if setype in line:
                    semanage_removed.append(line)
                    break
            else:
                semanage_valid.append(line)

    except CalledProcessError as e:
        api.current_logger().warning(
            "Failed to export SELinux customizations: {}".format(e.stderr))

    return (semanage_valid, semanage_removed)
예제 #5
0
def ipa_warn_pkg_installed(ipainfo):
    """
    Warn that unused ipa-server package is installed
    """
    if ipainfo.is_client_configured:
        summary = (
            "The ipa-server package is installed but only IdM client is "
            "configured on this system.")
    else:
        summary = (
            "The ipa-server package is installed but neither IdM server "
            "nor client is configured on this system.")
    entries = [
        reporting.Title(
            "ipa-server package is installed but no IdM is configured"),
        reporting.Summary(summary),
        reporting.Remediation(
            hint="Remove unused ipa-server package",
            commands=[["yum", "remove", "-y", "ipa-server"]],
        ),
        reporting.ExternalLink(
            url=MIGRATION_GUIDES[get_source_major_version()],
            title="Migrating IdM from RHEL 7 to 8",
        ),
        reporting.Severity(reporting.Severity.MEDIUM),
        reporting.Tags([reporting.Tags.SERVICES]),
        reporting.RelatedResource("package", "ipa-server"),
    ]
    return reporting.create_report(entries)
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))
예제 #7
0
    def get_source_pesid_repos(self, pesid):
        """
        Return the list of PESIDRepositoryEntry objects for a specified PES ID
        mathing the source 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 source OS.
        :rtype: List[PESIDRepositoryEntry]
        """
        return self.get_pesid_repos(pesid, get_source_major_version())
예제 #8
0
 def make_command(self, cmd):
     """ Transform the command to be executed with systemd-nspawn """
     binds = ['--bind={}'.format(bind) for bind in self.binds]
     setenvs = [
         '--setenv={}={}'.format(env.name, env.value)
         for env in self.env_vars
     ]
     final_cmd = ['systemd-nspawn', '--register=no', '--quiet']
     if get_source_major_version() != '7':
         # TODO: check whether we could use the --keep unit on el7 too.
         # in such a case, just add line into the previous solution..
         # TODO: the same about --capability=all
         final_cmd += ['--keep-unit', '--capability=all']
     return final_cmd + ['-D', self.target] + binds + setenvs + cmd
예제 #9
0
def get_leapp_packages():
    """
    Return the list of leapp and leapp-repository rpms that should be preserved
    during the upgrade.

    It's list of packages that should be preserved, not what is really
    installed.

    The snactor RPM doesn't have to be installed, but if so, we have to take
    care about that too as well to preven broken dnf transaction.
    """
    # TODO: should we set the seatbelt and exclude leapp RPMs from the target
    # system too?
    generic = ['leapp', 'snactor']
    if get_source_major_version() == '7':
        return generic + ['python2-leapp', 'leapp-upgrade-el7toel8']

    return generic + ['python3-leapp', 'leapp-upgrade-el8toel9']
예제 #10
0
    def get_expected_target_pesid_repos(self, src_repoids):
        """
        Return {target_pesid: PESIDRepositoryEntry} with expected target repositories.

        If some repositories are mapped to a target pesid for which no equivalent
        repository is discovered, such a key contains just None value.

        :param src_repoids: list of present source repoids that should be mapped to target repositories
        :type src_repoids: List[str]
        :rtype: {str: PESIDRepositoryEntry}
        """
        # {pesid: target_repo}
        target_repos_best_candidates = {}
        for src_repoid in src_repoids:
            src_pesidrepo = self.get_pesid_repo_entry(src_repoid, get_source_major_version())
            if not src_pesidrepo:
                # unmapped or custom repo -> skip this one
                continue

            for target_pesid, target_candidate in self.get_mapped_target_pesid_repos(src_pesidrepo).items():
                best_candidate = target_repos_best_candidates.get(target_pesid, None)
                if not best_candidate:
                    # we need to initialize the pesid even when the target_candidate is empty
                    # to know we possibly miss something
                    target_repos_best_candidates[target_pesid] = target_candidate
                if not target_candidate:
                    # It's not crucial in this moment - the pesid can be still filled
                    # by other maps. However log the warning as it is still unexpected
                    # with the valid repomap data
                    api.current_logger().warning(
                        'Cannot find any mapped target repository from the'
                        ' {pesid} family for the {repoid} repository.'
                        .format(repoid=src_repoid, pesid=target_pesid)
                    )
                    continue

                if best_candidate and _get_channel_prio(target_candidate) > _get_channel_prio(best_candidate):
                    # NOTE(pstodulk): we want just one target repository from the "PESID family"
                    # priority: beta < ga < all_else
                    # Why all_else?
                    # -> we do not expect multiple different premium channels present on the system
                    target_repos_best_candidates[target_pesid] = target_candidate
        return target_repos_best_candidates
예제 #11
0
def ipa_inhibit_upgrade(ipainfo):
    """
    Create upgrade inhibitor for configured ipa-server
    """
    entries = [
        reporting.Title("ipa-server does not support in-place upgrade"),
        reporting.Summary(
            "An IdM server installation was detected on the system. IdM "
            "does not support in-place upgrade."),
        reporting.Remediation(
            hint="Follow the IdM RHEL migration guide lines."),
        reporting.ExternalLink(
            url=MIGRATION_GUIDES[get_source_major_version()],
            title="IdM migration guide",
        ),
        reporting.Severity(reporting.Severity.HIGH),
        reporting.Flags([reporting.Flags.INHIBITOR]),
        reporting.Tags([reporting.Tags.SERVICES]),
        reporting.RelatedResource("package", "ipa-server"),
    ]
    return reporting.create_report(entries)
def check_module(name):
    """
    Check if given module contains one of removed types and comment out corresponding lines.

    The function expects a text file "$name" containing cil policy
    to be present in the current directory.

    Returns a list of invalid lines.
    """
    # get removed_types list based on upgrade path
    removed_types = REMOVED_TYPES_EL7 if version.get_source_major_version(
    ) == "7" else REMOVED_TYPES_EL8

    try:
        removed = run(["grep", "-w", "-E", "|".join(removed_types), name],
                      split=True)
        # Add ";" at the beginning of invalid lines (comment them out)
        run([
            "sed", "-i", "/{}/s/^/;/g".format(r"\|".join(removed_types)), name
        ])
        return removed.get("stdout", [])
    except CalledProcessError:
        return []
예제 #13
0
def _apply_yum_workaround(context):
    """
    Apply the yum workaround in the given context environment if on RHEL 7.
    """
    if get_source_major_version() == '7':
        utils.apply_yum_workaround(context)
예제 #14
0
def _get_releasever_path():
    default_manager = 'yum' if get_source_major_version() == '7' else 'dnf'
    return '/etc/{}/vars/releasever'.format(default_manager)