|
13 | 13 | from django.conf import settings |
14 | 14 | from django.db.models import Avg |
15 | 15 |
|
16 | | -from shared.channels import NixEvaluationChannel |
| 16 | +from shared.channels import NixEvaluationChannel, NixEvaluationCompleteChannel |
17 | 17 | from shared.evaluation import ( |
18 | 18 | SyncBatchAttributeIngester, |
19 | 19 | parse_evaluation_result, |
20 | 20 | ) |
21 | 21 | from shared.git import GitRepo |
22 | 22 | from shared.models import NixDerivation, NixEvaluation |
| 23 | +from shared.models.linkage import DerivationClusterProposalLink |
23 | 24 |
|
24 | 25 | logger = logging.getLogger(__name__) |
25 | 26 |
|
@@ -240,6 +241,14 @@ async def evaluation_entrypoint( |
240 | 241 | state=NixEvaluation.EvaluationState.COMPLETED, |
241 | 242 | elapsed=elapsed, |
242 | 243 | ) |
| 244 | + |
| 245 | + # Notify that we have a new evaluation ready and |
| 246 | + # any listeners should now proceed to an global update of old derivations |
| 247 | + # via attribute path. |
| 248 | + pgpubsub.notify( |
| 249 | + 'shared.channels.NixEvaluationCompleteChannel', |
| 250 | + model_id=evaluation.pk, |
| 251 | + ) |
243 | 252 | except Exception as e: |
244 | 253 | elapsed = time.time() - start |
245 | 254 | logger.exception( |
@@ -279,3 +288,29 @@ def run_evaluation_job(old: NixEvaluation, new: NixEvaluation) -> None: |
279 | 288 | new, |
280 | 289 | ) |
281 | 290 | ) |
| 291 | + |
| 292 | +def swap_derivations_based_on_attrpath(derivation_ids: list[int]): |
| 293 | + new_derivation_id_subquery = """ |
| 294 | + SELECT new_derivation.id |
| 295 | + FROM shared_nixderivation AS old_derivation |
| 296 | + JOIN shared_nixderivation AS new_derivation |
| 297 | + ON old_derivation.attribute = new_derivation.attribute |
| 298 | + WHERE |
| 299 | + DerivationClusterProposalLink.derivation_id = old_derivation.id |
| 300 | + AND new_derivation.parent_evaluation_id = %s |
| 301 | + """ |
| 302 | + |
| 303 | + |
| 304 | +@pgpubsub.listener(NixEvaluationCompleteChannel) |
| 305 | +def run_attribute_tracking_job(evaluation_id: int) -> None: |
| 306 | + # Our objective is to update: |
| 307 | + # - pending suggestions |
| 308 | + # - accepted suggestions |
| 309 | + # TODO: in the future, we should not update "mitigated" issues so we can easily revisit _which_ derivation was the last one. |
| 310 | + |
| 311 | + for proposal in CVEDerivationClusterProposal.objects.filter(status__in=(CVEDerivationClusterProposal.Status.PENDING, CVEDerivationClusterProposal.ACCEPTED)).iterator(): |
| 312 | + # Update all proposal |
| 313 | + swap_derivations_based_on_attrpath() |
| 314 | + |
| 315 | + # TODO: Update all cached variants as well. |
| 316 | + |
0 commit comments