Updates the APT database to latest packages based upon repositories

    Returns a dict, with the keys being package databases and the values being
    the result of the update attempt. Values can be one of the following:

    - ``True``: Database updated successfully
    - ``False``: Problem updating database
    - ``None``: Database already up-to-date

    cache_valid_time

        .. versionadded:: 2016.11.0

        Skip refreshing the package database if refresh has already occurred within
        <value> seconds

    failhard

        If False, return results of Err lines as ``False`` for the package database that
        encountered the error.
        If True, raise an error with a list of the package databases that encountered
        errors.

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.refresh_db

def refresh_db(cache_valid_time=0, failhard=False, **kwargs):
    '''
    Updates the APT database to latest packages based upon repositories

    Returns a dict, with the keys being package databases and the values being
    the result of the update attempt. Values can be one of the following:

    - ``True``: Database updated successfully
    - ``False``: Problem updating database
    - ``None``: Database already up-to-date

    cache_valid_time

        .. versionadded:: 2016.11.0

        Skip refreshing the package database if refresh has already occurred within
        <value> seconds

    failhard

        If False, return results of Err lines as ``False`` for the package database that
        encountered the error.
        If True, raise an error with a list of the package databases that encountered
        errors.

    CLI Example:

    .. code-block:: bash

        salt '*' pkg.refresh_db
    '''
    # Remove rtag file to keep multiple refreshes from happening in pkg states
    salt.utils.pkg.clear_rtag(__opts__)
    failhard = salt.utils.data.is_true(failhard)
    ret = {}
    error_repos = list()

    if cache_valid_time:
        try:
            latest_update = os.stat(APT_LISTS_PATH).st_mtime
            now = time.time()
            log.debug("now: %s, last update time: %s, expire after: %s seconds", now, latest_update, cache_valid_time)
            if latest_update + cache_valid_time > now:
                return ret
        except TypeError as exp:
            log.warning("expected integer for cache_valid_time parameter, failed with: %s", exp)
        except IOError as exp:
            log.warning("could not stat cache directory due to: %s", exp)

    call = _call_apt(['apt-get', '-q', 'update'], scope=False)
    if call['retcode'] != 0:
        comment = ''
        if 'stderr' in call:
            comment += call['stderr']

        raise CommandExecutionError(comment)
    else:
        out = call['stdout']

    for line in out.splitlines():
        cols = line.split()
        if not cols:
            continue
        ident = ' '.join(cols[1:])
        if 'Get' in cols[0]:
            # Strip filesize from end of line
            ident = re.sub(r' \[.+B\]$', '', ident)
            ret[ident] = True
        elif 'Ign' in cols[0]:
            ret[ident] = False
        elif 'Hit' in cols[0]:
            ret[ident] = None
        elif 'Err' in cols[0]:
            ret[ident] = False
            error_repos.append(ident)

    if failhard and error_repos:
        raise CommandExecutionError('Error getting repos: {0}'.format(', '.join(error_repos)))

    return ret