[lnst] Utils: Moved get_corespond_local_ip() to NetUtils
by Jiří Pírko
commit 5f3e82e813c9057a57fb895f1c46eb7a81227049
Author: Radek Pazdera <rpazdera(a)redhat.com>
Date: Mon Aug 13 12:01:44 2012 +0200
Utils: Moved get_corespond_local_ip() to NetUtils
This commit moves get_corespond_local_ip function from the general
utility module to the new network specific one.
Signed-off-by: Radek Pazdera <rpazdera(a)redhat.com>
Common/NetUtils.py | 20 ++++++++++++++++++++
Common/Utils.py | 20 ++------------------
NetTest/NetTestController.py | 2 +-
3 files changed, 23 insertions(+), 19 deletions(-)
---
diff --git a/Common/NetUtils.py b/Common/NetUtils.py
index 059ce6e..7e642b6 100644
--- a/Common/NetUtils.py
+++ b/Common/NetUtils.py
@@ -11,6 +11,26 @@ rpazdera(a)redhat.com (Radek Pazdera)
"""
import logging
+import re
+import socket
+import subprocess
def normalize_hwaddr(hwaddr):
return hwaddr.upper().rstrip("\n")
+
+def get_corespond_local_ip(query_ip):
+ """
+ Get ip address in local system which can communicate with query_ip.
+
+ @param query_ip: IP of client which want communicate with autotest machine.
+ @return: IP address which can communicate with query_ip
+ """
+ query_ip = socket.gethostbyname(query_ip)
+ ip = subprocess.Popen("ip route get %s" % (query_ip),
+ shell=True, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ ip = ip.communicate()[0]
+ ip = re.search(r"src ([0-9.]*)",ip)
+ if ip is None:
+ return ip
+ return ip.group(1)
diff --git a/Common/Utils.py b/Common/Utils.py
index 8f39729..f6ba201 100644
--- a/Common/Utils.py
+++ b/Common/Utils.py
@@ -9,7 +9,8 @@ published by the Free Software Foundation; see COPYING for details.
__autor__ = """
jzupka(a)redhat.com (Jiri Zupka)
"""
-import logging, time, subprocess, re, socket
+import logging
+import time
def die_when_parent_die():
try:
@@ -51,20 +52,3 @@ def wait_for(func, timeout, first=0.0, step=1.0, text=None):
logging.debug("Timeout elapsed")
return None
-
-
-def get_corespond_local_ip(query_ip):
- """
- Get ip address in local system which can communicate with quert_ip.
-
- @param query_ip: IP of client which want communicate with autotest machine.
- @return: IP address which can communicate with query_ip
- """
- query_ip = socket.gethostbyname(query_ip)
- ip = subprocess.Popen("ip route get %s" % (query_ip),
- shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- ip = ip.communicate()[0]
- ip = re.search(r"src ([0-9.]*)",ip)
- if ip is None:
- return ip
- return ip.group(1)
diff --git a/NetTest/NetTestController.py b/NetTest/NetTestController.py
index 8e23152..a997e37 100644
--- a/NetTest/NetTestController.py
+++ b/NetTest/NetTestController.py
@@ -20,7 +20,7 @@ from pprint import pprint, pformat
from Common.XmlRpc import ServerProxy
from NetTest.NetTestParse import NetTestParse
from Common.SlaveUtils import prepare_client_session
-from Common.Utils import get_corespond_local_ip
+from Common.NetUtils import get_corespond_local_ip
from NetTest.NetTestSlave import DefaultRPCPort
from NetTest.NetTestCommand import NetTestCommand, str_command
from Common.LoggingServer import LoggingServer
11 years, 3 months
[lnst] Common: New module NetUtils
by Jiří Pírko
commit 7402d6ca1fa19b69d2eca7b15ad026f5209f1ea8
Author: Radek Pazdera <rpazdera(a)redhat.com>
Date: Mon Aug 13 12:01:43 2012 +0200
Common: New module NetUtils
Created a new module for networking related code and utilities
in Common package.
The normalize_hwaddr() function was moved there.
Signed-off-by: Radek Pazdera <rpazdera(a)redhat.com>
Common/NetUtils.py | 16 ++++++++++++++++
NetConfig/NetConfigDevNames.py | 4 +---
NetTest/NetTestParse.py | 3 +--
3 files changed, 18 insertions(+), 5 deletions(-)
---
diff --git a/Common/NetUtils.py b/Common/NetUtils.py
new file mode 100644
index 0000000..059ce6e
--- /dev/null
+++ b/Common/NetUtils.py
@@ -0,0 +1,16 @@
+"""
+Networking related utilities and common code
+
+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 logging
+
+def normalize_hwaddr(hwaddr):
+ return hwaddr.upper().rstrip("\n")
diff --git a/NetConfig/NetConfigDevNames.py b/NetConfig/NetConfigDevNames.py
index 1220480..7c7f862 100644
--- a/NetConfig/NetConfigDevNames.py
+++ b/NetConfig/NetConfigDevNames.py
@@ -13,9 +13,7 @@ jpirko(a)redhat.com (Jiri Pirko)
import logging
import os
from NetConfigCommon import get_option
-
-def normalize_hwaddr(hwaddr):
- return hwaddr.upper().rstrip("\n")
+from Common.NetUtils import normalize_hwaddr
class NetConfigDevNames:
def __init__(self):
diff --git a/NetTest/NetTestParse.py b/NetTest/NetTestParse.py
index 32d75e1..746342c 100644
--- a/NetTest/NetTestParse.py
+++ b/NetTest/NetTestParse.py
@@ -16,8 +16,7 @@ import re
from Common.XmlProcessing import RecipeParser
from Common.XmlProcessing import XmlDomTreeInit
from Common.XmlProcessing import XmlProcessingError
-from NetConfig.NetConfigDevNames import normalize_hwaddr
-
+from Common.NetUtils import normalize_hwaddr
class NetTestParse(RecipeParser):
def __init__(self, recipe_filepath):
11 years, 3 months
[lnst] NetTest: Adding 'network' attribute to netdevice
by Jiří Pírko
commit 0ef6bee3be7a0c6b34647bcefde366cca42a66e0
Author: Radek Pazdera <rpazdera(a)redhat.com>
Date: Mon Aug 13 12:01:42 2012 +0200
NetTest: Adding 'network' attribute to netdevice
This commit introduces networks into LNST netdevices. Up to this point
we were unaware of how the devices are connected to each other. The
network attribute adds this information directly into the recipe.
So if you later receive a recipe, you can configure your underlying
physical network accordingly. This will be also useful with the
upcomming virtual networks and interfaces, because LNST will be able
to set up the virtual network automatically.
See the following example:
Machine 1:
<netdevice hwaddr="52:54:00:11:D5:A8" network="channel-1"
phys_id="1" type="eth"/>
<netdevice hwaddr="52:54:00:2E:CD:A8" network="channel-2"
phys_id="1" type="eth"/>
Machine 2:
<netdevice hwaddr="52:54:00:2E:D5:A8" network="channel-1"
phys_id="1" type="eth"/>
<netdevice hwaddr="52:54:00:2E:D5:A8" network="channel-2"
phys_id="1" type="eth"/>
Machine 1 is connected to machine 2 with two networks, channel-1 and
channel-2.
Signed-off-by: Radek Pazdera <rpazdera(a)redhat.com>
NetTest/NetTestController.py | 16 +++++++++++++++-
NetTest/NetTestParse.py | 1 +
2 files changed, 16 insertions(+), 1 deletions(-)
---
diff --git a/NetTest/NetTestController.py b/NetTest/NetTestController.py
index 4e34c90..8e23152 100644
--- a/NetTest/NetTestController.py
+++ b/NetTest/NetTestController.py
@@ -39,11 +39,14 @@ class NetTestController:
self._recipe = {}
definitions = {"recipe": self._recipe}
+ self._recipe["networks"] = {}
+
ntparse = NetTestParse(recipe_path)
ntparse.set_recipe(self._recipe)
ntparse.set_definitions(definitions)
- ntparse.register_event_handler("netdevice_ready", ignore_event)
+ ntparse.register_event_handler("netdevice_ready",
+ self._prepare_device)
ntparse.register_event_handler("machine_info_ready",
self._prepare_slave)
ntparse.register_event_handler("interface_config_ready",
@@ -75,6 +78,17 @@ class NetTestController:
session.command, status)
raise Exception("Session Die.")
+ def _prepare_device(self, machine_id, dev_id):
+ info = self._get_machineinfo(machine_id)
+ dev = self._recipe["machines"][machine_id]["netdevices"][dev_id]
+
+ dev_net = dev["network"]
+ networks = self._recipe["networks"]
+ if not dev_net in networks:
+ networks[dev_net] = {"members": []}
+
+ networks[dev_net]["members"].append((machine_id, dev_id))
+
def _prepare_interface(self, machine_id, netdev_config_id):
rpc = self._get_machinerpc(machine_id)
info = self._get_machineinfo(machine_id)
diff --git a/NetTest/NetTestParse.py b/NetTest/NetTestParse.py
index e52f0f3..32d75e1 100644
--- a/NetTest/NetTestParse.py
+++ b/NetTest/NetTestParse.py
@@ -145,6 +145,7 @@ class NetMachineConfigParse(RecipeParser):
dev = machine["netdevices"][phys_id] = {}
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"):
11 years, 3 months
[PATCH 00/12] 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 <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.
Radek
Radek Pazdera (12):
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
NetUtils: Moving scan_netdevs from NetConfig
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 | 102 +++++++++++++++++-
NetTest/NetTestParse.py | 38 ++++++-
NetTest/NetTestSlave.py | 11 ++
8 files changed, 504 insertions(+), 48 deletions(-)
create mode 100644 Common/NetUtils.py
create mode 100644 Common/VirtUtils.py
--
1.7.7.6
11 years, 3 months
[lnst] NetTestCommand: Code cleanup for bg processes
by Jiří Pírko
commit 448253960d314c1bebea59d600b5f6a3af6d3ae2
Author: Ondrej Lichtner <olichtne(a)redhat.com>
Date: Fri Aug 10 09:10:25 2012 +0200
NetTestCommand: Code cleanup for bg processes
This commit makes the function get_bg_process_result a method of class
BGProcesses. It makes more sense here since it is used for accessing
data from objects of this class.
I also moved the class BgProcessException to the same area so that it
doesn't interfere with NetTestCommand* classes.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
NetTest/NetTestCommand.py | 38 +++++++++++++++++++-------------------
1 files changed, 19 insertions(+), 19 deletions(-)
---
diff --git a/NetTest/NetTestCommand.py b/NetTest/NetTestCommand.py
index 1dbd2a2..8c0ef82 100644
--- a/NetTest/NetTestCommand.py
+++ b/NetTest/NetTestCommand.py
@@ -37,6 +37,14 @@ class CommandException(Exception):
def __str__(self):
return "CommandException: " + str(self.command)
+class BgProcessException(Exception):
+ """Base class for client errors."""
+ def __init__(self, str):
+ self._str = str
+
+ def __str__(self):
+ return "BgProcessError: " + self._str
+
class BGProcesses:
def __init__(self):
self._dict = {}
@@ -55,6 +63,15 @@ class BGProcesses:
def remove(self, bg_id):
del self._dict[bg_id]
+ def get_bg_process_result(self, bg_id):
+ pipe = self.get_pipe(bg_id)
+ tmp = os.read(pipe, 4096*10)
+ result = pickle.loads(tmp)
+ if "Exception" in result:
+ raise BgProcessException(result["Exception"])
+ os.close(pipe)
+ return result
+
bg_processes = BGProcesses()
def NetTestCommandTest(command):
@@ -154,30 +171,13 @@ class NetTestCommandSystemConfig(NetTestCommandGeneric):
res["res_data"] = res_data
self.set_result(res)
-class BgProcessException(Exception):
- """Base class for client errors."""
- def __init__(self, str):
- self._str = str
-
- def __str__(self):
- return "BgProcessError: " + self._str
-
-def get_bg_process_result(bg_id):
- pipe = bg_processes.get_pipe(bg_id)
- tmp = os.read(pipe, 4096*10)
- result = pickle.loads(tmp)
- if "Exception" in result:
- raise BgProcessException(result["Exception"])
- os.close(pipe)
- return result
-
class NetTestCommandWait(NetTestCommandGeneric):
def run(self):
bg_id = int(self._command["value"])
pid = bg_processes.get_pid(bg_id)
logging.debug("Waiting for background id \"%d\", pid \"%d\"" % (bg_id, pid))
os.waitpid(pid, 0)
- result = get_bg_process_result(bg_id)
+ result = bg_processes.get_bg_process_result(bg_id)
bg_processes.remove(bg_id)
self.set_result(result)
@@ -188,7 +188,7 @@ class NetTestCommandIntr(NetTestCommandGeneric):
logging.debug("Interrupting background id \"%d\", pid \"%d\"" % (bg_id, pid))
os.killpg(os.getpgid(pid), signal.SIGINT)
os.waitpid(pid, 0)
- result = get_bg_process_result(bg_id)
+ result = bg_processes.get_bg_process_result(bg_id)
bg_processes.remove(bg_id)
self.set_result(result)
11 years, 3 months
[PATCH 1/2] NetTestCommand: Code cleanup for bg processes
by Ondrej Lichtner
From: Ondrej Lichtner <olichtne(a)redhat.com>
This commit makes the function get_bg_process_result a method of class
BGProcesses. It makes more sense here since it is used for accessing
data from objects of this class.
I also moved the class BgProcessException to the same area so that it
doesn't interfere with NetTestCommand* classes.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
NetTest/NetTestCommand.py | 38 +++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/NetTest/NetTestCommand.py b/NetTest/NetTestCommand.py
index 1dbd2a2..8c0ef82 100644
--- a/NetTest/NetTestCommand.py
+++ b/NetTest/NetTestCommand.py
@@ -37,6 +37,14 @@ class CommandException(Exception):
def __str__(self):
return "CommandException: " + str(self.command)
+class BgProcessException(Exception):
+ """Base class for client errors."""
+ def __init__(self, str):
+ self._str = str
+
+ def __str__(self):
+ return "BgProcessError: " + self._str
+
class BGProcesses:
def __init__(self):
self._dict = {}
@@ -55,6 +63,15 @@ class BGProcesses:
def remove(self, bg_id):
del self._dict[bg_id]
+ def get_bg_process_result(self, bg_id):
+ pipe = self.get_pipe(bg_id)
+ tmp = os.read(pipe, 4096*10)
+ result = pickle.loads(tmp)
+ if "Exception" in result:
+ raise BgProcessException(result["Exception"])
+ os.close(pipe)
+ return result
+
bg_processes = BGProcesses()
def NetTestCommandTest(command):
@@ -154,30 +171,13 @@ class NetTestCommandSystemConfig(NetTestCommandGeneric):
res["res_data"] = res_data
self.set_result(res)
-class BgProcessException(Exception):
- """Base class for client errors."""
- def __init__(self, str):
- self._str = str
-
- def __str__(self):
- return "BgProcessError: " + self._str
-
-def get_bg_process_result(bg_id):
- pipe = bg_processes.get_pipe(bg_id)
- tmp = os.read(pipe, 4096*10)
- result = pickle.loads(tmp)
- if "Exception" in result:
- raise BgProcessException(result["Exception"])
- os.close(pipe)
- return result
-
class NetTestCommandWait(NetTestCommandGeneric):
def run(self):
bg_id = int(self._command["value"])
pid = bg_processes.get_pid(bg_id)
logging.debug("Waiting for background id \"%d\", pid \"%d\"" % (bg_id, pid))
os.waitpid(pid, 0)
- result = get_bg_process_result(bg_id)
+ result = bg_processes.get_bg_process_result(bg_id)
bg_processes.remove(bg_id)
self.set_result(result)
@@ -188,7 +188,7 @@ class NetTestCommandIntr(NetTestCommandGeneric):
logging.debug("Interrupting background id \"%d\", pid \"%d\"" % (bg_id, pid))
os.killpg(os.getpgid(pid), signal.SIGINT)
os.waitpid(pid, 0)
- result = get_bg_process_result(bg_id)
+ result = bg_processes.get_bg_process_result(bg_id)
bg_processes.remove(bg_id)
self.set_result(result)
--
1.7.11.2
11 years, 3 months
Bug tracking for LNST
by Radek Pazdera
Hi!
As our team grows (hello Ondra) and LNST codebase expands and gets more
and more complex, I think we could use some sort of bugzilla or bug
tracking software to keep ideas/bugs on one place accessible for all
of us.
What do you think about this?
Is there any way of getting LNST to the redhat bugzilla? Or some other
bug tracking software within RH that we could use?
There are always free options, for instance github has pretty good
issue tracking ...
Radek
11 years, 3 months
Virtual devices in recipes
by Radek Pazdera
Hi,
it's me again, with some problems (again) :-).
I'm working on the dynamic attachment of interfaces to virtual guests.
I'm trying to follow the convention as we discussed (and agreed on)
earlier at the meeting. But based on the experience I had with it,
I find it a little confusing.
I think we should decouple the physical an virtual world by default and
if someone will need to combine them, he should know what he's doing.
Here's an example of current status:
Machine #1:
<netmachineconfig>
<info hostname="192.168.122.11" libvirt_domain="RHEL6"
rootpass="redhat"/>
<netdevice hwaddr="52:54:00:2E:D5:A8" network="test_net"
phys_id="1" type="eth"/>
<netdevice hwaddr="52:54:00:90:23:0c" network="test_net"
phys_id="2" type="eth"/> <-- this one is virtual because the MAC doesn't
exist
</netmachineconfig>
Machine #2:
<netmachineconfig>
<info hostname="192.168.122.10" libvirt_domain="Fedora16-clone"
rootpass="redhat"/>
<netdevice hwaddr="52:54:00:91:01:9c" network="test_net"
phys_id="1" type="eth"/>
</netmachineconfig>
The network="test_net" attribute makes it look like that LNST will
somehow take care of
connecting all the devices together. But it won't be able to connect
virtual devices to
physical ones.
I like this solution:
Machine #1:
<netmachineconfig>
<info hostname="192.168.122.11" libvirt_domain="RHEL6"
rootpass="redhat"/>
<netdevice hwaddr="52:54:00:2E:D5:A8" phys_id="1" type="eth"/>
<netdevice hwaddr="52:54:00:90:23:0c" bridge="virbr0"
phys_id="2" type="eth"/>
</netmachineconfig>
Machine #2:
<netmachineconfig>
<info hostname="192.168.122.10" rootpass="redhat"/>
<netdevice hwaddr="52:54:00:91:01:9c" phys_id="1" type="eth"/>
</netmachineconfig>
Let's drop network completely and add 'bridge' parameter to interfaces
that can be
dynamically created. It will indicate to what bridge will be the new
interface
connected to.
In this case, fist machine is virtual, its first interface is virtual,
but is marked
physical and LNST will assume, that the user did the configuration. The
second device
will be created dynamically.
The second machine is a bare metal and again, user is responsible for
all the configuration.
LNST should care only for interfaces that it actually can control. If
there's some device
marked physical, we should consider it properly configured by the user
and don't touch that.
LNST cannot go to lab and swap wires or something ...
I will demonstrate it tomorrow at the meeting.
Radek :)
11 years, 3 months
[lnst] Fix small typo in dev_name function
by Jiří Pírko
commit 669b58a96bb646e5e10477fdc533461c931a188c
Author: Jan Tluka <jtluka(a)redhat.com>
Date: Mon Aug 6 18:31:27 2012 +0200
Fix small typo in dev_name function
Common/XmlTemplates.py | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
---
diff --git a/Common/XmlTemplates.py b/Common/XmlTemplates.py
index d79efe5..a3be062 100644
--- a/Common/XmlTemplates.py
+++ b/Common/XmlTemplates.py
@@ -274,13 +274,13 @@ class XmlTemplates:
msg = "First parameter of function devname() is invalid: "\
"Machine %s does not exist." % m_id
raise XmlTemplateError(msg)
- machines = recipe["machines"][m_id]
+ machine = recipe["machines"][m_id]
if if_id not in machine['netconfig']:
msg = "Second parameter of function devname() is invalid: "\
"Interface %s does not exist." % if_id
raise XmlTemplateError(msg)
- dev_name = machines['netconfig'][if_id]['name']
+ dev_name = machine['netconfig'][if_id]['name']
return dev_name
11 years, 3 months
[PATCH] Fix small typo in dev_name function
by Jan Tluka
---
Common/XmlTemplates.py | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Common/XmlTemplates.py b/Common/XmlTemplates.py
index d79efe5..a3be062 100644
--- a/Common/XmlTemplates.py
+++ b/Common/XmlTemplates.py
@@ -274,13 +274,13 @@ class XmlTemplates:
msg = "First parameter of function devname() is invalid: "\
"Machine %s does not exist." % m_id
raise XmlTemplateError(msg)
- machines = recipe["machines"][m_id]
+ machine = recipe["machines"][m_id]
if if_id not in machine['netconfig']:
msg = "Second parameter of function devname() is invalid: "\
"Interface %s does not exist." % if_id
raise XmlTemplateError(msg)
- dev_name = machines['netconfig'][if_id]['name']
+ dev_name = machine['netconfig'][if_id]['name']
return dev_name
--
1.7.6.5
11 years, 4 months