diff --git a/docs/source/api-reference/drivers/proxy.yaml b/docs/source/api-reference/drivers/proxy.yaml index 9fbc88fa2..34e5d6e0f 100644 --- a/docs/source/api-reference/drivers/proxy.yaml +++ b/docs/source/api-reference/drivers/proxy.yaml @@ -1,9 +1,6 @@ -children: - proxy: - ref: "foo.bar.power" - foo: - children: - bar: - children: - power: - type: "jumpstarter_driver_power.driver.MockPower" +proxy: + ref: "foo.bar.power" +foo: + bar: + power: + type: "jumpstarter_driver_power.driver.MockPower" diff --git a/packages/jumpstarter/jumpstarter/config/exporter.py b/packages/jumpstarter/jumpstarter/config/exporter.py index eeaee3674..5aa55c0d1 100644 --- a/packages/jumpstarter/jumpstarter/config/exporter.py +++ b/packages/jumpstarter/jumpstarter/config/exporter.py @@ -22,7 +22,11 @@ class ExporterConfigV1Alpha1DriverInstanceProxy(BaseModel): class ExporterConfigV1Alpha1DriverInstanceComposite(BaseModel): - children: dict[str, ExporterConfigV1Alpha1DriverInstance] = Field(default_factory=dict) + children: dict[str, ExporterConfigV1Alpha1DriverInstance] + + +class ExporterConfigV1Alpha1DriverInstanceCompositeSimplified(RootModel): + root: dict[str, ExporterConfigV1Alpha1DriverInstance] class ExporterConfigV1Alpha1DriverInstanceBase(BaseModel): @@ -34,6 +38,7 @@ class ExporterConfigV1Alpha1DriverInstance(RootModel): root: ( ExporterConfigV1Alpha1DriverInstanceBase | ExporterConfigV1Alpha1DriverInstanceComposite + | ExporterConfigV1Alpha1DriverInstanceCompositeSimplified | ExporterConfigV1Alpha1DriverInstanceProxy ) @@ -51,6 +56,13 @@ def instantiate(self) -> Driver: return Composite(children=children) + case ExporterConfigV1Alpha1DriverInstanceCompositeSimplified(): + from jumpstarter_driver_composite.driver import Composite + + children = {name: child.instantiate() for name, child in self.root.root.items()} + + return Composite(children=children) + case ExporterConfigV1Alpha1DriverInstanceProxy(): from jumpstarter_driver_composite.driver import Proxy @@ -79,7 +91,9 @@ class ExporterConfigV1Alpha1(BaseModel): tls: TLSConfigV1Alpha1 = Field(default_factory=TLSConfigV1Alpha1) token: str - export: dict[str, ExporterConfigV1Alpha1DriverInstance] = Field(default_factory=dict) + export: ExporterConfigV1Alpha1DriverInstance = Field( + default_factory=lambda: ExporterConfigV1Alpha1DriverInstance({}) + ) path: Path | None = Field(default=None, exclude=True) @@ -137,7 +151,7 @@ async def serve_unix_async(self): from jumpstarter.exporter import Session with Session( - root_device=ExporterConfigV1Alpha1DriverInstance(children=self.export).instantiate(), + root_device=self.export.instantiate(), ) as session: async with session.serve_unix_async() as path: yield path @@ -161,7 +175,7 @@ def channel_factory(): async with Exporter( channel_factory=channel_factory, - device_factory=ExporterConfigV1Alpha1DriverInstance(children=self.export).instantiate, + device_factory=self.export.instantiate, tls=self.tls, ) as exporter: await exporter.serve() diff --git a/packages/jumpstarter/jumpstarter/config/exporter_test.py b/packages/jumpstarter/jumpstarter/config/exporter_test.py index 17349b217..13eb92f67 100644 --- a/packages/jumpstarter/jumpstarter/config/exporter_test.py +++ b/packages/jumpstarter/jumpstarter/config/exporter_test.py @@ -26,15 +26,13 @@ async def test_exporter_serve(mock_controller): type="jumpstarter_driver_power.driver.MockPower", ), "nested": ExporterConfigV1Alpha1DriverInstance( - children={ - "tcp": ExporterConfigV1Alpha1DriverInstance( - type="jumpstarter_driver_network.driver.TcpNetwork", - config={ - "host": "127.0.0.1", - "port": 8080, - }, - ) - } + tcp=ExporterConfigV1Alpha1DriverInstance( + type="jumpstarter_driver_network.driver.TcpNetwork", + config={ + "host": "127.0.0.1", + "port": 8080, + }, + ) ), }, ) @@ -95,12 +93,22 @@ def test_exporter_config(monkeypatch: pytest.MonkeyPatch, tmp_path: Path): config: port: "/dev/ttyUSB0" baudrate: 115200 - nested: + nested-simplified: + custom: + type: "vendorpackage.CustomDriver" + config: + hello: "world" + nested-legacy: children: custom: type: "vendorpackage.CustomDriver" config: - hello: "world" + hello: "again" + nested-reserved-name: + ref: + type: "vendorpackage.CustomDriver" + config: + hello: "third-time" """ path.write_text( text, @@ -136,17 +144,32 @@ def test_exporter_config(monkeypatch: pytest.MonkeyPatch, tmp_path: Path): "baudrate": 115200, }, ), - "nested": ExporterConfigV1Alpha1DriverInstance( + "nested-simplified": ExporterConfigV1Alpha1DriverInstance( + custom=ExporterConfigV1Alpha1DriverInstance( + type="vendorpackage.CustomDriver", + config={ + "hello": "world", + }, + ) + ), + "nested-legacy": ExporterConfigV1Alpha1DriverInstance( children={ "custom": ExporterConfigV1Alpha1DriverInstance( type="vendorpackage.CustomDriver", - children={}, config={ - "hello": "world", + "hello": "again", }, - ) + ), }, ), + "nested-reserved-name": ExporterConfigV1Alpha1DriverInstance( + ref=ExporterConfigV1Alpha1DriverInstance( + type="vendorpackage.CustomDriver", + config={ + "hello": "third-time", + }, + ) + ), }, config={}, path=path,