From 93a20e79ec092a95de5c0951db8fe71c810239fe Mon Sep 17 00:00:00 2001 From: Konrad Sztyber Date: Thu, 3 Feb 2022 15:36:55 +0100 Subject: [PATCH] sma: loading out-of-tree plugins It's now possible to register SMA device managers defined in a module outside of the regular directory. To do that, a global variable called `devices` containing a list of device manager classes needs to be defined in a module that's added to SMA_PLUGINS environment variable. For example: ``` $ cat /path/to/plugins/external_devices/__init__.py import spdk.sma as sma class MyDeviceManager1(sma.DeviceManager): pass class MyDeviceManager2(sma.DeviceManager): pass devices = [MyDeviceManager1, MyDeviceManager2] $ SMA_PLUGINS=external_devices scripts/sma.py ``` Multiple plugins can be specified by separating them with a colon, e.g.: ``` SMA_PLUGINS=plugin1:plugin2 ``` Of course, the location at which these modules reside must be in PYTHONPATH. Signed-off-by: Konrad Sztyber Change-Id: I2bb4cfea5191710f97d66abe3a21e4deacc6338a Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/11412 Community-CI: Broadcom CI Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Ben Walker --- scripts/sma.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/scripts/sma.py b/scripts/sma.py index adceadfc3..555b19a3f 100755 --- a/scripts/sma.py +++ b/scripts/sma.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 from argparse import ArgumentParser +import importlib import logging import os import sys @@ -34,9 +35,19 @@ def register_device(agent, device): agent.register_device(device) +def load_plugins(agent, client, plugins): + for plugin in plugins: + module = importlib.import_module(plugin) + for device in getattr(module, 'devices', []): + logging.debug(f'Loading external device: {plugin}.{device.__name__}') + register_device(agent, device(client)) + + if __name__ == '__main__': argv = parse_argv() logging.basicConfig(level=os.environ.get('SMA_LOGLEVEL', 'WARNING').upper()) agent = sma.StorageManagementAgent(argv.address, argv.port) register_device(agent, sma.NvmfTcpDeviceManager(get_build_client(argv.socket))) + load_plugins(agent, get_build_client(argv.socket), + filter(None, os.environ.get('SMA_PLUGINS', '').split(':'))) agent.run()