Mon, Apr 20, 2020 at 08:25:17PM CEST, pgagne(a)redhat.com wrote:
From: Perry Gagne <pgagne(a)redhat.com>
Team devices now are created with a config dict that gets converted to json when
configuring them on the host.
Signed-off-by: Perry Gagne <pgagne(a)redhat.com>
---
lnst/Devices/TeamDevice.py | 54 ++++++++++++++++++---------------
lnst/Recipes/ENRT/TeamRecipe.py | 7 ++---
2 files changed, 32 insertions(+), 29 deletions(-)
diff --git a/lnst/Devices/TeamDevice.py b/lnst/Devices/TeamDevice.py
index 4f6eee5..fc05de4 100644
--- a/lnst/Devices/TeamDevice.py
+++ b/lnst/Devices/TeamDevice.py
@@ -9,44 +9,46 @@ published by the Free Software Foundation; see COPYING for details.
__author__ = """
olichtne(a)redhat.com (Ondrej Lichtner)
"""
-
-import re
+import json
from lnst.Common.ExecCmd import exec_cmd
-from lnst.Common.Utils import bool_it
+from lnst.Common.DeviceError import DeviceError, DeviceConfigError
from lnst.Devices.MasterDevice import MasterDevice
-def prepare_json_str(json_str):
- if not json_str:
- return "{}"
- json_str = json_str.replace('"', '\\"')
- json_str = re.sub('\s+', ' ', json_str)
- return json_str
-#TODO rework with pyroute2? don't know how json and teamd works with that...
+# TODO Rework with pyroute2 if thats possible.
+# See
https://github.com/svinota/pyroute2/issues/699#issuecomment-615367686
class TeamDevice(MasterDevice):
_name_template = "t_team"
def __init__(self, ifmanager, *args, **kwargs):
+ self._config = {}
+ self._dbus = False
super(TeamDevice, self).__init__(ifmanager, *args, **kwargs)
- self._config = kwargs.get("config", None)
- self._dbus = not bool_it(kwargs.get("disable_dbus", False))
-
@property
def config(self):
return self._config
+ @config.setter
+ def config(self, v: dict):
Just a question on this argument format. In this particular case, what's
the reason for specifying the type explicitly? I'm aware of PEP document for
the type hinting [1]. From that I understand this could be useful for static
analysis. Is there any other reason why you use it?
From the Python perspective, there's no type enforcement.
I'm just curious why we need this? I ask also because we never used
this elsewhere in LNST code.
-Jan
[1]
https://www.python.org/dev/peps/pep-0484/
+ if not isinstance(v, dict):
+ raise DeviceConfigError("team device config must be dict")
+ self._config = v
+
@property
def dbus(self):
return self._dbus
- def _create(self):
- teamd_config = prepare_json_str(self.config)
+ @dbus.setter
+ def dbus(self, v: bool):
+ if not isinstance(v, bool):
+ raise DeviceConfigError("team dbus setting must be bool")
+ self._dbus = v
- exec_cmd("teamd -r -d -c \"%s\" -t %s %s" %\
- (teamd_config,
- self.name,
- " -D" if self.dbus else ""))
+ def _create(self):
+ teamd_json = json.dumps(self.config)
+ exec_cmd(f"teamd -r -d -c '{teamd_json}' -t {self.name}"
+ " -D" if self.dbus else "")
retry = 0
while self._nl_msg is None and retry < 5:
@@ -56,11 +58,13 @@ class TeamDevice(MasterDevice):
def destroy(self):
exec_cmd("teamd -k -t %s" % self.name)
- def slave_add(self, dev, port_config=None):
- exec_cmd("teamdctl %s %s port config update %s \"%s\"" %\
- (" -D" if self.dbus else "",
- self.name,
- dev.name,
- prepare_json_str(port_config)))
+ def slave_add(self, dev, port_config={}):
+ if not isinstance(port_config, dict):
+ raise DeviceConfigError(f"team link {dev.name} port config must be
dict")
+
+ port_json = json.dumps(port_config)
+ opts = "-D" if self.dbus else ""
+ exec_cmd(f"teamdctl {opts} {self.name} port config "
+ f"update {dev.name} '{port_json}'")
dev.master = self
diff --git a/lnst/Recipes/ENRT/TeamRecipe.py b/lnst/Recipes/ENRT/TeamRecipe.py
index e083b90..e97a10b 100644
--- a/lnst/Recipes/ENRT/TeamRecipe.py
+++ b/lnst/Recipes/ENRT/TeamRecipe.py
@@ -9,6 +9,7 @@ from lnst.Recipes.ENRT.ConfigMixins.CommonHWSubConfigMixin import (
from lnst.RecipeCommon.Ping.PingEndpoints import PingEndpoints
from lnst.Devices import TeamDevice
+
class TeamRecipe(CommonHWSubConfigMixin, OffloadSubConfigMixin,
BaseEnrtRecipe):
host1 = HostReq()
@@ -30,10 +31,8 @@ class TeamRecipe(CommonHWSubConfigMixin, OffloadSubConfigMixin,
def test_wide_configuration(self):
host1, host2 = self.matched.host1, self.matched.host2
- #The config argument needs to be used with a team device normally
- #(e.g to specify the runner mode), but it is not used here due to
- #a bug in the TeamDevice module
- host1.team0 = TeamDevice()
+ teamd_config = {'runner': {'name': self.params.runner_name}}
+ host1.team0 = TeamDevice(config=teamd_config)
configuration = super().test_wide_configuration()
configuration.test_wide_devices = [host1.team0, host2.eth0]
--
2.21.1
_______________________________________________
LNST-developers mailing list -- lnst-developers(a)lists.fedorahosted.org
To unsubscribe send an email to lnst-developers-leave(a)lists.fedorahosted.org
Fedora Code of Conduct:
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines:
https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives:
https://lists.fedorahosted.org/archives/list/lnst-developers@lists.fedora...