<commit_before>import logging

from teuthology.config import config as teuth_config
from teuthology.orchestra import run
from teuthology import packaging

from .util import _get_builder_project, _get_local_dir

log = logging.getLogger(__name__)


def _remove(ctx, config, remote, rpm):
    """
    Removes RPM packages from remote

    :param ctx: the argparse.Namespace object
    :param config: the config dict
    :param remote: the teuthology.orchestra.remote.Remote object
    :param rpm: list of packages names to remove
    """
    rpm = _package_overrides(rpm, remote.os)
    log.info("Removing packages: {pkglist} on rpm system.".format(
        pkglist=", ".join(rpm)))
    builder = _get_builder_project(ctx, remote, config)
    dist_release = builder.dist_release

    if dist_release in ['opensuse', 'sle']:
        pkg_mng_cmd = 'zypper'
        pkg_mng_opts = '-n --no-gpg-checks'
        pkg_mng_subcommand_opts = '--capability'
    else:
        pkg_mng_cmd = 'yum'
        pkg_mng_opts = '-y'
        pkg_mng_subcommand_opts = ''

    remote.run(
        args=[
            'for', 'd', 'in',
        ] + rpm + [
            run.Raw(';'),
            'do',
            'sudo',
            pkg_mng_cmd, pkg_mng_opts, 'remove', pkg_mng_subcommand_opts,
            run.Raw('$d'), run.Raw('||'), 'true', run.Raw(';'),
            'done',
        ])
    if dist_release in ['opensuse', 'sle']:
        pkg_mng_opts = '-a'
    else:
        pkg_mng_opts = 'all'
    remote.run(
        args=[
            'sudo', pkg_mng_cmd, 'clean', pkg_mng_opts,
        ])

    builder.remove_repo()

    if dist_release not in ['opensuse', 'sle']:
        pkg_mng_opts = 'expire-cache'
    remote.run(
        args=[
            'sudo', pkg_mng_cmd, 'clean', pkg_mng_opts,
        ])


def _package_overrides(pkgs, os):
    """
    Replaces some package names with their distro-specific equivalents
    (currently "python3-*" -> "python34-*" for CentOS)

    :param pkgs: list of RPM package names
    :param os: the teuthology.orchestra.opsys.OS object
    """
    is_rhel = os.name in ['centos', 'rhel']
    result = []
    for pkg in pkgs:
        if is_rhel:
            if pkg.startswith('python3-') or pkg == 'python3':
                pkg = pkg.replace('3', '34', 1)
        result.append(pkg)
    return result


def _update_package_list_and_install(ctx, remote, rpm, config):
    """
    Installs the repository for the relevant branch, then installs
    the requested packages on the remote system.

    TODO: split this into at least two functions.

    :param ctx: the argparse.Namespace object
    :param remote: the teuthology.orchestra.remote.Remote object
    :param rpm: list of packages names to install
    :param config: the config dict
    """
    # rpm does not force installation of a particular version of the project
    # packages, so we can put extra_system_packages together with the rest
    system_pkglist = config.get('extra_system_packages')
    if system_pkglist:
        if isinstance(system_pkglist, dict):
            rpm += system_pkglist.get('rpm')
        else:
            rpm += system_pkglist
    rpm = _package_overrides(rpm, remote.os)
    builder = _get_builder_project(ctx, remote, config)
    log.info('Pulling from %s', builder.base_url)
    log.info('Package version is %s', builder.version)
    log.info("Installing packages: {pkglist} on remote rpm {arch}".format(
        pkglist=", ".join(rpm), arch=builder.arch))
    builder.install_repo()

    dist_release = builder.dist_release
    project = builder.project
    if dist_release not in ['opensuse', 'sle']:
        uri = builder.uri_reference
        _yum_fix_repo_priority(remote, project, uri)
        _yum_fix_repo_host(remote, project)
        _yum_set_check_obsoletes(remote)

    if dist_release in ['opensuse', 'sle']:
        remote.run(
            args=[
                'sudo', 'zypper', 'clean', '-a',
            ])
    else:
        remote.run(
            args=[
                'sudo', 'yum', 'clean', 'all',
            ])

    ldir = _get_local_dir(config, remote)

    if dist_release in ['opensuse', 'sle']:
        pkg_mng_cmd = 'zypper'
        pkg_mng_opts = '-n --no-gpg-checks'
        pkg_mng_subcommand_opts = '--capability'
        pkg_mng_install_opts = '--no-recommends'
    else:
        pkg_mng_cmd = 'yum'
        pkg_mng_opts = '-y'
        pkg_mng_subcommand_opts = ''
        pkg_mng_install_opts = ''

    for cpack in rpm:
        pkg = None
        if ldir:
            pkg = "{ldir}/{cpack}".format(
                ldir=ldir,
                cpack=cpack,
            )
            remote.run(
                args=['if', 'test', '-e',
                      run.Raw(pkg), run.Raw(';'), 'then',
                      'sudo', pkg_mng_cmd, pkg_mng_opts, 'remove',
                      pkg_mng_subcommand_opts, pkg, run.Raw(';'),
                      'sudo', pkg_mng_cmd, pkg_mng_opts, 'install',
                      pkg_mng_subcommand_opts, pkg_mng_install_opts,
                      pkg, run.Raw(';'),
                      'fi']
            )
        if pkg is None:
            remote.run(args=[
                'sudo', pkg_mng_cmd, pkg_mng_opts, 'install',
                pkg_mng_subcommand_opts, pkg_mng_install_opts, cpack
            ])
        else:
            remote.run(
                args=['if', 'test', run.Raw('!'), '-e',
                      run.Raw(pkg), run.Raw(';'), 'then',
                      'sudo', pkg_mng_cmd, pkg_mng_opts, 'install',
                      pkg_mng_subcommand_opts, pkg_mng_install_opts,
                      cpack, run.Raw(';'),
                      'fi'])


def _yum_fix_repo_priority(remote, project, uri):
    """
    On the remote, 'priority=1' lines to each enabled repo in:

        /etc/yum.repos.d/{project}.repo

    :param remote: the teuthology.orchestra.remote.Remote object
    :param project: the project whose repos need modification<commit_msg>install: rpm: only one option per variable<commit_after>import logging

from teuthology.config import config as teuth_config
from teuthology.orchestra import run
from teuthology import packaging

from .util import _get_builder_project, _get_local_dir

log = logging.getLogger(__name__)


def _remove(ctx, config, remote, rpm):
    """
    Removes RPM packages from remote

    :param ctx: the argparse.Namespace object
    :param config: the config dict
    :param remote: the teuthology.orchestra.remote.Remote object
    :param rpm: list of packages names to remove
    """
    rpm = _package_overrides(rpm, remote.os)
    log.info("Removing packages: {pkglist} on rpm system.".format(
        pkglist=", ".join(rpm)))
    builder = _get_builder_project(ctx, remote, config)
    dist_release = builder.dist_release

    if dist_release in ['opensuse', 'sle']:
        pkg_mng_cmd = 'zypper'
        pkg_mng_opts = '-n --no-gpg-checks'
        pkg_mng_subcommand_opts = '--capability'
    else:
        pkg_mng_cmd = 'yum'
        pkg_mng_opts = '-y'
        pkg_mng_subcommand_opts = ''

    remote.run(
        args=[
            'for', 'd', 'in',
        ] + rpm + [
            run.Raw(';'),
            'do',
            'sudo',
            pkg_mng_cmd, pkg_mng_opts, 'remove', pkg_mng_subcommand_opts,
            run.Raw('$d'), run.Raw('||'), 'true', run.Raw(';'),
            'done',
        ])
    if dist_release in ['opensuse', 'sle']:
        pkg_mng_opts = '-a'
    else:
        pkg_mng_opts = 'all'
    remote.run(
        args=[
            'sudo', pkg_mng_cmd, 'clean', pkg_mng_opts,
        ])

    builder.remove_repo()

    if dist_release not in ['opensuse', 'sle']:
        pkg_mng_opts = 'expire-cache'
    remote.run(
        args=[
            'sudo', pkg_mng_cmd, 'clean', pkg_mng_opts,
        ])


def _package_overrides(pkgs, os):
    """
    Replaces some package names with their distro-specific equivalents
    (currently "python3-*" -> "python34-*" for CentOS)

    :param pkgs: list of RPM package names
    :param os: the teuthology.orchestra.opsys.OS object
    """
    is_rhel = os.name in ['centos', 'rhel']
    result = []
    for pkg in pkgs:
        if is_rhel:
            if pkg.startswith('python3-') or pkg == 'python3':
                pkg = pkg.replace('3', '34', 1)
        result.append(pkg)
    return result


def _update_package_list_and_install(ctx, remote, rpm, config):
    """
    Installs the repository for the relevant branch, then installs
    the requested packages on the remote system.

    TODO: split this into at least two functions.

    :param ctx: the argparse.Namespace object
    :param remote: the teuthology.orchestra.remote.Remote object
    :param rpm: list of packages names to install
    :param config: the config dict
    """
    # rpm does not force installation of a particular version of the project
    # packages, so we can put extra_system_packages together with the rest
    system_pkglist = config.get('extra_system_packages')
    if system_pkglist:
        if isinstance(system_pkglist, dict):
            rpm += system_pkglist.get('rpm')
        else:
            rpm += system_pkglist
    rpm = _package_overrides(rpm, remote.os)
    builder = _get_builder_project(ctx, remote, config)
    log.info('Pulling from %s', builder.base_url)
    log.info('Package version is %s', builder.version)
    log.info("Installing packages: {pkglist} on remote rpm {arch}".format(
        pkglist=", ".join(rpm), arch=builder.arch))
    builder.install_repo()

    dist_release = builder.dist_release
    project = builder.project
    if dist_release not in ['opensuse', 'sle']:
        uri = builder.uri_reference
        _yum_fix_repo_priority(remote, project, uri)
        _yum_fix_repo_host(remote, project)
        _yum_set_check_obsoletes(remote)

    if dist_release in ['opensuse', 'sle']:
        remote.run(
            args=[
                'sudo', 'zypper', 'clean', '-a',
            ])
    else:
        remote.run(
            args=[
                'sudo', 'yum', 'clean', 'all',
            ])

    ldir = _get_local_dir(config, remote)

    if dist_release in ['opensuse', 'sle']:
        pkg_mng_cmd = 'zypper'
        pkg_mng_opts = '-n'
        pkg_mng_gpg_opt = '--no-gpg-checks'
        pkg_mng_subcommand_opts = '--capability'
        pkg_mng_install_opts = '--no-recommends'
    else:
        pkg_mng_cmd = 'yum'
        pkg_mng_opts = '-y'
        pkg_mng_gpg_opt = ''
        pkg_mng_subcommand_opts = ''
        pkg_mng_install_opts = ''

    for cpack in rpm:
        pkg = None
        if ldir:
            pkg = "{ldir}/{cpack}".format(
                ldir=ldir,
                cpack=cpack,
            )
            remote.run(
                args=['if', 'test', '-e',
                      run.Raw(pkg), run.Raw(';'), 'then',
                      'sudo', pkg_mng_cmd, pkg_mng_opts, 'remove',
                      pkg_mng_subcommand_opts, pkg, run.Raw(';'),
                      'sudo', pkg_mng_cmd, pkg_mng_opts, pkg_mng_gpg_opt, 'install',
                      pkg_mng_subcommand_opts, pkg_mng_install_opts,
                      pkg, run.Raw(';'),
                      'fi']
            )
        if pkg is None:
            remote.run(args=[
                'sudo', pkg_mng_cmd, pkg_mng_opts, pkg_mng_gpg_opt, 'install',
                pkg_mng_subcommand_opts, pkg_mng_install_opts, cpack
            ])
        else:
            remote.run(
                args=['if', 'test', run.Raw('!'), '-e',
                      run.Raw(pkg), run.Raw(';'), 'then',
                      'sudo', pkg_mng_cmd, pkg_mng_opts, 'install',
                      pkg_mng_subcommand_opts, pkg_mng_install_opts,
                      cpack, run.Raw(';'),
                      'fi'])


def _yum_fix_repo_priority(remote, project, uri):
    """
    On the remote, 'priority=1' lines to each enabled repo in:

        /etc/yum.repos.d/{project}.repo

    :param remote: the teuthology.orchestra.remote.Remote object
    :param project: the project whose repos need modification
{'fraction_non_alphanumeric': 0.11764705882352941, 'fraction_numerical': 0.001661681621801263, 'mean_word_length': 2.129745189807592, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2244847', 'n_tokens_mistral': 4055, 'n_tokens_neox': 3815, 'n_words': 925}