def upgrade(*names, **kwargs):
    '''
    Upgrade named or all packages (run a ``pkg upgrade``). If <package name> is
    omitted, the operation is executed on all packages.

    Returns a dictionary containing the changes:

    .. code-block:: python

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


    CLI Example:

    .. code-block:: bash

        salt '*' pkg.upgrade <package name>

    jail
        Audit packages within the specified jail

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.upgrade <package name> jail=<jail name or id>

    chroot
        Audit packages within the specified chroot (ignored if ``jail`` is
        specified)

    root
        Audit packages within the specified root (ignored if ``jail`` is
        specified)

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.upgrade <package name> chroot=/path/to/chroot


    Any of the below options can also be used with ``jail`` or ``chroot``.

    force
        Force reinstalling/upgrading the whole set of packages.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.upgrade <package name> force=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
        upgrade``.

        CLI Example:

        .. code-block:: bash

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

    dryrun
        Dry-run mode: show what packages have updates available, but do not
        perform any upgrades. Repository catalogs will be updated as usual
        unless the local option is also given.

        CLI Example:

        .. code-block:: bash

            salt '*' pkg.upgrade <package name> dryrun=True
    '''
    jail = kwargs.pop('jail', None)
    chroot = kwargs.pop('chroot', None)
    root = kwargs.pop('root', None)
    force = kwargs.pop('force', False)
    local = kwargs.pop('local', False)
    dryrun = kwargs.pop('dryrun', False)
    pkgs = kwargs.pop('pkgs', [])
    opts = ''
    if force:
        opts += 'f'
    if local:
        opts += 'L'
    if dryrun:
        opts += 'n'
    if not dryrun:
        opts += 'y'

    cmd = _pkg(jail, chroot, root)
    cmd.append('upgrade')
    if opts:
        cmd.append('-' + opts)
    if names:
        cmd.extend(names)
    if pkgs:
        cmd.extend(pkgs)

    old = list_pkgs()
    result = __salt__['cmd.run_all'](cmd,
                                     output_loglevel='trace',
                                     python_shell=False)
    __context__.pop(_contextkey(jail, chroot, root), None)
    __context__.pop(_contextkey(jail, chroot, root, prefix='pkg.origin'), None)
    new = list_pkgs()
    ret = salt.utils.data.compare_dicts(old, new)

    if result['retcode'] != 0:
        raise CommandExecutionError(
            'Problem encountered upgrading packages',
            info={'changes': ret, 'result': result}
        )

    return ret