debian-forge/osbuild/sources.py
Christian Kellner 879c56a3b5 sources: pass items via temporary file
Since source were converted to host services it now uses a unix
socket instead of stdin to pass the arguments, which includes
the list of items to download. The latter can become quite big,
in fact too big to fit into a single package (NB: SOCK_SEQPACKET
is used for the underlying transport).
Therefore write the actual items to a temporary file and pass
the fd of it along the message.
2021-09-24 08:27:19 +01:00

67 lines
1.7 KiB
Python

import abc
import contextlib
import os
import json
import tempfile
from . import host
from .objectstore import ObjectStore
from .util.types import PathLike
class Source:
"""
A single source with is corresponding options.
"""
def __init__(self, info, items, options) -> None:
self.info = info
self.items = items or {}
self.options = options
def download(self, mgr: host.ServiceManager, store: ObjectStore, libdir: PathLike):
source = self.info.name
cache = os.path.join(store.store, "sources")
args = {
"options": self.options,
"cache": cache,
"output": None,
"checksums": [],
"libdir": os.fspath(libdir)
}
client = mgr.start(f"source/{source}", self.info.path)
with self.make_items_file(store.tmp) as fd:
fds = [fd]
reply = client.call_with_fds("download", args, fds)
return reply
@contextlib.contextmanager
def make_items_file(self, tmp):
with tempfile.TemporaryFile("w+", dir=tmp, encoding="utf-8") as f:
json.dump(self.items, f)
f.seek(0)
yield f.fileno()
class SourceService(host.Service):
"""Source host service"""
@abc.abstractmethod
def download(self, items, cache, options):
pass
def dispatch(self, method: str, args, fds):
if method == "download":
with os.fdopen(fds.steal(0)) as f:
items = json.load(f)
r = self.download(items,
args["cache"],
args["options"])
return r, None
raise host.ProtocolError("Unknown method")