def get_releases(request): """ Return a defaultdict describing all Releases keyed by state. Args: request (pyramid.request.Request): The current web request. Unused. Returns: collections.defaultdict: A dictionary mapping release states to a list of JSON strings that describe the Releases that are in those states. """ from bodhi.server.models import Release return Release.all_releases()
def test_new_release(self): attrs = { "name": "F42", "long_name": "Fedora 42", "version": "42", "id_prefix": "FEDORA", "branch": "f42", "dist_tag": "f42", "stable_tag": "f42-updates", "testing_tag": "f42-updates-testing", "candidate_tag": "f42-updates-candidate", "pending_stable_tag": "f42-updates-pending", "pending_signing_tag": "f42-updates-testing-signing", "pending_testing_tag": "f42-updates-testing-pending", "override_tag": "f42-override", "package_manager": "dnf", "testing_repository": "updates-testing", "eol": date(2016, 6, 14), "csrf_token": self.get_csrf_token(), } self.app.post("/releases/", attrs, status=200) attrs.pop('csrf_token') attrs.pop('eol') r = self.db.query(Release).filter(Release.name == attrs["name"]).one() for k, v in attrs.items(): if k in ['state', 'package_manager']: assert getattr(r, k).value == v else: assert getattr(r, k) == v assert r.state == ReleaseState.disabled # Let's check Release cache content releases = Release.all_releases() disabled_releases = releases["disabled"] assert disabled_releases[0]["name"] == "F42" assert disabled_releases[1]["name"] == "F22" assert len(disabled_releases) == 2 current_releases = releases["current"] assert current_releases[0]["name"] == "F17" assert len(current_releases) == 1
def query_updates(request): """ Search updates by given criteria. Args: request (pyramid.request): The current request. Returns: dict: A dictionary with at least the following key mappings: updates: An iterable of the updates that match the query. page: The current page. pages: The total number of pages. rows_per_page: How many results on on the page. total: The total number of updates matching the query. package: The package corresponding to the first update found in the search. """ db = request.db data = request.validated query = db.query(Update) approved_since = data.get('approved_since') if approved_since is not None: query = query.filter(Update.date_approved >= approved_since) approved_before = data.get('approved_before') if approved_before is not None: query = query.filter(Update.date_approved < approved_before) bugs = data.get('bugs') if bugs is not None: query = query.join(Update.bugs) query = query.filter(or_(*[Bug.bug_id == bug_id for bug_id in bugs])) critpath = data.get('critpath') if critpath is not None: query = query.filter(Update.critpath == critpath) like = data.get('like') if like is not None: query = query.join(Update.builds) query = query.filter(Build.nvr.like('%%%s%%' % like)) search = data.get('search') if search is not None: query = query.join(Update.builds) query = query.filter( or_(Build.nvr.ilike('%%%s%%' % search), Update.alias.ilike('%%%s%%' % search))) locked = data.get('locked') if locked is not None: query = query.filter(Update.locked == locked) modified_since = data.get('modified_since') if modified_since is not None: query = query.filter(Update.date_modified >= modified_since) modified_before = data.get('modified_before') if modified_before is not None: query = query.filter(Update.date_modified < modified_before) packages = data.get('packages') if packages is not None: query = query.join(Update.builds).join(Build.package) query = query.filter(or_(*[Package.name == pkg for pkg in packages])) package = None if packages and len(packages): package = packages[0] builds = data.get('builds') if builds is not None: query = query.join(Update.builds) query = query.filter(or_(*[Build.nvr == build for build in builds])) pushed = data.get('pushed') if pushed is not None: query = query.filter(Update.pushed == pushed) pushed_since = data.get('pushed_since') if pushed_since is not None: query = query.filter(Update.date_pushed >= pushed_since) pushed_before = data.get('pushed_before') if pushed_before is not None: query = query.filter(Update.date_pushed < pushed_before) releases = data.get('releases') if releases is not None: query = query.filter(or_(*[Update.release == r for r in releases])) # This singular version of the plural "releases" is purely for bodhi1 # backwards compat (mostly for RSS feeds) - threebean release = data.get('release') if release is not None: query = query.filter(Update.release == release) req = data.get('request') if req is not None: query = query.filter(Update.request == req) severity = data.get('severity') if severity is not None: query = query.filter(Update.severity == severity) status = data.get('status') if status is not None: query = query.filter(or_(*[Update.status == s for s in status])) submitted_since = data.get('submitted_since') if submitted_since is not None: query = query.filter(Update.date_submitted >= submitted_since) submitted_before = data.get('submitted_before') if submitted_before is not None: query = query.filter(Update.date_submitted < submitted_before) suggest = data.get('suggest') if suggest is not None: query = query.filter(Update.suggest == suggest) type = data.get('type') if type is not None: query = query.filter(Update.type == type) content_type = data.get('content_type') if content_type is not None: query = query.join(Update.builds) query = query.filter(Build.type == content_type) gating_status = data.get('gating') if gating_status is not None: query = query.filter(Update.test_gating_status == gating_status) user = data.get('user') if user is not None: query = query.filter(or_(*[Update.user == u for u in user])) updateid = data.get('updateid') if updateid is not None: query = query.filter(or_(*[Update.alias == uid for uid in updateid])) alias = data.get('alias') if alias is not None: query = query.filter(or_(*[Update.alias == a for a in alias])) from_side_tag = data.get('from_side_tag') if from_side_tag is not None: if from_side_tag: query = query.filter(Update.from_tag.isnot(None)) else: query = query.filter(Update.from_tag.is_(None)) query = query.order_by(Update.date_submitted.desc()) # We can't use ``query.count()`` here because it is naive with respect to # all the joins that we're doing above. count_query = query.with_labels().statement\ .with_only_columns([func.count(distinct(Update.id))])\ .order_by(None) total = db.execute(count_query).scalar() page = data.get('page') rows_per_page = data.get('rows_per_page') pages = int(math.ceil(total / float(rows_per_page))) query = query.offset(rows_per_page * (page - 1)).limit(rows_per_page) return_values = dict( updates=query.all(), page=page, pages=pages, rows_per_page=rows_per_page, total=total, chrome=data.get('chrome'), display_user=data.get('display_user', False), display_request=data.get('display_request', True), package=package, ) # we need some extra information for the searching / filterings interface # when rendering the html, so we add this here. if request.accept.accept_html(): return_values.update( gating_statuses=sorted( list(bodhi.server.models.TestGatingStatus.values())), types=list(bodhi.server.models.UpdateType.values()), severities=sorted(list( bodhi.server.models.UpdateSeverity.values()), key=bodhi.server.util.sort_severity), statuses=list(bodhi.server.models.UpdateStatus.values()), releases=Release.all_releases(), ) return return_values
def query_overrides(request): """ Search for overrides by various criteria. The following optional parameters may be used when searching for overrides: builds (list): A list of NVRs to search overrides by. expired (bool): If True, limit search to expired overrides. If False, limit search to active overrides. like (str): Perform an SQL "like" query against build NVRs with the given string. packages (list): A list of package names to search overrides by. releases (list): A list of release names to limit the overrides search by. search (str): Perform an SQL "ilike" query against build NVRs with the given string. submitter (str): Search for overrides submitted by the given username. Returns: dict: A dictionary with the following keys: overrides: An iterable containing the matched overrides. page: The current page number in the results. pages: The number of pages of results that match the query. rows_per_page: The number of rows on the page. total: The total number of overrides that match the criteria. chrome: The caller supplied chrome. display_user: The current username. """ db = request.db data = request.validated query = db.query(BuildrootOverride) expired = data.get('expired') if expired is not None: if expired: query = query.filter(BuildrootOverride.expired_date.isnot(None)) else: query = query.filter(BuildrootOverride.expired_date.is_(None)) builds = data.get('builds') if builds is not None: query = query.join(BuildrootOverride.build) query = query.filter(or_(*[Build.nvr == bld for bld in builds])) packages = data.get('packages') if packages is not None: query = query.join(BuildrootOverride.build).join(Build.package) query = query.filter( or_(*[Package.name == pkg.name for pkg in packages])) releases = data.get('releases') if releases is not None: query = query.join(BuildrootOverride.build).join(Build.release) query = query.filter(or_(*[Release.name == r.name for r in releases])) like = data.get('like') if like is not None: query = query.join(BuildrootOverride.build) query = query.filter(or_(*[Build.nvr.like('%%%s%%' % like)])) search = data.get('search') if search is not None: query = query.join(BuildrootOverride.build) query = query.filter(Build.nvr.ilike('%%%s%%' % search)) submitter = data.get('user') if submitter is not None: query = query.filter( or_(*[BuildrootOverride.submitter == s for s in submitter])) query = query.order_by(BuildrootOverride.submission_date.desc()) # We can't use ``query.count()`` here because it is naive with respect to # all the joins that we're doing above. count_query = query.with_labels().statement\ .with_only_columns([func.count(distinct(BuildrootOverride.id))])\ .order_by(None) total = db.execute(count_query).scalar() page = data.get('page') rows_per_page = data.get('rows_per_page') pages = int(math.ceil(total / float(rows_per_page))) query = query.offset(rows_per_page * (page - 1)).limit(rows_per_page) return_values = dict( overrides=query.all(), page=page, pages=pages, rows_per_page=rows_per_page, total=total, chrome=data.get('chrome'), display_user=data.get('display_user'), ) # we need some extra information for the searching / filterings interface # when rendering the html, so we add this here. if request.accept.accept_html(): return_values.update(releases=Release.all_releases(), ) return return_values
def query_releases_html(request): """ Return all releases, collated by state, rendered as HTML. Args: request (pyramid.request): The current request. Returns: dict: A dictionary with a single key, releases, mapping another dictionary that maps release states to a list of Release objects that are in that state. """ def _get_status_counts(basequery, status): """ Return a dictionary with the counts of objects found in the basequery. The return data is specified by total count, newpackage count, bugfix count, enhancement count and security count. The dictionary keys will be named with the template {status}_{type}_total. For example, if status is models.UpdateStatus.stable, a dictionary with the following keys would be returned: stable_updates_total Args: basequery (sqlalchemy.orm.query.Query): The basequery of updates we want to count and further filter on. status (bodhi.server.models.UpdateStatus): The update status we want to filter by in basequery Return: dict: A dictionary describing the counts of the updates, as described above. """ basequery = basequery.filter(Update.status == status) return { '{}_updates_total'.format(status.description): basequery.count(), } def get_update_counts(releaseid): """ Return counts for the various states and types of updates in the given release. This function returns a dictionary that tabulates the counts of the various types of Bodhi updates at the various states they can appear in. The dictionary has the following keys, with pretty self-explanatory names: pending_updates_total testing_updates_total stable_updates_total Args: releaseid (str): The id of the Release object you would like the counts performed on Returns: dict: A dictionary expressing the counts, as described above. """ release = Release.get(releaseid) basequery = Update.query.filter(Update.release == release) counts = {} counts.update(_get_status_counts(basequery, UpdateStatus.pending)) counts.update(_get_status_counts(basequery, UpdateStatus.testing)) counts.update(_get_status_counts(basequery, UpdateStatus.stable)) return counts release_updates_counts = {} releases = Release.all_releases() for release in releases['current'] + releases['pending'] + releases[ 'archived']: release_updates_counts[release["name"]] = get_update_counts( release["name"]) return {"release_updates_counts": release_updates_counts}