[Git][security-tracker-team/security-tracker][master] Revert "bin/tracker_service.py: open the database connection for each request"

Emilio Pozuelo Monfort (@pochu) pochu at debian.org
Wed Aug 26 15:25:48 BST 2026



Emilio Pozuelo Monfort pushed to branch master at Debian Security Tracker / security-tracker


Commits:
2dc305a8 by Emilio Pozuelo Monfort at 2026-08-26T16:25:26+02:00
Revert "bin/tracker_service.py: open the database connection for each request"

This reverts commit 4a4f1de03f75d4298de8fc4aac257954248f6bfd.

- - - - -


2 changed files:

- bin/tracker_service.py
- lib/python/security_db.py


Changes:

=====================================
bin/tracker_service.py
=====================================
@@ -110,7 +110,7 @@ class TrackerService(WebServiceBase):
 
     def __init__(self, db_name):
         WebServiceBase.__init__(self)
-        self.db_name = db_name
+        self.db = security_db.DB(db_name, readonly=True)
 
         self.stable_releases = config.get_supported_releases()
         self.stable_releases.remove(config.get_release_codename('testing'))
@@ -156,10 +156,6 @@ class TrackerService(WebServiceBase):
         self.register('distributions.json', self.page_distributions_json)
         self.register('script.js', self.page_script_js)
 
-    def open_db(self):
-        return security_db.DB(self.db_name, readonly=True)
-
-
     def page_style_css(self, path, params, url):
         with open('../static/style.css', 'rb') as f:
             content=f.read()
@@ -275,6 +271,8 @@ data source.""")],
         return self.page_object_or_redirect(url, obj, True)
 
     def page_object_or_redirect(self, url, obj, redirect):
+        c = self.db.cursor()
+
         if not obj:
             # Redirect to start page.
             return RedirectResult(url.scriptRelativeFull(""))
@@ -291,34 +289,30 @@ data source.""")],
                 bugnumber = int(obj)
         except ValueError:
             pass
+        if bugnumber:
+            buglist = list(self.db.getBugsFromDebianBug(c, bugnumber))
+            if buglist:
+                return self.page_debian_bug(url, bugnumber, buglist, fake_bug)
+            if redirect:
+                return RedirectResult(self.url_debian_bug(url, str(bugnumber)),
+                                      permanent=False)
 
-        with self.open_db() as db:
-            c = db.cursor()
-
-            if bugnumber:
-                buglist = list(db.getBugsFromDebianBug(c, bugnumber))
-                if buglist:
-                    return self.page_debian_bug(url, bugnumber, buglist, fake_bug)
-                if redirect:
-                    return RedirectResult(self.url_debian_bug(url, str(bugnumber)),
-                                          permanent=False)
-
-            if 'A' <= obj[0] <= 'Z':
-                # Bug names start with a capital letter.
-                return self.page_bug(db, url, obj, redirect)
+        if 'A' <= obj[0] <= 'Z':
+            # Bug names start with a capital letter.
+            return self.page_bug(url, obj, redirect)
 
-            if db.isSourcePackage(c, obj):
-                return RedirectResult(self.url_source_package(url, obj, full=True))
+        if self.db.isSourcePackage(c, obj):
+            return RedirectResult(self.url_source_package(url, obj, full=True))
 
         return self.page_not_found(url, obj)
 
-    def page_bug(self, db, url, name, redirect):
+    def page_bug(self, url, name, redirect):
         # FIXME: Normalize CAN-* to CVE-* when redirecting.  Too many
         # people still use CAN.
         if redirect and name[0:4] == 'CAN-':
             name = 'CVE-' + name[4:]
 
-        cursor = db.cursor()
+        cursor = self.db.cursor()
         try:
             bug = bugs.BugFromDB(cursor, name)
         except ValueError:
@@ -336,7 +330,7 @@ data source.""")],
         def gen_header():
             yield B("Name"), bug.name
 
-            nvd = db.getNVD(cursor, bug.name)
+            nvd = self.db.getNVD(cursor, bug.name)
 
             if nvd and nvd.cve_desc:
                 yield B("Description"), nvd.cve_desc
@@ -398,7 +392,7 @@ data source.""")],
             if source_xref:
                 yield B("Source"), source_xref
 
-            xref = list(db.getBugXrefs(cursor, bug.name))
+            xref = list(self.db.getBugXrefs(cursor, bug.name))
             if xref:
                 yield B("References"), self.make_xref_list(url, xref)
 
@@ -423,7 +417,7 @@ data source.""")],
             def gen_source():
                 old_pkg = ''
                 for (package, release, version, vulnerable) \
-                        in db.getSourcePackages(cursor, bug.name):
+                        in self.db.getSourcePackages(cursor, bug.name):
                     if package == old_pkg:
                         package = ''
                     else:
@@ -589,262 +583,258 @@ to improve our documentation and procedures, so feedback is welcome.""")])])
 
         pkg = path[0]
 
-        with self.open_db() as db:
-            if not db.isSourcePackage(db.cursor(), pkg):
-                return self.page_not_found(url, pkg)
-
-            data = security_db.getBugsForSourcePackage(db.cursor(), pkg)
-
-            def gen_versions():
-                for (release, version) in db.getSourcePackageVersions(
-                        db.cursor(), pkg):
-                    yield release, version
-            def gen_bug_list(lst):
-                for bug in lst:
-                    yield self.make_xref(url, bug.bug), bug.description
-
-            def format_summary_entry(per_release):
-                if per_release is None:
-                    return self.make_purple('unknown')
-                if per_release.vulnerable == security_db.Vulnerable.AFFECTED:
-                    if per_release.state == 'no-dsa':
-                        if per_release.reason:
-                            text = 'vulnerable (no DSA, %s)' % per_release.reason
-                        else:
-                            text = 'vulnerable (no DSA)'
-                        hint = per_release.comment
-                        return self.make_mouseover((self.make_yellow(text),),
-                                                   text=hint)
+        if not self.db.isSourcePackage(self.db.cursor(), pkg):
+            return self.page_not_found(url, pkg)
+
+        data = security_db.getBugsForSourcePackage(self.db.cursor(), pkg)
+
+        def gen_versions():
+            for (release, version) in self.db.getSourcePackageVersions(
+                    self.db.cursor(), pkg):
+                yield release, version
+        def gen_bug_list(lst):
+            for bug in lst:
+                yield self.make_xref(url, bug.bug), bug.description
+
+        def format_summary_entry(per_release):
+            if per_release is None:
+                return self.make_purple('unknown')
+            if per_release.vulnerable == security_db.Vulnerable.AFFECTED:
+                if per_release.state == 'no-dsa':
+                    if per_release.reason:
+                        text = 'vulnerable (no DSA, %s)' % per_release.reason
                     else:
-                        return self.make_red('vulnerable')
-                if per_release.vulnerable == security_db.Vulnerable.UNDETERMINED:
-                    return self.make_purple('undetermined')
-                assert per_release.vulnerable == security_db.Vulnerable.FIXED
-                return self.make_green('fixed')
-
-            def gen_summary(bugs):
-                for bug in bugs:
-                    status_row = tuple(
-                        format_summary_entry(bug.releases.get(rel, None))
-                        for rel in data.all_releases)
-                    yield (self.make_xref(url, bug.bug),) + status_row \
-                        + (bug.description,)
+                        text = 'vulnerable (no DSA)'
+                    hint = per_release.comment
+                    return self.make_mouseover((self.make_yellow(text),),
+                                               text=hint)
+                else:
+                    return self.make_red('vulnerable')
+            if per_release.vulnerable == security_db.Vulnerable.UNDETERMINED:
+                return self.make_purple('undetermined')
+            assert per_release.vulnerable == security_db.Vulnerable.FIXED
+            return self.make_green('fixed')
+
+        def gen_summary(bugs):
+            for bug in bugs:
+                status_row = tuple(
+                    format_summary_entry(bug.releases.get(rel, None))
+                    for rel in data.all_releases)
+                yield (self.make_xref(url, bug.bug),) + status_row \
+                    + (bug.description,)
 
-            return self.create_page(
-                url, 'Information on source package ' + pkg,
-                [make_menu(lambda x: x,
-                           (self.url_pts(url, pkg),
-                            pkg + ' in the Package Tracking System'),
-                           (self.url_debian_bug_pkg(url, pkg),
-                            pkg + ' in the Bug Tracking System'),
-                           (self.url_source_code(url, pkg),
-                            pkg + ' source code'),
-                           (self.url_testing_status(url, pkg),
-                            pkg + ' in the testing migration checker')),
-                 make_table(gen_versions(), title=H2('Available versions'), caption=('Release', 'Version')),
-
-                 make_table(
-                     gen_summary(data.open),
-                     title=H2('Open issues'),
-                     caption=('Bug',) + data.all_releases + ('Description',),
-                     replacement='No known open issues.'
-                 ),
-
-
-                 make_table(
-                     gen_summary(data.unimportant),
-                     title=H2('Open unimportant issues'),
-                     caption=('Bug',) + data.all_releases + ('Description',),
-                     replacement='No known unimportant issues.'
-                 ),
-
-                 make_table(gen_bug_list(data.resolved),
-                            title=H2('Resolved issues'),
-                            caption=('Bug', 'Description'),
-                            replacement='No known resolved issues.'),
-
-                 make_table(gen_bug_list(db.getDSAsForSourcePackage
-                                         (db.cursor(), pkg)),
-                            title=H2('Security announcements'),
-                            caption=('DSA / DLA', 'Description'),
-                            replacement='No known security announcements.')
-                 ])
+        return self.create_page(
+            url, 'Information on source package ' + pkg,
+            [make_menu(lambda x: x,
+                       (self.url_pts(url, pkg),
+                        pkg + ' in the Package Tracking System'),
+                       (self.url_debian_bug_pkg(url, pkg),
+                        pkg + ' in the Bug Tracking System'),
+                       (self.url_source_code(url, pkg),
+                        pkg + ' source code'),
+                       (self.url_testing_status(url, pkg),
+                        pkg + ' in the testing migration checker')),
+             make_table(gen_versions(), title=H2('Available versions'), caption=('Release', 'Version')),
+
+             make_table(
+                 gen_summary(data.open),
+                 title=H2('Open issues'),
+                 caption=('Bug',) + data.all_releases + ('Description',),
+                 replacement='No known open issues.'
+             ),
+
+
+             make_table(
+                 gen_summary(data.unimportant),
+                 title=H2('Open unimportant issues'),
+                 caption=('Bug',) + data.all_releases + ('Description',),
+                 replacement='No known unimportant issues.'
+             ),
+
+             make_table(gen_bug_list(data.resolved),
+                        title=H2('Resolved issues'),
+                        caption=('Bug', 'Description'),
+                        replacement='No known resolved issues.'),
+
+             make_table(gen_bug_list(self.db.getDSAsForSourcePackage
+                                     (self.db.cursor(), pkg)),
+                        title=H2('Security announcements'),
+                        caption=('DSA / DLA', 'Description'),
+                        replacement='No known security announcements.')
+             ])
 
     def page_status_release_stable_like(self, path, params, url):
         release = os.path.basename(url.path_info)
 
         bf = BugFilter(params)
 
-        with self.open_db() as db:
-            def gen():
-                old_pkg_name = ''
-                for (pkg_name, bug_name, archive, urgency, vulnerable, remote, no_dsa, no_dsa_reason) in \
-                        db.cursor().execute(
-                    """SELECT package, bug, section, urgency, vulnerable, remote, no_dsa, no_dsa_reason
-                    FROM %s_status
-                    WHERE (bug LIKE 'CVE-%%' OR bug LIKE 'TEMP-%%')
-                    ORDER BY package, bug COLLATE version""" % release):
-                    if bf.urgencyFiltered(urgency, vulnerable):
-                        continue
-                    if bf.remoteFiltered(remote):
-                        continue
-                    if bf.nodsaFiltered(no_dsa):
-                        continue
-                    if bf.ignoredFiltered(no_dsa_reason):
-                        continue
-                    if bf.postponedFiltered(no_dsa_reason):
-                        continue
-
-                    if pkg_name == old_pkg_name:
-                        pkg_name = ''
-                        title = None
-                    else:
-                        old_pkg_name = pkg_name
-                        title = None
-                        if archive != 'main':
-                            title = "%s (%s)" % (pkg_name, archive)
-
-                    if remote is None:
-                        remote = '?'
-                    elif remote:
-                        remote = 'yes'
-                    else:
-                        remote = 'no'
-
-                    if urgency.startswith('high'):
-                        urgency = self.make_red(urgency)
-                    elif vulnerable == security_db.Vulnerable.UNDETERMINED:
-                        urgency = self.make_purple(urgency)
-                    else:
-                        if no_dsa:
-                            urgency = urgency + '*'
-
-                    yield self.make_source_package_ref(url, pkg_name, title), self.make_xref(url, bug_name), urgency, remote
+        def gen():
+            old_pkg_name = ''
+            for (pkg_name, bug_name, archive, urgency, vulnerable, remote, no_dsa, no_dsa_reason) in \
+                    self.db.cursor().execute(
+                """SELECT package, bug, section, urgency, vulnerable, remote, no_dsa, no_dsa_reason
+                FROM %s_status
+                WHERE (bug LIKE 'CVE-%%' OR bug LIKE 'TEMP-%%')
+                ORDER BY package, bug COLLATE version""" % release):
+                if bf.urgencyFiltered(urgency, vulnerable):
+                    continue
+                if bf.remoteFiltered(remote):
+                    continue
+                if bf.nodsaFiltered(no_dsa):
+                    continue
+                if bf.ignoredFiltered(no_dsa_reason):
+                    continue
+                if bf.postponedFiltered(no_dsa_reason):
+                    continue
+
+                if pkg_name == old_pkg_name:
+                    pkg_name = ''
+                    title = None
+                else:
+                    old_pkg_name = pkg_name
+                    title = None
+                    if archive != 'main':
+                        title = "%s (%s)" % (pkg_name, archive)
+
+                if remote is None:
+                    remote = '?'
+                elif remote:
+                    remote = 'yes'
+                else:
+                    remote = 'no'
+
+                if urgency.startswith('high'):
+                    urgency = self.make_red(urgency)
+                elif vulnerable == security_db.Vulnerable.UNDETERMINED:
+                    urgency = self.make_purple(urgency)
+                else:
+                    if no_dsa:
+                        urgency = urgency + '*'
+
+                yield self.make_source_package_ref(url, pkg_name, title), self.make_xref(url, bug_name), urgency, remote
 
-            return self.create_page(
-                url, 'Vulnerable source packages in the %s suite' % release,
-                [bf.actions(url), BR(),
-                 make_table(gen(), caption=("Package", "Bug", "Urgency", "Remote")),
-                 P('''If a "*" is included in the urgency field, no DSA is planned
-                      for this vulnerability.'''),
-                 self.nvd_text])
+        return self.create_page(
+            url, 'Vulnerable source packages in the %s suite' % release,
+            [bf.actions(url), BR(),
+             make_table(gen(), caption=("Package", "Bug", "Urgency", "Remote")),
+             P('''If a "*" is included in the urgency field, no DSA is planned
+                  for this vulnerability.'''),
+             self.nvd_text])
 
     def page_status_release_testing(self, path, params, url):
         bf = BugFilter(params)
 
-        with self.open_db() as db:
-            def gen():
-                old_pkg_name = ''
-                for (pkg_name, bug_name, archive, urgency, vulnerable,
-                     sid_vulnerable, ts_fixed, remote, no_dsa) \
-                     in db.cursor().execute(
-                    """SELECT package, bug, section, urgency, vulnerable,
-                    unstable_vulnerable, testing_security_fixed, remote, no_dsa
-                    FROM testing_status
-                    ORDER BY package, bug COLLATE version"""):
-                    if bf.urgencyFiltered(urgency, vulnerable):
-                        continue
-                    if bf.remoteFiltered(remote):
-                        continue
-                    if bf.nodsaFiltered(no_dsa):
-                        continue
-
-                    if pkg_name == old_pkg_name:
-                        pkg_name = ''
-                        title = None
-                    else:
-                        old_pkg_name = pkg_name
-                        title = None
-                        if archive != 'main':
-                            title = "%s (%s)" % (pkg_name, archive)
-
-                    if remote is None:
-                        remote = '?'
-                    elif remote:
-                        remote = 'yes'
-                    else:
-                        remote = 'no'
-
-                    if ts_fixed:
-                        status = 'fixed in testing-security'
+        def gen():
+            old_pkg_name = ''
+            for (pkg_name, bug_name, archive, urgency, vulnerable,
+                 sid_vulnerable, ts_fixed, remote, no_dsa) \
+                 in self.db.cursor().execute(
+                """SELECT package, bug, section, urgency, vulnerable,
+                unstable_vulnerable, testing_security_fixed, remote, no_dsa
+                FROM testing_status
+                ORDER BY package, bug COLLATE version"""):
+                if bf.urgencyFiltered(urgency, vulnerable):
+                    continue
+                if bf.remoteFiltered(remote):
+                    continue
+                if bf.nodsaFiltered(no_dsa):
+                    continue
+
+                if pkg_name == old_pkg_name:
+                    pkg_name = ''
+                    title = None
+                else:
+                    old_pkg_name = pkg_name
+                    title = None
+                    if archive != 'main':
+                        title = "%s (%s)" % (pkg_name, archive)
+
+                if remote is None:
+                    remote = '?'
+                elif remote:
+                    remote = 'yes'
+                else:
+                    remote = 'no'
+
+                if ts_fixed:
+                    status = 'fixed in testing-security'
+                else:
+                    if sid_vulnerable:
+                        status = self.make_red('unstable is vulnerable')
                     else:
-                        if sid_vulnerable:
-                            status = self.make_red('unstable is vulnerable')
-                        else:
-                            status = self.make_dangerous('fixed in unstable')
+                        status = self.make_dangerous('fixed in unstable')
 
-                    if urgency.startswith('high'):
-                        urgency = self.make_red(urgency)
-                    elif vulnerable == security_db.Vulnerable.UNDETERMINED:
-                        urgency = self.make_purple(urgency)
+                if urgency.startswith('high'):
+                    urgency = self.make_red(urgency)
+                elif vulnerable == security_db.Vulnerable.UNDETERMINED:
+                    urgency = self.make_purple(urgency)
 
-                    yield (self.make_source_package_ref(url, pkg_name, title), self.make_xref(url, bug_name),
-                           urgency, remote, status)
+                yield (self.make_source_package_ref(url, pkg_name, title), self.make_xref(url, bug_name),
+                       urgency, remote, status)
 
-            return self.create_page(
-                url, 'Vulnerable source packages in the testing suite',
-                [make_menu(url.scriptRelative,
-                           ("status/dtsa-candidates", "Candidates for DTSAs")),
-                 bf.actions(url), BR(),
-                 make_table(gen(), caption=("Package", "Bug", "Urgency", "Remote", 'Status')),
-                 self.nvd_text])
+        return self.create_page(
+            url, 'Vulnerable source packages in the testing suite',
+            [make_menu(url.scriptRelative,
+                       ("status/dtsa-candidates", "Candidates for DTSAs")),
+             bf.actions(url), BR(),
+             make_table(gen(), caption=("Package", "Bug", "Urgency", "Remote", 'Status')),
+             self.nvd_text])
 
     def page_status_release_unstable_like(self, path, params, url,
                                           rel, title, subrel=""):
         bf = BugFilter(params,nonodsa=True,noignored=True,nopostponed=True)
 
-        with self.open_db() as db:
-            def gen():
-                old_pkg_name = ''
-                for (pkg_name, bug_name, section, urgency, vulnerable, remote) \
-                        in db.cursor().execute(
-                    """SELECT DISTINCT sp.name, st.bug_name,
-                    sp.archive, st.urgency, st.vulnerable,
-                    (SELECT range_remote FROM nvd_data
-                     WHERE cve_name = st.bug_name)
-                    FROM source_package_status AS st, source_packages AS sp
-                    WHERE st.vulnerable != ? AND sp.rowid = st.package
-                    AND sp.release = ?  AND sp.subrelease = ''
-                    ORDER BY sp.name, st.bug_name COLLATE version""",
-                    (security_db.Vulnerable.FIXED, rel,)):
-                    if bf.urgencyFiltered(urgency, vulnerable):
-                        continue
-                    if bf.remoteFiltered(remote):
-                        continue
-
-                    if pkg_name == old_pkg_name:
-                        pkg_name = ''
-                        title = None
-                    else:
-                        old_pkg_name = pkg_name
-                        title = None
-                        if section != 'main':
-                            title = "%s (%s)" % (pkg_name, section)
-
-                    if remote is None:
-                        remote = '?'
-                    elif remote:
-                        remote = 'yes'
-                    else:
-                        remote = 'no'
-
-                    if urgency.startswith('high'):
-                        urgency = self.make_red(urgency)
-                    elif vulnerable == security_db.Vulnerable.UNDETERMINED:
-                        urgency = self.make_purple(urgency)
-
-                    yield self.make_source_package_ref(url, pkg_name, title), self.make_xref(url, bug_name), urgency, remote
+        def gen():
+            old_pkg_name = ''
+            for (pkg_name, bug_name, section, urgency, vulnerable, remote) \
+                    in self.db.cursor().execute(
+                """SELECT DISTINCT sp.name, st.bug_name,
+                sp.archive, st.urgency, st.vulnerable,
+                (SELECT range_remote FROM nvd_data
+                 WHERE cve_name = st.bug_name)
+                FROM source_package_status AS st, source_packages AS sp
+                WHERE st.vulnerable != ? AND sp.rowid = st.package
+                AND sp.release = ?  AND sp.subrelease = ''
+                ORDER BY sp.name, st.bug_name COLLATE version""",
+                (security_db.Vulnerable.FIXED, rel,)):
+                if bf.urgencyFiltered(urgency, vulnerable):
+                    continue
+                if bf.remoteFiltered(remote):
+                    continue
+
+                if pkg_name == old_pkg_name:
+                    pkg_name = ''
+                    title = None
+                else:
+                    old_pkg_name = pkg_name
+                    title = None
+                    if section != 'main':
+                        title = "%s (%s)" % (pkg_name, section)
+
+                if remote is None:
+                    remote = '?'
+                elif remote:
+                    remote = 'yes'
+                else:
+                    remote = 'no'
+
+                if urgency.startswith('high'):
+                    urgency = self.make_red(urgency)
+                elif vulnerable == security_db.Vulnerable.UNDETERMINED:
+                    urgency = self.make_purple(urgency)
+
+                yield self.make_source_package_ref(url, pkg_name, title), self.make_xref(url, bug_name), urgency, remote
 
-            return self.create_page(
-                url, title,
-                [P("""Note that the list below is based on source packages.
-                This means that packages are not listed here once a new,
-                fixed source version has been uploaded to the archive, even
-                if there are still some vulnerable binary packages present
-                in the archive."""),
-                 bf.actions(url), BR(),
-                 make_table(gen(), caption=('Package', 'Bug', 'Urgency', 'Remote')),
-                 self.nvd_text])
+        return self.create_page(
+            url, title,
+            [P("""Note that the list below is based on source packages.
+            This means that packages are not listed here once a new,
+            fixed source version has been uploaded to the archive, even
+            if there are still some vulnerable binary packages present
+            in the archive."""),
+             bf.actions(url), BR(),
+             make_table(gen(), caption=('Package', 'Bug', 'Urgency', 'Remote')),
+             self.nvd_text])
 
     def page_status_release_unstable(self, path, params, url):
         return self.page_status_release_unstable_like(
@@ -864,78 +854,77 @@ to improve our documentation and procedures, so feedback is welcome.""")])])
     def page_status_dtsa_candidates(self, path, params, url):
         bf = BugFilter(params,nonodsa=True,noignored=True,nopostponed=True)
 
-        with self.open_db() as db:
-            def gen():
-                old_pkg_name = ''
-                for (pkg_name, bug_name, archive, urgency, vulnerable,
-                     stable_later, remote) \
-                        in db.cursor().execute(
-                    """SELECT package, bug, section, urgency, vulnerable,
-                    (SELECT testing.version_id < stable.version_id
-                     FROM source_packages AS testing, source_packages AS stable
-                     WHERE testing.name = testing_status.package
-                     AND testing.release = ?
-                     AND testing.subrelease = ''
-                     AND testing.archive = testing_status.section
-                     AND stable.name = testing_status.package
-                     AND stable.release = ?
-                     AND stable.subrelease = 'security'
-                     AND stable.archive = testing_status.section),
-                    (SELECT range_remote FROM nvd_data
-                     WHERE cve_name = bug)
-                    FROM testing_status
-                    WHERE (NOT unstable_vulnerable)
-                    AND (NOT testing_security_fixed)""",
-                    (config.get_release_codename('testing'), config.get_release_codename('stable'))):
-                    if bf.urgencyFiltered(urgency, vulnerable):
-                        continue
-                    if bf.remoteFiltered(remote):
-                        continue
-
-                    if pkg_name == old_pkg_name:
-                        pkg_name = ''
-                        migration = ''
-                        title = None
-                    else:
-                        old_pkg_name = pkg_name
-                        title = None
-                        migration = A(self.url_testing_status(url, pkg_name),
-                                      "check")
-                        if archive != 'main':
-                            title = "%s (%s)" % (pkg_name, archive)
-
-                    if remote is None:
-                        remote = '?'
-                    elif remote:
-                        remote = 'yes'
-                    else:
-                        remote = 'no'
-
-                    if urgency.startswith('high'):
-                        urgency = self.make_red(urgency)
-                    elif vulnerable == security_db.Vulnerable.UNDETERMINED:
-                        urgency = self.make_purple(urgency)
-
-                    if stable_later:
-                        notes = "(fixed in stable?)"
-                    else:
-                        notes = ''
-
-                    yield (self.make_source_package_ref(url, pkg_name, title), migration, self.make_xref(url, bug_name),
-                           urgency, remote, notes)
+        def gen():
+            old_pkg_name = ''
+            for (pkg_name, bug_name, archive, urgency, vulnerable,
+                 stable_later, remote) \
+                    in self.db.cursor().execute(
+                """SELECT package, bug, section, urgency, vulnerable,
+                (SELECT testing.version_id < stable.version_id
+                 FROM source_packages AS testing, source_packages AS stable
+                 WHERE testing.name = testing_status.package
+                 AND testing.release = ?
+                 AND testing.subrelease = ''
+                 AND testing.archive = testing_status.section
+                 AND stable.name = testing_status.package
+                 AND stable.release = ?
+                 AND stable.subrelease = 'security'
+                 AND stable.archive = testing_status.section),
+                (SELECT range_remote FROM nvd_data
+                 WHERE cve_name = bug)
+                FROM testing_status
+                WHERE (NOT unstable_vulnerable)
+                AND (NOT testing_security_fixed)""",
+                (config.get_release_codename('testing'), config.get_release_codename('stable'))):
+                if bf.urgencyFiltered(urgency, vulnerable):
+                    continue
+                if bf.remoteFiltered(remote):
+                    continue
+
+                if pkg_name == old_pkg_name:
+                    pkg_name = ''
+                    migration = ''
+                    title = None
+                else:
+                    old_pkg_name = pkg_name
+                    title = None
+                    migration = A(self.url_testing_status(url, pkg_name),
+                                  "check")
+                    if archive != 'main':
+                        title = "%s (%s)" % (pkg_name, archive)
+
+                if remote is None:
+                    remote = '?'
+                elif remote:
+                    remote = 'yes'
+                else:
+                    remote = 'no'
+
+                if urgency.startswith('high'):
+                    urgency = self.make_red(urgency)
+                elif vulnerable == security_db.Vulnerable.UNDETERMINED:
+                    urgency = self.make_purple(urgency)
+
+                if stable_later:
+                    notes = "(fixed in stable?)"
+                else:
+                    notes = ''
+
+                yield (self.make_source_package_ref(url, pkg_name, title), migration, self.make_xref(url, bug_name),
+                       urgency, remote, notes)
 
-            return self.create_page(
-                url, "Candidates for DTSAs",
-                [P("""The table below lists packages which are fixed
-    in unstable, but unfixed in testing.  Use the testing migration
-    checker to find out why they have not entered testing yet."""),
-                 make_menu(url.scriptRelative,
-                           ("status/release/testing",
-                            "List of vulnerable packages in testing")),
-                 bf.actions(url), BR(),
-                 make_table(gen(),
-                            caption=("Package", "Migration", "Bug", "Urgency",
-                                     "Remote", ""))])
+        return self.create_page(
+            url, "Candidates for DTSAs",
+            [P("""The table below lists packages which are fixed
+in unstable, but unfixed in testing.  Use the testing migration
+checker to find out why they have not entered testing yet."""),
+             make_menu(url.scriptRelative,
+                       ("status/release/testing",
+                        "List of vulnerable packages in testing")),
+             bf.actions(url), BR(),
+             make_table(gen(),
+                        caption=("Package", "Migration", "Bug", "Urgency",
+                                 "Remote", ""))])
 
     def page_status_todo(self, path, params, url):
         hide_check = bool(params.get('hide_check', False))
@@ -946,120 +935,116 @@ to improve our documentation and procedures, so feedback is welcome.""")])])
             flags = A(url.updateParamsDict({'hide_check' : '1'}),
                   'Hide "check" TODOs')
 
-        with self.open_db() as db:
-            def gen():
-                for (bug, description, note) in db.getTODOs(hide_check=hide_check):
-                    yield self.make_xref(url, bug), description, note
-            return self.create_page(
-                url, 'Bugs with TODO items',
-                [P(flags), make_table(gen(), caption=('Bug', 'Description', 'Note'))])
+        def gen():
+            for (bug, description, note) in self.db.getTODOs(hide_check=hide_check):
+                yield self.make_xref(url, bug), description, note
+        return self.create_page(
+            url, 'Bugs with TODO items',
+            [P(flags), make_table(gen(), caption=('Bug', 'Description', 'Note'))])
 
     def page_status_undetermined(self, path, params, url):
-        with self.open_db() as db:
-            def gen():
-                outrel = []
-                old_bug = ''
-                old_pkg = ''
-                old_dsc = ''
-                last_displayed = ''
-                releases = config.get_supported_releases()
-                for (pkg_name, bug_name, release, desc) in db.cursor().execute(
-                        """SELECT DISTINCT sp.name, st.bug_name, sp.release,
-                        bugs.description
-                        FROM source_package_status AS st, source_packages AS sp, bugs
-                        WHERE st.vulnerable == ? AND sp.rowid = st.package
-                        AND sp.release IN (""" + ",".join("?" * len(releases)) + """)
-                        AND sp.subrelease = '' AND st.bug_name == bugs.name
-                        ORDER BY sp.name, st.bug_name COLLATE version""",
-                        (security_db.Vulnerable.UNDETERMINED, *releases)):
-
-                    if old_bug == '':
-                        old_bug = bug_name
-                        old_pkg = pkg_name
-                        old_dsc = desc
-                    elif old_bug != bug_name:
-                        if old_pkg == last_displayed:
-                            to_display = ''
-                        else:
-                            to_display = old_pkg
-                        yield to_display, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
-                        last_displayed = old_pkg
-                        old_bug = bug_name
-                        old_pkg = pkg_name
-                        old_dsc = desc
-                        outrel = []
-                    outrel.append( release )
-                yield old_pkg, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
-
-            return self.create_page(url, 'Packages that may be vulnerable but need to be checked      (undetermined issues)',
-                [P("""This page lists packages that may or may not be affected
-                by known issues.  This means that some additional work needs to
-                be done to determined whether the package is actually
-                vulnerable or not.  This list is a good area for new
-                contributors to make quick and meaningful contributions."""),
-                make_table(gen(), caption=('Package', 'Bug', 'Description', 'Releases'))])
+        def gen():
+            outrel = []
+            old_bug = ''
+            old_pkg = ''
+            old_dsc = ''
+            last_displayed = ''
+            releases = config.get_supported_releases()
+            for (pkg_name, bug_name, release, desc) in self.db.cursor().execute(
+                    """SELECT DISTINCT sp.name, st.bug_name, sp.release,
+                    bugs.description
+                    FROM source_package_status AS st, source_packages AS sp, bugs
+                    WHERE st.vulnerable == ? AND sp.rowid = st.package
+                    AND sp.release IN (""" + ",".join("?" * len(releases)) + """)
+                    AND sp.subrelease = '' AND st.bug_name == bugs.name
+                    ORDER BY sp.name, st.bug_name COLLATE version""",
+                    (security_db.Vulnerable.UNDETERMINED, *releases)):
+
+                if old_bug == '':
+                    old_bug = bug_name
+                    old_pkg = pkg_name
+                    old_dsc = desc
+                elif old_bug != bug_name:
+                    if old_pkg == last_displayed:
+                        to_display = ''
+                    else:
+                        to_display = old_pkg
+                    yield to_display, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
+                    last_displayed = old_pkg
+                    old_bug = bug_name
+                    old_pkg = pkg_name
+                    old_dsc = desc
+                    outrel = []
+                outrel.append( release )
+            yield old_pkg, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
+
+        return self.create_page(url, 'Packages that may be vulnerable but need to be checked      (undetermined issues)',
+            [P("""This page lists packages that may or may not be affected
+            by known issues.  This means that some additional work needs to
+            be done to determined whether the package is actually
+            vulnerable or not.  This list is a good area for new
+            contributors to make quick and meaningful contributions."""),
+            make_table(gen(), caption=('Package', 'Bug', 'Description', 'Releases'))])
 
     def page_status_unimportant(self, path, params, url):
-        with self.open_db() as db:
-            def gen():
-                outrel = []
-                old_bug = ''
-                old_pkg = ''
-                old_dsc = ''
-                old_name = ''
-                last_displayed = ''
-                releases = config.get_supported_releases()
-                for (pkg_name, bug_name, release, desc) in db.cursor().execute(
-                        """SELECT DISTINCT sp.name, st.bug_name, sp.release,
-                        bugs.description
-                        FROM source_package_status AS st, source_packages AS sp, bugs
-                        WHERE st.vulnerable != ? AND sp.rowid = st.package
-                        AND sp.release IN (""" + ",".join("?" * len(releases)) +  """)
-                        AND st.urgency == 'unimportant'
-                        AND sp.subrelease = '' AND st.bug_name == bugs.name
-                        ORDER BY sp.name, st.bug_name COLLATE version""",
-                        (security_db.Vulnerable.FIXED, *releases)):
-
-                    if old_bug == '':
-                        old_bug = bug_name
-                        old_pkg = pkg_name
-                        old_dsc = desc
-                    elif old_bug != bug_name:
-                        if old_pkg == last_displayed:
-                            to_display = ''
-                        else:
-                            to_display = old_pkg
-                        yield to_display, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
-                        last_displayed = old_pkg
-                        old_bug = bug_name
-                        old_pkg = pkg_name
-                        old_dsc = desc
-                        outrel = []
-                    outrel.append( release )
-                yield old_pkg, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
-
-            return self.create_page(url, 'Packages that have open unimportant issues',
-                [P("""This page lists packages that are affected by issues
-                that are considered unimportant from a security perspective.
-                These issues are thought to be unexploitable or uneffective
-                in most situations (for example, browser denial-of-services)."""),
-                make_table(gen(), caption=('Package', 'Bug', 'Description', 'Releases'))])
+        def gen():
+            outrel = []
+            old_bug = ''
+            old_pkg = ''
+            old_dsc = ''
+            old_name = ''
+            last_displayed = ''
+            releases = config.get_supported_releases()
+            for (pkg_name, bug_name, release, desc) in self.db.cursor().execute(
+                    """SELECT DISTINCT sp.name, st.bug_name, sp.release,
+                    bugs.description
+                    FROM source_package_status AS st, source_packages AS sp, bugs
+                    WHERE st.vulnerable != ? AND sp.rowid = st.package
+                    AND sp.release IN (""" + ",".join("?" * len(releases)) +  """)
+                    AND st.urgency == 'unimportant'
+                    AND sp.subrelease = '' AND st.bug_name == bugs.name
+                    ORDER BY sp.name, st.bug_name COLLATE version""",
+                    (security_db.Vulnerable.FIXED, *releases)):
+
+                if old_bug == '':
+                    old_bug = bug_name
+                    old_pkg = pkg_name
+                    old_dsc = desc
+                elif old_bug != bug_name:
+                    if old_pkg == last_displayed:
+                        to_display = ''
+                    else:
+                        to_display = old_pkg
+                    yield to_display, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
+                    last_displayed = old_pkg
+                    old_bug = bug_name
+                    old_pkg = pkg_name
+                    old_dsc = desc
+                    outrel = []
+                outrel.append( release )
+            yield old_pkg, self.make_xref(url, old_bug), old_dsc, ', '.join(outrel)
+
+        return self.create_page(url, 'Packages that have open unimportant issues',
+            [P("""This page lists packages that are affected by issues
+            that are considered unimportant from a security perspective.
+            These issues are thought to be unexploitable or uneffective
+            in most situations (for example, browser denial-of-services)."""),
+            make_table(gen(), caption=('Package', 'Bug', 'Description', 'Releases'))])
 
     def page_status_itp(self, path, params, url):
-        with self.open_db() as db:
-            def gen():
-                old_pkg = ''
-                for pkg, bugs, debian_bugs in db.getITPs(db.cursor()):
-                    if pkg == old_pkg:
-                        pkg = ''
-                    else:
-                        old_pkg = pkg
-                    yield (pkg, self.make_xref_list(url, bugs),
-                           self.make_debian_bug_list(url, debian_bugs))
-            return self.create_page(
-                url, "ITPs with potential security issues",
-                [make_table(gen(), caption=("Package", "Issue", "Debian Bugs"),
-                            replacement="No ITP bugs are currently known.")])
+        def gen():
+            old_pkg = ''
+            for pkg, bugs, debian_bugs in self.db.getITPs(self.db.cursor()):
+                if pkg == old_pkg:
+                    pkg = ''
+                else:
+                    old_pkg = pkg
+                yield (pkg, self.make_xref_list(url, bugs),
+                       self.make_debian_bug_list(url, debian_bugs))
+        return self.create_page(
+            url, "ITPs with potential security issues",
+            [make_table(gen(), caption=("Package", "Issue", "Debian Bugs"),
+                        replacement="No ITP bugs are currently known.")])
 
     def page_status_unreported(self, path, params, url):
         show_ignored = params.get('show_ignored', False)
@@ -1071,219 +1056,210 @@ to improve our documentation and procedures, so feedback is welcome.""")])])
         else:
             flags = A(url.updateParamsDict({'show_ignored' : '1'}),
                   'Show ignored issues')
-        with self.open_db() as db:
-            def gen():
-                for (bug, packages) in db.getUnreportedVulnerabilities(show_ignored=show_ignored_flag):
-                    pkgs = make_list([self.make_source_package_ref(url, pkg)
-                                      for pkg in packages], ", ")
-                    yield self.make_xref(url, bug), pkgs
-            return self.create_page(
-                url, "Unfixed vulnerabilities in unstable without a filed bug",
-                [P(flags), P("""The list below contains vulnerabilities for which no matching
-    Debian bug has been filed, and there is still an unfixed package in sid."""),
-                 make_table(gen(), caption=("Bug", "Packages"))])
+        def gen():
+            for (bug, packages) in self.db.getUnreportedVulnerabilities(show_ignored=show_ignored_flag):
+                pkgs = make_list([self.make_source_package_ref(url, pkg)
+                                  for pkg in packages], ", ")
+                yield self.make_xref(url, bug), pkgs
+        return self.create_page(
+            url, "Unfixed vulnerabilities in unstable without a filed bug",
+            [P(flags), P("""The list below contains vulnerabilities for which no matching
+Debian bug has been filed, and there is still an unfixed package in sid."""),
+             make_table(gen(), caption=("Bug", "Packages"))])
 
     def page_data_unknown_packages(self, path, params, url):
-        with self.open_db() as db:
-            def gen():
-                for name, bugs in db.getUnknownPackages(db.cursor()):
-                    yield name, self.make_xref_list(url, bugs)
-            return self.create_page(
-                url, "Unknown packages",
-                [P("""Sometimes, a package referenced in a bug report
-    cannot be found in the database.  This can be the result of a spelling
-    error, or a historic entry refers to a
-    package which is no longer in the archive."""),
-                 make_table(gen(), caption=("Package", "Bugs"),
-                     replacement="No unknown packages are referenced in the database.")])
+        def gen():
+            for name, bugs in self.db.getUnknownPackages(self.db.cursor()):
+                yield name, self.make_xref_list(url, bugs)
+        return self.create_page(
+            url, "Unknown packages",
+            [P("""Sometimes, a package referenced in a bug report
+cannot be found in the database.  This can be the result of a spelling
+error, or a historic entry refers to a
+package which is no longer in the archive."""),
+             make_table(gen(), caption=("Package", "Bugs"),
+        replacement="No unknown packages are referenced in the database.")])
 
     def page_data_missing_epochs(self, path, params, url):
-        with self.open_db() as db:
-            def gen():
-                old_bug = ''
-                old_pkg = ''
-                for bug, pkg, ver1, ver2 in db.cursor().execute(
-                    """SELECT DISTINCT bug_name, n.package,
-                    n.fixed_version, sp.version
-                    FROM package_notes AS n, source_packages AS sp
-                    WHERE n.package_kind = 'source'
-                    AND n.fixed_version NOT LIKE '%:%'
-                    AND n.fixed_version <> '0'
-                    AND n.bug_origin = ''
-                    AND sp.name = n.package
-                    AND sp.version LIKE '%:%'
-                    ORDER BY bug_name COLLATE version, package"""):
-                    if bug == old_bug:
-                        bug = ''
-                    else:
-                        old_bug = bug
-                        old_pkg = ''
-                        bug = self.make_xref(url, bug)
-                    if pkg == old_pkg:
-                        pkg = ''
-                    else:
-                        old_pkg = pkg
-                        pkg = self.make_source_package_ref(url, pkg)
-                    yield bug, pkg, ver1, ver2
+        def gen():
+            old_bug = ''
+            old_pkg = ''
+            for bug, pkg, ver1, ver2 in self.db.cursor().execute(
+                """SELECT DISTINCT bug_name, n.package,
+                n.fixed_version, sp.version
+                FROM package_notes AS n, source_packages AS sp
+                WHERE n.package_kind = 'source'
+                AND n.fixed_version NOT LIKE '%:%'
+                AND n.fixed_version <> '0'
+                AND n.bug_origin = ''
+                AND sp.name = n.package
+                AND sp.version LIKE '%:%'
+                ORDER BY bug_name COLLATE version, package"""):
+                if bug == old_bug:
+                    bug = ''
+                else:
+                    old_bug = bug
+                    old_pkg = ''
+                    bug = self.make_xref(url, bug)
+                if pkg == old_pkg:
+                    pkg = ''
+                else:
+                    old_pkg = pkg
+                    pkg = self.make_source_package_ref(url, pkg)
+                yield bug, pkg, ver1, ver2
 
-            return self.create_page(
-                url, "Missing epochs in package versions",
-                [make_table(gen(),
-                    caption=("Bug", "Package", "Version 1", "Version 2"),
-                    replacement="No source package version with missing epochs.")])
+        return self.create_page(
+            url, "Missing epochs in package versions",
+            [make_table(gen(),
+                caption=("Bug", "Package", "Version 1", "Version 2"),
+                replacement="No source package version with missing epochs.")])
 
     def page_data_latently_vulnerable(self, path, params, url):
-        with self.open_db() as db:
-            def gen():
-                for pkg, bugs in db.cursor().execute(
-                    """SELECT package, string_set(bug_name)
-                    FROM package_notes AS p1
-                    WHERE release <> ''
-                    AND (bug_name LIKE 'CVE-%' OR bug_name LIKE 'TEMP-%')
-                    AND NOT EXISTS (SELECT 1 FROM package_notes AS p2
-                                    WHERE p2.bug_name = p1.bug_name
-                                    AND p2.package = p1.package
-                                    AND release = '')
-                    AND EXISTS (SELECT 1 FROM source_packages
-                               WHERE name = p1.package AND release = 'sid')
-                    GROUP BY package
-                    ORDER BY package"""):
-                    pkg = self.make_source_package_ref(url, pkg)
-                    bugs = bugs.split(',')
-                    yield pkg, self.make_xref_list(url, bugs)
-
-            def gen_unimportant():
-                for pkg, bugs in db.cursor().execute(
-                    """SELECT package, string_set(bug_name)
-                    FROM package_notes AS p1
-                    WHERE release <> ''
-                    AND urgency <> 'unimportant'
-                    AND (bug_name LIKE 'CVE-%' OR bug_name LIKE 'TEMP-%')
-                    AND EXISTS (SELECT 1 FROM package_notes AS p2
-                                    WHERE p2.bug_name = p1.bug_name
-                                    AND p2.package = p1.package
-                                    AND release = '')
-                    AND NOT EXISTS (SELECT 1 FROM package_notes AS p2
-                                    WHERE p2.bug_name = p1.bug_name
-                                    AND p2.package = p1.package
-                                    AND urgency <> 'unimportant'
-                                    AND release = '')
-                    AND EXISTS (SELECT 1 FROM source_packages
-                               WHERE name = p1.package AND release = 'sid')
-                    GROUP BY package
-                    ORDER BY package"""):
-                    pkg = self.make_source_package_ref(url, pkg)
-                    bugs = bugs.split(',')
-                    yield pkg, self.make_xref_list(url, bugs)
+        def gen():
+            for pkg, bugs in self.db.cursor().execute(
+                """SELECT package, string_set(bug_name)
+                FROM package_notes AS p1
+                WHERE release <> ''
+                AND (bug_name LIKE 'CVE-%' OR bug_name LIKE 'TEMP-%')
+                AND NOT EXISTS (SELECT 1 FROM package_notes AS p2
+                                WHERE p2.bug_name = p1.bug_name
+                                AND p2.package = p1.package
+                                AND release = '')
+                AND EXISTS (SELECT 1 FROM source_packages
+                           WHERE name = p1.package AND release = 'sid')
+                GROUP BY package
+                ORDER BY package"""):
+                pkg = self.make_source_package_ref(url, pkg)
+                bugs = bugs.split(',')
+                yield pkg, self.make_xref_list(url, bugs)
+
+        def gen_unimportant():
+            for pkg, bugs in self.db.cursor().execute(
+                """SELECT package, string_set(bug_name)
+                FROM package_notes AS p1
+                WHERE release <> ''
+                AND urgency <> 'unimportant'
+                AND (bug_name LIKE 'CVE-%' OR bug_name LIKE 'TEMP-%')
+                AND EXISTS (SELECT 1 FROM package_notes AS p2
+                                WHERE p2.bug_name = p1.bug_name
+                                AND p2.package = p1.package
+                                AND release = '')
+                AND NOT EXISTS (SELECT 1 FROM package_notes AS p2
+                                WHERE p2.bug_name = p1.bug_name
+                                AND p2.package = p1.package
+                                AND urgency <> 'unimportant'
+                                AND release = '')
+                AND EXISTS (SELECT 1 FROM source_packages
+                           WHERE name = p1.package AND release = 'sid')
+                GROUP BY package
+                ORDER BY package"""):
+                pkg = self.make_source_package_ref(url, pkg)
+                bugs = bugs.split(',')
+                yield pkg, self.make_xref_list(url, bugs)
 
-            return self.create_page(
-                url, "Latently vulnerable packages in unstable",
-                [P(
-    """A package is latently vulnerable in unstable if it is vulnerable in
-    any release, and there is no package note for the same vulnerability
-    and package in unstable (and the package is still available in
-    unstable, of course)."""),
-                 make_table(gen(),
-                    caption=("Package", "Bugs"),
-                    replacement="No latently vulnerable packages were found."),
-                 P(
-    """The next table lists issues which are marked unimportant for
-    unstable, but for which release-specific annotations exist which are
-    not unimportant."""),
-                 make_table(gen_unimportant(),
-                    caption=("Package", "Bugs"),
-                    replacement=
-        "No packages with unimportant latent vulnerabilities were found."),
-                ])
+        return self.create_page(
+            url, "Latently vulnerable packages in unstable",
+            [P(
+"""A package is latently vulnerable in unstable if it is vulnerable in
+any release, and there is no package note for the same vulnerability
+and package in unstable (and the package is still available in
+unstable, of course)."""),
+             make_table(gen(),
+                caption=("Package", "Bugs"),
+                replacement="No latently vulnerable packages were found."),
+             P(
+"""The next table lists issues which are marked unimportant for
+unstable, but for which release-specific annotations exist which are
+not unimportant."""),
+             make_table(gen_unimportant(),
+                caption=("Package", "Bugs"),
+                replacement=
+    "No packages with unimportant latent vulnerabilities were found."),
+            ])
 
     def page_data_releases(self, path, params, url):
-        with self.open_db() as db:
-            def gen():
-                for (rel, subrel, archive, sources, archs) \
-                        in db.availableReleases():
-                    if 'source' in archs:
-                        archs.remove('source')
-                    yield rel, subrel, archive, "yes" if sources else "no", make_list(archs)
-            return self.create_page(
-                url, "Available releases",
-                [P("""The security issue database is checked against
-    the Debian releases listed in the table below."""),
-                 make_table(gen(),
-                            caption=("Release", "Subrelease", "Archive",
-                                     "Sources", "Architectures"))])
+        def gen():
+            for (rel, subrel, archive, sources, archs) \
+                    in self.db.availableReleases():
+                if 'source' in archs:
+                    archs.remove('source')
+                yield rel, subrel, archive, "yes" if sources else "no" , make_list(archs)
+        return self.create_page(
+            url, "Available releases",
+            [P("""The security issue database is checked against
+the Debian releases listed in the table below."""),
+             make_table(gen(),
+                        caption=("Release", "Subrelease", "Archive",
+                                 "Sources", "Architectures"))])
 
     def page_data_funny_versions(self, path, params, url):
-        with self.open_db() as db:
-            def gen():
-                for name, release, archive, version, source_version \
-                    in db.getFunnyPackageVersions():
-                    yield name, release, archive, source_version, version
+        def gen():
+            for name, release, archive, version, source_version \
+                in self.db.getFunnyPackageVersions():
+                yield name, release, archive, source_version, version
 
-            return self.create_page(
-                url, "Version conflicts between source/binary packages",
-                [P("""The table below lists source packages
-                which have a binary package of the same name, but with a different
-                version.  This means that extra care is necessary to determine
-                the version of a package which has been fixed.  (Note that
-                the bug tracker prefers source versions to binary versions
-                in this case.)"""),
-                 make_table(gen(),
-                            caption=("Package",
-                                     "Release",
-                                     "Archive",
-                                     "Source Version",
-                                     "Binary Version")),
-                 P("""Technically speaking, these version numbering is fine,
-    but it makes version-based bug tracking quite difficult for these packages."""),
-                 P("""There are many binary packages which are built from source
-                 packages with different version numbering schemes.  However, as
-                 long as none of the binary packages carries the same name as the
-                 source package, most confusion is avoided or can be easily
-                 explained.""")])
+        return self.create_page(
+            url, "Version conflicts between source/binary packages",
+            [P("""The table below lists source packages
+            which have a binary package of the same name, but with a different
+            version.  This means that extra care is necessary to determine
+            the version of a package which has been fixed.  (Note that
+            the bug tracker prefers source versions to binary versions
+            in this case.)"""),
+             make_table(gen(),
+                        caption=("Package",
+                                 "Release",
+                                 "Archive",
+                                 "Source Version",
+                                 "Binary Version")),
+             P("""Technically speaking, these version numbering is fine,
+but it makes version-based bug tracking quite difficult for these packages."""),
+             P("""There are many binary packages which are built from source
+             packages with different version numbering schemes.  However, as
+             long as none of the binary packages carries the same name as the
+             source package, most confusion is avoided or can be easily
+             explained.""")])
 
     def page_data_fake_names(self, path, params, url):
-        with self.open_db() as db:
-            def gen(v):
-                for (bug, description) in db.getFakeBugs(vulnerability=v):
-                    yield self.make_xref(url, bug), description
-            return self.create_page(
-                url, "Automatically generated issue names",
-                [P("""Some issues have not been assigned CVE names, but are still
-    tracked by this database.  In this case, the system automatically assigns
-    a unique name.  These names are not stable and can change when the database
-    is updated, so they should not be used in external references."""),
-                 P('''The automatically generated names come in two flavors:
-    the first kind starts with the string "''', CODE("TEMP-000000-"),
-                   '''".  This means that no Debian bug has been assigned to this
-    issue (or a bug has been created and is not recorded in this database).
-    In the second kind of names, there is a Debian bug for the issue, and the "''',
-                   CODE("000000"), '''"part of the name is replaced with the
-    Debian bug number.'''),
-                 make_table(gen(security_db.Vulnerable.AFFECTED),title=H2('With unfixed issues'), caption=("Bug", "Description")),
-                 make_table(gen(security_db.Vulnerable.FIXED),title=H2('The rest'), caption=("Bug", "Description")),
-                ])
+        def gen(v):
+            for (bug, description) in self.db.getFakeBugs(vulnerability=v):
+                yield self.make_xref(url, bug), description
+        return self.create_page(
+            url, "Automatically generated issue names",
+            [P("""Some issues have not been assigned CVE names, but are still
+tracked by this database.  In this case, the system automatically assigns
+a unique name.  These names are not stable and can change when the database
+is updated, so they should not be used in external references."""),
+             P('''The automatically generated names come in two flavors:
+the first kind starts with the string "''', CODE("TEMP-000000-"),
+               '''".  This means that no Debian bug has been assigned to this
+issue (or a bug has been created and is not recorded in this database).
+In the second kind of names, there is a Debian bug for the issue, and the "''',
+               CODE("000000"), '''"part of the name is replaced with the
+Debian bug number.'''),
+             make_table(gen(security_db.Vulnerable.AFFECTED),title=H2('With unfixed issues'), caption=("Bug", "Description")),
+             make_table(gen(security_db.Vulnerable.FIXED),title=H2('The rest'), caption=("Bug", "Description")),
+            ])
 
     def page_data_pts(self, path, params, url):
         data = []
-        with self.open_db() as db:
-            for pkg, bugs in db.cursor().execute(
-                    """SELECT package, COUNT(DISTINCT bug) FROM
-                    (SELECT package, bug, urgency FROM stable_status
-                     UNION ALL SELECT DISTINCT sp.name, st.bug_name, st.urgency
-                       FROM source_package_status AS st, source_packages AS sp
-                       WHERE st.vulnerable != ? AND st.urgency <> 'unimportant'
-                       AND sp.rowid = st.package AND sp.release = 'sid'
-                       AND sp.subrelease = '') x WHERE urgency <> 'unimportant'
-                    GROUP BY package ORDER BY package""", (security_db.Vulnerable.FIXED,)):
-                data.append(pkg)
-                data.append(':')
-                data.append(str(bugs))
-                data.append('\n')
+        for pkg, bugs in self.db.cursor().execute(
+                """SELECT package, COUNT(DISTINCT bug) FROM
+                (SELECT package, bug, urgency FROM stable_status
+                 UNION ALL SELECT DISTINCT sp.name, st.bug_name, st.urgency
+                   FROM source_package_status AS st, source_packages AS sp
+                   WHERE st.vulnerable != ? AND st.urgency <> 'unimportant'
+                   AND sp.rowid = st.package AND sp.release = 'sid'
+                   AND sp.subrelease = '') x WHERE urgency <> 'unimportant'
+                GROUP BY package ORDER BY package""", (security_db.Vulnerable.FIXED,)):
+            data.append(pkg)
+            data.append(':')
+            data.append(str(bugs))
+            data.append('\n')
         return BinaryResult(''.join(data).encode("utf-8"), 'application/octet-stream')
 
     def exported_result(self, path, url):
-        with self.open_db() as db:
-            data = db.getExported(path)
+        data = self.db.getExported(path)
         if data:
             result = BinaryResult(data[0], data[1])
             if data[2]:


=====================================
lib/python/security_db.py
=====================================
@@ -321,12 +321,6 @@ class DB:
                 raise SchemaMismatch(repr(user_version))
         self._initViews(c)
 
-    def __enter__(self):
-        return self
-
-    def __exit__(self, _exc_type, _exc_value, _traceback):
-        self.db.close()
-
     def __del__(self):
         self.db.close()
 



View it on GitLab: https://salsa.debian.org/security-tracker-team/security-tracker/-/commit/2dc305a8e872da3da4dfd7ec7af20aaca11cad54

-- 
View it on GitLab: https://salsa.debian.org/security-tracker-team/security-tracker/-/commit/2dc305a8e872da3da4dfd7ec7af20aaca11cad54
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-security-tracker-commits/attachments/20260826/268d1c36/attachment-0001.htm>


More information about the debian-security-tracker-commits mailing list