[lnst] NetTestController: Implementing libvirt-integration
Jiří Pírko
jirka at fedoraproject.org
Mon Aug 13 11:38:02 UTC 2012
commit 0e7960c51a5d1b8a042e63be702be79ef2b8b3e5
Author: Radek Pazdera <rpazdera at redhat.com>
Date: Mon Aug 13 12:01:52 2012 +0200
NetTestController: Implementing libvirt-integration
This commit adds the necessary changes to NetTestController that
implements integration with libvirt.
Signed-off-by: Radek Pazdera <rpazdera at redhat.com>
NetTest/NetTestController.py | 92 +++++++++++++++++++++++++++++++++++++++--
1 files changed, 87 insertions(+), 5 deletions(-)
---
diff --git a/NetTest/NetTestController.py b/NetTest/NetTestController.py
index 1dcfc69..296150d 100644
--- a/NetTest/NetTestController.py
+++ b/NetTest/NetTestController.py
@@ -20,10 +20,14 @@ from pprint import pprint, pformat
from Common.XmlRpc import ServerProxy
from NetTest.NetTestParse import NetTestParse
from Common.SlaveUtils import prepare_client_session
-from Common.NetUtils import get_corespond_local_ip
+from Common.NetUtils import get_corespond_local_ip, MacPool
from NetTest.NetTestSlave import DefaultRPCPort
from NetTest.NetTestCommand import NetTestCommand, str_command
from Common.LoggingServer import LoggingServer
+from Common.VirtUtils import VirtNetCtl, VirtDomainCtl, BridgeCtl
+from Common.Utils import wait_for
+
+MAC_POOL_RANGE = {"start": "52:54:01:00:00:01", "end": "52:54:01:FF:FF:FF"}
class NetTestError(Exception):
pass
@@ -43,6 +47,8 @@ class NetTestController:
definitions = {"recipe": self._recipe}
self._recipe["networks"] = {}
+ self._mac_pool = MacPool(MAC_POOL_RANGE["start"],
+ MAC_POOL_RANGE["end"])
ntparse = NetTestParse(recipe_path)
ntparse.set_recipe(self._recipe)
@@ -83,14 +89,71 @@ class NetTestController:
def _prepare_device(self, machine_id, dev_id):
info = self._get_machineinfo(machine_id)
+ rpc = self._get_machinerpc(machine_id)
dev = self._recipe["machines"][machine_id]["netdevices"][dev_id]
- dev_net = dev["network"]
+ dev_net_name = dev["network"]
networks = self._recipe["networks"]
- if not dev_net in networks:
- networks[dev_net] = {"members": []}
+ if not dev_net_name in networks:
+ networks[dev_net_name] = {"members": []}
+
+ dev_net = networks[dev_net_name]
+ dev_net["members"].append((machine_id, dev_id))
+
+ if dev["create"] == "libvirt":
+ if not "virt_domain_ctl" in info:
+ msg = "Cannot create device. " \
+ "Machine '%d' is not virtual." % (machine_id)
+ raise NetTestError(msg)
+
+ if not "hwaddr" in dev:
+ dev["hwaddr"] = self._mac_pool.get_addr()
+
+ if "target_bridge" in dev:
+ brctl = BridgeCtl(dev["target_bridge"])
+ else:
+ if "default_bridge" in dev_net:
+ brctl = dev_net["default_bridge"]
+ else:
+ brctl = BridgeCtl()
+ dev_net["default_bridge"] = brctl
+
+ br_name = brctl.get_name()
+ brctl.init()
+
+ logging.info("Creating netdevice %d (%s) on machine %d",
+ dev_id, dev["hwaddr"], machine_id)
+
+ domain_ctl = info["virt_domain_ctl"]
+ domain_ctl.attach_interface(dev["hwaddr"], br_name)
- networks[dev_net]["members"].append((machine_id, dev_id))
+ ready_check_func = lambda: self._device_ready(machine_id, dev_id)
+ ready = wait_for(ready_check_func, timeout=10)
+
+ if not ready:
+ msg = "Netdevice initialization failed." \
+ "Unable to create device %d (%s) on machine %d" \
+ % (dev_id, dev["hwaddr"], machine_id)
+ raise NetTestError(msg)
+
+ phys_devs = rpc.get_devices_by_hwaddr(dev["hwaddr"])
+ if len(phys_devs) == 1:
+ pass
+ elif len(phys_devs) < 1:
+ msg = "Device %d not found on machine %d" \
+ % (dev_id, machine_id)
+ raise NetTestError(msg)
+ elif len(phys_devs) > 1:
+ msg = "Multiple netdevices with same address %s on machine %d" \
+ % (dev["hwaddr"], machine_id)
+ raise NetTestError(msg)
+
+ def _device_ready(self, machine_id, dev_id):
+ rpc = self._get_machinerpc(machine_id)
+ dev = self._recipe["machines"][machine_id]["netdevices"][dev_id]
+
+ devs = rpc.get_devices_by_hwaddr(dev["hwaddr"])
+ return len(devs) > 0
def _prepare_interface(self, machine_id, netdev_config_id):
rpc = self._get_machinerpc(machine_id)
@@ -122,6 +185,10 @@ class NetTestController:
logging.info("Preparing machine #%d", machine_id)
info = self._get_machineinfo(machine_id)
+ if "libvirt_domain" in info:
+ domain_ctl = VirtDomainCtl(info["libvirt_domain"])
+ info["virt_domain_ctl"] = domain_ctl
+
if self._remoteexec and not "session" in info:
self._init_slave_session(machine_id)
@@ -184,6 +251,21 @@ class NetTestController:
for if_id in reversed(info["configured_interfaces"]):
rpc.deconfigure_interface(if_id)
+ # detach dynamically created devices
+ machine = self._recipe["machines"][machine_id]
+ for dev_id, dev in machine["netdevices"].iteritems():
+ if dev["create"] == "libvirt":
+ logging.info("Removing netdevice %d (%s) from machine %d",
+ dev_id, dev["hwaddr"], machine_id)
+ domain_ctl = info["virt_domain_ctl"]
+ domain_ctl.detach_interface(dev["hwaddr"])
+
+ # remove dynamically created bridges
+ networks = self._recipe["networks"]
+ for net in networks.itervalues():
+ if "default_bridge" in net:
+ net["default_bridge"].cleanup()
+
def _disconnect_slaves(self):
for machine_id in self._recipe["machines"]:
info = self._get_machineinfo(machine_id)
More information about the LNST-developers
mailing list