Install package(s) from a repository

    name
        The name of the package to install

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name>

    jail
        Install the package into the specified jail

    chroot
        Install the package into the specified chroot (ignored if ``jail`` is
        specified)

    root
        Install the package into the specified root (ignored if ``jail`` is
        specified)

    orphan
        Mark the installed package as orphan. Will be automatically removed
        if no other packages depend on them. For more information please
        refer to ``pkg-autoremove(8)``.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name> orphan=True

    force
        Force the reinstallation of the package if already installed.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name> force=True

    glob
        Treat the package names as shell glob patterns.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name> glob=True

    local
        Do not update the repository catalogs with ``pkg-update(8)``.  A
        value of ``True`` here is equivalent to using the ``-U`` flag with
        ``pkg install``.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name> local=True

    dryrun
        Dru-run mode. The list of changes to packages is always printed,
        but no changes are actually made.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name> dryrun=True

    quiet
        Force quiet output, except when dryrun is used, where pkg install
        will always show packages to be installed, upgraded or deleted.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name> quiet=True

    reinstall_requires
        When used with force, reinstalls any packages that require the
        given package.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name> reinstall_requires=True force=True

        .. versionchanged:: 2014.7.0
            ``require`` kwarg renamed to ``reinstall_requires``

    fromrepo
        In multi-repo mode, override the pkg.conf ordering and only attempt
        to download packages from the named repository.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name> fromrepo=repo

    regex
        Treat the package names as a regular expression

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <regular expression> regex=True

    pcre
        Treat the package names as extended regular expressions.

        CLI Example:

        .. code-block:: bash


    batch
        Use BATCH=true for pkg install, skipping all questions.
        Be careful when using in production.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name> batch=True

def install(name=None,
            fromrepo=None,
            pkgs=None,
            sources=None,
            jail=None,
            chroot=None,
            root=None,
            orphan=False,
            force=False,
            glob=False,
            local=False,
            dryrun=False,
            quiet=False,
            reinstall_requires=False,
            regex=False,
            pcre=False,
            batch=False,
            **kwargs):
    '''
    Install package(s) from a repository

    name
        The name of the package to install

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name>

    jail
        Install the package into the specified jail

    chroot
        Install the package into the specified chroot (ignored if ``jail`` is
        specified)

    root
        Install the package into the specified root (ignored if ``jail`` is
        specified)

    orphan
        Mark the installed package as orphan. Will be automatically removed
        if no other packages depend on them. For more information please
        refer to ``pkg-autoremove(8)``.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name> orphan=True

    force
        Force the reinstallation of the package if already installed.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name> force=True

    glob
        Treat the package names as shell glob patterns.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name> glob=True

    local
        Do not update the repository catalogs with ``pkg-update(8)``.  A
        value of ``True`` here is equivalent to using the ``-U`` flag with
        ``pkg install``.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name> local=True

    dryrun
        Dru-run mode. The list of changes to packages is always printed,
        but no changes are actually made.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name> dryrun=True

    quiet
        Force quiet output, except when dryrun is used, where pkg install
        will always show packages to be installed, upgraded or deleted.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name> quiet=True

    reinstall_requires
        When used with force, reinstalls any packages that require the
        given package.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name> reinstall_requires=True force=True

        .. versionchanged:: 2014.7.0
            ``require`` kwarg renamed to ``reinstall_requires``

    fromrepo
        In multi-repo mode, override the pkg.conf ordering and only attempt
        to download packages from the named repository.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name> fromrepo=repo

    regex
        Treat the package names as a regular expression

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <regular expression> regex=True

    pcre
        Treat the package names as extended regular expressions.

        CLI Example:

        .. code-block:: bash


    batch
        Use BATCH=true for pkg install, skipping all questions.
        Be careful when using in production.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.install <package name> batch=True
    '''
    try:
        pkg_params, pkg_type = __salt__['pkg_resource.parse_targets'](
            name, pkgs, sources, **kwargs
        )
    except MinionError as exc:
        raise CommandExecutionError(exc)

    if not pkg_params:
        return {}

    env = {}
    opts = 'y'
    if salt.utils.data.is_true(orphan):
        opts += 'A'
    if salt.utils.data.is_true(force):
        opts += 'f'
    if salt.utils.data.is_true(glob):
        opts += 'g'
    if salt.utils.data.is_true(local):
        opts += 'U'
    if salt.utils.data.is_true(dryrun):
        opts += 'n'
    if salt.utils.data.is_true(quiet):
        opts += 'q'
    if salt.utils.data.is_true(reinstall_requires):
        opts += 'R'
    if salt.utils.data.is_true(regex):
        opts += 'x'
    if salt.utils.data.is_true(pcre):
        opts += 'X'
    if salt.utils.data.is_true(batch):
        env = {
                "BATCH": "true",
                "ASSUME_ALWAYS_YES": "YES"
              }

    old = list_pkgs(jail=jail, chroot=chroot, root=root)

    if pkg_type == 'file':
        pkg_cmd = 'add'
        # pkg add has smaller set of options (i.e. no -y or -n), filter below
        opts = ''.join([opt for opt in opts if opt in 'AfIMq'])
        targets = pkg_params
    elif pkg_type == 'repository':
        pkg_cmd = 'install'
        if pkgs is None and kwargs.get('version') and len(pkg_params) == 1:
            # Only use the 'version' param if 'name' was not specified as a
            # comma-separated list
            pkg_params = {name: kwargs.get('version')}
        targets = []
        for param, version_num in six.iteritems(pkg_params):
            if version_num is None:
                targets.append(param)
            else:
                targets.append('{0}-{1}'.format(param, version_num))
    else:
        raise CommandExecutionError('Problem encountered installing package(s)')

    cmd = _pkg(jail, chroot, root)
    cmd.append(pkg_cmd)
    if fromrepo:
        cmd.extend(['-r', fromrepo])
    if opts:
        cmd.append('-' + opts)
    cmd.extend(targets)

    if pkg_cmd == 'add' and salt.utils.data.is_true(dryrun):
        # pkg add doesn't have a dry-run mode, so echo out what will be run
        return ' '.join(cmd)

    out = __salt__['cmd.run_all'](
        cmd,
        output_loglevel='trace',
        python_shell=False,
        env=env
    )

    if out['retcode'] != 0 and out['stderr']:
        errors = [out['stderr']]
    else:
        errors = []

    __context__.pop(_contextkey(jail, chroot, root), None)
    __context__.pop(_contextkey(jail, chroot, root, prefix='pkg.origin'), None)
    new = list_pkgs(jail=jail, chroot=chroot, root=root)
    ret = salt.utils.data.compare_dicts(old, new)

    if errors:
        raise CommandExecutionError(
            'Problem encountered installing package(s)',
            info={'errors': errors, 'changes': ret}
        )

    return ret