Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding an option to use the rafs-based VDB image #167

Merged
merged 2 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 62 additions & 12 deletions depscan/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
import argparse
import json
import os
import shutil
import subprocess
import sys
import tarfile
import tempfile

import oras.client
Expand Down Expand Up @@ -37,6 +40,7 @@
license_data_dir,
spdx_license_list,
vdb_database_url,
vdb_rafs_database_url,
)
from depscan.lib.csaf import export_csaf, write_toml
from depscan.lib.license import build_license_data, bulk_lookup
Expand Down Expand Up @@ -465,6 +469,43 @@ def summarise(
return summary, vdr_file, pkg_vulnerabilities, pkg_group_rows


def download_rafs_based_image():
rafs_image_downloaded, paths_list = False, None
nydus_image_command = shutil.which("nydus-image", mode=os.X_OK)
if nydus_image_command is not None:
LOG.info(
"About to download the vulnerability database from %s. This might take a while ...",
vdb_rafs_database_url,
)

try:
oras_client = oras.client.OrasClient()
rafs_data_dir = tempfile.TemporaryDirectory()
paths_list = oras_client.pull(target=vdb_rafs_database_url, outdir=rafs_data_dir.name)

if os.path.exists(f'{rafs_data_dir.name}/data.rafs') and os.path.exists(f'{rafs_data_dir.name}/meta.rafs'):
nydus_download_command = f"{nydus_image_command} unpack --blob {rafs_data_dir.name}/data.rafs --output {data_dir}/vdb.tar --bootstrap {rafs_data_dir.name}/meta.rafs"
_ = subprocess.run(nydus_download_command.split(), check=True)
if os.path.exists(f'{data_dir}/vdb.tar'):
rafs_image_downloaded = True
with tarfile.open(f"{data_dir}/vdb.tar", 'r') as tar:
tar.extractall(path=data_dir)
os.remove(f"{data_dir}/vdb.tar")
else:
raise FileNotFoundError('vdb.tar not found')
else:
raise FileNotFoundError('data.rafs or meta.rafs not found')

except Exception as e:
LOG.info(f"Error: {e}")
LOG.info(
f"Unable to pull the vulnerability database (rafs image) from {vdb_rafs_database_url}. Trying to pull the non-rafs-based VDB image."
)
rafs_image_downloaded = False

return rafs_image_downloaded, data_dir


@app.get("/")
async def index():
"""
Expand All @@ -482,12 +523,18 @@ async def cache():
"""
db = db_lib.get()
if not db_lib.index_count(db["index_file"]):
oras_client = oras.client.OrasClient()
oras_client.pull(target=vdb_database_url, outdir=data_dir)
return {
"error": "false",
"message": "vulnerability database cached successfully",
}
rafs_image_downloaded, _ = download_rafs_based_image()
if not rafs_image_downloaded:
LOG.info(
"About to download the vulnerability database from %s. This might take a while ...",
vdb_database_url,
)
oras_client = oras.client.OrasClient()
oras_client.pull(target=vdb_database_url, outdir=data_dir)
return {
"error": "false",
"message": "vulnerability database cached successfully",
}
return {
"error": "false",
"message": "vulnerability database already exists",
Expand Down Expand Up @@ -826,12 +873,15 @@ def main():
except Exception:
pass
if run_cacher:
LOG.info(
"About to download the vulnerability database from %s. This might take a while ...",
vdb_database_url,
)
oras_client = oras.client.OrasClient()
paths_list = oras_client.pull(target=vdb_database_url, outdir=data_dir)
rafs_image_downloaded, paths_list = download_rafs_based_image()
if not rafs_image_downloaded:
LOG.info(
"About to download the vulnerability database from %s. This might take a while ...",
vdb_database_url,
)
oras_client = oras.client.OrasClient()
paths_list = oras_client.pull(target=vdb_database_url, outdir=data_dir)

LOG.debug("VDB data is stored at: %s", paths_list)
run_cacher = False
db = db_lib.get()
Expand Down
1 change: 1 addition & 0 deletions depscan/lib/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ def get_int_from_env(name, default):
pypi_server = "https://pypi.org/pypi"

vdb_database_url = "ghcr.io/appthreat/vdb:v5"
vdb_rafs_database_url = "ghcr.io/appthreat/vdb:v5-rafs"

# Package risk scoring using a simple weighted formula with no backing
# research All parameters and their max value and weight can be overridden
Expand Down