← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~enriqueesanchz/launchpad:add-distropackage-tags into launchpad:master

 

Enrique Sánchez has proposed merging ~enriqueesanchz/launchpad:add-distropackage-tags into launchpad:master.

Commit message:
Add SVT DistroPackage.tags

This will support package tags from cve files

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~enriqueesanchz/launchpad/+git/launchpad/+merge/484969
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~enriqueesanchz/launchpad:add-distropackage-tags into launchpad:master.
diff --git a/lib/contrib/cve_lib.py b/lib/contrib/cve_lib.py
index 863bdee..7080368 100644
--- a/lib/contrib/cve_lib.py
+++ b/lib/contrib/cve_lib.py
@@ -979,6 +979,10 @@ VALID_TAGS = {
         "Independent Executables in Ubuntu. For more details see "
         "https://wiki.ubuntu.com/Security/Features#pie";
     ),
+    "review-break-fix": (
+        "This vulnerability automatically received break-fix commits entries "
+        "when it was added and needs to be reviewed."
+    ),
 }
 
 # Possible CVE priorities
diff --git a/lib/lp/bugs/scripts/tests/test_uct.py b/lib/lp/bugs/scripts/tests/test_uct.py
index 8ac253a..790f5fe 100644
--- a/lib/lp/bugs/scripts/tests/test_uct.py
+++ b/lib/lp/bugs/scripts/tests/test_uct.py
@@ -353,7 +353,7 @@ class TestCVE(TestCaseWithFactory):
                         ),
                     ],
                     priority=None,
-                    tags=set(),
+                    tags={"not-ue", "universe-binary"},
                     patches=[
                         UCTRecord.Patch(
                             patch_type="upstream",
@@ -420,11 +420,13 @@ class TestCVE(TestCaseWithFactory):
                     target=dsp1,
                     importance=None,
                     package_name=dsp1.sourcepackagename,
+                    tags={"not-ue", "universe-binary"},
                 ),
                 CVE.DistroPackage(
                     target=dsp2,
                     importance=BugTaskImportance.HIGH,
                     package_name=dsp2.sourcepackagename,
+                    tags=set(),
                 ),
             ],
             series_packages=[
@@ -673,11 +675,13 @@ class TestUCTImporterExporter(TestCaseWithFactory):
                     target=self.ubuntu_package,
                     importance=BugTaskImportance.LOW,
                     package_name=self.ubuntu_package.sourcepackagename,
+                    tags={"review-break-fix"},
                 ),
                 CVE.DistroPackage(
                     target=self.esm_package,
                     importance=None,
                     package_name=self.esm_package.sourcepackagename,
+                    tags={"universe-binary"},
                 ),
             ],
             series_packages=[
@@ -816,6 +820,8 @@ class TestUCTImporterExporter(TestCaseWithFactory):
 
         package_importances = {}
 
+        tags = set()
+
         for distro_package in cve.distro_packages:
             self.assertIn(distro_package.target, bug_tasks_by_target)
             t = bug_tasks_by_target[distro_package.target]
@@ -830,10 +836,16 @@ class TestUCTImporterExporter(TestCaseWithFactory):
             else:
                 expected_importance = package_importance
                 expected_status = BugTaskStatus.NEW
+
+            for tag in distro_package.tags:
+                tags.add(f"{distro_package.package_name.name}.{tag}")
+
             self.assertEqual(expected_importance, t.importance)
             self.assertEqual(expected_status, t.status)
             self.assertIsNone(t.status_explanation)
 
+        self.assertEqual(tags, set(bug.tags))
+
         for series_package in cve.series_packages:
             self.assertIn(series_package.target, bug_tasks_by_target)
             t = bug_tasks_by_target[series_package.target]
@@ -1002,6 +1014,7 @@ class TestUCTImporterExporter(TestCaseWithFactory):
                     target=affected_package,
                     importance=BugTaskImportance.LOW,
                     package_name=affected_package.sourcepackagename,
+                    tags={"universe-binary", "not-ue"},
                 ),
             ],
             series_packages=[
@@ -1097,6 +1110,7 @@ class TestUCTImporterExporter(TestCaseWithFactory):
                 target=package,
                 package_name=package.sourcepackagename,
                 importance=BugTaskImportance.HIGH,
+                tags={"review-break-fix"},
             )
         )
         cve.series_packages.append(
@@ -1169,6 +1183,7 @@ class TestUCTImporterExporter(TestCaseWithFactory):
                 target=new_dsp,
                 package_name=new_dsp.sourcepackagename,
                 importance=BugTaskImportance.HIGH,
+                tags={"not-ue"},
             )
         )
         cve.series_packages.append(
@@ -1298,6 +1313,17 @@ class TestUCTImporterExporter(TestCaseWithFactory):
         self.importer.update_bug(bug, cve, self.lp_cve)
         self.checkBug(bug, cve)
 
+    def test_update_distro_packages_tags(self):
+        bug = self.importer.create_bug(self.cve, self.lp_cve)
+        cve = self.cve
+
+        # Add new tags
+        cve.distro_packages[0].tags.add("test-tag")
+        cve.distro_packages[0].tags.add("another-test-tag")
+
+        self.importer.update_bug(bug, cve, self.lp_cve)
+        self.checkBug(bug, cve)
+
     def test_import_cve(self):
         self.importer.import_cve(self.cve)
         self.assertIsNotNone(
diff --git a/lib/lp/bugs/scripts/uct/models.py b/lib/lp/bugs/scripts/uct/models.py
index 66130f6..e607c5f 100644
--- a/lib/lp/bugs/scripts/uct/models.py
+++ b/lib/lp/bugs/scripts/uct/models.py
@@ -428,10 +428,14 @@ class CVE:
     Do not confuse this with `Cve` database model.
     """
 
+    # XXX enriqueesanchz 2025-04-21: We add tags to DistroPackage as we have
+    # only one DistroPackage per UCTRecord.Package, so we match
+    # UCTRecord.Package.tags with CVE.DistroPackage.tags
     class DistroPackage(NamedTuple):
         target: DistributionSourcePackage
         package_name: SourcePackageName
         importance: Optional[BugTaskImportance]
+        tags: Set[str]
 
     class SeriesPackage(NamedTuple):
         target: SourcePackage
@@ -597,6 +601,7 @@ class CVE:
                     ),
                     package_name=source_package_name,
                     importance=package_importance,
+                    tags=uct_package.tags,
                 )
                 if distro_package not in distro_packages:
                     distro_packages.append(distro_package)
@@ -740,7 +745,7 @@ class CVE:
                     if distro_package.importance
                     else None
                 ),
-                tags=set(),
+                tags=distro_package.tags,
                 patches=[],
             )
 
diff --git a/lib/lp/bugs/scripts/uct/uctexport.py b/lib/lp/bugs/scripts/uct/uctexport.py
index 37ad4c0..47b64a0 100644
--- a/lib/lp/bugs/scripts/uct/uctexport.py
+++ b/lib/lp/bugs/scripts/uct/uctexport.py
@@ -109,6 +109,10 @@ class UCTExporter:
 
         cve_importance = vulnerability.importance
 
+        tags_by_pkg = defaultdict(set)
+        for tag in bug.tags:
+            tags_by_pkg[tag.split(".")[0]].add(tag.split(".")[1])
+
         # When exporting, we shouldn't output the importance value if it
         # hasn't been specified in the original UCT file.
         # So, the following logic is used:
@@ -136,6 +140,11 @@ class UCTExporter:
                 package_name_by_product[product] = target.sourcepackagename
             dp_importance = bug_task.importance
             package_importances[target.sourcepackagename] = dp_importance
+
+            tags = set()
+            if tags_by_pkg[target.sourcepackagename.name]:
+                tags = tags.union(tags_by_pkg[target.sourcepackagename.name])
+
             distro_packages.append(
                 CVE.DistroPackage(
                     target=target,
@@ -145,6 +154,7 @@ class UCTExporter:
                         if dp_importance != cve_importance
                         else None
                     ),
+                    tags=tags,
                 )
             )
 
diff --git a/lib/lp/bugs/scripts/uct/uctimport.py b/lib/lp/bugs/scripts/uct/uctimport.py
index 76f3294..f006898 100644
--- a/lib/lp/bugs/scripts/uct/uctimport.py
+++ b/lib/lp/bugs/scripts/uct/uctimport.py
@@ -15,7 +15,7 @@ For each entry in UCT we:
 4. Update the statuses of Bug Tasks based on the information in the CVE entry
 5. Update the information the related Launchpad's `Cve` model, if necessary
 
-Three types of bug tags are created:
+Three types of bug tasks are created:
 
 1. Bug tasks with a distribution package as a target - they represent
    importance of the package
@@ -171,11 +171,13 @@ class UCTImporter:
                 target=distro_package.target,
                 importance=distro_package.importance,
                 cve=lp_cve,
+                tags=set(),
             )
         )
 
         self._update_external_bug_urls(bug, cve.bug_urls)
         self._update_patches(bug, cve.patch_urls)
+        self._update_distro_packages_tags(bug, cve.distro_packages)
 
         self._create_bug_tasks(
             bug,
@@ -233,6 +235,7 @@ class UCTImporter:
         self._assign_bug_tasks(bug, cve.assignee)
         self._update_external_bug_urls(bug, cve.bug_urls)
         self._update_patches(bug, cve.patch_urls)
+        self._update_distro_packages_tags(bug, cve.distro_packages)
 
         # Update or add new Vulnerabilities
         vulnerabilities_by_distro = {
@@ -245,6 +248,16 @@ class UCTImporter:
             else:
                 self._update_vulnerability(vulnerability, cve)
 
+    def _update_distro_packages_tags(
+        self, bug: BugModel, distro_packages: List
+    ):
+        tags = set()
+        for distro_package in distro_packages:
+            for tag in distro_package.tags:
+                tags.add(f"{distro_package.package_name.name}.{tag}")
+
+        bug.tags = tags
+
     def _find_existing_bug(
         self, cve: CVE, lp_cve: CveModel
     ) -> Optional[BugModel]: