Skip to content

Commit ecd6947

Browse files
committed
feat(download): add plugin functionality for resolvers
Add the option to use plugins for resolving download location of packages. Signed-off-by: Christoph Steiger <[email protected]>
1 parent d0b771f commit ecd6947

File tree

5 files changed

+64
-1
lines changed

5 files changed

+64
-1
lines changed

docs/source/api.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ Package Downloader
2828
.. automodule:: debsbom.download.download
2929
:members:
3030

31+
.. _package-resolving-label:
32+
3133
Package Resolving
3234
-----------------
3335

docs/source/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ debsbom documentation
99
design-decisions
1010
commands
1111
examples
12+
plugins
1213
api
1314

1415
Indices and tables

docs/source/plugins.rst

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
Plugins
2+
=======
3+
4+
``debsbom`` provides plugin capability for select functionality.
5+
6+
Resolver Plugin
7+
---------------
8+
9+
In the ``download`` command ``debsbom`` is downloading packages described by an SBOM. For this it needs to resolve from the package to a download location. What resolver to use can be controlled by the ``--resolver`` flag. ``debsbom`` per default provides a resolver for the Debian snapshot mirror (snapshot.debian.org).
10+
11+
Builders of custom Debian distributions might have different repositories where packages can be downloaded from. Some of these solutions might not be publicly available, or its implementation not relevant for the general public for some other reason. In these cases code for a resolver for these repositories should not land in ``debsbom`` proper, but we still want to give the option to use it as a fully integrated part of ``debsbom``.
12+
13+
A resolver plugin provides an additional choice for the ``--resolver`` option, which can be selected in the CLI once the plugin is loaded.
14+
15+
Implementing a Resolver Plugin
16+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17+
18+
Plugin discovery happens by entry points. ``debsbom`` specifically looks for the ``debsbom.download.resolver`` entry point. The name of the entry point is the name of the resolver, and its content is a setup function for a resolver. The signature of the setup function looks like this:
19+
20+
.. code-block:: python
21+
22+
from request import Session
23+
from debsbom.download.plugin import Resolver
24+
25+
def setup_resolver(session: Session) -> Resolver
26+
pass
27+
28+
The passed in ``request.Session`` is later used by ``debsbom`` to download the packages. It is not required to use it, but consider reusing it instead of opening a new session.
29+
30+
The resolver itself needs to inherit from the ``Resolver`` class. See the documentation here: :ref:`package-resolving-label`. The important part here is implementing the ``resolve`` function, which takes a package representation and returns a list of ``RemoteFile``, the locations from where files associated with the package can be downloaded. A minimal implementation could look like this:
31+
32+
.. code-block:: python
33+
34+
from request import Session
35+
from debsbom.download.plugin import Package, RemoteFile, Resolver, ResolveError
36+
37+
class MyResolver(Resolver):
38+
39+
def resolve(self, pkg: Package) -> list[RemoteFile]:
40+
try:
41+
my_remotefile = get_remotefile(pkg)
42+
except Exception as e:
43+
raise ResolveError
44+
return my_remotefile
45+
46+
All functionality required for implementing a plugin is exposed in the ``debsbom.download.plugin`` module.
47+
48+
A full example implementation can be found in the ``debsbom_plugin_examples`` repository, which is kept up to date for all releases: TODO

src/debsbom/commands/download.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
#
33
# SPDX-License-Identifier: MIT
44

5-
from importlib.metadata import version
5+
from importlib.metadata import entry_points, version
6+
67
from io import BytesIO
78
import logging
89
from pathlib import Path
@@ -35,6 +36,11 @@ def setup_snapshot_resolver(session: requests.Session):
3536

3637
RESOLVERS = {"debian-snapshot": setup_snapshot_resolver}
3738

39+
resolver_endpoints = entry_points(group="debsbom.download.resolver")
40+
for ep in resolver_endpoints:
41+
setup_fn = ep.load()
42+
RESOLVERS[ep.name] = setup_fn
43+
3844

3945
class DownloadCmd(SbomInput, PkgStreamInput):
4046
"""

src/debsbom/download/plugin.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Copyright (C) 2025 Siemens
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
from .resolver import RemoteFile, ResolveError, Resolver
6+
from ..dpkg.package import Package

0 commit comments

Comments
 (0)