Hello,
this mail is status update on PyRecipes. I'm sorry there is no visible
progress yet, but it's because I was considering several different formats
and tried to satisfy both parties, which won't be probably possible.
Current use cases of LNST (RedHat vs Mellanox)
==============================================
Currently, we have both sides, each with their own use case scenarios. Red
Hat is using LNST for performance regression testing, along with PerfRepo.
Each test uses same tools (ethtool, netperf, ping). The setups are very
similar, as for hosts and eth ifaces, what is changing is soft interface
setup (bond, team, VLAN, ovs, bridge). Setup of soft interfaces is
currently done via XML and in task is only execution of test tools and
additional setup (ethtool, MTU). Currently, the code is duplicated in every
task (perfrepo methods, ethtool setups, mtu setups, netperf inits and
calls) so a new layer of abstraction would be welcomed in order to simplify
the code and maintainability.
As for Mellanox side, I can only speak about what I can see in switchdev
recipes. Their approach is to define only hardware interfaces in XML and do
all soft interface setting in the task. In order to create an abstraction
layer a TestLib was created, which looks really appealing to me.
What do RH/Mellanox expect from PyRecipes
=========================================
We had a video call in January about PyRecipes with olichtne (RH) and
jpirko (Mellanox). Both sides had different view of PyRecipes.
Red Hat POW
-----------
1. Wants to be able to define soft and hard interfaces together in setup
2. Wants to be able to combine network setup with different tasks
3. Task should be understood as a function, with network as argument
4. Task should be generic
Mellanox POW
------------
1. Wants to get rid of ID's (hosts and interfaces)
2. Wants soft iface definition only in task, not in setup
3. Task should be specific
4. Wrappers for generic stuff
5. 1 task == 1 test == 1 file, do not combine it
Proposed approach #1 (Mlx like)
===============================
Description: Setup and task is in one file, no IDs are used, soft interface
definition is part of task
Example:
import lnst
m1 = lnst.add_host()
m2 = lnst.add_host()
m1_eth1 = m1.add_interface(label="tnet")
m1_eth2 = m1.add_interface(label="tnet")
m2_eth1 = m2.add_interface(label="tnet")
while match(match=lnst.SingleMatch):
m1_team = m1.create_team([m1_eth1, m1_eth2], ip="1.2.3.4/24")
m2_eth1.reset(["1.2.3.5/24"])
ping_mod = ...
m1_team.run(ping_mod)
Proposed approach #2 (RH like)
==============================
Description: Soft interfaces can be defined in both setup() and task()
methods. IDs muset used due to different scopes of variables. Setup can be
in separate file and can be imported in multiple tasks. In one file,
multiple tasks can be called.
Example:
import lnst
def setup():
m1 = lnst.add_host("m1")
m2 = lnst.add_host("m2")
m1_eth1 = m1.add_interface(id="eth1", label="tnet")
m1_eth2 = m1.add_interface(id="eth2", label="tnet")
m2_eth1 = m2.add_interface(id="eth1", label="tnet",
ip="1.1.1.1/24")
m1.create_team(id="team1", slaves=[m1_eth1, m1_eth2],
ip="1.1.1.2/24")
def task():
m1 = lnst.get_host("m1")
m2 = lnst.get_host("m2")
m1_team = m1.get_interface("team1")
m2_eth1 = m2.get_interface("eth1")
ping_mod = ...
m1_team.run(ping_mod)
lnst.run(match=lnst.SingleMatch,
setup,
task)
Proposed approach #3 (RH like)
==============================
Description: Task method is portable, it uses machine and interface objects
as args so no IDs are required. Soft interfaces can be created in both
do_task and in setup phase. In one file, multiple tasks can be called.
Example:
import lnst
def do_task(m1, if1, if2):
ping_mod = ...src=if1, dst=if2...
m1.run(ping_mod)
m1 = lnst.add_machine()
m2 = lnst.add_machine()
m1_eth1 = m1.add_interface(label="tnet")
m1_eth2 = m1.add_interface(label="tnet")
m1_team = m1.create_team(slaves=[m1_eth1, m1_eth2], ip="1.1.1.1/24")
m2_eth1 = m2.add_interface(label="tnet", ip="1.1.1.2/24")
while lnst.match(match=lnst.SingleMatch):
do_task(m1, m1_team, m2_eth1)
Summary
=======
Drafts above are not meant to be final, it sure can be improved and
modified to satisfy our needs. But we need to come to conclusion for both
Mlx and RH side, so I can start working on it.
Some important questions regarding PyRecipes:
---------------------------------------------
I. Soft interfaces - in setup phase and task phase or only in task phase?
II. Portability - one task == one recipe, or allow combinations of networks
with different tasks?
III. Should task be generic or specific?
IV. Do we have to get rid of IDs?
My opinion on the matter
========================
Favourite approach - #3
Answers to questions:
---------------------
I. Soft interfaces - only in task phase - to follow 1 task == 1 recipe
mentality, will bring easier maintaining
II. Portability - one task == one recipe - even our use case shows, that
tests don't allow so much combination (1 task is being used in avg. 1-2
recipes in phase1, 2-3 recipes in phase2), so I don't thinks its so
important to use to preserve it
III. Specific task - generic stuff can be defined by a new layer of
abstraction, like TestLib in switchdev tests
IV. I do not think IDs are such evil that we should get rid of it, altough
I agree object oriented approach (which we want to follow, thus PyRecipes
became a thing in the first place) should be only using instances of
objects in both task and setup.
Summary
=======
Please, devs from RH and Mlx, take a look on these drafts and send an email
with your opinion on the matter. Ideally, next week starting Wed I would
like to have it decided so I can start implementing it.
In the end, probably we will have to compromise, but hopefully, both
parties will end up satisfied and all this work will lead to improving of
the quality of the whole LNST.
Thanks for reading,
Jiri Prochazka