Add a package lock. Specify packages to lock by exact name.

    root
        operate on a different root directory.

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.add_lock <package name>
        salt '*' pkg.add_lock <package1>,<package2>,<package3>
        salt '*' pkg.add_lock pkgs='["foo", "bar"]'

    :param name:
    :param pkgs:
    :param kwargs:
    :return:

def hold(name=None, pkgs=None, **kwargs):
    '''
    Add a package lock. Specify packages to lock by exact name.

    root
        operate on a different root directory.

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.add_lock <package name>
        salt '*' pkg.add_lock <package1>,<package2>,<package3>
        salt '*' pkg.add_lock pkgs='["foo", "bar"]'

    :param name:
    :param pkgs:
    :param kwargs:
    :return:
    '''
    ret = {}
    root = kwargs.get('root')
    if (not name and not pkgs) or (name and pkgs):
        raise CommandExecutionError('Name or packages must be specified.')
    elif name:
        pkgs = [name]

    locks = list_locks(root=root)
    added = []
    try:
        pkgs = list(__salt__['pkg_resource.parse_targets'](pkgs)[0].keys())
    except MinionError as exc:
        raise CommandExecutionError(exc)

    for pkg in pkgs:
        ret[pkg] = {'name': pkg, 'changes': {}, 'result': False, 'comment': ''}
        if not locks.get(pkg):
            added.append(pkg)
            ret[pkg]['comment'] = 'Package {0} is now being held.'.format(pkg)
        else:
            ret[pkg]['comment'] = 'Package {0} is already set to be held.'.format(pkg)

    if added:
        __zypper__(root=root).call('al', *added)

    return ret