inputs: introduce new input manager class

Introduce a new class to manage inputs, `InputManger` and move the
code to map inputs from the `Input` here. The main insight of why
the logic should be place here is that certain information is needed
to map inputs, independently of specific type: the path to the input
directory, `root`, the store API, `storeapi` and the service manager
instance to start the actual service. Instead of passing all this
information again and again to the `Input` class, we now have a
specialized (service) manager class for inputs that has all the
needed information all the time.
This commit is contained in:
Christian Kellner 2022-06-23 14:34:20 +02:00
parent 923cc60fdb
commit 7eb58ea348
2 changed files with 22 additions and 14 deletions

View file

@ -58,39 +58,46 @@ class Input:
m.update(json.dumps(self.options, sort_keys=True).encode()) m.update(json.dumps(self.options, sort_keys=True).encode())
return m.hexdigest() return m.hexdigest()
def map(self,
mgr: host.ServiceManager,
storeapi: StoreServer,
root: PathLike) -> Tuple[str, Dict]:
target = os.path.join(root, self.name) class InputManager:
def __init__(self, mgr: host.ServiceManager, storeapi: StoreServer, root: PathLike) -> Dict:
self.service_manager = mgr
self.storeapi = storeapi
self.root = root
self.inputs = {}
def map(self, ip: Input) -> Tuple[str, Dict]:
target = os.path.join(self.root, ip.name)
os.makedirs(target) os.makedirs(target)
args = { args = {
# mandatory bits # mandatory bits
"origin": self.origin, "origin": ip.origin,
"refs": self.refs, "refs": ip.refs,
"target": target, "target": target,
# global options # global options
"options": self.options, "options": ip.options,
# API endpoints # API endpoints
"api": { "api": {
"store": storeapi.socket_address "store": self.storeapi.socket_address
} }
} }
client = mgr.start(f"input/{self.name}", self.info.path) client = self.service_manager.start(f"input/{ip.name}", ip.info.path)
reply = client.call("map", args) reply = client.call("map", args)
path = reply["path"] path = reply["path"]
if not path.startswith(root): if not path.startswith(self.root):
raise RuntimeError(f"returned {path} has wrong prefix") raise RuntimeError(f"returned {path} has wrong prefix")
reply["path"] = os.path.relpath(path, root) reply["path"] = os.path.relpath(path, self.root)
self.inputs[ip.name] = reply
return reply return reply

View file

@ -11,7 +11,7 @@ from . import host
from . import objectstore from . import objectstore
from . import remoteloop from . import remoteloop
from .devices import Device, DeviceManager from .devices import Device, DeviceManager
from .inputs import Input from .inputs import Input, InputManager
from .mounts import Mount, MountManager from .mounts import Mount, MountManager
from .sources import Source from .sources import Source
from .util import osrelease from .util import osrelease
@ -203,8 +203,9 @@ class Stage:
mgr = host.ServiceManager(monitor=monitor) mgr = host.ServiceManager(monitor=monitor)
cm.enter_context(mgr) cm.enter_context(mgr)
ipmgr = InputManager(mgr, storeapi, inputs_tmpdir)
for key, ip in self.inputs.items(): for key, ip in self.inputs.items():
data = ip.map(mgr, storeapi, inputs_tmpdir) data = ipmgr.map(ip)
inputs[key] = data inputs[key] = data
devmgr = DeviceManager(mgr, build_root.dev, tree) devmgr = DeviceManager(mgr, build_root.dev, tree)