Skip to content

Commit 56eb442

Browse files
authored
Merge pull request #1739 from aboutcode-org/fix-alpine-purl
Use proper apk package type for Alpine
2 parents 47063de + 411ae70 commit 56eb442

File tree

11 files changed

+232
-102
lines changed

11 files changed

+232
-102
lines changed

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ else
4242
SUDO_POSTGRES=
4343
endif
4444

45+
ifeq ($(UNAME), Darwin)
46+
GET_SECRET_KEY=`head /dev/urandom | base64 | head -c50`
47+
endif
48+
4549
virtualenv:
4650
@echo "-> Bootstrap the virtualenv with PYTHON_EXE=${PYTHON_EXE}"
4751
@${PYTHON_EXE} ${VIRTUALENV_PYZ} --never-download --no-periodic-update ${VENV}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
from datetime import datetime
2+
from datetime import timezone
3+
4+
from aboutcode.pipeline import LoopProgress
5+
from django.db import migrations
6+
from packageurl import PackageURL
7+
8+
CHUNK_SIZE = 50000
9+
BATCH_SIZE = 500
10+
11+
12+
class Migration(migrations.Migration):
13+
def fix_alpine_purl_type(apps, schema_editor):
14+
"""Use proper apk package type for Alpine"""
15+
16+
Package = apps.get_model("vulnerabilities", "Package")
17+
batch = []
18+
alpine_packages_query = Package.objects.filter(type="alpine")
19+
20+
log(f"\nFixing PURL for {alpine_packages_query.count():,d} alpine packages")
21+
progress = LoopProgress(
22+
total_iterations=alpine_packages_query.count(),
23+
progress_step=10,
24+
logger=log,
25+
)
26+
for package in progress.iter(alpine_packages_query.iterator(chunk_size=CHUNK_SIZE)):
27+
package.type = "apk"
28+
package.namespace = "alpine"
29+
30+
package.package_url = update_alpine_purl(package.package_url, "apk", "alpine")
31+
package.plain_package_url = update_alpine_purl(
32+
package.plain_package_url, "apk", "alpine"
33+
)
34+
35+
batch.append(package)
36+
if len(batch) >= BATCH_SIZE:
37+
bulk_update_package(Package, batch)
38+
batch.clear()
39+
40+
bulk_update_package(Package, batch)
41+
42+
def reverse_fix_alpine_purl_type(apps, schema_editor):
43+
Package = apps.get_model("vulnerabilities", "Package")
44+
batch = []
45+
alpine_packages_query = Package.objects.filter(type="apk", namespace="alpine")
46+
47+
log(f"\nREVERSE: Fix for {alpine_packages_query.count():,d} alpine packages")
48+
progress = LoopProgress(
49+
total_iterations=alpine_packages_query.count(),
50+
progress_step=10,
51+
logger=log,
52+
)
53+
for package in progress.iter(alpine_packages_query.iterator(chunk_size=CHUNK_SIZE)):
54+
package.type = "alpine"
55+
package.namespace = ""
56+
57+
package.package_url = update_alpine_purl(package.package_url, "alpine", "")
58+
package.plain_package_url = update_alpine_purl(package.plain_package_url, "alpine", "")
59+
60+
batch.append(package)
61+
if len(batch) >= BATCH_SIZE:
62+
bulk_update_package(Package, batch)
63+
batch.clear()
64+
65+
bulk_update_package(Package, batch)
66+
67+
dependencies = [
68+
("vulnerabilities", "0087_update_alpine_advisory_created_by"),
69+
]
70+
71+
operations = [
72+
migrations.RunPython(
73+
code=fix_alpine_purl_type,
74+
reverse_code=reverse_fix_alpine_purl_type,
75+
),
76+
]
77+
78+
79+
def bulk_update_package(package, batch):
80+
if batch:
81+
package.objects.bulk_update(
82+
objs=batch,
83+
fields=[
84+
"type",
85+
"namespace",
86+
"package_url",
87+
"plain_package_url",
88+
],
89+
)
90+
91+
92+
def update_alpine_purl(purl, purl_type, purl_namespace):
93+
package_url = PackageURL.from_string(purl).to_dict()
94+
package_url["type"] = purl_type
95+
package_url["namespace"] = purl_namespace
96+
return str(PackageURL(**package_url))
97+
98+
99+
def log(message):
100+
now_local = datetime.now(timezone.utc).astimezone()
101+
timestamp = now_local.strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
102+
message = f"{timestamp} {message}"
103+
print(message)

vulnerabilities/models.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@
1010
import hashlib
1111
import json
1212
import logging
13-
import typing
1413
from contextlib import suppress
1514
from functools import cached_property
16-
from typing import Optional
1715
from typing import Union
1816

1917
from cwe2.database import Database
@@ -56,7 +54,7 @@
5654
models.CharField.register_lookup(Trim)
5755

5856
# patch univers for missing entry
59-
RANGE_CLASS_BY_SCHEMES["alpine"] = AlpineLinuxVersionRange
57+
RANGE_CLASS_BY_SCHEMES["apk"] = AlpineLinuxVersionRange
6058

6159

6260
class BaseQuerySet(models.QuerySet):

vulnerabilities/pipelines/alpine_linux_importer.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,8 @@ def load_advisories(
254254
affected_packages.append(
255255
AffectedPackage(
256256
package=PackageURL(
257-
type="alpine",
257+
type="apk",
258+
namespace="alpine",
258259
name=pkg_infos["name"],
259260
qualifiers=qualifiers,
260261
),
@@ -266,7 +267,8 @@ def load_advisories(
266267
affected_packages.append(
267268
AffectedPackage(
268269
package=PackageURL(
269-
type="alpine",
270+
type="apk",
271+
namespace="alpine",
270272
name=pkg_infos["name"],
271273
qualifiers=qualifiers,
272274
),

0 commit comments

Comments
 (0)