devices: introduce new device manager class
Introduce a new class to manage devices, `DeviceManger` and move the code to open devices from the `Device` here. The main insight of why the logic should be place here is that certain information is needed to open the devices, independently of specific type: the path to the device node directory, `devpath`, the actual `tree` and the service manager instance to start the actual service. Instead of passing all this information again and again to the `Device` class, we now have a specialized (service) manager class for devices that has all the needed information all the time. Additionally, the special handling of parent devices is moved from the pipeline to the service manager, which is where it belongs. This will make even more sense for mounts, where the `DeviceManger` can then be passed to access the individual devices. Port the test to use the `DeviceManager`.
This commit is contained in:
parent
94d8fb1ff7
commit
a5e07cf506
3 changed files with 33 additions and 13 deletions
|
|
@ -44,21 +44,43 @@ class Device:
|
|||
m.update(json.dumps(self.options, sort_keys=True).encode())
|
||||
return m.hexdigest()
|
||||
|
||||
def open(self, mgr: host.ServiceManager, dev: str, parent: str, tree: str) -> Dict:
|
||||
|
||||
class DeviceManager:
|
||||
"""Manager for Devices
|
||||
|
||||
Uses a `host.ServiceManager` to open `Device` instances.
|
||||
"""
|
||||
|
||||
def __init__(self, mgr: host.ServiceManager, devpath: str, tree: str) -> Dict:
|
||||
self.service_manager = mgr
|
||||
self.devpath = devpath
|
||||
self.tree = tree
|
||||
self.devices = {}
|
||||
|
||||
def open(self, dev: Device) -> Dict:
|
||||
|
||||
if dev.parent:
|
||||
parent = self.devices[dev.parent.name]["path"]
|
||||
else:
|
||||
parent = None
|
||||
|
||||
args = {
|
||||
# global options
|
||||
"dev": dev,
|
||||
"tree": tree,
|
||||
"dev": self.devpath,
|
||||
"tree": self.tree,
|
||||
|
||||
"parent": parent,
|
||||
|
||||
# per device options
|
||||
"options": self.options,
|
||||
"options": dev.options,
|
||||
}
|
||||
|
||||
client = mgr.start(f"device/{self.name}", self.info.path)
|
||||
mgr = self.service_manager
|
||||
|
||||
client = mgr.start(f"device/{dev.name}", dev.info.path)
|
||||
res = client.call("open", args)
|
||||
|
||||
self.devices[dev.name] = res
|
||||
return res
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ from . import buildroot
|
|||
from . import host
|
||||
from . import objectstore
|
||||
from . import remoteloop
|
||||
from .devices import Device
|
||||
from .devices import Device, DeviceManager
|
||||
from .inputs import Input
|
||||
from .mounts import Mount
|
||||
from .sources import Source
|
||||
|
|
@ -164,12 +164,9 @@ class Stage:
|
|||
data = ip.map(mgr, storeapi, inputs_tmpdir)
|
||||
inputs[key] = data
|
||||
|
||||
for key, dev in self.devices.items():
|
||||
parent = None
|
||||
if dev.parent:
|
||||
parent = devices[dev.parent.name]["path"]
|
||||
reply = dev.open(mgr, build_root.dev, parent, tree)
|
||||
devices[key] = reply
|
||||
devmgr = DeviceManager(mgr, build_root.dev, tree)
|
||||
for name, dev in self.devices.items():
|
||||
devices[name] = devmgr.open(dev)
|
||||
|
||||
for key, mount in self.mounts.items():
|
||||
relpath = devices[mount.device.name]["path"]
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ def test_loopback_basic(tmpdir):
|
|||
dev = devices.Device("loop", info, None, options)
|
||||
|
||||
with host.ServiceManager() as mgr:
|
||||
reply = dev.open(mgr, devpath, None, tree)
|
||||
devmgr = devices.DeviceManager(mgr, devpath, tree)
|
||||
reply = devmgr.open(dev)
|
||||
assert reply
|
||||
assert reply["path"]
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue