Hello everyone,
so after many meetings and ideas, I bring first "runnable" implementation
of PyRecipes. Please, read this cover letter, look at the implementation,
try to run it, try creating some tests for it and let me know in case
you have any questions or recommendations.
Brief explanation of how PyRecipes look:
For the first phase of this feature, we agreed on not ditching XML files
completely. So you still need .xml file, where network and tasks are defined.
Since this implementation is backwards compatible with the old one, you can
mix them together.
Network definition:
You don't need to specify any <host> tags anymore, all you need is to put
attribute python in network tag and write path to Python file with class
for network definition in it. Example:
<network python="/path/to/pyrecipe_network.py" />
Now let's take a look in what should Python file contain.
# 1) Import of lnst.Controller.PyRecipe.LnstNetwork
# This class will be used as parent class for our own class with network setup.
from lnst.Controller.PyRecipe import LnstNetwork
# 2) Class definition with parent class LnstNetwork and method setup()
class MyNetwork(LnstNetwork):
def setup(self):
# here will be described network topology
# 3) Described network topology in setup() method like here
def setup(self):
# create host with id 'm1'
m1 = self.add_host(id='m1')
# create host with id 'm2'
m2 = self.add_host(id='m2')
# create eth interface on host m1, with id 'eth1' in network 'tnet'
m1_eth1 = m1.add_interface(id='eth1', type='eth', label='tnet')
# create eth interface on host m2, with id 'eth1' in network 'tnet'
m2_eth1 = m2.add_interface(id='eth1', type='eth', label='tnet')
# assign IP address to eth interface on m1
m1_eth1.add_address("192.168.111.1/24")
# assign IP address to eth interface on m2
m2_eth1.add_address("192.168.111.2/24")
LnstNetwork supported methods:
add_host(self, id) ... creates Host
Host supported methods:
add_interface(self, type, id, label=None, netns=None) ... creates an Interface
Please note that label must be specified only on eth interfaces. netns is optional.
Allowed types of interfaces: eth, vlan, bond, team, bridge, veth, macvlan, lo,
vti, ovs_bridge, vxlan
add_param(self, param) ... take dictionary with format {'key' : 'value'} and sets
it like param for respective host.
pair_veths(self, iface1, iface2) ... takes two veth interfaces as param and pairs
them
Interface supported methods:
add_address(self, address) ... takes address as string and assigns it to interface
add_addresses(self, addresses) ... runs add_address method on list of addresses
add_ovs_bond_slave(self, bond_id, iface) ... meant to be used on ovs_bridge interface,
enslaves iface on ovs bond with id bond_id. If bond with that id does not exist, create it
add_ovs_bond_slaves(self, bond_id, ifaces) ... same as above, but for list of interfaces
add_ovs_vlan_slave(self, vlan_tag, iface) ... same as add_ovs_bond_slave, but for ovs VLANs
add_ovs_vlan_slaves(self, vlan_tag, ifaces) ... same as above, but for list of interfaces
add_option(self, option) ... takes dict in format {'key' : 'value'} and sets it as option for
non-eth type interface
add_param(self, param) ... takes dict in format {'key' : 'value'} and sets it as param for
eth type interafce
add_slave(self, iface) ... enslaves iface to self (works on vlan, vxlan, team, bond, bridge, macvlan, ovs_bridge)
add_slaves(self, ifaces) ... same as above, but for list of interfaces
Task definition:
Task definition remains the same. Example:
<task python="/path/to/pyrecipe_task.py" />
The file pyrecipe_task.py will loke like this:
#1) Import of LnstTask
from lnst.Controller.PyRecipe import LnstTask
#2) Create class with Task and method task()
class MyTask(LnstTask):
def task(self):
#3) The rest remains the same, only controller handler
#is not imported directly, but is part of LnstTask class.
ctl = self.ctl
m1 = ctl.get_machine("m1")
...
Methods available for use are same TaskAPI methods as before.
You can have multiple classes with tasks in one file, example:
class MyTask1(LnstTask):
def task(self):
...
class MyTask2(LnstTask):
def task(self):
...
For more info ask me on lnst-dev mailing list.
Thanks,
Jiri
Jiri Prochazka (5):
PyRecipes: add PyRecipe module
RecipeParser: add support for PyRecipes
schema-recipe: add support for PyRecipes
NetTestController: add support for PyRecipes
PyRecipes: add example recipes for PyRecipes implementation
lnst/Controller/NetTestController.py | 39 ++++-
lnst/Controller/PyRecipe.py | 225 ++++++++++++++++++++++++++++
lnst/Controller/RecipeParser.py | 12 +-
recipes/examples/pyrecipes/2_hosts.py | 12 ++
recipes/examples/pyrecipes/README | 39 +++++
recipes/examples/pyrecipes/bond_vs_team.py | 62 ++++++++
recipes/examples/pyrecipes/bond_vs_team.xml | 4 +
recipes/examples/pyrecipes/ping_flood.py | 23 +++
recipes/examples/pyrecipes/ping_flood.xml | 4 +
recipes/examples/pyrecipes/vlan.py | 60 ++++++++
recipes/examples/pyrecipes/vlan.xml | 15 ++
schema-recipe.rng | 7 +-
12 files changed, 494 insertions(+), 8 deletions(-)
create mode 100644 lnst/Controller/PyRecipe.py
create mode 100644 recipes/examples/pyrecipes/2_hosts.py
create mode 100644 recipes/examples/pyrecipes/README
create mode 100644 recipes/examples/pyrecipes/bond_vs_team.py
create mode 100644 recipes/examples/pyrecipes/bond_vs_team.xml
create mode 100644 recipes/examples/pyrecipes/ping_flood.py
create mode 100644 recipes/examples/pyrecipes/ping_flood.xml
create mode 100644 recipes/examples/pyrecipes/vlan.py
create mode 100644 recipes/examples/pyrecipes/vlan.xml
--
2.4.3