[PATCH v2 00/11] libvirt integration
by Radek Pazdera
From: Radek Pazdera <rpazdera(a)redhat.com>
This patchset integrates LNST with libvirt and add support for dynamically
adding arbitrary netdevices to the test machines in case they are libvirt
virtual domains.
To take advantage of this, you need to have libvirt (including virsh)
installed on the controller machine.
To indicate that your machine is virtualized on controller, specify
'libvirt_domain=<your_domain_name_here>' attribute to <info> tag in
netmachine config.
After that you can mark your dynamic devices by enclosing them in
<libvirt_create> tag.
Some other changes were added along with this patchset. Netdevices are now
groupped in <netdevices> tag (it's necessary to fix this in your older
recipes to use them from now on).
Each netdevice now has a required attribute called 'network'. This can
be later used to determine the topology within lnst. You can chose any
network name you want as long as its unique within your recipe. The
semantics of this attribute is to indicate that all the devices tagged
with the same network name are available on a single link segment.
Hope this patchset doesn't break anything else :). In case it does,
please let me know.
v2: create tag changed to libvirt_create
target_bridge changed to libvirt_bridge
dev["dynamic"] changed to dev["create"]
fixed copy-paste string error in NetUtils
added forgotten exception raise to NetTestController
Radek
Radek Pazdera (11):
NetTest: Adding 'network' attribute to netdevice
Common: New module NetUtils
Utils: Moved get_corespond_local_ip() to NetUtils
NetConfigDevNames: Separating scan_netdevs method
NetTestController: Adding new exception
NetTestSlave: Adding RPC method for dev querying
NetTestParse: Adding support for libvirt-integration
NetConfig: Adding device rescan to add methods
NetUtils: Adding AddressPool class
Common: Adding VirtUtils module
NetTestController: Implementing libvirt-integration
Common/NetUtils.py | 108 ++++++++++++++++++
Common/Utils.py | 20 +---
Common/VirtUtils.py | 242 ++++++++++++++++++++++++++++++++++++++++
NetConfig/NetConfig.py | 4 +
NetConfig/NetConfigDevNames.py | 27 +----
NetTest/NetTestController.py | 103 +++++++++++++++++-
NetTest/NetTestParse.py | 39 ++++++-
NetTest/NetTestSlave.py | 11 ++
8 files changed, 506 insertions(+), 48 deletions(-)
create mode 100644 Common/NetUtils.py
create mode 100644 Common/VirtUtils.py
--
1.7.7.6
11 years, 3 months
[lnst] NetTestController: Implementing libvirt-integration
by Jiří Pírko
commit 0e7960c51a5d1b8a042e63be702be79ef2b8b3e5
Author: Radek Pazdera <rpazdera(a)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(a)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)
11 years, 3 months
[lnst] Common: Adding VirtUtils module
by Jiří Pírko
commit fd3977338b84246c1d3001262f2e5d125d1cc57e
Author: Radek Pazdera <rpazdera(a)redhat.com>
Date: Mon Aug 13 12:01:51 2012 +0200
Common: Adding VirtUtils module
This commit adds VirtUtils module to Common.
VirtUtils is a set of classes that can be used to manage virtual
domains and networks.
VirtDomainCtl can control libvirt domains,
VirtNetCtl can control libvirt networks,
BridgeCtl can control network bridges.
Signed-off-by: Radek Pazdera <rpazdera(a)redhat.com>
Common/VirtUtils.py | 242 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 242 insertions(+), 0 deletions(-)
---
diff --git a/Common/VirtUtils.py b/Common/VirtUtils.py
new file mode 100644
index 0000000..28a3d7e
--- /dev/null
+++ b/Common/VirtUtils.py
@@ -0,0 +1,242 @@
+"""
+Utilities for manipulating virtualization host, its guests and
+connections between them
+
+Copyright 2012 Red Hat, Inc.
+Licensed under the GNU General Public License, version 2 as
+published by the Free Software Foundation; see COPYING for details.
+"""
+
+__author__ = """
+rpazdera(a)redhat.com (Radek Pazdera)
+"""
+
+import os
+import re
+import copy
+import time
+import logging
+from tempfile import NamedTemporaryFile
+from xml.dom import minidom
+from ExecCmd import exec_cmd, ExecCmdFail
+from Common.NetUtils import normalize_hwaddr, scan_netdevs
+
+class VirtUtilsError(Exception):
+ pass
+
+def _ip(cmd):
+ try:
+ exec_cmd("ip %s" % cmd)
+ except ExecCmdFail as err:
+ raise VirtUtilsError("ip command error: %s" % err)
+
+def _brctl(cmd):
+ try:
+ exec_cmd("brctl %s" % cmd)
+ except ExecCmdFail as err:
+ raise VirtUtilsError("brctl error: %s" % err)
+
+def _virsh(cmd):
+ try:
+ exec_cmd("virsh %s" % cmd)
+ except ExecCmdFail as err:
+ raise VirtUtilsError("virsh error: %s" % err)
+
+
+class VirtDomainCtl:
+ _name = None
+
+ def __init__(self, domain_name):
+ self._name = domain_name
+
+ def start(self):
+ _virsh("start %s" % self._name)
+
+ def stop(self):
+ _virsh("destroy %s" % self._name)
+
+ def restart(self):
+ _virsh("reboot %s" % self._name)
+
+ def attach_interface(self, hwaddr, net_name, net_type="bridge"):
+ _virsh("attach-interface %s %s %s --mac %s" % \
+ (self._name, net_type, net_name, hwaddr))
+ self.ifup(hwaddr)
+
+ def detach_interface(self, hwaddr, net_type="bridge"):
+ _virsh("detach-interface %s %s %s" % (self._name, net_type, hwaddr))
+
+ def ifup(self, hwaddr):
+ _virsh("domif-setlink %s %s up" % (self._name, hwaddr))
+
+ def ifdown(self, hwaddr):
+ _virsh("domif-setlink %s %s down" % (self._name, hwaddr))
+
+class NetCtl(object):
+ _name = None
+
+ def __init__(self, name):
+ self._name = name
+
+ def get_name(self):
+ return self._name
+
+ def init(self):
+ pass
+
+ def cleanup(self):
+ pass
+
+class VirtNetCtl(NetCtl):
+ _addr = None
+ _mask = None
+
+ _dhcp_from = None
+ _dhcp_to = None
+ _static_mappings = []
+ _lease_file = None
+
+ def setup_dhcp_server(self, addr, mask, range_start, range_end,
+ static_map=None):
+ self._addr = addr
+ self._mask = mask
+ self._dhcp_from = range_start
+ self._dhcp_to = range_end
+ self._lease_file = "/var/lib/libvirt/dnsmasq/%s.leases" % self._name
+ if static_map:
+ self._static_mappings = static_map
+
+ def get_dhcp_mapping(self, hwaddr, timeout=30):
+ wait = timeout
+ while True:
+ addr = self._get_map(hwaddr)
+ if addr or not wait:
+ break
+
+ time.sleep(1)
+ wait -= 1
+
+ return addr
+
+ def _get_map(self, hwaddr):
+
+ try:
+ leases_file = open(self._lease_file, "r")
+ except IOError as err:
+ raise VirtUtilsError("Unable to resolve IP mapping (%s)" % err)
+
+ addr = None
+ normalized_hwaddr = normalize_hwaddr(hwaddr)
+ for entry in leases_file:
+ match = re.match(r"\d+\s+([0-9a-f:]+)\s+([0-9\.]+)", entry)
+ if match:
+ entry_hwaddr = normalize_hwaddr(match.group(1))
+ entry_addr = match.group(2)
+ if entry_hwaddr == normalized_hwaddr:
+ addr = entry_addr
+ break
+
+ leases_file.close()
+ return addr
+
+
+ def init(self):
+ tmp_file = NamedTemporaryFile(delete=False)
+ doc = self._get_net_xml_dom()
+
+ doc.writexml(tmp_file)
+ tmp_file.close()
+
+ _virsh("net-create %s" % tmp_file.name)
+ os.unlink(tmp_file.name)
+
+ def cleanup(self):
+ _virsh("net-destroy %s" % self._name)
+ exec_cmd("rm -f %s" % self._lease_file)
+
+ def _get_net_xml_dom(self):
+ doc = minidom.Document()
+
+ net = doc.createElement("network")
+ doc.appendChild(net)
+
+ name = doc.createElement("name")
+ name_text = doc.createTextNode(self._name)
+ name.appendChild(name_text)
+ net.appendChild(name)
+
+ if self._addr:
+ ip = doc.createElement("ip")
+ ip.setAttribute("address", self._addr)
+ ip.setAttribute("netmask", self._mask)
+ net.appendChild(ip)
+
+ dhcp = doc.createElement("dhcp")
+ ip.appendChild(dhcp)
+
+ dhcp_range = doc.createElement("range")
+ dhcp_range.setAttribute("start", self._dhcp_from)
+ dhcp_range.setAttribute("end", self._dhcp_to)
+ dhcp.appendChild(dhcp_range)
+
+ for mapping in self._static_mappings:
+ hwaddr, addr = mapping
+ host = doc.createElement("host")
+ host.setAttribute("mac", hwaddr)
+ host.setAttribute("ip", addr)
+ dhcp.appendChild(host)
+
+ return doc
+
+class BridgeCtl(NetCtl):
+ _remove = False
+
+ def __init__(self, name=None):
+ if not name:
+ name = self._generate_name()
+
+ self._check_name(name)
+ self._name = name
+
+ @staticmethod
+ def _check_name(name):
+ if len(name) > 16:
+ msg = "Bridge name '%s' longer than 16 characters" % name
+ raise VirtUtilsError(msg)
+
+ @staticmethod
+ def _generate_name():
+ devs = scan_netdevs()
+
+ index = 0
+ while True:
+ name = "lnstbr%d" % index
+ index += 1
+ unique = True
+ for dev in devs:
+ if name == dev["name"]:
+ unique = False
+ break
+
+ if unique:
+ return name
+
+ def _exists(self):
+ devs = scan_netdevs()
+ for dev in devs:
+ if self._name == dev["name"]:
+ return True
+
+ return False
+
+ def init(self):
+ if not self._exists():
+ _brctl("addbr %s" % self._name)
+ self._remove = True
+
+ _ip("link set %s up" % self._name)
+
+ def cleanup(self):
+ if self._remove:
+ _ip("link set %s down" % self._name)
+ _brctl("delbr %s" % self._name)
11 years, 3 months
[lnst] NetUtils: Adding AddressPool class
by Jiří Pírko
commit 55eb30f5672a61e85f31637a4eb9ce6975c733e8
Author: Radek Pazdera <rpazdera(a)redhat.com>
Date: Mon Aug 13 12:01:50 2012 +0200
NetUtils: Adding AddressPool class
This commit introduces AddressPool class (and its two children -
MacPool and IpPool). This class can be used to generate (and keep
a track of) different types of network addresses within a defined
range.
Signed-off-by: Radek Pazdera <rpazdera(a)redhat.com>
Common/NetUtils.py | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 53 insertions(+), 0 deletions(-)
---
diff --git a/Common/NetUtils.py b/Common/NetUtils.py
index 42ee6f0..8594a23 100644
--- a/Common/NetUtils.py
+++ b/Common/NetUtils.py
@@ -53,3 +53,56 @@ def get_corespond_local_ip(query_ip):
if ip is None:
return ip
return ip.group(1)
+
+class AddressPool:
+ def __init__(self, start, end):
+ self._next = self._addr_to_byte_string(start)
+ self._final = self._addr_to_byte_string(end)
+
+ def _inc_byte_string(self, byte_string):
+ if len(byte_string):
+ byte_string[-1] += 1
+ if byte_string[-1] > 255:
+ del byte_string[-1]
+ self._inc_byte_string(byte_string)
+ byte_string.append(0)
+
+ def _addr_to_byte_string(self, addr):
+ pass
+
+ def _byte_string_to_addr(self, byte_string):
+ pass
+
+ def get_addr(self):
+ if self._next > self._final:
+ msg = "Pool exhausted, no free addresses available"
+ raise Exception(msg)
+
+ addr_str = self._byte_string_to_addr(self._next)
+ self._inc_byte_string(self._next)
+
+ return addr_str
+
+class MacPool(AddressPool):
+ def _addr_to_byte_string(self, addr):
+ bs = [int(byte, 16) for byte in addr.split(":")]
+
+ if len(bs) != 6:
+ raise Exception("Malformed MAC address")
+
+ return bs
+
+ def _byte_string_to_addr(self, byte_string):
+ return ':'.join(map(lambda x: "%02x" % x, byte_string))
+
+class IpPool(AddressPool):
+ def _addr_to_byte_string(self, addr):
+ bs = [int(byte) for byte in addr.split(".")]
+
+ if len(bs) != 4:
+ raise Exception("Malformed IP address")
+
+ return bs
+
+ def _byte_string_to_addr(self, byte_string):
+ return '.'.join(map(str, byte_string))
11 years, 3 months
[lnst] NetConfig: Adding device rescan to add methods
by Jiří Pírko
commit b14157984d8e33cd10408c87c2df18778f559621
Author: Radek Pazdera <rpazdera(a)redhat.com>
Date: Mon Aug 13 12:01:49 2012 +0200
NetConfig: Adding device rescan to add methods
Now, when devices can be added dynamically to the slaves, NetConfig
is obligated to rescan the existing devices each time a new device
is configured.
Signed-off-by: Radek Pazdera <rpazdera(a)redhat.com>
NetConfig/NetConfig.py | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
---
diff --git a/NetConfig/NetConfig.py b/NetConfig/NetConfig.py
index 41a99d8..75d5129 100644
--- a/NetConfig/NetConfig.py
+++ b/NetConfig/NetConfig.py
@@ -65,6 +65,8 @@ class NetConfig:
NetConfigDeviceType(dev_type).type_init()
self._config[if_id] = config
+
+ self._devnames.rescan_netdevs()
self._devnames.assign_name(if_id, self._config)
def remove_interface_config(self, if_id):
@@ -125,6 +127,8 @@ class NetConfig:
if "slaves" in params:
netdev["slaves"] = params["slaves"]
self._config[dev_id] = netdev
+
+ self._devnames.rescan_netdevs()
self._devnames.assign_name(dev_id, self._config)
return dev_id
11 years, 3 months
[lnst] NetTestParse: Adding support for libvirt-integration
by Jiří Pírko
commit e96a033b5e6504cd194988356f109ee7b7bd1297
Author: Radek Pazdera <rpazdera(a)redhat.com>
Date: Mon Aug 13 12:01:48 2012 +0200
NetTestParse: Adding support for libvirt-integration
This commit adds necessary changes to the parser in LNST in order
to support the libvirt device creation.
Netdevice tags are now grouped under a <netdevices> parent tag
within <netmachineconfig>.
On top of that a special mode for defining netdevices (called create)
was added. Devices defined in this mode are not present in the machine
and will be created on test execution.
This mode is available only on virtual test machines created using
libvirt. Here's an exmaple config of such a machine:
<machine id="1">
<netmachineconfig>
<info hostname="192.168.122.11" libvirt_domain="RHEL6"
rootpass="redhat"/>
<netdevices>
<libvirt_create>
<netdevice network="tnet" phys_id="1" type="eth"/>
<netdevice network="tnet" phys_id="2" type="eth"/>
</libvirt_create>
</netdevices>
</netmachineconfig>
<netconfig>
<interface id="1" phys_id="1" type="eth">
<addresses>
<address value="192.168.100.226/24"/>
</addresses>
</interface>
<interface id="2" phys_id="2" type="eth">
<addresses>
<address value="192.168.100.240/24"/>
</addresses>
</interface>
</netconfig>
</machine>
The dynamic devices are enclosed within the <libvirt_create> tag. Their
hwaddr doesn't need to be specified (it will be generated if missing).
Additionally, 'libvirt_bridge' attribute can be added to these devices
to override the default LNST internal bridge, that these devices are
connected to.
Signed-off-by: Radek Pazdera <rpazdera(a)redhat.com>
NetTest/NetTestParse.py | 35 ++++++++++++++++++++++++++++++++---
1 files changed, 32 insertions(+), 3 deletions(-)
---
diff --git a/NetTest/NetTestParse.py b/NetTest/NetTestParse.py
index 746342c..fbe5adc 100644
--- a/NetTest/NetTestParse.py
+++ b/NetTest/NetTestParse.py
@@ -118,7 +118,7 @@ class NetMachineConfigParse(RecipeParser):
def parse(self, node):
scheme = {"info": self._info,
- "netdevice": self._netdevice}
+ "netdevices": self._netdevices}
self._process_child_nodes(node, scheme)
def _info(self, node, params):
@@ -127,6 +127,10 @@ class NetMachineConfigParse(RecipeParser):
info["hostname"] = self._get_attribute(node, "hostname")
+ if self._has_attribute(node, "libvirt_domain"):
+ info["libvirt_domain"] = self._get_attribute(node,
+ "libvirt_domain")
+
if self._has_attribute(node, "rootpass"):
info["rootpass"] = self._get_attribute(node, "rootpass")
@@ -138,18 +142,43 @@ class NetMachineConfigParse(RecipeParser):
self._trigger_event("machine_info_ready",
{"machine_id": self._machine_id})
+ def _netdevices(self, node, params):
+ scheme = {"netdevice": self._netdevice,
+ "libvirt_create": self._libvirt_create}
+
+ new_params = {"create": None}
+ self._process_child_nodes(node, scheme, new_params)
+
+ def _libvirt_create(self, node, params):
+ scheme = {"netdevice": self._netdevice}
+
+ new_params = {"create": "libvirt"}
+ self._process_child_nodes(node, scheme, new_params)
+
def _netdevice(self, node, params):
machine = self._machine
phys_id = self._get_attribute(node, "phys_id", int)
dev = machine["netdevices"][phys_id] = {}
+ dev["create"] = params["create"]
dev["type"] = self._get_attribute(node, "type")
dev["network"] = self._get_attribute(node, "network")
- dev["hwaddr"] = normalize_hwaddr(self._get_attribute(node, "hwaddr"))
- if self._has_attribute(node, "name"):
+ # hwaddr attribute is optional for dynamic devices,
+ # but it is required by non-dynamic devices
+ if dev["create"] == None or self._has_attribute(node, "hwaddr"):
+ hwaddr = self._get_attribute(node, "hwaddr")
+ dev["hwaddr"] = normalize_hwaddr(hwaddr)
+
+ # name attribute is only valid when the device is not dynamic
+ if dev["create"] == None and self._has_attribute(node, "name"):
dev["name"] = self._get_attribute(node, "name")
+ # bridge attribute is valid only when the device is dynamic
+ if dev["create"] == "libvirt" and \
+ self._has_attribute(node, "libvirt_bridge"):
+ dev["libvirt_bridge"] = self._get_attribute(node, "libvirt_bridge")
+
self._trigger_event("netdevice_ready", {"machine_id": self._machine_id,
"dev_id": phys_id})
11 years, 3 months
[lnst] NetTestSlave: Adding RPC method for dev querying
by Jiří Pírko
commit b9e74f589baa657ad0c034b570a0c2b958a6f079
Author: Radek Pazdera <rpazdera(a)redhat.com>
Date: Mon Aug 13 12:01:47 2012 +0200
NetTestSlave: Adding RPC method for dev querying
This commit adds simple RPC method to the slave that allows the
controler to issue a device queries and obtain information about
available devices by hwaddr.
Signed-off-by: Radek Pazdera <rpazdera(a)redhat.com>
NetTest/NetTestSlave.py | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
---
diff --git a/NetTest/NetTestSlave.py b/NetTest/NetTestSlave.py
index 12440f7..a7722e4 100644
--- a/NetTest/NetTestSlave.py
+++ b/NetTest/NetTestSlave.py
@@ -22,6 +22,7 @@ from NetConfig.NetConfig import NetConfig
from NetConfig.NetConfigDevice import NetConfigDeviceAllCleanup
from NetTest.NetTestCommand import NetTestCommand, CommandException
from Common.Utils import die_when_parent_die
+from Common.NetUtils import scan_netdevs
DefaultRPCPort = 9999
@@ -46,6 +47,16 @@ class NetTestSlaveXMLRPC:
Logs.append_network_hadler(logger_address, port)
return True
+ def get_devices_by_hwaddr(self, hwaddr):
+ name_scan = scan_netdevs()
+ netdevs = []
+
+ for entry in name_scan:
+ if entry["hwaddr"] == hwaddr:
+ netdevs.append(entry)
+
+ return netdevs
+
def get_interface_info(self, if_id):
if_config = self._netconfig.get_interface_config(if_id)
info = {}
11 years, 3 months
[lnst] NetTestController: Adding new exception
by Jiří Pírko
commit e727d27ca39dff656db0703f160f56522e68ca3f
Author: Radek Pazdera <rpazdera(a)redhat.com>
Date: Mon Aug 13 12:01:46 2012 +0200
NetTestController: Adding new exception
This commit adds new exception to NetTestController that will be used
to indicate errors in recipe execution.
Signed-off-by: Radek Pazdera <rpazdera(a)redhat.com>
NetTest/NetTestController.py | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
---
diff --git a/NetTest/NetTestController.py b/NetTest/NetTestController.py
index a997e37..1dcfc69 100644
--- a/NetTest/NetTestController.py
+++ b/NetTest/NetTestController.py
@@ -25,6 +25,9 @@ from NetTest.NetTestSlave import DefaultRPCPort
from NetTest.NetTestCommand import NetTestCommand, str_command
from Common.LoggingServer import LoggingServer
+class NetTestError(Exception):
+ pass
+
def ignore_event(**kwarg):
pass
11 years, 3 months
[lnst] NetConfigDevNames: Separating scan_netdevs method
by Jiří Pírko
commit af216c39d4ed7bc02c94373248e99661ffb527c1
Author: Radek Pazdera <rpazdera(a)redhat.com>
Date: Mon Aug 13 12:01:45 2012 +0200
NetConfigDevNames: Separating scan_netdevs method
I separated scan_netdevs method from the class, changed it to
regular function and moved it into the Common.NetUtils module,
because it will be useful elsewhere in the code, but not in the
context of the class and outside of the NetConfig module.
Signed-off-by: Radek Pazdera <rpazdera(a)redhat.com>
Common/NetUtils.py | 19 +++++++++++++++++++
NetConfig/NetConfigDevNames.py | 23 +++--------------------
2 files changed, 22 insertions(+), 20 deletions(-)
---
diff --git a/Common/NetUtils.py b/Common/NetUtils.py
index 7e642b6..42ee6f0 100644
--- a/Common/NetUtils.py
+++ b/Common/NetUtils.py
@@ -11,6 +11,7 @@ rpazdera(a)redhat.com (Radek Pazdera)
"""
import logging
+import os
import re
import socket
import subprocess
@@ -18,6 +19,24 @@ import subprocess
def normalize_hwaddr(hwaddr):
return hwaddr.upper().rstrip("\n")
+def scan_netdevs():
+ sys_dir = "/sys/class/net"
+ scan = []
+ for root, dirs, files in os.walk(sys_dir):
+ if "lo" in dirs:
+ dirs.remove("lo")
+ for d in dirs:
+ dev_path = os.path.join(sys_dir, d)
+ addr_path = os.path.join(dev_path, "address")
+ if not os.path.isfile(addr_path):
+ continue
+ handle = open(addr_path, "rb")
+ addr = handle.read()
+ handle.close()
+ addr = normalize_hwaddr(addr)
+ scan.append({"name": d, "hwaddr": addr})
+ return scan
+
def get_corespond_local_ip(query_ip):
"""
Get ip address in local system which can communicate with query_ip.
diff --git a/NetConfig/NetConfigDevNames.py b/NetConfig/NetConfigDevNames.py
index 7c7f862..0f246d9 100644
--- a/NetConfig/NetConfigDevNames.py
+++ b/NetConfig/NetConfigDevNames.py
@@ -14,31 +14,14 @@ import logging
import os
from NetConfigCommon import get_option
from Common.NetUtils import normalize_hwaddr
+from Common.NetUtils import scan_netdevs
class NetConfigDevNames:
def __init__(self):
- self._scan = self._scan_netdevs()
-
- def _scan_netdevs(self):
- sys_dir = "/sys/class/net"
- scan = []
- for root, dirs, files in os.walk(sys_dir):
- if "lo" in dirs:
- dirs.remove("lo")
- for d in dirs:
- dev_path = os.path.join(sys_dir, d)
- addr_path = os.path.join(dev_path, "address")
- if not os.path.isfile(addr_path):
- continue
- handle = open(addr_path, "rb")
- addr = handle.read()
- handle.close()
- addr = normalize_hwaddr(addr)
- scan.append({"name": d, "hwaddr": addr})
- return scan
+ self._scan = scan_netdevs()
def rescan_netdevs(self):
- self._scan = self._scan_netdevs()
+ self._scan = scan_netdevs()
def assign_name_by_scan(self, dev_id, netdev):
if (not "hwaddr" in netdev or
11 years, 3 months