Merge ~andrey-fedoseev/launchpad:uct-import-upstream-packaging-model into launchpad:master
- Git
- lp:~andrey-fedoseev/launchpad
- uct-import-upstream-packaging-model
- Merge into master
Proposed by
Andrey Fedoseev
Status: | Merged |
---|---|
Approved by: | Andrey Fedoseev |
Approved revision: | d4942b80229011a3192faaa8bc888e6666af328a |
Merge reported by: | Otto Co-Pilot |
Merged at revision: | not available |
Proposed branch: | ~andrey-fedoseev/launchpad:uct-import-upstream-packaging-model |
Merge into: | launchpad:master |
Diff against target: |
693 lines (+171/-103) 4 files modified
lib/lp/bugs/scripts/tests/test_uct.py (+80/-46) lib/lp/bugs/scripts/uct/models.py (+58/-36) lib/lp/bugs/scripts/uct/uctexport.py (+24/-4) lib/lp/bugs/scripts/uct/uctimport.py (+9/-17) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Colin Watson (community) | Approve | ||
Review via email: mp+429109@code.launchpad.net |
Commit message
UCT import: use `Packaging` model for `upstream`
Description of the change
Previously, we were trying to find an LP `Product` with exactly the same name as a package in UCT record to handle the status of `upstream`.
Now, we use the `Packaging` model to locate a `Product` by package name.
More specifically, we use the `DistributionSo
To post a comment you must log in.
Revision history for this message
Andrey Fedoseev (andrey-fedoseev) wrote : | # |
Colin,
I moved all changes related to Packaging security to https:/
Revision history for this message
Colin Watson (cjwatson) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/lib/lp/bugs/scripts/tests/test_uct.py b/lib/lp/bugs/scripts/tests/test_uct.py |
2 | index 71b1abb..9a1a2ce 100644 |
3 | --- a/lib/lp/bugs/scripts/tests/test_uct.py |
4 | +++ b/lib/lp/bugs/scripts/tests/test_uct.py |
5 | @@ -186,14 +186,17 @@ class TestCVE(TestCaseWithFactory): |
6 | status=SeriesStatus.DEVELOPMENT, |
7 | name="kinetic", |
8 | ) |
9 | - product_1 = self.factory.makeProduct() |
10 | - product_2 = self.factory.makeProduct() |
11 | - dsp1 = self.factory.makeDistributionSourcePackage( |
12 | - sourcepackagename=product_1.name, distribution=ubuntu |
13 | - ) |
14 | - dsp2 = self.factory.makeDistributionSourcePackage( |
15 | - sourcepackagename=product_2.name, distribution=ubuntu |
16 | - ) |
17 | + dsp1 = self.factory.makeDistributionSourcePackage(distribution=ubuntu) |
18 | + dsp2 = self.factory.makeDistributionSourcePackage(distribution=ubuntu) |
19 | + product_1 = self.factory.makePackagingLink( |
20 | + sourcepackagename=dsp1.sourcepackagename, |
21 | + distroseries=current_series, |
22 | + ).productseries.product |
23 | + product_2 = self.factory.makePackagingLink( |
24 | + sourcepackagename=dsp2.sourcepackagename, |
25 | + distroseries=current_series, |
26 | + ).productseries.product |
27 | + |
28 | assignee = self.factory.makePerson() |
29 | |
30 | self.uct_record = UCTRecord( |
31 | @@ -307,65 +310,73 @@ class TestCVE(TestCaseWithFactory): |
32 | ), |
33 | distro_packages=[ |
34 | CVE.DistroPackage( |
35 | - package=dsp1, |
36 | + target=dsp1, |
37 | importance=None, |
38 | + package_name=dsp1.sourcepackagename, |
39 | ), |
40 | CVE.DistroPackage( |
41 | - package=dsp2, |
42 | + target=dsp2, |
43 | importance=BugTaskImportance.HIGH, |
44 | + package_name=dsp2.sourcepackagename, |
45 | ), |
46 | ], |
47 | series_packages=[ |
48 | CVE.SeriesPackage( |
49 | - package=SourcePackage( |
50 | + target=SourcePackage( |
51 | sourcepackagename=dsp1.sourcepackagename, |
52 | distroseries=supported_series, |
53 | ), |
54 | + package_name=dsp1.sourcepackagename, |
55 | importance=BugTaskImportance.MEDIUM, |
56 | status=BugTaskStatus.INVALID, |
57 | status_explanation="reason 1", |
58 | ), |
59 | CVE.SeriesPackage( |
60 | - package=SourcePackage( |
61 | + target=SourcePackage( |
62 | sourcepackagename=dsp1.sourcepackagename, |
63 | distroseries=current_series, |
64 | ), |
65 | + package_name=dsp1.sourcepackagename, |
66 | importance=BugTaskImportance.MEDIUM, |
67 | status=BugTaskStatus.FIXRELEASED, |
68 | status_explanation="reason 2", |
69 | ), |
70 | CVE.SeriesPackage( |
71 | - package=SourcePackage( |
72 | + target=SourcePackage( |
73 | sourcepackagename=dsp1.sourcepackagename, |
74 | distroseries=devel_series, |
75 | ), |
76 | + package_name=dsp1.sourcepackagename, |
77 | importance=None, |
78 | status=BugTaskStatus.FIXRELEASED, |
79 | status_explanation="reason 3", |
80 | ), |
81 | CVE.SeriesPackage( |
82 | - package=SourcePackage( |
83 | + target=SourcePackage( |
84 | sourcepackagename=dsp2.sourcepackagename, |
85 | distroseries=supported_series, |
86 | ), |
87 | + package_name=dsp2.sourcepackagename, |
88 | importance=None, |
89 | status=BugTaskStatus.DOESNOTEXIST, |
90 | status_explanation="", |
91 | ), |
92 | CVE.SeriesPackage( |
93 | - package=SourcePackage( |
94 | + target=SourcePackage( |
95 | sourcepackagename=dsp2.sourcepackagename, |
96 | distroseries=current_series, |
97 | ), |
98 | + package_name=dsp2.sourcepackagename, |
99 | importance=None, |
100 | status=BugTaskStatus.DOESNOTEXIST, |
101 | status_explanation="", |
102 | ), |
103 | CVE.SeriesPackage( |
104 | - package=SourcePackage( |
105 | + target=SourcePackage( |
106 | sourcepackagename=dsp2.sourcepackagename, |
107 | distroseries=devel_series, |
108 | ), |
109 | + package_name=dsp2.sourcepackagename, |
110 | importance=None, |
111 | status=BugTaskStatus.FIXRELEASED, |
112 | status_explanation="", |
113 | @@ -373,13 +384,15 @@ class TestCVE(TestCaseWithFactory): |
114 | ], |
115 | upstream_packages=[ |
116 | CVE.UpstreamPackage( |
117 | - package=product_1, |
118 | + target=product_1, |
119 | + package_name=dsp1.sourcepackagename, |
120 | importance=None, |
121 | status=BugTaskStatus.FIXRELEASED, |
122 | status_explanation="reason 4", |
123 | ), |
124 | - CVE.SeriesPackage( |
125 | - package=product_2, |
126 | + CVE.UpstreamPackage( |
127 | + target=product_2, |
128 | + package_name=dsp2.sourcepackagename, |
129 | importance=None, |
130 | status=BugTaskStatus.FIXRELEASED, |
131 | status_explanation="", |
132 | @@ -450,14 +463,21 @@ class TestUCTImporterExporter(TestCaseWithFactory): |
133 | status=SeriesStatus.CURRENT, |
134 | name="trusty", |
135 | ) |
136 | - self.product_1 = self.factory.makeProduct() |
137 | - self.product_2 = self.factory.makeProduct() |
138 | self.ubuntu_package = self.factory.makeDistributionSourcePackage( |
139 | - sourcepackagename=self.product_1.name, distribution=self.ubuntu |
140 | + distribution=self.ubuntu |
141 | ) |
142 | self.esm_package = self.factory.makeDistributionSourcePackage( |
143 | - sourcepackagename=self.product_2.name, distribution=self.esm |
144 | + distribution=self.esm |
145 | ) |
146 | + self.product_1 = self.factory.makePackagingLink( |
147 | + sourcepackagename=self.ubuntu_package.sourcepackagename, |
148 | + distroseries=self.ubuntu_current_series, |
149 | + ).productseries.product |
150 | + self.product_2 = self.factory.makePackagingLink( |
151 | + sourcepackagename=self.esm_package.sourcepackagename, |
152 | + distroseries=self.esm_current_series, |
153 | + ).productseries.product |
154 | + |
155 | for series in ( |
156 | self.ubuntu_supported_series, |
157 | self.ubuntu_current_series, |
158 | @@ -493,56 +513,63 @@ class TestUCTImporterExporter(TestCaseWithFactory): |
159 | ), |
160 | distro_packages=[ |
161 | CVE.DistroPackage( |
162 | - package=self.ubuntu_package, |
163 | + target=self.ubuntu_package, |
164 | importance=BugTaskImportance.LOW, |
165 | + package_name=self.ubuntu_package.sourcepackagename, |
166 | ), |
167 | CVE.DistroPackage( |
168 | - package=self.esm_package, |
169 | + target=self.esm_package, |
170 | importance=None, |
171 | + package_name=self.esm_package.sourcepackagename, |
172 | ), |
173 | ], |
174 | series_packages=[ |
175 | CVE.SeriesPackage( |
176 | - package=SourcePackage( |
177 | + target=SourcePackage( |
178 | sourcepackagename=self.ubuntu_package.sourcepackagename, # noqa: E501 |
179 | distroseries=self.ubuntu_supported_series, |
180 | ), |
181 | + package_name=self.ubuntu_package.sourcepackagename, |
182 | importance=BugTaskImportance.HIGH, |
183 | status=BugTaskStatus.FIXRELEASED, |
184 | status_explanation="released", |
185 | ), |
186 | CVE.SeriesPackage( |
187 | - package=SourcePackage( |
188 | + target=SourcePackage( |
189 | sourcepackagename=self.ubuntu_package.sourcepackagename, # noqa: E501 |
190 | distroseries=self.ubuntu_current_series, |
191 | ), |
192 | + package_name=self.ubuntu_package.sourcepackagename, |
193 | importance=None, |
194 | status=BugTaskStatus.DOESNOTEXIST, |
195 | status_explanation="does not exist", |
196 | ), |
197 | CVE.SeriesPackage( |
198 | - package=SourcePackage( |
199 | + target=SourcePackage( |
200 | sourcepackagename=self.ubuntu_package.sourcepackagename, # noqa: E501 |
201 | distroseries=self.ubuntu_devel_series, |
202 | ), |
203 | + package_name=self.ubuntu_package.sourcepackagename, |
204 | importance=None, |
205 | status=BugTaskStatus.INVALID, |
206 | status_explanation="not affected", |
207 | ), |
208 | CVE.SeriesPackage( |
209 | - package=SourcePackage( |
210 | + target=SourcePackage( |
211 | sourcepackagename=self.esm_package.sourcepackagename, |
212 | distroseries=self.esm_supported_series, |
213 | ), |
214 | + package_name=self.esm_package.sourcepackagename, |
215 | importance=None, |
216 | status=BugTaskStatus.WONTFIX, |
217 | status_explanation="ignored", |
218 | ), |
219 | CVE.SeriesPackage( |
220 | - package=SourcePackage( |
221 | + target=SourcePackage( |
222 | sourcepackagename=self.esm_package.sourcepackagename, |
223 | distroseries=self.esm_current_series, |
224 | ), |
225 | + package_name=self.esm_package.sourcepackagename, |
226 | importance=None, |
227 | status=BugTaskStatus.UNKNOWN, |
228 | status_explanation="needs triage", |
229 | @@ -550,13 +577,15 @@ class TestUCTImporterExporter(TestCaseWithFactory): |
230 | ], |
231 | upstream_packages=[ |
232 | CVE.UpstreamPackage( |
233 | - package=self.product_1, |
234 | + target=self.product_1, |
235 | + package_name=self.ubuntu_package.sourcepackagename, |
236 | importance=BugTaskImportance.HIGH, |
237 | status=BugTaskStatus.FIXRELEASED, |
238 | status_explanation="fix released", |
239 | ), |
240 | CVE.UpstreamPackage( |
241 | - package=self.product_2, |
242 | + target=self.product_2, |
243 | + package_name=self.esm_package.sourcepackagename, |
244 | importance=BugTaskImportance.LOW, |
245 | status=BugTaskStatus.WONTFIX, |
246 | status_explanation="ignored", |
247 | @@ -615,11 +644,11 @@ class TestUCTImporterExporter(TestCaseWithFactory): |
248 | package_importances = {} |
249 | |
250 | for distro_package in cve.distro_packages: |
251 | - self.assertIn(distro_package.package, bug_tasks_by_target) |
252 | - t = bug_tasks_by_target[distro_package.package] |
253 | + self.assertIn(distro_package.target, bug_tasks_by_target) |
254 | + t = bug_tasks_by_target[distro_package.target] |
255 | package_importance = distro_package.importance or cve.importance |
256 | package_importances[ |
257 | - distro_package.package.sourcepackagename.name |
258 | + distro_package.target.sourcepackagename.name |
259 | ] = package_importance |
260 | conjoined_primary = t.conjoined_primary |
261 | if conjoined_primary: |
262 | @@ -633,10 +662,10 @@ class TestUCTImporterExporter(TestCaseWithFactory): |
263 | self.assertIsNone(t.status_explanation) |
264 | |
265 | for series_package in cve.series_packages: |
266 | - self.assertIn(series_package.package, bug_tasks_by_target) |
267 | - t = bug_tasks_by_target[series_package.package] |
268 | + self.assertIn(series_package.target, bug_tasks_by_target) |
269 | + t = bug_tasks_by_target[series_package.target] |
270 | package_importance = package_importances[ |
271 | - series_package.package.sourcepackagename.name |
272 | + series_package.target.sourcepackagename.name |
273 | ] |
274 | sp_importance = series_package.importance or package_importance |
275 | self.assertEqual(sp_importance, t.importance) |
276 | @@ -646,10 +675,10 @@ class TestUCTImporterExporter(TestCaseWithFactory): |
277 | ) |
278 | |
279 | for upstream_package in cve.upstream_packages: |
280 | - self.assertIn(upstream_package.package, bug_tasks_by_target) |
281 | - t = bug_tasks_by_target[upstream_package.package] |
282 | + self.assertIn(upstream_package.target, bug_tasks_by_target) |
283 | + t = bug_tasks_by_target[upstream_package.target] |
284 | package_importance = package_importances[ |
285 | - upstream_package.package.name |
286 | + upstream_package.package_name.name |
287 | ] |
288 | sp_importance = upstream_package.importance or package_importance |
289 | self.assertEqual(sp_importance, t.importance) |
290 | @@ -787,16 +816,18 @@ class TestUCTImporterExporter(TestCaseWithFactory): |
291 | |
292 | cve.distro_packages.append( |
293 | CVE.DistroPackage( |
294 | - package=package, |
295 | + target=package, |
296 | + package_name=package.sourcepackagename, |
297 | importance=BugTaskImportance.HIGH, |
298 | ) |
299 | ) |
300 | cve.series_packages.append( |
301 | CVE.SeriesPackage( |
302 | - package=SourcePackage( |
303 | + target=SourcePackage( |
304 | sourcepackagename=package.sourcepackagename, |
305 | distroseries=self.ubuntu_current_series, |
306 | ), |
307 | + package_name=package.sourcepackagename, |
308 | importance=BugTaskImportance.CRITICAL, |
309 | status=BugTaskStatus.FIXRELEASED, |
310 | status_explanation="fix released", |
311 | @@ -823,10 +854,11 @@ class TestUCTImporterExporter(TestCaseWithFactory): |
312 | |
313 | cve.series_packages.append( |
314 | CVE.SeriesPackage( |
315 | - package=SourcePackage( |
316 | + target=SourcePackage( |
317 | sourcepackagename=self.ubuntu_package.sourcepackagename, |
318 | distroseries=new_series, |
319 | ), |
320 | + package_name=self.ubuntu_package.sourcepackagename, |
321 | importance=BugTaskImportance.CRITICAL, |
322 | status=BugTaskStatus.FIXRELEASED, |
323 | status_explanation="fix released", |
324 | @@ -856,16 +888,18 @@ class TestUCTImporterExporter(TestCaseWithFactory): |
325 | |
326 | cve.distro_packages.append( |
327 | CVE.DistroPackage( |
328 | - package=new_dsp, |
329 | + target=new_dsp, |
330 | + package_name=new_dsp.sourcepackagename, |
331 | importance=BugTaskImportance.HIGH, |
332 | ) |
333 | ) |
334 | cve.series_packages.append( |
335 | CVE.SeriesPackage( |
336 | - package=SourcePackage( |
337 | + target=SourcePackage( |
338 | sourcepackagename=new_dsp.sourcepackagename, |
339 | distroseries=new_series, |
340 | ), |
341 | + package_name=new_dsp.sourcepackagename, |
342 | importance=BugTaskImportance.CRITICAL, |
343 | status=BugTaskStatus.FIXRELEASED, |
344 | status_explanation="fix released", |
345 | diff --git a/lib/lp/bugs/scripts/uct/models.py b/lib/lp/bugs/scripts/uct/models.py |
346 | index 4234fdd..b7b7f6e 100644 |
347 | --- a/lib/lp/bugs/scripts/uct/models.py |
348 | +++ b/lib/lp/bugs/scripts/uct/models.py |
349 | @@ -18,7 +18,6 @@ from lp.bugs.interfaces.bugtask import BugTaskImportance, BugTaskStatus |
350 | from lp.registry.interfaces.distribution import IDistributionSet |
351 | from lp.registry.interfaces.distroseries import IDistroSeriesSet |
352 | from lp.registry.interfaces.person import IPersonSet |
353 | -from lp.registry.interfaces.product import IProductSet |
354 | from lp.registry.interfaces.series import SeriesStatus |
355 | from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet |
356 | from lp.registry.model.distribution import Distribution |
357 | @@ -421,7 +420,8 @@ class CVE: |
358 | DistroPackage = NamedTuple( |
359 | "DistroPackage", |
360 | ( |
361 | - ("package", DistributionSourcePackage), |
362 | + ("target", DistributionSourcePackage), |
363 | + ("package_name", SourcePackageName), |
364 | ("importance", Optional[BugTaskImportance]), |
365 | ), |
366 | ) |
367 | @@ -429,7 +429,8 @@ class CVE: |
368 | SeriesPackage = NamedTuple( |
369 | "SeriesPackage", |
370 | ( |
371 | - ("package", SourcePackage), |
372 | + ("target", SourcePackage), |
373 | + ("package_name", SourcePackageName), |
374 | ("importance", Optional[BugTaskImportance]), |
375 | ("status", BugTaskStatus), |
376 | ("status_explanation", str), |
377 | @@ -439,7 +440,8 @@ class CVE: |
378 | UpstreamPackage = NamedTuple( |
379 | "UpstreamPackage", |
380 | ( |
381 | - ("package", Product), |
382 | + ("target", Product), |
383 | + ("package_name", SourcePackageName), |
384 | ("importance", Optional[BugTaskImportance]), |
385 | ("status", BugTaskStatus), |
386 | ("status_explanation", str), |
387 | @@ -530,10 +532,13 @@ class CVE: |
388 | |
389 | distro_packages = [] |
390 | series_packages = [] |
391 | - upstream_packages = [] |
392 | |
393 | spn_set = getUtility(ISourcePackageNameSet) |
394 | |
395 | + upstream_statuses = ( |
396 | + OrderedDict() |
397 | + ) # type: Dict[SourcePackageName, UCTRecord.SeriesPackageStatus] |
398 | + |
399 | for uct_package in uct_record.packages: |
400 | source_package_name = spn_set.getOrCreateByName(uct_package.name) |
401 | package_importance = ( |
402 | @@ -558,19 +563,7 @@ class CVE: |
403 | ) |
404 | |
405 | if uct_package_status.series == "upstream": |
406 | - product = cls.get_product(uct_package.name) |
407 | - if product is None: |
408 | - continue |
409 | - upstream_packages.append( |
410 | - cls.UpstreamPackage( |
411 | - package=product, |
412 | - importance=series_package_importance, |
413 | - status=cls.BUG_TASK_STATUS_MAP[ |
414 | - uct_package_status.status |
415 | - ], |
416 | - status_explanation=uct_package_status.reason, |
417 | - ) |
418 | - ) |
419 | + upstream_statuses[source_package_name] = uct_package_status |
420 | continue |
421 | |
422 | distro_series = cls.get_distro_series( |
423 | @@ -580,10 +573,11 @@ class CVE: |
424 | continue |
425 | |
426 | distro_package = cls.DistroPackage( |
427 | - package=DistributionSourcePackage( |
428 | + target=DistributionSourcePackage( |
429 | distribution=distro_series.distribution, |
430 | sourcepackagename=source_package_name, |
431 | ), |
432 | + package_name=source_package_name, |
433 | importance=package_importance, |
434 | ) |
435 | if distro_package not in distro_packages: |
436 | @@ -591,10 +585,11 @@ class CVE: |
437 | |
438 | series_packages.append( |
439 | cls.SeriesPackage( |
440 | - package=SourcePackage( |
441 | + target=SourcePackage( |
442 | sourcepackagename=source_package_name, |
443 | distroseries=distro_series, |
444 | ), |
445 | + package_name=source_package_name, |
446 | importance=series_package_importance, |
447 | status=cls.BUG_TASK_STATUS_MAP[ |
448 | uct_package_status.status |
449 | @@ -603,6 +598,40 @@ class CVE: |
450 | ) |
451 | ) |
452 | |
453 | + upstream_packages = [] |
454 | + for source_package_name, upstream_status in upstream_statuses.items(): |
455 | + for distro_package in distro_packages: |
456 | + if source_package_name != distro_package.package_name: |
457 | + continue |
458 | + # This is the `Product` corresponding to the package of this |
459 | + # name with the highest version across any of this |
460 | + # distribution's series that has a packaging link |
461 | + # (it can make a difference if a package name switches to a |
462 | + # different upstream project between series) |
463 | + product = distro_package.target.upstream_product |
464 | + if product is not None: |
465 | + break |
466 | + else: |
467 | + logger.warning( |
468 | + "Could not find the product for: %s", |
469 | + source_package_name.name, |
470 | + ) |
471 | + continue |
472 | + |
473 | + upstream_packages.append( |
474 | + cls.UpstreamPackage( |
475 | + target=product, |
476 | + package_name=source_package_name, |
477 | + importance=( |
478 | + cls.PRIORITY_MAP[upstream_status.priority] |
479 | + if upstream_status.priority |
480 | + else None |
481 | + ), |
482 | + status=cls.BUG_TASK_STATUS_MAP[upstream_status.status], |
483 | + status_explanation=upstream_status.reason, |
484 | + ) |
485 | + ) |
486 | + |
487 | if uct_record.assigned_to: |
488 | assignee = getUtility(IPersonSet).getByName(uct_record.assigned_to) |
489 | if not assignee: |
490 | @@ -643,25 +672,25 @@ class CVE: |
491 | list |
492 | ) # type: Dict[SourcePackageName, List[CVE.SeriesPackage]] |
493 | for series_package in self.series_packages: |
494 | - series_packages_by_name[ |
495 | - series_package.package.sourcepackagename |
496 | - ].append(series_package) |
497 | + series_packages_by_name[series_package.package_name].append( |
498 | + series_package |
499 | + ) |
500 | |
501 | packages_by_name = OrderedDict() # type: Dict[str, UCTRecord.Package] |
502 | processed_packages = set() # type: Set[SourcePackageName] |
503 | for distro_package in self.distro_packages: |
504 | - spn = distro_package.package.sourcepackagename |
505 | + spn = distro_package.package_name |
506 | if spn in processed_packages: |
507 | continue |
508 | processed_packages.add(spn) |
509 | statuses = [] # type: List[UCTRecord.SeriesPackageStatus] |
510 | for series_package in series_packages_by_name[spn]: |
511 | - series = series_package.package.distroseries |
512 | + series = series_package.target.distroseries |
513 | if series.status == SeriesStatus.DEVELOPMENT: |
514 | series_name = "devel" |
515 | else: |
516 | series_name = series.name |
517 | - distro_name = distro_package.package.distribution.name |
518 | + distro_name = distro_package.target.distribution.name |
519 | if distro_name != "ubuntu": |
520 | if distro_name == "ubuntu-esm": |
521 | distro_name = "esm" |
522 | @@ -708,7 +737,7 @@ class CVE: |
523 | else None |
524 | ), |
525 | ) |
526 | - package_name = upstream_package.package.name |
527 | + package_name = upstream_package.package_name.name |
528 | if package_name in packages_by_name: |
529 | packages_by_name[package_name].statuses.append(status) |
530 | else: |
531 | @@ -743,11 +772,11 @@ class CVE: |
532 | |
533 | @cachedproperty |
534 | def affected_distributions(self) -> Set[Distribution]: |
535 | - return {p.package.distribution for p in self.distro_packages} |
536 | + return {p.target.distribution for p in self.distro_packages} |
537 | |
538 | @cachedproperty |
539 | def affected_distro_series(self) -> Set[DistroSeries]: |
540 | - return {p.package.distroseries for p in self.series_packages} |
541 | + return {p.target.distroseries for p in self.series_packages} |
542 | |
543 | @classmethod |
544 | def infer_vulnerability_status( |
545 | @@ -797,10 +826,3 @@ class CVE: |
546 | "Could not find the distro series: %s", distro_series_name |
547 | ) |
548 | return distro_series |
549 | - |
550 | - @classmethod |
551 | - def get_product(cls, product_name: str) -> Optional[Product]: |
552 | - product = getUtility(IProductSet).getByName(product_name) |
553 | - if not product: |
554 | - logger.warning("Could not find the product: %s", product_name) |
555 | - return product |
556 | diff --git a/lib/lp/bugs/scripts/uct/uctexport.py b/lib/lp/bugs/scripts/uct/uctexport.py |
557 | index f14d994..65af0ef 100644 |
558 | --- a/lib/lp/bugs/scripts/uct/uctexport.py |
559 | +++ b/lib/lp/bugs/scripts/uct/uctexport.py |
560 | @@ -4,7 +4,7 @@ |
561 | import logging |
562 | from collections import defaultdict |
563 | from pathlib import Path |
564 | -from typing import List, NamedTuple, Optional |
565 | +from typing import Dict, List, NamedTuple, Optional |
566 | |
567 | from zope.component import getUtility |
568 | from zope.security.proxy import removeSecurityProxy |
569 | @@ -20,6 +20,7 @@ from lp.registry.model.distributionsourcepackage import ( |
570 | ) |
571 | from lp.registry.model.product import Product |
572 | from lp.registry.model.sourcepackage import SourcePackage |
573 | +from lp.registry.model.sourcepackagename import SourcePackageName |
574 | |
575 | __all__ = [ |
576 | "UCTExporter", |
577 | @@ -112,6 +113,7 @@ class UCTExporter: |
578 | # DistroPackage importance |
579 | package_importances = {} |
580 | |
581 | + package_name_by_product = {} # type: Dict[Product, SourcePackageName] |
582 | # We need to process all distribution package tasks before processing |
583 | # the distro-series tasks to collect importance value for each package. |
584 | distro_packages = [] |
585 | @@ -119,11 +121,20 @@ class UCTExporter: |
586 | target = removeSecurityProxy(bug_task.target) |
587 | if not isinstance(target, DistributionSourcePackage): |
588 | continue |
589 | + # This is the `Product` corresponding to the package of this |
590 | + # name with the highest version across any of this |
591 | + # distribution's series that has a packaging link |
592 | + # (it can make a difference if a package name switches to a |
593 | + # different upstream project between series) |
594 | + product = target.upstream_product |
595 | + if product: |
596 | + package_name_by_product[product] = target.sourcepackagename |
597 | dp_importance = bug_task.importance |
598 | package_importances[target.sourcepackagename] = dp_importance |
599 | distro_packages.append( |
600 | CVE.DistroPackage( |
601 | - package=target, |
602 | + target=target, |
603 | + package_name=target.sourcepackagename, |
604 | importance=( |
605 | dp_importance |
606 | if dp_importance != cve_importance |
607 | @@ -141,7 +152,8 @@ class UCTExporter: |
608 | package_importance = package_importances[target.sourcepackagename] |
609 | series_packages.append( |
610 | CVE.SeriesPackage( |
611 | - package=target, |
612 | + target=target, |
613 | + package_name=target.sourcepackagename, |
614 | importance=( |
615 | sp_importance |
616 | if sp_importance != package_importance |
617 | @@ -157,11 +169,19 @@ class UCTExporter: |
618 | target = removeSecurityProxy(bug_task.target) |
619 | if not isinstance(target, Product): |
620 | continue |
621 | + if target not in package_name_by_product: |
622 | + logger.warning( |
623 | + "Could not find a source package for product %s", |
624 | + target.name, |
625 | + ) |
626 | + continue |
627 | + package_name = package_name_by_product[target] |
628 | up_importance = bug_task.importance |
629 | package_importance = package_importances.get(target.name) |
630 | upstream_packages.append( |
631 | CVE.UpstreamPackage( |
632 | - package=target, |
633 | + target=target, |
634 | + package_name=package_name, |
635 | importance=( |
636 | up_importance |
637 | if up_importance != package_importance |
638 | diff --git a/lib/lp/bugs/scripts/uct/uctimport.py b/lib/lp/bugs/scripts/uct/uctimport.py |
639 | index 87d6b0d..ad6b53e 100644 |
640 | --- a/lib/lp/bugs/scripts/uct/uctimport.py |
641 | +++ b/lib/lp/bugs/scripts/uct/uctimport.py |
642 | @@ -156,7 +156,7 @@ class UCTImporter: |
643 | title=cve.sequence, |
644 | information_type=InformationType.PUBLICSECURITY, |
645 | owner=self.bug_importer, |
646 | - target=distro_package.package, |
647 | + target=distro_package.target, |
648 | importance=distro_package.importance, |
649 | cve=lp_cve, |
650 | ) |
651 | @@ -271,12 +271,11 @@ class UCTImporter: |
652 | bug_tasks = bug.bugtasks # type: List[BugTask] |
653 | bug_task_by_target = {t.target: t for t in bug_tasks} |
654 | bug_task_set = getUtility(IBugTaskSet) |
655 | - for target in ( |
656 | - p.package |
657 | - for p in chain(distro_packages, series_packages, upstream_packages) |
658 | + for package in chain( |
659 | + distro_packages, series_packages, upstream_packages |
660 | ): |
661 | - if target not in bug_task_by_target: |
662 | - bug_task_set.createTask(bug, self.bug_importer, target) |
663 | + if package.target not in bug_task_by_target: |
664 | + bug_task_set.createTask(bug, self.bug_importer, package.target) |
665 | |
666 | def _create_vulnerability( |
667 | self, |
668 | @@ -391,21 +390,14 @@ class UCTImporter: |
669 | package_importances = {} # type: Dict[str, BugTaskImportance] |
670 | |
671 | for dp in distro_packages: |
672 | - task = bug_task_by_target[dp.package] |
673 | + task = bug_task_by_target[dp.target] |
674 | dp_importance = dp.importance or cve_importance |
675 | - package_importances[ |
676 | - dp.package.sourcepackagename.name |
677 | - ] = dp_importance |
678 | + package_importances[dp.package_name.name] = dp_importance |
679 | task.transitionToImportance(dp_importance) |
680 | |
681 | for sp in chain(series_packages, upstream_packages): |
682 | - task = bug_task_by_target[sp.package] |
683 | - if isinstance(sp, CVE.SeriesPackage): |
684 | - package_name = sp.package.sourcepackagename.name |
685 | - elif isinstance(sp, CVE.UpstreamPackage): |
686 | - package_name = sp.package.name |
687 | - else: |
688 | - raise AssertionError() |
689 | + task = bug_task_by_target[sp.target] |
690 | + package_name = sp.package_name.name |
691 | package_importance = package_importances[package_name] |
692 | sp_importance = sp.importance or package_importance |
693 | task.transitionToImportance(sp_importance) |
Looks like the right path, but I think we need a few more fixes around `Packaging` security before we can land this - retrofitting reasonable security to something that has been historically more open is always fiddly!