From: Jiri Pirko <jiri(a)mellanox.com>
This patch allows LNST tasks to create on-fly soft-devices. So far,
bridge, bonds, teams and vlans are supported. It is easy to extend this
to all devices supported by LNST.
This allows user to define machine network config in Task like in
following example:
-------------------------------------------------------------------------------
from lnst.Controller.Task import ctl
m1 = ctl.get_host("machine1")
if1 = m1.get_interface("if1")
if2 = m1.get_interface("if2")
if3 = m1.get_interface("if3")
if4 = m1.get_interface("if4")
team_config = '{"runner" : {"name" : "lacp"}}'
team_if1_config = '{"prio": 11}'
team = m1.create_team(slaves=[(if1, team_if1_config), if2], config=team_config)
br = m1.create_bridge(slaves=[if3, team], options={"stp_state": 0})
vlan = m1.create_vlan(br, 100, ip="192.168.1.1/24")
if4.reset(ip="192.168.2.1/24")
-------------------------------------------------------------------------------
As you can see, it is quite easy and intuitive.
Next step is to allow device destruction in Tasks. Should be quite easy
to implement as well. That would allow on-fly change of network
configuration for running tasks.
This allows to reduce LNST xml recipes to just plain definition of
physical devices used for match. Next step is to allow to do this
definition of physical devices in so-called python-recipe. That would
allow user to use pure-python LNST recipes and tasks. Cool, isn't it?
Signed-off-by: Jiri Pirko <jiri(a)mellanox.com>
---
lnst/Controller/Task.py | 74 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 74 insertions(+)
diff --git a/lnst/Controller/Task.py b/lnst/Controller/Task.py
index 242d046..8670150 100644
--- a/lnst/Controller/Task.py
+++ b/lnst/Controller/Task.py
@@ -363,6 +363,67 @@ class HostAPI(object):
self._m.sync_resources(sync_table)
+ def _add_iface(self, if_type, if_id, netns, ip, options, slaves):
+ interface = self._m.new_soft_interface(if_id, if_type)
+ iface = InterfaceAPI(interface, self)
+ self._ifaces[if_id] = iface
+
+ if slaves:
+ for slave in slaves:
+ if type(slave) == type(()):
+ slave_iface = slave[0]
+ slave_options = slave[1]
+ for key in slave_options:
+ interface.set_slave_option(slave_iface.get_id(),
+ key, slave_options[key])
+ else:
+ slave_iface = slave
+ interface.add_slave(slave_iface._if)
+
+ if ip:
+ interface.add_address(ip)
+
+ if options:
+ for key in options:
+ interface.set_option(key, options[key])
+
+ if netns:
+ interface.set_netns(netns)
+
+ interface.configure()
+ interface.up()
+ return iface
+
+ def create_bond(self, if_id=None, netns=None, ip=None,
+ options=None, slaves=None):
+ return self._add_iface("bond", if_id, netns, ip, options, slaves)
+
+ def create_bridge(self, if_id=None, netns=None, ip=None,
+ options=None, slaves=None):
+ return self._add_iface("bridge", if_id, netns, ip, options, slaves)
+
+ def create_team(self, config=None, if_id=None, netns=None, ip=None,
+ slaves=None):
+ out_slaves = []
+ for slave in slaves:
+ if type(slave) == type(()):
+ slave_iface = slave[0]
+ slave_config = slave[1]
+ out_slaves.append((slave_iface,
+ {"teamd_port_config": slave_config}))
+ else:
+ out_slaves.append(slave)
+
+ options = {}
+ if config:
+ options["teamd_config"] = config
+
+ return self._add_iface("team", if_id, netns, ip, options, out_slaves)
+
+ def create_vlan(self, realdev_iface, vlan_tci, if_id=None, netns=None, ip=None):
+ return self._add_iface("vlan", if_id, netns, ip, {"vlan_tci":
vlan_tci},
+ [realdev_iface])
+
class InterfaceAPI(object):
def __init__(self, interface, host):
self._if = interface
@@ -422,6 +483,19 @@ class InterfaceAPI(object):
def get_host(self):
return self._host
+ def reset(self, ip=None, netns=None):
+ self._if.down()
+ self._if.deconfigure()
+
+ if ip:
+ self._if.add_address(ip)
+
+ if netns:
+ self._if.set_netns(netns)
+
+ self._if.configure()
+ self._if.up()
+
class ModuleAPI(object):
""" An API class representing a module. """
--
2.4.3