|
7 | 7 | # See https://aboutcode.org for more information about nexB OSS projects. |
8 | 8 | # |
9 | 9 | from aboutcode.pipeline import LoopProgress |
| 10 | +from django.db.models import Max |
10 | 11 | from django.db.models import Prefetch |
11 | 12 |
|
12 | 13 | from vulnerabilities.models import AdvisoryExploit |
|
15 | 16 | from vulnerabilities.models import AdvisoryV2 |
16 | 17 | from vulnerabilities.models import PackageV2 |
17 | 18 | from vulnerabilities.pipelines import VulnerableCodePipeline |
18 | | -from vulnerabilities.risk import compute_package_risk_v2 |
19 | 19 | from vulnerabilities.risk import compute_vulnerability_risk_factors |
20 | 20 |
|
21 | 21 |
|
@@ -130,45 +130,47 @@ def compute_and_store_vulnerability_risk_score(self): |
130 | 130 | ) |
131 | 131 |
|
132 | 132 | def compute_and_store_package_risk_score(self): |
133 | | - affected_packages = (PackageV2.objects.filter(affected_in_impacts__isnull=False)).distinct() |
| 133 | + qs = ( |
| 134 | + PackageV2.objects.filter(affected_in_impacts__advisory__risk_score__isnull=False) |
| 135 | + .annotate(computed_risk=Max("affected_in_impacts__advisory__risk_score")) |
| 136 | + .only("id") |
| 137 | + ) |
134 | 138 |
|
135 | | - self.log(f"Calculating risk for {affected_packages.count():,d} affected package records") |
| 139 | + estimated = qs.count() |
136 | 140 |
|
137 | 141 | progress = LoopProgress( |
138 | | - total_iterations=affected_packages.count(), |
| 142 | + total_iterations=estimated, |
139 | 143 | logger=self.log, |
140 | 144 | progress_step=5, |
141 | 145 | ) |
142 | 146 |
|
143 | | - updatables = [] |
144 | | - updated_package_count = 0 |
145 | | - batch_size = 1000 |
| 147 | + self.log(f"Computing risk for {estimated:,d} packages") |
146 | 148 |
|
147 | | - for package in progress.iter(affected_packages.iterator(chunk_size=batch_size)): |
148 | | - try: |
149 | | - risk_score = compute_package_risk_v2(package) |
150 | | - if not risk_score: |
151 | | - continue |
152 | | - package.risk_score = risk_score |
153 | | - updatables.append(package) |
154 | | - except Exception as e: |
155 | | - self.log(f"Error computing risk score for package {package.purl}: {e}") |
156 | | - continue |
| 149 | + batch = [] |
| 150 | + batch_size = 5000 |
| 151 | + updated = 0 |
157 | 152 |
|
158 | | - if len(updatables) >= batch_size: |
159 | | - updated_package_count += bulk_update( |
| 153 | + for pkg in progress.iter(qs.iterator(chunk_size=batch_size)): |
| 154 | + |
| 155 | + pkg.risk_score = round(float(pkg.computed_risk), 1) |
| 156 | + batch.append(pkg) |
| 157 | + |
| 158 | + if len(batch) >= batch_size: |
| 159 | + updated += bulk_update( |
160 | 160 | model=PackageV2, |
161 | | - items=updatables, |
| 161 | + items=batch, |
162 | 162 | fields=["risk_score"], |
163 | 163 | logger=self.log, |
164 | 164 | ) |
165 | | - updated_package_count += bulk_update( |
| 165 | + batch.clear() |
| 166 | + |
| 167 | + updated += bulk_update( |
166 | 168 | model=PackageV2, |
167 | | - items=updatables, |
| 169 | + items=batch, |
168 | 170 | fields=["risk_score"], |
169 | 171 | logger=self.log, |
170 | 172 | ) |
171 | | - self.log(f"Successfully added risk score for {updated_package_count:,d} package") |
| 173 | + self.log(f"Successfully added risk score for {updated:,d} package") |
172 | 174 |
|
173 | 175 |
|
174 | 176 | def bulk_update(model, items, fields, logger): |
|
0 commit comments