Ejemplo n.º 1
0
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()
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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}