diff --git a/osbuild/sources.py b/osbuild/sources.py index 97f6a898..235cc0db 100644 --- a/osbuild/sources.py +++ b/osbuild/sources.py @@ -1,7 +1,59 @@ +import os +import importlib import json import subprocess + from . import api +from .objectstore import ObjectStore from .util import jsoncomm +from .util.types import PathLike + + +class Source: + """ + A single source with is corresponding options. + """ + def __init__(self, info, options) -> None: + self.info = info + self.options = options + + def download(self, store: ObjectStore, libdir: PathLike): + source = self.info.name + cache = os.path.join(store.store, "sources", source) + msg = { + "options": self.options, + "cache": cache, + "output": None, + "checksums": [], + "libdir": os.fspath(libdir) + } + + # We want the `osbuild` python package that contains this + # very module, which might be different from the system wide + # installed one, to be accessible to the Input programs so + # we detect our origin and set the `PYTHONPATH` accordingly + modorigin = importlib.util.find_spec("osbuild").origin + modpath = os.path.dirname(modorigin) + env = os.environ.copy() + env["PYTHONPATH"] = os.path.dirname(modpath) + + r = subprocess.run([self.info.path], + env=env, + input=json.dumps(msg), + stdout=subprocess.PIPE, + encoding="utf-8", + check=False) + + try: + reply = json.loads(r.stdout) + except ValueError: + raise RuntimeError(f"{source}: error: {r.stderr}") from None + + if "error" in reply: + raise RuntimeError(f"{source}: " + reply["error"]) + + if r.returncode != 0: + raise RuntimeError(f"{source}: error {r.returncode}") class SourcesServer(api.BaseAPI):