diff --git a/bodhi/model.py b/bodhi/model.py index f03aa4a..dd8e13f 100644 --- a/bodhi/model.py +++ b/bodhi/model.py @@ -40,7 +40,7 @@ except ImportError: from bodhi import buildsys, mail from bodhi.util import get_nvr, rpm_fileheader, header, get_age, get_age_in_days from bodhi.util import Singleton, authorized_user, flash_log, build_evr, url -from bodhi.util import link, isint +from bodhi.util import link, isint, get_critpath_pkgs from bodhi.exceptions import RPMNotFound, InvalidRequest from bodhi.identity.tables import * @@ -1076,12 +1076,11 @@ class PackageUpdate(SQLObject): @property def critpath(self): """ Return whether or not this update is in the critical path """ - # HACK: Avoid the current critpath policy for EPEL - if self.release.name.startswith('EL'): - return False - critical = False - critpath_pkgs = config.get('critpath').split() + critpath_pkgs = get_critpath_pkgs(self.release.name) + if not critpath_pkgs: + # Optimize case where there's no critpath packages + return False for build in self.builds: if build.package.name in critpath_pkgs: critical = True diff --git a/bodhi/util.py b/bodhi/util.py index e4d0858..8f524b0 100644 --- a/bodhi/util.py +++ b/bodhi/util.py @@ -31,7 +31,7 @@ from kid import Element from yum import repoMDObject from yum.misc import checksum from os.path import isdir, join, dirname, basename, isfile -from datetime import datetime +from datetime import datetime, timedelta from decorator import decorator from turbogears import config, flash, redirect from fedora.client import PackageDB @@ -52,6 +52,9 @@ header = lambda x: "%s\n %s\n%s\n" % ('=' * 80, x, '=' * 80) pluralize = lambda val, name: val == 1 and name or "%ss" % name +# Setup one pkgdb client instance to use with any function here +pkgdb = PackageDB(config.get('pkgdb_url')) + def rpm_fileheader(pkgpath): log.debug("Grabbing the rpm header of %s" % pkgpath) is_oldrpm = hasattr(rpm, 'opendb') @@ -261,7 +264,6 @@ def get_pkg_pushers(pkgName, collectionName='Fedora', collectionVersion='devel') if config.get('acl_system') == 'dummy': return (['guest'], ['guest']), (['guest'], ['guest']) - pkgdb = PackageDB(config.get('pkgdb_url')) # Note if AppError is raised (for no pkgNamme or other server errors) we # do not catch the exception here. pkg = pkgdb.get_owners(pkgName, collectionName, collectionVersion) @@ -294,6 +296,49 @@ def get_pkg_pushers(pkgName, collectionName='Fedora', collectionVersion='devel') return ((pAllowed, pNotify), (gAllowed, gNotify)) +def cache_with_expire(expire=600): + # expire is the number of seconds to cache for. + # Default is 600s == 10 minutes + _cache = {} + def cached(func, *args, **kwargs): + # Setup the args + if kwargs: + key = args, frozenset(kwargs.iteritems()) + else: + key = args + + # Retrieve from cache + entry = None + if key in _cache: + entry = _cache[key] + if (datetime.utcnow() - entry[0]) < timedelta(0, expire, 0): + # Unexpired cache + result = entry[1] + else: + # Expired cache + del _cache[key] + entry = None + + # Retrieve fresh entry + if entry is None: + result = func(*args, **kwargs) + _cache[key] = (datetime.utcnow(), result) + return result + return decorator(cached) + +@cache_with_expire +def get_critpath_pkgs(collection): + critpath_type = config.get('critpath.type', None) + if critpath_type == 'pkgdb': + critpath_pkgs = pkgdb.get_critpath_pkgs([collection]) + else: + critpath_pkgs = [] + # HACK: Avoid the current critpath policy for EPEL + if not collection.startswith('EL'): + # Note: ''.split() == [] + critpath_pkgs = config.get('critpath', '').split() + return critpath_pkgs + def build_evr(build): if not build['epoch']: build['epoch'] = 0