HEX
Server: Apache
System: Linux server2.voipitup.com.au 4.18.0-553.109.1.lve.el8.x86_64 #1 SMP Thu Mar 5 20:23:46 UTC 2026 x86_64
User: posscale (1027)
PHP: 8.2.30
Disabled: exec,passthru,shell_exec,system
Upload Files
File: //opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/__pycache__/yumpkg.cpython-310.pyc
o

�N�g���@sddZddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
ZddlZddl
ZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlmZmZmZddlmZe�e�ZdZdZ dZ!dd	�Z"d
d�Z#dd
�Z$edfdd�Z%dd�Z&dd�Z'dd�Z(d�dd�Z)dd�Z*dd�Z+d�dd�Z,d�dd �Z-d�d!d"�Z.d#d$�Z/d%d&�Z0d'd(�Z1ej2j3�4e1d)�Z5d*d+�Z6d,d-�Z7d�d/d0�Z8d1d2�Z9d�d3d4�Z:d5d6�Z;d�d7d8�Z<ej2j3�4e<d9�Z=d:d;�Z>d<d=�Z?d>d?�Z@d@dA�ZAGdBdC�dCej2jBjC�ZD		.	.			.	.		.	D	.d�dEdF�ZE				.		.		d�dGdH�ZF				.		.	.d�dIdJ�ZGd�dKdL�ZHd�dMdN�ZI	d�dOdP�ZJd�dQdR�ZKedfdSdT�ZLej2j3�4eLdU�ZMdVdW�ZNdXdY�ZOd�dZd[�ZPd\d]�ZQd�d_d`�ZRej2j3�4eRda�ZSd�dbdc�ZTd�ddde�ZUd�dfdg�ZVd�dhdi�ZWd�djdk�ZXdldm�ZYdndo�ZZdpdq�Z[drds�Z\dtdu�Z]dvdw�Z^d�dxdy�Z_d�dzd{�Z`d|d}�Zad~d�ZbdS)�ak
Support for YUM/DNF

.. important::
    If you feel that Salt should be using this module to manage packages on a
    minion, and it is using a different module (or gives an error similar to
    *'pkg.install' is not available*), see :ref:`here
    <module-provider-override>`.

.. note::
    DNF is fully supported as of version 2015.5.10 and 2015.8.4 (partial
    support for DNF was initially added in 2015.8.0), and DNF is used
    automatically in place of YUM in Fedora 22 and newer.

.. versionadded:: 3003
    Support for ``tdnf`` on Photon OS.
.. versionadded:: 3006.10
    Support for ``dnf5``` on Fedora 41
�N)�CommandExecutionError�MinionError�SaltInvocationError��LooseVersionz[\w+]+(?:[.-][^-]+)*�.�pkgcCsnt�d�dkr	dSztd��}td��}Wn
ty!YdSwd}|dks,||vr5t�d	ur3d
StSdS)z2
    Confine this module to yum based systems
    Zyum_providerZ
yumpkg_api)Fz0Module yumpkg: yumpkg_api provider not available�os�	os_family)Fz+Module yumpkg: no yum based system detected)ZamazonZxcpZ	xenserverZvirtuozzolinuxZ	virtuozzozissabel pbxZ	openeulerZredhatN)FzDNF nor YUM found)�__opts__�get�
__grains__�lower�	Exception�_yum�__virtualname__)Zos_grainr
�enabled�r�G/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/yumpkg.py�__virtual__8s�

rcGsN|sd}ndd�|D�}d}tjj�|d�D]}|��|vr$||d7}q|S)N)zinstalled packageszavailable packageszavailable upgradeszupdated packageszupgraded packagescS�g|]}|���qSr)r��.0�xrrr�
<listcomp>_�z"_strip_headers.<locals>.<listcomp>��
)�salt�utils�	itertools�splitr)�output�argsZargs_lc�ret�linerrr�_strip_headersUs�r&cCs4|�dd�d}|�dd�}d|d�d|d��S)N�:��/zcopr:copr.fedorainfracloud.org:r)r!)�coprrrr�_get_copr_repogsr+TcCs�|rt�dvrd|�d�}nd|�d�}nt�dvr!d|�d�}nd|�d�}t�||�}|rQ|sL|�d��dd�d}|�d	d�d}|�d	d�dS|�d�Sd
S)z�
    Resolve a package name from a line containing the hold expression. If the
    regex is not matched, None is returned.

    yum ==> 2:vim-enhanced-7.4.629-5.el6.*
    dnf ==> vim-enhanced-2:7.4.827-1.fc22.*
    ��dnf�dnf5�(z-\S+)z(\d+:z\d+:(r(rr�-N)r�re�search�group�rsplit)r%�pattern�fullZlock_re�matchZwoarchZworelrrr�	_get_holdms


r8cs�ddl��fdd�}zt}Wntyi}Ynwd}||vrk�j�d�j���j�D]>}|�j�	|d��r=d||<n.|�j�	|d��rLd||<n|�j�	|d	��r[d	||<n|�j�	|d
��rjd
||<nq,|�|�S)zm
    Determine package manager name (yum or dnf[5]),
    depending on the executable existence in $PATH.
    rNcs.�j�|�o��|�j�jB�o�j�|�S�N)�path�exists�access�F_OK�X_OK�isdir)�file�r	rr�_check�s
��z_yum.<locals>._checkZyum_bin�PATHr.r-�tdnf�yum)
r	�__context__�	NameError�environr�defpathr!�pathsepr:�join)rB�context�
contextkey�dirrrArr�s0��
rcKszddtjj�t��d�}|�|�g}tjj�t�r(t	ddd�r(|�
ddg�|�t��|�
|�t	d	|fi|��S)
z
    Call yum/dnf.
    �traceF)�output_loglevel�python_shell�envz
config.getz
systemd.scopeTzsystemd-runz--scopezcmd.run_all)
rrZenvironmentZget_module_environment�globals�update�systemdZ	has_scoperF�__salt__�extend�appendr)r#�kwargs�params�cmdrrr�	_call_yum�s�
�
r\c	cs
�i}t�d�}tjj�t|��}td}t||�D]h\}}|dkrSz|�dd�\|d<|d<Wnt	yA||d<||d<Ynwtjj
j�|d|d|�|d<q|dkr]|�
d�}n	|d	krf|�d
�}|||<|d	kr�tjj
jjdi|��}i}|dur�|VqdS)
z�
    Parse yum/dnf output (which could contain irregular line breaks if package
    names are long) retrieving the name, version, etc., and return a list of
    pkginfo namedtuples.
    )�name�version�repoid�osarchr]rr(�archr^r0r_�@Nr)r �cyclerrr!r&r
�zipr4�
ValueErrorr�rpm�resolve_name�rstrip�lstrip�pkginfo)r"Zcur�keys�valuesr`�key�valuerjrrr�_yum_pkginfo�s8�
�

�
��rocCs�|durt}t�dvr-|d��dkr t|�d��dkrdSdSt|�d	��d
kr+dSdSt�dkr6td
��t|�d	��dkrAdSdS)z3
    Determine versionlock plugin package name
    Nr,r	ZfedoraZ	osrelease�zpython3-dnf-plugin-versionlockz&python3-dnf-plugins-extras-versionlock�osmajorrelease�zpython2-dnf-plugin-versionlockrDz'Cannot proceed, no versionlock for tdnf�zyum-versionlockzyum-plugin-versionlock)r
rr�intrr)Zgrainsrrr�_versionlock_pkg�s&
���
���rucCs$t�}|t�vrtd|�d���dS)zC
    Ensure that the appropriate versionlock plugin is present
    zCannot proceed, z is not installed.N)ru�	list_pkgsr)Z	vl_pluginrrr�_check_versionlocks
�rwcKs*|�dd�}|�dd�}|�dd�}|�dd�}|�dd�}|�dd�}|�dd	�}|d	ur1g}ntjj�|�}|�d
d�}|rD|sD|}g}	|rYt�d|�|	�d
d|��g�n>|rxt|t	�sc|gn|}
t�dd�
|
��|	�dd�|
D��|r�t|t	�s�|gn|}
t�dd�
|
��|	�dd�|
D��|r�t�d|�|	�d|���|r�t�d|�|	�d|���|D]}t�d|�|	�d|��g�q�|�rt|�D]7}|�
d�r�q�||}
t|
t�r�t�d||
�|	�d|�d|
���q�|
du�r	t�d |�|	�d|���q�|	�rt�d!|	�|	S)"zi
    Returns a list of options to be used in the yum/dnf[5] command, based on the
    kwargs passed.
    �fromrepor�repo�disablerepo�
enablerepo�disableexcludes�branch�setoptN�get_extra_optionsFzRestricting to repo '%s'z--disablerepo=*�
--enablerepo=zDisabling repo(s): %s�, cS�g|]}d|���qS)z--disablerepo=rrrrrr4�z _get_options.<locals>.<listcomp>zEnabling repo(s): %scSr�)r�rrrrrr8r�zDisabling excludes for '%s'z--disableexcludes=zAdding branch '%s'z	--branch=z Adding configuration option '%s'z	--setopt=�__zFound extra option --%s=%sz--�=TzFound extra option --%szAdding extra options: %s)�poprrr#�split_input�log�inforW�
isinstance�listrKrX�sorted�
startswith�str)rYrxryrzr{r|r}r~rr$�targets�itemrmrnrrr�_get_optionssd�


�r�c
Cs�dddgi}d}d}|D]}tj�|�r|}nq|s"td|����tj|d�}z|�|�WntyE}z
td|�d	|����d}~ww|�d
�rr|�	d
�D]}|dvrgdd
�|�
d
|��d�D�||<qP|�
d
|�||<qP|St�
d|�|S)aa
    Returns a dict representing the yum config options and values.

    We try to pull all of the yum config options into a standard dict object.
    This is currently only used to get the reposdir settings, but could be used
    for other things if needed.

    We try to read the yum.conf directly ourselves with a minimal set of
    "defaults".
    �reposdirz/etc/yum/repos.dz/etc/yum.repos.dN)z/etc/yum/yum.confz
/etc/yum.confz/etc/dnf/dnf.confz/etc/tdnf/tdnf.confz&No suitable yum config file found in: ��strictzUnable to read from z: �main)r�ZcommandsZexcludescSrr��striprrrrr�rz#_get_yum_config.<locals>.<listcomp>�,z<Could not find [main] section in %s, using internal defaults)r	r:r;r�configparser�ConfigParser�read�OSErrorZhas_section�optionsrr!r��warning)�
strict_parser�conf�fn�pathsr:Zcp�exc�optrrr�_get_yum_configXs4
����
"�r�cCst|�}||vr
|�|�SdS)zB
    Look for a specific config variable and return its value
    N)r�r)r]�
strict_configr�rrr�_get_yum_config_value�s
r�cCsRt|t�rdd�|�d�D�}|durg}|std|�}t|t�r#|s'td��|S)z�
    Takes a basedir argument as a string or a list. If the string or list is
    empty, then look up the default from the 'reposdir' option in the yum
    config.

    Returns a list of directories.
    cSrrr�rrrrr�rz&_normalize_basedir.<locals>.<listcomp>r�Nr�z(Could not determine any repo directories)r�r�r!r�r�r)�basedirr�rrr�_normalize_basedir�s
	
r�cCs�z|�td�d}|tjjjjdvr|WSWnty"|YSw|tddfvs7tjjjj	|tdd�rB|dt
|�d�S|S)ab
    Strips the architecture from the specified package name, if necessary.
    Circumstances where this would be done include:

    * If the arch is 32 bit and the package name ends in a 32-bit arch.
    * If the arch matches the OS arch, or is ``noarch``.

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.normalize_name zsh.x86_64
    r(�����noarchr`r��r`N)r4�PKG_ARCH_SEPARATORrrrrf�ARCHESrer
�check_32�len�r]rarrr�normalize_name�s���r�cCsVd\}}z
|�td�\}}Wn	tyYnw|tjjjjdvr&|}d}||d�S)z�
    Parse name and architecture from the specified package name.

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.parse_arch zsh.x86_64
    �NNr(r�Nr�)r4r�rerrrrfr�)r]�_nameZ_archrrr�
parse_arch�s
�
r�c	s�tjj�|�dd��}|sdStdi|��}|rtdi|��tdd��dg}|�|�|�ddg�|�|�t	|dd�}|d	d
krb|dr_t
�fdd
�|D��s_t�dd�
|�|d�g}n
tt|d�dd�dd�}�fdd�}i}|D]T�z��dd�d}	|	tjjjjvr�td}	Wn
ty�td}	Ynw�fdd�|D�D] }
|
jdks�|
j|	ks�tjjj�|
j�r�||
�r�|
j|�<nq�d|�<qyt|�dkr�||d
S|S)aN
    Return the latest version of the named package available for upgrade or
    installation. If more than one package name is specified, a dict of
    name/version pairs is returned.

    If the latest version of a given package is already installed, an empty
    string will be returned for that package.

    A specific repo can be requested using the ``fromrepo`` keyword argument,
    and the ``disableexcludes`` option is also supported.

    .. versionadded:: 2014.7.0
        Support for the ``disableexcludes`` option

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.latest_version <package name>
        salt '*' pkg.latest_version <package name> fromrepo=epel-testing
        salt '*' pkg.latest_version <package name> disableexcludes=main
        salt '*' pkg.latest_version <package1> <package2> <package3> ...
    �refreshTr��versions_as_list�--quietr��	available��ignore_retcode�retcoder�stderrcsg|]}|�v�qSrrr��cur_pkgsrrr
rz"latest_version.<locals>.<listcomp>z`Problem encountered getting latest version for the following package(s): %s. Stderr follows: 
%sr��stdoutcSs
t|j�Sr9)rr^)rjrrr�<lambda>s
z latest_version.<locals>.<lambda>)rm�reversecs@|j�vr�|jD]}tjjj|d|jtd�rdSq
dSdS)N�>=)�ver1�oper�ver2�cmp_funcFT)r]rr�versions�comparer^�version_cmp)rZinstalled_versionr�rr�
_check_curs
��z"latest_version.<locals>._check_currr(r�r`c3s�|]
}|j�kr|VqdSr9�r]rr�rr�	<genexpr>Gs�z!latest_version.<locals>.<genexpr>r�Nr)rr�data�is_truer�r��
refresh_dbrvrWr\�allr��errorrKr�ror4rrfr�r
rerar�r^r�)�namesrYr�r�r[�out�updatesr�r$rarr)r�r]r�latest_version�sf


�
���


�
��r��available_versioncKst|fi|��dkS)z�
    Check whether or not an upgrade is available for a given package

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.upgrade_available <package name>
    r)r�)r]rYrrr�upgrade_availablebs
r�cO�td|i|��S)aY
    Returns a string representing the package version or an empty string if not
    installed. If more than one package name is specified, a dict of
    name/version pairs is returned.

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.version <package name>
        salt '*' pkg.version <package1> <package2> <package3> ...
    �pkg_resource.version�rV�r�rYrrrr^os
r^FcKstd|||d�S)a�
    .. versionadded:: 2015.5.4

    Do a cmp-style comparison on two packages. Return -1 if pkg1 < pkg2, 0 if
    pkg1 == pkg2, and 1 if pkg1 > pkg2. Return None if there was a problem
    making the comparison.

    ignore_epoch : False
        Set to ``True`` to ignore the epoch when comparing versions

        .. versionadded:: 2015.8.10,2016.3.2

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.version_cmp '0.2-001' '0.2.0.1-002'
    zlowpkg.version_cmp)�ignore_epochr�)Zpkg1Zpkg2r�rYrrrr�sr�cCstdt|||�S)z'
    Use pkg list from __context__
    �pkg_resource.format_pkg_list)rVrF)r�rM�attrrrr�_list_pkgs_from_context�s
�r�c	s�tjj�|�}t�fdd�dD��riS��d�}|dur(|dkr(tjj�|�}d}|tvr:��dd	�r:t	|||�Si}d
ddd
dtjj
jj�
dd�dg}td|ddd�}|��D]F}tjj
jj|tdd�}|dur�|j}	d}
d}d|	vr�|	�dd�\}
}	d|	vr�|	�dd�\}	}|
|	||j|j|jd�}td||j|�q[|D]}
t||
dd�d�||
<q�|t|<td t|||�S)!a�
    List the packages currently installed as a dict. By default, the dict
    contains versions as a comma separated string::

        {'<package_name>': '<version>[,<version>...]'}

    versions_as_list:
        If set to true, the versions are provided as a list

        {'<package_name>': ['<version>', '<version>']}

    attr:
        If a list of package attributes is specified, returned value will
        contain them in addition to version, eg.::

        {'<package_name>': [{'version' : 'version', 'arch' : 'arch'}]}

        Valid attributes are: ``epoch``, ``version``, ``release``, ``arch``,
        ``install_date``, ``install_date_time_t``.

        If ``all`` is specified, all valid attributes will be returned.

            .. versionadded:: 2018.3.0

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.list_pkgs
        salt '*' pkg.list_pkgs attr=version,arch
        salt '*' pkg.list_pkgs attr='["version", "arch"]'
    cs g|]}tjj���|���qSr)rrr�r�rr�rYrrr�s zlist_pkgs.<locals>.<listcomp>)ZremovedZ
purge_desiredr�Nr��
pkg.list_pkgsZuse_contextTrfz-qaz
--nodigestz
--nosignature�
--queryformatz	%{REPOID}z(none)r�cmd.runFrO)rQrPr`r�r'r(r0)�epochr^�releasera�install_date�install_date_time_tzpkg_resource.add_pkgcSs|dS)Nr^r)�drrrr��szlist_pkgs.<locals>.<lambda>)rmr�)rrr�r��anyrr#r�rFr�rrfZQUERYFORMAT�replacerV�
splitlinesZ
parse_pkginfor
r^r!rar�r�r]r�)r�rYr�rMr$r[r"r%rj�pkgverr�r�Zall_attr�pkgnamerr�rrv�sZ!�
���
�rvcs|�dd�}|�dd�}|�dd�pd}|�dd�pd�|�dd�p#d�td1d|i|��}|rVt|t�sVzdd	�|�d
�D�}WntyUdd	�t|��d
�D�}Ynw�rt�t�szdd	���d
�D��Wnty~d
d	�t���d
�D��Ynw�r�t�t�s�zdd	���d
�D��Wnty�dd	�t���d
�D��Ynw|r�|�n��fdd	�td1i|����D��i�dd��d2����fdd�	}t	�dkr�dnt
tdddgdd���d�
��}|�r|t
d�k�rdg}|r�|�d�|�d�dD]}	t||	gd d!�}
|
d"dk�r||
d#d d$��qn|�rY|t
d%�k�rYdd&g}|�r5|�d�|�d�dD]}	t||	gd d!�}
|
d"dk�rV||
d#d d$��q<nE�D]B}t	�d'k�rldd(|��dg}ndd&d)|dg}|�r{|�d�|���t|d d!�}
|
d"dk�r�d*|
d#v�r��q[||
d#��q[|�rˈD]%}
�|
D]}td+d,��|
|D�d d-�}d.d	�|D��|
|<�q��q��Si}�D]}
�|
D]}|�|g���|
|��qՐq�|D]}td/d,�||D�d d-�}d0d	�|D�||<�q�|S)3a�
    .. versionadded:: 2014.1.0
    .. versionchanged:: 2014.7.0
        All available versions of each package are now returned. This required
        a slight modification to the structure of the return dict. The return
        data shown below reflects the updated return dict structure. Note that
        packages which are version-locked using :py:mod:`pkg.hold
        <salt.modules.yumpkg.hold>` will only show the currently-installed
        version, as locking a package will make other versions appear
        unavailable to yum/dnf.
    .. versionchanged:: 2017.7.0
        By default, the versions for each package are no longer organized by
        repository. To get results organized by repository, use
        ``byrepo=True``.

    Returns all available packages. Optionally, package names (and name globs)
    can be passed and the results will be filtered to packages matching those
    names. This is recommended as it speeds up the function considerably.

    .. warning::
        Running this function on RHEL/CentOS 6 and earlier will be more
        resource-intensive, as the version of yum that ships with older
        RHEL/CentOS has no yum subcommand for listing packages from a
        repository. Thus, a ``yum list installed`` and ``yum list available``
        are run, which generates a lot of output, which must then be analyzed
        to determine which package information to include in the return data.

    This function can be helpful in discovering the version or repo to specify
    in a :mod:`pkg.installed <salt.states.pkg.installed>` state.

    The return data will be a dictionary mapping package names to a list of
    version numbers, ordered from newest to oldest. If ``byrepo`` is set to
    ``True``, then the return dictionary will contain repository names at the
    top level, and each repository will map packages to lists of version
    numbers. For example:

    .. code-block:: python

        # With byrepo=False (default)
        {
            'bash': ['4.1.2-15.el6_5.2',
                     '4.1.2-15.el6_5.1',
                     '4.1.2-15.el6_4'],
            'kernel': ['2.6.32-431.29.2.el6',
                       '2.6.32-431.23.3.el6',
                       '2.6.32-431.20.5.el6',
                       '2.6.32-431.20.3.el6',
                       '2.6.32-431.17.1.el6',
                       '2.6.32-431.11.2.el6',
                       '2.6.32-431.5.1.el6',
                       '2.6.32-431.3.1.el6',
                       '2.6.32-431.1.2.0.1.el6',
                       '2.6.32-431.el6']
        }
        # With byrepo=True
        {
            'base': {
                'bash': ['4.1.2-15.el6_4'],
                'kernel': ['2.6.32-431.el6']
            },
            'updates': {
                'bash': ['4.1.2-15.el6_5.2', '4.1.2-15.el6_5.1'],
                'kernel': ['2.6.32-431.29.2.el6',
                           '2.6.32-431.23.3.el6',
                           '2.6.32-431.20.5.el6',
                           '2.6.32-431.20.3.el6',
                           '2.6.32-431.17.1.el6',
                           '2.6.32-431.11.2.el6',
                           '2.6.32-431.5.1.el6',
                           '2.6.32-431.3.1.el6',
                           '2.6.32-431.1.2.0.1.el6']
            }
        }

    fromrepo : None
        Only include results from the specified repo(s). Multiple repos can be
        specified, comma-separated.

    enablerepo (ignored if ``fromrepo`` is specified)
        Specify a disabled package repository (or repositories) to enable.
        (e.g., ``yum --enablerepo='somerepo'``)

        .. versionadded:: 2017.7.0

    disablerepo (ignored if ``fromrepo`` is specified)
        Specify an enabled package repository (or repositories) to disable.
        (e.g., ``yum --disablerepo='somerepo'``)

        .. versionadded:: 2017.7.0

    byrepo : False
        When ``True``, the return data for each package will be organized by
        repository.

        .. versionadded:: 2017.7.0

    cacheonly : False
        When ``True``, the repo information will be retrieved from the cached
        repo metadata. This is equivalent to passing the ``-C`` option to
        yum/dnf.

        .. versionadded:: 2017.7.0

    setopt
        A comma-separated or Python list of key=value options. This list will
        be expanded and ``--setopt`` prepended to each in the yum/dnf command
        that is run.

        .. versionadded:: 2019.2.0

    CLI Examples:

    .. code-block:: bash

        salt '*' pkg.list_repo_pkgs
        salt '*' pkg.list_repo_pkgs foo bar baz
        salt '*' pkg.list_repo_pkgs 'samba4*' fromrepo=base,updates
        salt '*' pkg.list_repo_pkgs 'python2-*' byrepo=True
    �byrepoF�	cacheonlyrxrrzr{cSrrr�rrrrr{rz"list_repo_pkgs.<locals>.<listcomp>r�cSrrr�rrrrr}rcS�g|]
}|dkr|���qS��*r�rrrrr��cSr�r�r�rrrrr�r�cSr�r�r�rrrrr�r�cSr�r�r�rrrrr�r�cs8g|]\}}|�vs|�vrt|�dd��dkr|�qS)r�1)r�r)rZ	repo_nameZ	repo_info)rzr{rrr�s�cSs |D]}t�||�r
dSqdS)zp
        Do glob matching on args and return True if a match was found.
        Otherwise, return False
        TF��fnmatch)r#r]�argrrr�_check_args�s
�z#list_repo_pkgs.<locals>._check_argscsXt|�D]%}|r|j�vs��|j�sq��|ji�}|�|jt��}|�|j�qdSr9)ror_r]�
setdefault�set�addr^)r"r�rZ	repo_dictZversion_list)r�r#�reposr$rr�
_parse_output�s�z%list_repo_pkgs.<locals>._parse_outputrENr�z	--version�rQrz3.2.13r�z-Cr�)�	installedr�Tr�r�r�r�z3.4.3z--showduplicatesrDr�zrepository-packages�Error:cs��|]}t|�VqdSr9rrrrrr����z!list_repo_pkgs.<locals>.<genexpr>)r�cS�g|]}|j�qSr�Zvstringrrrrr��csrr9rrrrrr��rcSrrrrrrrr�rr�F)r�r�r�r�r!�AttributeErrorr��
list_repos�itemsrrrVr�r�rXr\rWr�r�)r#rYr�r�rxZrepo_argrZyum_version�
cmd_prefixZpkg_srcr�ryr[�reponamer�Zsorted_versionsZ
byrepo_retr)r�r#rzr{r�r$r�list_repo_pkgs�s�x����



����


��

���

����rcKs�tdi|��}tjj�|�rtdddi|��dg}|�|�|�dt�dvr)dndg�t|dd	�}|d
dkr?d|vr?iSd
d�t	|d�D�S)a�
    Check whether or not an upgrade is available for all packages

    The ``fromrepo``, ``enablerepo``, and ``disablerepo`` arguments are
    supported, as used in pkg states, and the ``disableexcludes`` option is
    also supported.

    .. versionadded:: 2014.7.0
        Support for the ``disableexcludes`` option

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.list_upgrades
    �check_updateFr�r�r,z
--upgradesr�Tr�r�rrcSsi|]}|j|j�qSr)r]r^rrrr�
<dictcomp>r�z!list_upgrades.<locals>.<dictcomp>r�Nr)
r�rrr�r�r�rWrr\ro)r�rYr�r[r�rrr�
list_upgrades�s
r�list_updatesc
Ks�tj�dt��}i}tjj�|�D]>\}}}t�|d�D]2}tj�||�}t	d|�}t
tj�|��}	|tj�|�|	t
j
�|	���d�|�|di�|d<qq|S)z�
    .. versionadded:: 2017.7.0

    List prefetched packages downloaded by Yum in the local disk.

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.list_downloaded
    �
/var/cachez*.rpm�lowpkg.bin_pkg_info)r:�sizeZcreation_date_time_tZcreation_date_timer]r^)r	r:rKrrrZos_walkr��filterrVrt�getctime�getsize�datetime�
fromtimestamp�	isoformatr�)
rY�	CACHE_DIRr$�root�dirnames�	filenames�filename�package_path�pkg_infoZ
pkg_timestamprrr�list_downloadeds"
���r$cOs�|�dd�}t�}td|i|����D]9\}}|r|n|g}|D]+}t�}|��D]\}	}
|	dkr7|
|d<q*|
||	<q*|sC|||<q!|�|g��|�q!q|S)a�
    .. versionadded:: 2015.8.1

    Return the information of the named package(s), installed on the system.

    :param all_versions:
        Include information for all versions of the packages installed on the minion.

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.info_installed <package1>
        salt '*' pkg.info_installed <package1> <package2> <package3> ...
        salt '*' pkg.info_installed <package1> <package2> <package3> all_versions=True
    �all_versionsFzlowpkg.infoZ
source_rpm�source)r�dictrVrr�rX)r�rYr%r$�pkg_nameZpkgs_nfoZpkg_nfoZ_nfoZt_nformrnrrr�info_installed:s


�r)cKs�tjj�t�dddd�}d}|�dd�}tdi|��}gd�}|�|�t|dd�|rUgd�}t	�
d	�d
krDt	�
d�dkrD|�d
�|�|�|�
t|dd�dd�}|S)a�
    Check the yum repos for updated packages

    Returns:

    - ``True``: Updates are available
    - ``False``: An error occurred
    - ``None``: No updates are available

    repo
        Refresh just the specified repo

    disablerepo
        Do not refresh the specified repo

    enablerepo
        Refresh a disabled repo using this option

    branch
        Add the specified branch when refreshing

    disableexcludes
        Disable the excludes defined in your config files. Takes one of three
        options:
        - ``all`` - disable all excludes
        - ``main`` - disable excludes defined in [main] in yum.conf
        - ``repoid`` - disable excludes defined for that repo

    setopt
        A comma-separated or Python list of key=value options. This list will
        be expanded and ``--setopt`` prepended to each in the yum/dnf command
        that is run.

        .. versionadded:: 2019.2.0

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.refresh_db
    TNF)�drr(r)r��--assumeyesZcleanzexpire-cacher�)r�r+zcheck-updater
ZRedHatrq�z'--setopt=autocheck_running_kernel=falser�r)rrrZ
clear_rtagrr�r�rWr\r
rrX)rYZretcodesr$Z
check_update_r�Z	clean_cmdZ
update_cmdrrrr�^s&+�


r�cKstdi|��S)z�
    .. versionadded:: 2014.1.0

    Cleans local yum metadata. Functionally identical to :mod:`refresh_db()
    <salt.modules.yumpkg.refresh_db>`.

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.clean_metadata
    Nr)r�r�rrr�clean_metadata�s
r-cs,eZdZ�fdd�Zdd�Zdd�Z�ZS)�AvailablePackagescst���||_||_dSr9)�super�__init__�_args�_kwargs)�selfr#rY��	__class__rrr0�s

zAvailablePackages.__init__cCs|��dS�NT)�	_load_all)r3rmrrr�_load�szAvailablePackages._loadcCst|ji|j��|_d|_dSr6)rr1r2�_dictZloaded)r3rrrr7�s
zAvailablePackages._load_all)�__name__�
__module__�__qualname__r0r8r7�
__classcell__rrr4rr.�sr.�basec3
s�|�d�durt|d�|d<tdFi|���tjj�|�r$tdFi|��tjj�|�}ztd|||f|	|o;|�dd�d�|��\}}
Wnt	yT}zt
|��d}~ww|sYiS|�d�}�sftd|d	�nt�}�sptdd
�nt�}g}g}g}i}|
dkr�g}g}|�
�D]*\}}zd|vr�|�|�n|�d
�s�|�d�r�|�|�Wq�ttfy�Yq�wt||ddi|��}|�
�}nR|
dkr�g}t�}|D]}||vr�t
d|�d���|�|�q�n2g}|D]-}dtvr�td|�}nd}|du�rt�d|�|�|g�q�|�|d||dg�q�g�|D�]�}|
dk�r%|\}} n$|
dk�r/|}d} nz|\}}!} Wnt�yHd}|d}!d} Ynw| du�r�|
dk�rm|�rd||v�rd|�||f��q|�||f��q|
dk�r{|�||f��q|�||!f��q|
dk�rR| �d�} ||v�r�|�|g�}"tjjj| |"t|
d�}#|#du�r���d�|| |"�r�d�|"�nd���q|#} t�dk�r�|
du�r�| �dd�d} d}$z
|�d d�\}%}&Wn
t�y�Ynw|&tjjjj v�r|&t!d!k�s|�dd��rd |&}$|%}d| v�r5|�|g�}"tjj"�#|"| �}'|'du�r!|'} n��d"�| ||"�r/d�|"�nd#���q|
du�rD|�d$| �|$��}(nd%�|| �dd�d|$�}(n|!}(|�|g�})|�r~|)�r~|)D]}*tjj$j%| d&|*t|
d'��rz|�||(f�n�qb�q|)�s�|�||(f��q|)D]}*tjj$j%| d(|*t|
d'��r�|�||(f�n�q�|du�r�t&�'d)|��r�|�||(f��q|�||(f��q���fd*d+�}+zt(dd,��Wnt)�y�g�t�*d-�Ynwg�t+j,����fd.d/��},g}-|,||-��^|-�rQ|
dk�r
d0d1�|-D�}-d2g}.t�d3k�r|.�-d4d5g�|+|.�|.�|
dk�r'd6nd7�t�d8k�r7|.�-d4d5g�|.�-|-�t.|.ddd9�}/|/d:dk�rQ��|/d;�Wd�n	1�s\wYg}-|,||-��0|-�r�d2g}.|+|.�|.�d<�|.�-|-�t.|.dd=�}/|/d:dk�r���|/d;�Wd�n	1�s�wYg}-|,||-��0|-�r�d2g}.|+|.�|.�d>�|.�-|-�t.|.dd=�}/|/d:dk�rш�|/d;�Wd�n	1�s�wYt/�0d?d���s�td|d	�nt�}0tjj�1||0�}1|D]!\}}2||1v�s||v�r|1�2||�|d�|0�|d�d@�i��q���r-��dA�d�������rAt
dB�|�r8dCnd��|1dD�dE��|1S)GaK
    .. versionchanged:: 2015.8.12,2016.3.3,2016.11.0
        On minions running systemd>=205, `systemd-run(1)`_ is now used to
        isolate commands which modify installed packages from the
        ``salt-minion`` daemon's control group. This is done to keep systemd
        from killing any yum/dnf commands spawned by Salt when the
        ``salt-minion`` service is restarted. (see ``KillMode`` in the
        `systemd.kill(5)`_ manpage for more information). If desired, usage of
        `systemd-run(1)`_ can be suppressed by setting a :mod:`config option
        <salt.modules.config.get>` called ``systemd.scope``, with a value of
        ``False`` (no quotes).

    .. _`systemd-run(1)`: https://www.freedesktop.org/software/systemd/man/systemd-run.html
    .. _`systemd.kill(5)`: https://www.freedesktop.org/software/systemd/man/systemd.kill.html

    Install the passed package(s), add refresh=True to clean the yum database
    before package is installed.

    name
        The name of the package to be installed. Note that this parameter is
        ignored if either "pkgs" or "sources" is passed. Additionally, please
        note that this option can only be used to install packages from a
        software repository. To install a package file manually, use the
        "sources" option.

        32-bit packages can be installed on 64-bit systems by appending the
        architecture designation (``.i686``, ``.i586``, etc.) to the end of the
        package name.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name>

    refresh
        Whether or not to update the yum database before executing.

    reinstall
        Specifying reinstall=True will use ``yum reinstall`` rather than
        ``yum install`` for requested packages that are already installed.

        If a version is specified with the requested package, then
        ``yum reinstall`` will only be used if the installed version
        matches the requested version.

        Works with ``sources`` when the package header of the source can be
        matched to the name and version of an installed package.

        .. versionadded:: 2014.7.0

    skip_verify
        Skip the GPG verification check (e.g., ``--nogpgcheck``)

    downloadonly
        Only download the packages, do not install.

    version
        Install a specific version of the package, e.g. 1.2.3-4.el5. Ignored
        if "pkgs" or "sources" is passed.

        .. versionchanged:: 2018.3.0
            version can now contain comparison operators (e.g. ``>1.2.3``,
            ``<=2.0``, etc.)

    update_holds : False
        If ``True``, and this function would update the package version, any
        packages held using the yum/dnf "versionlock" plugin will be unheld so
        that they can be updated. Otherwise, if this function attempts to
        update a held package, the held package(s) will be skipped and an
        error will be raised.

        .. versionadded:: 2016.11.0

    setopt
        A comma-separated or Python list of key=value options. This list will
        be expanded and ``--setopt`` prepended to each in the yum/dnf command
        that is run.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install foo setopt='obsoletes=0,plugins=0'

        .. versionadded:: 2019.2.0

    Repository Options:

    fromrepo
        Specify a package repository (or repositories) from which to install.
        (e.g., ``yum --disablerepo='*' --enablerepo='somerepo'``)

    enablerepo (ignored if ``fromrepo`` is specified)
        Specify a disabled package repository (or repositories) to enable.
        (e.g., ``yum --enablerepo='somerepo'``)

    disablerepo (ignored if ``fromrepo`` is specified)
        Specify an enabled package repository (or repositories) to disable.
        (e.g., ``yum --disablerepo='somerepo'``)

    disableexcludes
        Disable exclude from main, for a repo or for everything.
        (e.g., ``yum --disableexcludes='main'``)

        .. versionadded:: 2014.7.0

    ignore_epoch : False
        Only used when the version of a package is specified using a comparison
        operator (e.g. ``>4.1``). If set to ``True``, then the epoch will be
        ignored when comparing the currently-installed version to the desired
        version.

        .. versionadded:: 2018.3.0


    Multiple Package Installation Options:

    pkgs
        A list of packages to install from a software repository. Must be
        passed as a python list. A specific version number can be specified
        by using a single-element dict representing the package and its
        version.

        CLI Examples:

        .. code-block:: bash

            salt '*' pkg.install pkgs='["foo", "bar"]'
            salt '*' pkg.install pkgs='["foo", {"bar": "1.2.3-4.el5"}]'

    sources
        A list of RPM packages to install. Must be passed as a list of dicts,
        with the keys being package names, and the values being the source URI
        or local path to the package.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install sources='[{"foo": "salt://foo.rpm"}, {"bar": "salt://bar.rpm"}]'

    normalize : True
        Normalize the package name by removing the architecture. This is useful
        for poorly created packages which might include the architecture as an
        actual part of the name such as kernel modules which match a specific
        kernel version.

        .. code-block:: bash

            salt -G role:nsd pkg.install gpfs.gplbin-2.6.32-279.31.1.el6.x86_64 normalize=False

        .. versionadded:: 2014.7.0

    split_arch : True
        If set to False it prevents package name normalization more strict way
        than ``normalize`` set to ``False`` does.

        .. versionadded:: 3006.0

    diff_attr:
        If a list of package attributes is specified, returned value will
        contain them, eg.::

            {'<package>': {
                'old': {
                    'version': '<old-version>',
                    'arch': '<old-arch>'},

                'new': {
                    'version': '<new-version>',
                    'arch': '<new-arch>'}}}

        Valid attributes are: ``epoch``, ``version``, ``release``, ``arch``,
        ``install_date``, ``install_date_time_t``.

        If ``all`` is specified, all valid attributes will be returned.

        .. versionadded:: 2018.3.0

    Returns a dict containing the new package names and versions::

        {'<package>': {'old': '<old-version>',
                       'new': '<new-version>'}}

    If an attribute list in diff_attr is specified, the dict will also contain
    any specified attribute, eg.::

        {'<package>': {
            'old': {
                'version': '<old-version>',
                'arch': '<old-arch>'},

            'new': {
                'version': '<new-version>',
                'arch': '<new-arch>'}}}
    r^N�pkg_resource.parse_targets�
split_archT)�saltenv�	normalize�	diff_attrF)r�r�r�Z
repositoryr��<�>r�Zadvisoryz
Advisory id "z" not foundrz�pkg.install: Unable to get rpm information for %s. Version comparisons will be unavailable, and return data may be inaccurate if reinstall=True.r]rr�)r�r�z9No version matching '{}{}' could be found (available: {})r�rEr'r(r�rrr`z?No version matching '{}' found for package '{}' (available: {})Znoner0�{}-{}{}z==)r�r�r�r�r�r�z^kernel(|-devel)$cs.|����r|�d��r|�d�dSdS)zI
        DRY function to add args common to all yum/dnf commands
        �--nogpgcheckz--downloadonlyN)rWrX)r[)�downloadonlyr��skip_verifyrr�_add_common_args�s

�z!install.<locals>._add_common_args�r6zAFailed to get holds, versionlock plugin is probably not installedc	
3s�i}|D]\}}|�vr�r|||<q��|�q|�|�q|s'dVdSt�dd�|��zWz(t|���}t|d���D]\}}|drO|�||�q?��|�q?dVWntyw}z��d�	d�|�|��WYd}~n
d}~wwWt
|d�dSWt
|d�dSt
|d�w)z�
        Temporarily unhold packages that need to be updated. Add any
        successfully-removed ones (and any packages not in the list of current
        holds) to the list of targets.
        NzUnholding packages: %sr�)�pkgs�resultz+Error encountered unholding packages {}: {})rXr��debugrKr�rk�unholdrr�format�hold)	rLr�Z	to_unholdr��pkgstrZunhold_namesZ
unheld_pkg�outcomer�)�errors�holds�unhold_prevented�update_holdsrr�_temporarily_unhold�s<�



������z$install.<locals>._temporarily_unholdcSr�)z--advisory=r)r�trrrr�r�zinstall.<locals>.<listcomp>�-yr-z--bestz--allowerasing�installrTr.)r��redirect_stderrr�r�Z	downgrade)r\�	reinstallr�)�old�newz�The following package(s) could not be updated because they are being held: {}. Set 'update_holds' to True to temporarily unhold these packages so that they can be updated.z&Error occurred installing{} package(s)z
/reinstalling�rT�changes�r�r)3rr�r�rrr�r�r�rVrrrvr$rrXr��	TypeErrorrer.�list_patchesr�r�rirZ
match_versionr�rPrKrr!r4rfr�r
r Zfnmatch_multipler�r�r1r7�
list_holdsrrN�
contextlib�contextmanagerrWr\rFr��
compare_dictsrT)3r]r�rIrL�sourcesrHr]rBrWrAr�rY�
pkg_paramsZpkg_typer�rCr^Zold_as_listZ
to_installZto_downgradeZto_reinstallZ
_availableZ
has_wildcardsZhas_comparisonr�r�Zpkg_params_itemsZcur_patches�advisory_idZ
pkg_sourceZrpm_infoZ
pkg_item_listZversion_num�pkgpathZ
candidates�targetra�namepart�archpartr7rRZcver�verrJrXr�r[r�r_r$�_r)rHrTrUr�rIrVrWrr[�sT�����
���
�����
�
��



�





�
��
�
�
�
��
��	����


�
�)

��

��


��
��������r[c
Ks�t�dvr |s dd�tjj�|�dg��D�}	|	�d�|	|d<tdddi|��}
tjj�	|�r7t
di|��t|d�}g}|sB|rlztd	d||d
|d�|��d}
Wnt
yd}zt|��d
}~ww|
rl|�|
�d
dg}|�|
�|r||�d�|r�|�|s�dnd�nt�dvr�|�|s�dnd�n	|�|s�dnd�|�|�t|�}t�dd
�t|d�}tjj�||�}|ddkr�td||d�d��|S)a|
    Run a full system upgrade (a ``yum upgrade`` or ``dnf upgrade``), or
    upgrade specified packages. If the packages aren't installed, they will
    not be installed.

    .. versionchanged:: 2014.7.0
    .. versionchanged:: 2015.8.12,2016.3.3,2016.11.0
        On minions running systemd>=205, `systemd-run(1)`_ is now used to
        isolate commands which modify installed packages from the
        ``salt-minion`` daemon's control group. This is done to keep systemd
        from killing any yum/dnf commands spawned by Salt when the
        ``salt-minion`` service is restarted. (see ``KillMode`` in the
        `systemd.kill(5)`_ manpage for more information). If desired, usage of
        `systemd-run(1)`_ can be suppressed by setting a :mod:`config option
        <salt.modules.config.get>` called ``systemd.scope``, with a value of
        ``False`` (no quotes).

    .. _`systemd-run(1)`: https://www.freedesktop.org/software/systemd/man/systemd-run.html
    .. _`systemd.kill(5)`: https://www.freedesktop.org/software/systemd/man/systemd.kill.html

    .. versionchanged:: 2019.2.0
        Added ``obsoletes`` and ``minimal`` arguments

    Returns a dictionary containing the changes:

    .. code-block:: python

        {'<package>':  {'old': '<old-version>',
                        'new': '<new-version>'}}

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.upgrade
        salt '*' pkg.upgrade name=openssl

    Repository Options:

    fromrepo
        Specify a package repository (or repositories) from which to install.
        (e.g., ``yum --disablerepo='*' --enablerepo='somerepo'``)

    enablerepo (ignored if ``fromrepo`` is specified)
        Specify a disabled package repository (or repositories) to enable.
        (e.g., ``yum --enablerepo='somerepo'``)

    disablerepo (ignored if ``fromrepo`` is specified)
        Specify an enabled package repository (or repositories) to disable.
        (e.g., ``yum --disablerepo='somerepo'``)

    disableexcludes
        Disable exclude from main, for a repo or for everything.
        (e.g., ``yum --disableexcludes='main'``)

        .. versionadded:: 2014.7.0

    name
        The name of the package to be upgraded. Note that this parameter is
        ignored if "pkgs" is passed.

        32-bit packages can be upgraded on 64-bit systems by appending the
        architecture designation (``.i686``, ``.i586``, etc.) to the end of the
        package name.

        Warning: if you forget 'name=' and run pkg.upgrade openssl, ALL packages
        are upgraded. This will be addressed in next releases.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.upgrade name=openssl

        .. versionadded:: 2016.3.0

    pkgs
        A list of packages to upgrade from a software repository. Must be
        passed as a python list. A specific version number can be specified
        by using a single-element dict representing the package and its
        version. If the package was not already installed on the system,
        it will not be installed.

        CLI Examples:

        .. code-block:: bash

            salt '*' pkg.upgrade pkgs='["foo", "bar"]'
            salt '*' pkg.upgrade pkgs='["foo", {"bar": "1.2.3-4.el5"}]'

        .. versionadded:: 2016.3.0

    normalize : True
        Normalize the package name by removing the architecture. This is useful
        for poorly created packages which might include the architecture as an
        actual part of the name such as kernel modules which match a specific
        kernel version.

        .. code-block:: bash

            salt -G role:nsd pkg.upgrade gpfs.gplbin-2.6.32-279.31.1.el6.x86_64 normalize=False

        .. versionadded:: 2016.3.0

    minimal : False
        Use upgrade-minimal instead of upgrade (e.g., ``yum upgrade-minimal``)
        Goes to the 'newest' package match which fixes a problem that affects your system.

        .. code-block:: bash

            salt '*' pkg.upgrade minimal=True

        .. versionadded:: 2019.2.0

    obsoletes : True
        Controls whether yum/dnf should take obsoletes into account and remove them.
        If set to ``False`` yum will use ``update`` instead of ``upgrade``
        and dnf will be run with ``--obsoletes=False``

        .. code-block:: bash

            salt '*' pkg.upgrade obsoletes=False

        .. versionadded:: 2019.2.0

    setopt
        A comma-separated or Python list of key=value options. This list will
        be expanded and ``--setopt`` prepended to each in the yum/dnf command
        that is run.

        .. versionadded:: 2019.2.0

    diff_attr:
        If a list of package attributes is specified, returned value will
        contain them, eg.::

            {'<package>': {
                'old': {
                    'version': '<old-version>',
                    'arch': '<old-arch>'},

                'new': {
                    'version': '<new-version>',
                    'arch': '<new-arch>'}}}

        Valid attributes are: ``epoch``, ``version``, ``release``, ``arch``,
        ``install_date``, ``install_date_time_t``.

        If ``all`` is specified, all valid attributes will be returned.

        .. versionadded:: 3006.0

    .. note::
        To add extra arguments to the ``yum upgrade`` command, pass them as key
        word arguments. For arguments without assignments, pass ``True``

    .. code-block:: bash

        salt '*' pkg.upgrade security=True exclude='kernel*'
    r,cSsg|]	}|�d�s|�qS)z
obsoletes=�r�)rr�rrrr�s��zupgrade.<locals>.<listcomp>r~zobsoletes=FalserT)r�r?N)r]rLrirBrr�rZrG�upgradezupgrade-minimalrTzupdate-minimalr�r�z&Problem encountered upgrading packages)rarMrbr)rrrr#r�r�rXr�r�r�r�rvrVrrrWr\rFrh)r]rLr�rIrB�minimal�	obsoletesrCrYZ_setoptr�r^r�rjr�r[rMr_r$rrrrss^,�

�����





�rscKst|||||||fi|��S)aS
    .. versionadded:: 2019.2.0

    Calls :py:func:`pkg.upgrade <salt.modules.yumpkg.upgrade>` with
    ``obsoletes=False``. Mirrors the CLI behavior of ``yum update``.
    See :py:func:`pkg.upgrade <salt.modules.yumpkg.upgrade>` for
    further documentation.

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.update
    )rs)r]rLr�rIrBrtrurYrrrrTs
��rTc
s�ztd||�d�Wnty}zt|��d}~wwt�}g}i}t��D]�d�vr<��fdd�|D�}����q'��|��D]f}||vrKqD�|}||vr[|s[|�|�qD||vr�|||�d�vr�d}	|}
z
|
�	d	d
�\}}Wn	t
yYnw|tjj
jjvr�|tdks�|�dd
�r�d	|}	|}
|�d�|
|�dd
�d|	��qD|s�iStddg|�}
|
ddkr�|
dr�|
dg}ng}t�dd�t�}tjj�||�}|r�td||d�d��|S)a
    .. versionchanged:: 2015.8.12,2016.3.3,2016.11.0
        On minions running systemd>=205, `systemd-run(1)`_ is now used to
        isolate commands which modify installed packages from the
        ``salt-minion`` daemon's control group. This is done to keep systemd
        from killing any yum/dnf[5] commands spawned by Salt when the
        ``salt-minion`` service is restarted. (see ``KillMode`` in the
        `systemd.kill(5)`_ manpage for more information). If desired, usage of
        `systemd-run(1)`_ can be suppressed by setting a :mod:`config option
        <salt.modules.config.get>` called ``systemd.scope``, with a value of
        ``False`` (no quotes).

    .. _`systemd-run(1)`: https://www.freedesktop.org/software/systemd/man/systemd-run.html
    .. _`systemd.kill(5)`: https://www.freedesktop.org/software/systemd/man/systemd.kill.html

    Remove packages

    name
        The name of the package to be removed


    Multiple Package Options:

    pkgs
        A list of packages to delete. Must be passed as a python list. The
        ``name`` parameter will be ignored if this option is passed.

    .. versionadded:: 0.16.0

    split_arch : True
        If set to False it prevents package name normalization by removing arch.

        .. versionadded:: 3006.0


    Returns a dict containing the changes.

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.remove <package name>
        salt '*' pkg.remove <package1>,<package2>,<package3>
        salt '*' pkg.remove pkgs='["foo", "bar"]'
    r?rNr�cs"i|]
}t�|��r|���qSrr�r�Z	pkg_paramrjrrrZs
��zremove.<locals>.<dictcomp>r�rrr(r`r@TrFr'r�rZ�remover�r�r�z"Error occurred removing package(s)r`rb)rVrrrvr�r�rTrXr!r4rerrrrfr�r
rrPr\rFr�rh)r]rLrYr�r^r�Zpkg_matchesrmZversion_to_removerar�rnror�rTr_r$rrvrrwsl.���
�
����rwcKst||d�S)a�
    .. versionchanged:: 2015.8.12,2016.3.3,2016.11.0
        On minions running systemd>=205, `systemd-run(1)`_ is now used to
        isolate commands which modify installed packages from the
        ``salt-minion`` daemon's control group. This is done to keep systemd
        from killing any yum/dnf[5] commands spawned by Salt when the
        ``salt-minion`` service is restarted. (see ``KillMode`` in the
        `systemd.kill(5)`_ manpage for more information). If desired, usage of
        `systemd-run(1)`_ can be suppressed by setting a :mod:`config option
        <salt.modules.config.get>` called ``systemd.scope``, with a value of
        ``False`` (no quotes).

    .. _`systemd-run(1)`: https://www.freedesktop.org/software/systemd/man/systemd-run.html
    .. _`systemd.kill(5)`: https://www.freedesktop.org/software/systemd/man/systemd.kill.html

    Package purges are not supported by yum, this function is identical to
    :mod:`pkg.remove <salt.modules.yumpkg.remove>`.

    name
        The name of the package to be purged


    Multiple Package Options:

    pkgs
        A list of packages to delete. Must be passed as a python list. The
        ``name`` parameter will be ignored if this option is passed.

    .. versionadded:: 0.16.0


    Returns a dict containing the changes.

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.purge <package name>
        salt '*' pkg.purge <package1>,<package2>,<package3>
        salt '*' pkg.purge pkgs='["foo", "bar"]'
    )r]rL)rw)r]rLrYrrr�purge�s*rxcKs�t�|s
|s
|s
td��|r|rtd��g}|r|�|�n|r2|D]
}|�tt|�����q#n|�|�tdd�}i}|D]�}	t|	t	�rOtt|	����}	|	iddd�||	<|	|vr�dt
vrwt
drw||	jdd	�d
|	�d�||	d<q@td
|	g�}
|
ddkr�||	jdd	�d�
|	�||	d<d||	dd<d||	dd<q@d�
|	�||	d<q@||	jdd	�d�
|	�||	d<q@|S)a�
    .. versionadded:: 2014.7.0

    Version-lock packages

    .. note::
        Requires the appropriate ``versionlock`` plugin package to be installed:

        - On RHEL 5: ``yum-versionlock``
        - On RHEL 6 & 7: ``yum-plugin-versionlock``
        - On Fedora: ``python-dnf-plugins-extras-versionlock``


    name
        The name of the package to be held.

    Multiple Package Options:

    pkgs
        A list of packages to hold. Must be passed as a python list. The
        ``name`` parameter will be ignored if this option is passed.

    Returns a dict containing the changes.

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.hold <package name>
        salt '*' pkg.hold pkgs='["foo", "bar"]'
    �0One of name, pkgs, or sources must be specified.�-Only one of pkgs or sources can be specified.FrKr�r]rarM�comment�testN�rM�Package z is set to be held.r|�versionlockr�rTzPackage {} is now being held.rQrar_r^z!Package {} was unable to be held.z%Package {} is already set to be held.)rwrrWrX�next�iterrkrer�r'rrTr\rP)r]rLrirBrYr�r&�
current_locksr$rmr�rrrrQ�sN"�


���rQc
s�t�|s
|s
|s
td��|r|rtd��g}|r|�|�n|r0|D]}|�tt|���q#n|�|�tt�dkd�}i}|D]��t�t	�rPtt��
�����iddd�|�<t�dvrh�fd	d
�|D�}n	�fdd
�|D�}|r�tdr�|�jd
d�d�
��|�d<qAtddg|�}	|	ddkr�|�jdd�d�
��|�d<d|�dd<d|�dd<qAd��d�|�d<qA|�jdd�d��d�|�d<qA|S)a�
    .. versionadded:: 2014.7.0

    Remove version locks

    .. note::
        Requires the appropriate ``versionlock`` plugin package to be installed:

        - On RHEL 5: ``yum-versionlock``
        - On RHEL 6 & 7: ``yum-plugin-versionlock``
        - On Fedora: ``python-dnf-plugins-extras-versionlock``


    name
        The name of the package to be unheld

    Multiple Package Options:

    pkgs
        A list of packages to unhold. Must be passed as a python list. The
        ``name`` parameter will be ignored if this option is passed.

    Returns a dict containing the changes.

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.unhold <package name>
        salt '*' pkg.unhold pkgs='["foo", "bar"]'
    ryrzrErKFrr{r,csg|]}|�kr|�qSrrr�rmrrrQ	�zunhold.<locals>.<listcomp>cs4g|]}t�|d��d��r�t|dd�kr|�qS)r�FrK)r�r8rr�rrrX	s��r}Nr~zPackage {} is set to be unheld.r|r��deleter�rTzPackage {} is no longer held.rar_rQr^rz was unable to be unheld.z is not being held.)rwrrWrXr�r�rerr�r'rkrrTrPr\)
r]rLrirYr�r&r�r$Zsearch_locksr�rr�rrO	sZ �



���
��rOcCs\t�tdt�ddgdd�}g}tjj�|d�D]}t|||d�}|dur+|�|�q|S)	a"
    .. versionchanged:: 2015.5.10,2015.8.4,2016.3.0
        Function renamed from ``pkg.get_locked_pkgs`` to ``pkg.list_holds``.

    List information on locked packages

    .. note::
        Requires the appropriate ``versionlock`` plugin package to be installed:

        - On RHEL 5: ``yum-versionlock``
        - On RHEL 6 & 7: ``yum-plugin-versionlock``
        - On Fedora: ``python-dnf-plugins-extras-versionlock``

    pattern : \w+(?:[.-][^-]+)*
        Regular expression used to match the package name

    full : True
        Show the full hold definition including version and epoch. Set to
        ``False`` to return just the name of the package(s) being held.

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.list_holds
        salt '*' pkg.list_holds full=False
    r�r�r�Frr)r5r6N)	rwrVrrrr r!r8rX)r5r6r�r$r%r7rrrrex	s
�re�get_locked_packagescOr�)a�
    .. versionadded:: 2014.1.0

    Runs an rpm -Va on a system, and returns the results in a dict

    Pass options to modify rpm verify behavior using the ``verify_options``
    keyword argument

    Files with an attribute of config, doc, ghost, license or readme in the
    package header can be ignored using the ``ignore_types`` keyword argument

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.verify
        salt '*' pkg.verify httpd
        salt '*' pkg.verify 'httpd postfix'
        salt '*' pkg.verify 'httpd postfix' ignore_types=['config','doc']
        salt '*' pkg.verify 'httpd postfix' verify_options=['nodeps','nosize']
    z
lowpkg.verifyr�r�rrr�verify�	sr�c
Cs�ggggid�}dddddd�}tdt�d	d
gddd
�}d}tjj�|d�D]I}|��}|dkr4|S|�|�}|durD||krD|}q'|durIq'|��}|dkrY||�	|�q't
�d|�}|rp|��\}}	||	d�|||<q'|S)z�
    .. versionadded:: 2014.1.0

    Lists all groups known by yum on this system

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.group_list
    )rr��installed environments�available environments�available languagesrr�r�r�r�)zinstalled groups:zavailable groups:zinstalled environment groups:zavailable environment groups:zavailable language groups:�cmd.run_stdoutZ	grouplistZhiddenrOF�rPrQNrZdonez
(.+) \[(.+)\])r]�language)
rVrrrr r!rrr�rXr1r7�groups)
r$Zsection_mapr�rmr%Zline_lcZsection_lookupr7r]�langrrr�
group_list�	sH
�	��
��r�c	Ks\d}i}|D]}t�||<qtd#idd�|��D���}t�dg|d|g}td|ddd	�}	i}
tjj�|	d
�D]}zdd�|�d
�D�\}}
|
|
|�	�<Wq:t
yYYq:wd|
vrcd|d<nd|
vrkd|d<|
�d�pt|
�d�|d<|
�d�p�|
�d�|d<|ds�|ds�td|�d���|
�dd�|d<|p�g}dd�
|�d}|D]s}d}tjj�|	d
�D]f}|���tj�}t�|d|�	��}|r�|r�nM|�d�|kr�d}q�|�r|�r|ddk�r|r�||vr�q�t�d||�|�|�td |d|d!�}|D]}||�t||���qq�||�|�q�q�|D]}t||�||<�q |S)$a�
    .. versionadded:: 2014.1.0
    .. versionchanged:: 2015.5.10,2015.8.4,2016.3.0,3001
        The return data has changed. A new key ``type`` has been added to
        distinguish environment groups from package groups. Also, keys for the
        group name and group ID have been added. The ``mandatory packages``,
        ``optional packages``, and ``default packages`` keys have been renamed
        to ``mandatory``, ``optional``, and ``default`` for accuracy, as
        environment groups include other groups, and not packages. Finally,
        this function now properly identifies conditional packages.
    .. versionchanged:: 3006.2
        Support for ``fromrepo``, ``enablerepo``, and ``disablerepo`` (as used
        in :py:func:`pkg.install <salt.modules.yumpkg.install>`) has been
        added.

    Lists packages belonging to a certain group

    name
        Name of the group to query

    expand : False
        If the specified group is an environment group, then the group will be
        expanded and the return data will include package names instead of
        group names.

        .. versionadded:: 2016.3.0

    ignore_groups : None
        This parameter can be used to pass a list of groups to ignore when
        expanding subgroups. It is used during recursion in order to prevent
        expanding the same group multiple times.

        .. versionadded:: 3001

    fromrepo
        Restrict ``yum groupinfo`` to the specified repo(s).
        (e.g., ``yum --disablerepo='*' --enablerepo='somerepo'``)

        .. versionadded:: 3006.2

    enablerepo (ignored if ``fromrepo`` is specified)
        Specify a disabled package repository (or repositories) to enable.
        (e.g., ``yum --enablerepo='somerepo'``)

        .. versionadded:: 3006.2

    disablerepo (ignored if ``fromrepo`` is specified)
        Specify an enabled package repository (or repositories) to disable.
        (e.g., ``yum --disablerepo='somerepo'``)

        .. versionadded:: 3006.2

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.group_info 'Perl Support'
        salt '*' pkg.group_info 'Perl Support' fromrepo=base,updates
        salt '*' pkg.group_info 'Perl Support' enablerepo=somerepo
    ��	mandatoryZoptional�defaultZconditionalcSsi|]\}}|dvr||�qS))rxr{rzr)rrm�valrrrr9
s
�zgroup_info.<locals>.<dictcomp>r�Z	groupinfor�rOFr�rcss�|]}|��VqdSr9r�rrrrr�F
rzgroup_info.<locals>.<genexpr>r'zenvironment group�typer3z
package groupzenvironment-idzgroup-id�idzGroup 'z' not found�descriptionrr/�|�)z (?:groups|packages):\s*$r(Tz'Adding group "%s" to completed list: %srb)�expand�
ignore_groupsNr)r�r�rrrVrrr r!rrerrrKr�ri�string�punctuationr1r7r3r�rOrX�
group_inforTr�r�)r]r�r�rY�pkgtypesr$�pkgtyper�r[r�Zg_infor%rmrnZcompleted_groupsZpkgtypes_capturegroupZtarget_foundr7ZexpandedZp_typerrrr��	s�=���
��

���r�cKs�d}i}|D]	}ggd�||<qt�}t|fddi|��}|D]"}|�|g�D]}||vr7||d�|�q'||d�|�q'q|S)a�
    .. versionadded:: 2014.1.0
    .. versionchanged:: 2015.5.10,2015.8.4,2016.3.0
        Environment groups are now supported. The key names have been renamed,
        similar to the changes made in :py:func:`pkg.group_info
        <salt.modules.yumpkg.group_info>`.
    .. versionchanged:: 3006.2
        Support for ``fromrepo``, ``enablerepo``, and ``disablerepo`` (as used
        in :py:func:`pkg.install <salt.modules.yumpkg.install>`) has been
        added.

    Lists which of a group's packages are installed and which are not
    installed

    name
        The name of the group to check

    fromrepo
        Restrict ``yum groupinfo`` to the specified repo(s).
        (e.g., ``yum --disablerepo='*' --enablerepo='somerepo'``)

        .. versionadded:: 3006.2

    enablerepo (ignored if ``fromrepo`` is specified)
        Specify a disabled package repository (or repositories) to enable.
        (e.g., ``yum --enablerepo='somerepo'``)

        .. versionadded:: 3006.2

    disablerepo (ignored if ``fromrepo`` is specified)
        Specify an enabled package repository (or repositories) to disable.
        (e.g., ``yum --disablerepo='somerepo'``)

        .. versionadded:: 3006.2

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.group_diff 'Perl Support'
        salt '*' pkg.group_diff 'Perl Support' fromrepo=base,updates
        salt '*' pkg.group_diff 'Perl Support' enablerepo=somerepo
    r�)r�
not installedr�Trr�)rvr�rrX)r]rYr�r$r�rLZ
group_pkgs�memberrrr�
group_diff�
s,�r�rc	st|t�r
|�d�n|}|std��t|t�std��t�t�r%��d��t�ttf�s0td��t|t�r:|�d�}t|ttf�sEtd��g}|D]}t|�}|�|�dg��|��fdd�|�d	g�D��qI|rp|�|�d
d�|D�}|s{iSt	d
dtt
|��i|��S)a|
    .. versionadded:: 2014.1.0

    Install the passed package group(s). This is basically a wrapper around
    :py:func:`pkg.install <salt.modules.yumpkg.install>`, which performs
    package group resolution for the user. This function is currently
    considered experimental, and should be expected to undergo changes.

    name
        Package group to install. To install more than one group, either use a
        comma-separated list or pass the value as a python list.

        CLI Examples:

        .. code-block:: bash

            salt '*' pkg.group_install 'Group 1'
            salt '*' pkg.group_install 'Group 1,Group 2'
            salt '*' pkg.group_install '["Group 1", "Group 2"]'

    skip
        Packages that would normally be installed by the package group
        ("default" packages), which should not be installed. Can be passed
        either as a comma-separated list or a python list.

        CLI Examples:

        .. code-block:: bash

            salt '*' pkg.group_install 'My Group' skip='foo,bar'
            salt '*' pkg.group_install 'My Group' skip='["foo", "bar"]'

    include
        Packages which are included in a group, which would not normally be
        installed by a ``yum groupinstall`` ("optional" packages). Note that
        this will not enforce group membership; if you include packages which
        are not members of the specified groups, they will still be installed.
        Can be passed either as a comma-separated list or a python list.

        CLI Examples:

        .. code-block:: bash

            salt '*' pkg.group_install 'My Group' include='foo,bar'
            salt '*' pkg.group_install 'My Group' include='["foo", "bar"]'

    .. note::
        Because this is essentially a wrapper around pkg.install, any argument
        which can be passed to pkg.install may also be included here, and it
        will be passed along wholesale.
    r�zno groups specifiedz'groups' must be a listz'skip' must be a listz'include' must be a listr�c�g|]}|�vr|�qSrr)rr��skiprrrr�z!group_install.<locals>.<listcomp>r�cSsg|]	}|t�vr|�qSr)rvrrrrrsrLNr)r�r�r!rr��tupler�rWrr[r�)	r]r�ZincluderYr�r�r3Zgroup_detailrLrr�r�
group_install�
s44




�
r��groupinstallcKs�|�dd�}t||�}i}t�d|�|D]6}tj�|�sqt�|�D]'}|�d|��}|�d�s2q#t	||�d}|D]}	||	}
||
d<|
||	<q;q#q|S)a�
    Lists all repos in <basedir> (default: all dirs in `reposdir` yum option).

    Strict parsing of configuration files is the default, this can be disabled
    using the  ``strict_config`` keyword argument set to False

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.list_repos
        salt '*' pkg.list_repos basedir=/path/to/dir
        salt '*' pkg.list_repos basedir=/path/to/dir,/path/to/another/dir strict_config=False
    r�TzSearching for repos in %sr)�.repor(r@)
rr�r�rNr	r:r;�listdir�endswith�_parse_repo_file)r�rYr��basedirsr�Zbdir�repofileZrepopath�	filereposrryrrrrs&


��	rcKsnt|fi|��}|�d�rt|�}d}|D]}||kr!||d}q|r5|�dd�}t||�d}||SiS)a?
    Display a repo from <basedir> (default basedir: all dirs in ``reposdir``
    yum option).

    CLI Examples:

    .. code-block:: bash

        salt '*' pkg.get_repo myrepo
        salt '*' pkg.get_repo myrepo basedir=/path/to/dir
        salt '*' pkg.get_repo myrepo basedir=/path/to/dir,/path/to/another/dir
    �copr:rr@r�Tr()rr�r+rr�)ryr�rYr�r�Z	list_repor�r�rrr�get_repo@s
�r�cKs�|�d�r	t|�}|�dd�}t||�}t|fi|��}||vr(d|�d|��Sd}|D]}||kr8||d}q,d}|D]}||krDq=||d|krNd}q=|r_t�|�d	|�d
|�d�St||�\}	}
|	}|
��D]Z}||krsqld}
d|
|��vr�t	j
jj�
|
|d�}
|
|d=|d
|�d�7}|
|D]#}|
||}t|t�r�d|vr�d�|�d��}|d|�d|��7}q�|d|
�d�7}qlt	j
j�|d��}|�t	j
j�|��Wd�n1s�wYd|�d|��S)ac
    Delete a repo from <basedir> (default basedir: all dirs in `reposdir` yum
    option).

    If the .repo file in which the repo exists does not contain any other repo
    configuration, the file itself will be deleted.

    Strict parsing of configuration files is the default, this can be disabled
    using the  ``strict_config`` keyword argument set to False

    CLI Examples:

    .. code-block:: bash

        salt '*' pkg.del_repo myrepo
        salt '*' pkg.del_repo myrepo basedir=/path/to/dir strict_config=False
        salt '*' pkg.del_repo myrepo basedir=/path/to/dir,/path/to/another/dir
    r�r�TzError: the z repo does not exist in rr@FzFile z containing repo z has been removed�commentsz
[�]r�
 r��wNzRepo z has been removed from )r�r+rr�rr	rwr�rkrrrrf�combine_commentsr�r�rKr!�files�fopen�write�stringutils�to_str)ryr�rYr�r�r�r�ZarepoZonlyrepo�headerr��content�stanzar�r%rn�fileoutrrr�del_repo`sX

��


�
�r�c	s��fdd��D��t�fdd�dD��rtd��d}|�d�r-|�d	d
�d
}t|�}d}g}t��D]}�|dkrG�|sG�|=|�|�q3d
�vrR|�d�n	d�vr[|�d
�d|vrctd��i}��dd�}t||�}	t	|	fi���}d}
d}i}||v�rd}
|	D]}t
j�|�r�|}
nq�|
s�td�
|	���|
�d|�d�}
|r�d}t�dvr�d}nd}td|�s�t|�d���tdd|dg�}|dr�td �
|t�|d|d!���t	|	fi���}||d"}
t|
|�\}}n1|
�d|�d�}
d�v�rtd#��d�v�rd
�v�rtd$��i||<n
||d"}
t|
|�\}}d|v�r7d
�v�r7d
||v�r7td%��d
|v�rLd�v�rLd||v�rLtd&��|D]}|||����v�r`|||=�qNd'd(�}||���|}|��D]T}tjjj�||�d)g��}|d*|�d+�7}||��D].}|||}t|t��r�d,|v�r�d-�|�d,��}|d.�
|t|t��s�|n||��7}�q�||d,7}�qstjj �!|
d/��}|�"tjj#�$|��Wd�|
|iS1�s�wY|
|iS)0a�
    Modify one or more values for a repo. If the repo does not exist, it will
    be created, so long as the following values are specified:

    repo
        name by which the yum refers to the repo
    name
        a human-readable name for the repo
    baseurl
        the URL for yum to reference
    mirrorlist
        the URL for yum to reference

    Key/Value pairs may also be removed from a repo's configuration by setting
    a key to a blank value. Bear in mind that a name cannot be deleted, and a
    baseurl can only be deleted if a mirrorlist is specified (or vice versa).

    Strict parsing of configuration files is the default, this can be disabled
    using the  ``strict_config`` keyword argument set to False

    CLI Examples:

    .. code-block:: bash

        salt '*' pkg.mod_repo reponame enabled=1 gpgcheck=1
        salt '*' pkg.mod_repo reponame basedir=/path/to/dir enabled=1 strict_config=False
        salt '*' pkg.mod_repo reponame baseurl= mirrorlist=http://host.com/
    cs(i|]}|�d�s|dvr|�|�qS)r�)rArrrr�rrr�s
�zmod_repo.<locals>.<dictcomp>c3s�|]}|�vVqdSr9rr)�	repo_optsrrr��rzmod_repo.<locals>.<genexpr>)�
mirrorlist�baseurlz7Only one of 'mirrorlist' and 'baseurl' can be specifiedFr�r'r(Trr�r�r]zThe repo name cannot be deletedr�rNzhThe repo does not exist and needs to be created, but none of the following basedir directories exist: {}r)r�r,zdnf-plugins-corezyum-plugin-coprr�z must be installed to use COPRr*�enablerZr�z<Unable to add COPR '{}'. '{}' exited with status {!s}: '{}' r�r@zIThe repo does not exist and needs to be created, but a name was not givenzgThe repo does not exist and needs to be created, but either a baseurl or a mirrorlist needs to be givenz3Cannot delete baseurl without specifying mirrorlistz3Cannot delete mirrorlist without specifying baseurlcSs|rdSdS)Nr��0r)rrrr�_bool_to_strCszmod_repo.<locals>._bool_to_strr��[z]
rr�z{}={}
r�)%r�rr�r!r+r�rXrr�rr	r:r;rPrrVr\rr��copyrkrTrrrrfr�r�r�r�rK�boolr�r�r�r�r�)ryr�rYZuse_coprZ	copr_nameZtodeletermr�r�r�r�r�r�Znewdirr�Zcopr_plugin_namer�r�r�r�r�r%rnr�r)rYr�r�mod_repo�s�
��

�


��
���
��

�
�
�
�
�
��r�c
Cs�tj|d�}i}z|�|�Wntjy.}zt�d||j�difWYd}~Sd}~ww|jD]}t|j|�}|�	dd�|||<q2d}d}t
jj�
|d��^}|D]S}	t
jj�|	�}	|	��}	|	�d�r�|durr||	d7}qUz||�d	g�}
|
�|	d
d����WqUty�t�d||	�YqUw|	�d�r�|	�d
�r�|	d
d�}qUWd�n1s�wY|t
jj�|�fS)z-
    Turn a single repo file into a dict
    r�z"Failed to parse file %s, error: %srNr:�r�#rr�r(zKFound comment in %s which does not appear to belong to any repo section: %sr�r�r�)r�r�r�ZMissingSectionHeaderErrorr�r��messageZ	_sectionsr'r�rrr�r�r�Z
to_unicoder�r�r�rXri�KeyErrorrNr�r��decode)r!r��parsedZconfig�err�sectionZsection_dict�headersr�r%r�rrrr�_sL��


�����r�cO�td|�S)ar
    .. versionadded:: 2014.1.0

    List the files that belong to a package. Not specifying any packages will
    return a list of *every* file on the system's rpm database (not generally
    recommended).

    CLI Examples:

    .. code-block:: bash

        salt '*' pkg.file_list httpd
        salt '*' pkg.file_list httpd postfix
        salt '*' pkg.file_list
    zlowpkg.file_listr���packagesrYrrr�	file_list��r�cOr�)a�
    .. versionadded:: 2014.1.0

    List the files that belong to a package, grouped by package. Not
    specifying any packages will return a list of *every* file on the system's
    rpm database (not generally recommended).

    CLI Examples:

    .. code-block:: bash

        salt '*' pkg.file_list httpd
        salt '*' pkg.file_list httpd postfix
        salt '*' pkg.file_list
    zlowpkg.file_dictr�r�rrr�	file_dict�r�r�cOsr|sdSi}gd�}|D]}td||gddd�||<d||��vr(d||<qt|�dkr7tt|����S|S)	a�
    .. versionadded:: 2014.7.0

    Return the name of the package that owns the file. Multiple file paths can
    be passed. Like :mod:`pkg.version <salt.modules.yumpkg.version>`, if a
    single path is passed, a string will be returned, and if multiple paths are
    passed, a dictionary of file/package name pairs will be returned.

    If the file is not owned by a package, or is not present on the minion,
    then an empty string will be returned for that path.

    CLI Examples:

    .. code-block:: bash

        salt '*' pkg.owner /usr/bin/apachectl
        salt '*' pkg.owner /usr/bin/apachectl /etc/httpd/conf/httpd.conf
    r)rfz-qfr�z%{name}r�rOFr�z	not ownedr()rVrr�r�r�rl)r�rYr$r
r:rrr�owner�s
��r�cOr�)a�
    List the modified files that belong to a package. Not specifying any packages
    will return a list of _all_ modified files on the system's RPM database.

    .. versionadded:: 2015.5.0

    Filtering by flags (True or False):

    size
        Include only files where size changed.

    mode
        Include only files which file's mode has been changed.

    checksum
        Include only files which MD5 checksum has been changed.

    device
        Include only files which major and minor numbers has been changed.

    symlink
        Include only files which are symbolic link contents.

    owner
        Include only files where owner has been changed.

    group
        Include only files where group has been changed.

    time
        Include only files where modification time of the file has been
        changed.

    capabilities
        Include only files where capabilities differ or not. Note: supported
        only on newer RPM versions.

    CLI Examples:

    .. code-block:: bash

        salt '*' pkg.modified
        salt '*' pkg.modified httpd
        salt '*' pkg.modified httpd postfix
        salt '*' pkg.modified httpd owner=True group=False
    zlowpkg.modifiedr�)r��flagsrrr�modified�s0r�cs�tjj�d�std��|std��tj�dt�d��tj�	��s%t�
��t���}g}|D]�|���fdd�|D��q.t
|�D](}t�d|�zt�|�WqBtyj}z
t�d	||�WYd
}~qBd
}~wwddd���g}|�|�td
|ddd�i�t���D],}|�d�s�q�d
}d
}	|D]}
|�|
�d��r�|
}|}	nq�|	d
ur�tj��|	��|<q��s�td�d�|�����fdd�|D�}|r�d�d�|���d<�S)a�
    .. versionadded:: 2015.5.0

    Download packages to the local disk. Requires ``yumdownloader`` from
    ``yum-utils`` or ``dnf-utils`` package.

    .. note::

        ``yum-utils`` or ``dnf-utils`` will already be installed on the minion
        if the package was installed from the EPEL / Fedora repositories.

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.download httpd
        salt '*' pkg.download httpd postfix
    Z
yumdownloaderz%'yumdownloader' command not availablezNo packages were specifiedrr�cs*g|]}|���d��rtj��|��qS)r0)r�r	r:rKr)rrrrr*
s*zdownload.<locals>.<listcomp>zRemoving cached package %szUnable to remove %s: %sNz-qz
--destdir=r�rOFr�z.rpmr0z4Unable to download any of the following packages: {}r�cr�rrr)r$rrrK
r�z/The following package(s) failed to download: {}�_error)rrr:�whichrrr	rKrr;�makedirsr�rWr�r�rN�unlinkr�r�rVr�r�rP)r�rYZcached_pkgsZto_purgeZpurge_targetr�r[Z
dld_resultr(Zpkg_fileZ	query_pkgZfailedr)rrr$r�download

sf

���

�����r�c
Os�i}i}|D])}td|�}|stj�|�rdpd||<q|�|�dur(g||<||�|�q|rWtd|���}|��D]\}}|D]}	td||d|	�pRd||	<qDq>|S)	a�
    Return a formatted diff between current files and original in a package.
    NOTE: this function includes all files (configuration and not), but does
    not work on binary content.

    :param path: Full path to the installed file
    :return: Difference string or raises and exception if examined file is binary.

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.diff /etc/apache2/httpd.conf /etc/sudoers
    zlowpkg.ownerzNot managedzN/ANzpkg.downloadzlowpkg.diffr:Z	Unchanged)rVr	r:r;rrXrkr)
r�rYr$Zpkg_to_pathsZpthZpth_pkgZ
local_pkgsrr�r:rrr�diffS
s$��r�c
	Cs�i}t�ddddg}td|dd�}d}tjj�|tj�D]B}zt�	d|��
�\}}}}	Wnty8d	}Yqw||vrL|d
krCd	nd|	gd�||<q||d�|	�|d
kr_d||d
<q|rkt
�dd�|��|rvdd�|��D�}|S)z*
    List all known patches in repos.
    r�Z
updateinfor�r�r�Frz%([i|\s]) ([^\s]+) +([^\s]+) +([^\s]+)T�i)r�summaryr�rzVSkipped some unexpected output while running '%s' to list patches. Please check output� cSsi|]\}}|dr||�qS)rr)r�k�vrrrr�
sz _get_patches.<locals>.<dictcomp>)rrVrrr r!r	�linesepr1r7r�rrXr�r�rKr)
�installed_onlyZpatchesr[r$Zparsing_errorsr%�instrkZsevrrrr�_get_patchesz
s>������r�cKs|rt�t�S)a:
    .. versionadded:: 2017.7.0

    List all known advisory patches from available repos.

    refresh
        force a refresh if set to True.
        If set to False (default) it depends on yum if a refresh is
        executed.

    CLI Examples:

    .. code-block:: bash

        salt '*' pkg.list_patches
    )r�r�)r�rYrrrrd�
srdcKs
tdd�S)z�
    .. versionadded:: 2017.7.0

    List installed advisory patches on the system.

    CLI Examples:

    .. code-block:: bash

        salt '*' pkg.list_installed_patches
    T)r�)r�r�rrr�list_installed_patches�
s
r�c	Ks�t�dvr	td��tjj�t�std��t�dkrgd�}ngd�}td|dd	�}|s.gSt�}|�	d
�D]}|�
d�\}}}|rRtjj�|���}|rR|�
|�q6t|�S)a

    .. versionadded:: 3003

    List services that use files which have been changed by the
    package manager. It might be needed to restart them.

    Requires systemd.

    CLI Examples:

    .. code-block:: bash

        salt '*' pkg.services_need_restart
    r,z2dnf or dnf5 is required to list outdated services.z.systemd is required to list outdated services.r.)r.r��needs-restarting)r-r�r�r�Frrr')rrrrrUZbootedrFrVr�r!�	partitionZpid_to_servicer�r�r�)	rYr[Z
dnf_outputZservicesr%�pidZ	has_delimrqZservicerrr�services_need_restart�
s*
�


�r�r9)Tr6r	)NFFNNFFTFr>F)NNTFTFTN)NNTFTFFr�)NNNT)NNN)FN)rr)c�__doc__r�rfrr�r �loggingr	r1r�Zsalt.utils.argsrZsalt.utils.dataZsalt.utils.environmentZsalt.utils.filesZsalt.utils.functoolsZsalt.utils.itertoolsZsalt.utils.lazyZsalt.utils.pathZsalt.utils.pkgZsalt.utils.pkg.rpmZsalt.utils.systemdZsalt.utils.versionsZsalt.exceptionsrrrr�	getLoggerr:r�Z__HOLD_PATTERNr�rrr&r+r8rr\rorurwr�r�r�r�r�r�r�r�	functoolsZalias_functionr�r�r^r�r�rvrrrr$r)r�r-ZlazyZLazyDictr.r[rsrTrwrxrQrOrer�r�r�r�r�r�r�rr�r�r�r�r�r�r�r�r�r�r�rdr�r�rrrr�<module>s�
(
&	
G
4

~�

	Z
!$I
�Z
�g
�

w.
�
Sd'�
9
<Z

#
 
N
20"3I
'
)