[PATCH] Machine: fix timeout handling
by Ondrej Lichtner
From: Ondrej Lichtner <olichtne(a)redhat.com>
Before the reimplementation of controller <-> slave communication we
used socket timeouts to implement command timeouts. However since now we
are using select calls over all our connections this doesn't work
anymore. Furthermore using select timeout isn't very usefull as we are
continually recieving log messages from other slaves.
This commit implements the timeout mechanism by using the signal.alarm
call. The handler function raises an Exception that indicates a timeout
of a command.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Controller/Machine.py | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/lnst/Controller/Machine.py b/lnst/Controller/Machine.py
index d8162fc..006a5a0 100644
--- a/lnst/Controller/Machine.py
+++ b/lnst/Controller/Machine.py
@@ -17,6 +17,7 @@ import os
import re
import pickle
import tempfile
+import signal
from time import sleep
from xmlrpclib import Binary
from pprint import pprint, pformat
@@ -158,22 +159,24 @@ class Machine(object):
self._configured = False
+ def _timeout_handler(self, signum, frame):
+ msg = "RPC connection to machine %s timed out" % self.get_id()
+ raise MachineError(msg)
+
def run_command(self, command):
""" Run a command on the machine """
+ prev_handler = signal.signal(signal.SIGALRM, self._timeout_handler)
+
if "timeout" in command:
timeout = command["timeout"]
- logging.debug("Setting socket timeout to \"%d\"", timeout)
- socket.setdefaulttimeout(timeout)
- try:
- cmd_res = self._rpc_call("run_command", command)
- except socket.timeout:
- msg = "RPC connection to machine %s timed out" % self.get_id()
- raise Machine(msg)
- finally:
- if "timeout" in command:
- logging.debug("Setting socket timeout to default value")
- socket.setdefaulttimeout(None)
+ logging.debug("Setting timeout to \"%d\"", timeout)
+ signal.alarm(timeout)
+
+ cmd_res = self._rpc_call("run_command", command)
+
+ signal.alarm(0)
+ signal.signal(signal.SIGALRM, prev_handler)
return cmd_res
--
1.8.1.4
10 years, 10 months
[PATCH] VirtUtils: bridge initialization adds iptables rules
by Ondrej Lichtner
From: Ondrej Lichtner <olichtne(a)redhat.com>
When creating virtual networks we are using bridge interfaces on the
host machine. The default behaviour of these bridges is to filter
packets through iptables, which resulted in IPv6 communication being
blocked. This commit fixes that by adding iptable calls to the bridge
initialization. Every newly created bridge now works as an isolated
network.
>From what I've seen these are the same rules added by libvirt when
creating an isolated network.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
lnst/Common/VirtUtils.py | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/lnst/Common/VirtUtils.py b/lnst/Common/VirtUtils.py
index 71659ef..e13bfe2 100644
--- a/lnst/Common/VirtUtils.py
+++ b/lnst/Common/VirtUtils.py
@@ -36,6 +36,18 @@ def _brctl(cmd):
except ExecCmdFail as err:
raise VirtUtilsError("brctl error: %s" % err)
+def _iptables(cmd):
+ try:
+ exec_cmd("iptables %s" % cmd)
+ except ExecCmdFail as err:
+ raise VirtUtilsError("iptables error: %s" % err)
+
+def _ip6tables(cmd):
+ try:
+ exec_cmd("ip6tables %s" % cmd)
+ except ExecCmdFail as err:
+ raise VirtUtilsError("ip6tables error: %s" % err)
+
def _virsh(cmd):
try:
exec_cmd("virsh %s" % cmd, log_outputs=False)
@@ -233,6 +245,14 @@ class BridgeCtl(NetCtl):
def init(self):
if not self._exists():
_brctl("addbr %s" % self._name)
+ _iptables("-I FORWARD 1 -j REJECT -i %s -o any" % self._name)
+ _iptables("-I FORWARD 1 -j REJECT -i any -o %s" % self._name)
+ _iptables("-I FORWARD 1 -j ACCEPT -i %s -o %s" %
+ (self._name, self._name))
+ _ip6tables("-I FORWARD 1 -j REJECT -i %s -o any" % self._name)
+ _ip6tables("-I FORWARD 1 -j REJECT -i any -o %s" % self._name)
+ _ip6tables("-I FORWARD 1 -j ACCEPT -i %s -o %s" %
+ (self._name, self._name))
self._remove = True
_ip("link set %s up" % self._name)
@@ -241,3 +261,11 @@ class BridgeCtl(NetCtl):
if self._remove:
_ip("link set %s down" % self._name)
_brctl("delbr %s" % self._name)
+ _iptables("-D FORWARD -j REJECT -i %s -o any" % self._name)
+ _iptables("-D FORWARD -j REJECT -i any -o %s" % self._name)
+ _iptables("-D FORWARD -j ACCEPT -i %s -o %s" %
+ (self._name, self._name))
+ _ip6tables("-D FORWARD -j REJECT -i %s -o any" % self._name)
+ _ip6tables("-D FORWARD -j REJECT -i any -o %s" % self._name)
+ _ip6tables("-D FORWARD -j ACCEPT -i %s -o %s" %
+ (self._name, self._name))
--
1.8.1.4
10 years, 10 months
[lnst] RecipeParse: restrict bg_id usage
by Jiří Pírko
commit 89614a0528e690332854ea1920dd040a99bf0ae5
Author: Ondrej Lichtner <olichtne(a)redhat.com>
Date: Fri May 31 13:15:42 2013 +0200
RecipeParse: restrict bg_id usage
The previous commit changed the execution of the system_config command,
which now cannot run in the background as it would break the
application. This commit adds a check to the recipe parser that will not
allow bg_id to be used in commands of type system_config, wait, intr and
kill.
This commit also updates the recipe schema accordingly.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
Signed-off-by: Jiri Pirko <jiri(a)resnulli.us>
lnst/Controller/RecipeParse.py | 5 ++++
recipe-schema.rng | 48 ++++++++++++++++++++++++++++++---------
2 files changed, 42 insertions(+), 11 deletions(-)
---
diff --git a/lnst/Controller/RecipeParse.py b/lnst/Controller/RecipeParse.py
index 8cac525..d2d1171 100644
--- a/lnst/Controller/RecipeParse.py
+++ b/lnst/Controller/RecipeParse.py
@@ -458,6 +458,11 @@ class CommandParse(LnstParser):
if self._has_attribute(node, "bg_id"):
command["bg_id"] = self._get_attribute(node, "bg_id")
+ if command["type"] in ["system_config", "wait", "intr", "kill"]:
+ msg = "Command %s cannot be run in the background!" \
+ % command["type"]
+ raise XmlProcessingError(msg, node)
+
if self._has_attribute(node, "desc"):
command["desc"] = self._get_attribute(node, "desc")
diff --git a/recipe-schema.rng b/recipe-schema.rng
index aa6d375..57445b4 100644
--- a/recipe-schema.rng
+++ b/recipe-schema.rng
@@ -319,7 +319,8 @@
<ref name="ctl_wait"/>
<ref name="exec"/>
<ref name="system_config"/>
- <ref name="other_commands"/>
+ <ref name="test"/>
+ <ref name="control_commands"/>
</choice>
<optional>
@@ -386,10 +387,6 @@
</attribute>
<optional>
- <attribute name="bg_id"/>
- </optional>
-
- <optional>
<attribute name="value"/>
</optional>
@@ -421,12 +418,45 @@
</optional>
</define>
- <define name="other_commands">
+ <define name="test">
+ <attribute name="machine_id"/>
+
+ <attribute name="type">
+ <value>test</value>
+ </attribute>
+
+ <optional>
+ <attribute name="bg_id"/>
+ </optional>
+
+ <optional>
+ <attribute name="value"/>
+ </optional>
+
+ <optional>
+ <attribute name="timeout">
+ <data type="integer"/>
+ </attribute>
+ </optional>
+
+ <optional>
+ <attribute name="option"/>
+ </optional>
+
+ <optional>
+ <attribute name="desc"/>
+ </optional>
+
+ <optional>
+ <attribute name="source"/>
+ </optional>
+ </define>
+
+ <define name="control_commands">
<attribute name="machine_id"/>
<attribute name="type">
<choice>
- <value>test</value>
<value>wait</value>
<value>intr</value>
<value>kill</value>
@@ -434,10 +464,6 @@
</attribute>
<optional>
- <attribute name="bg_id"/>
- </optional>
-
- <optional>
<attribute name="value"/>
</optional>
10 years, 10 months
[lnst] NetTestSlave: fix restoration of system configuration
by Jiří Pírko
commit 16534640eaca8133cb6201672049cf9d040fb7d1
Author: Ondrej Lichtner <olichtne(a)redhat.com>
Date: Fri May 31 13:15:41 2013 +0200
NetTestSlave: fix restoration of system configuration
When the NetTestController code was refactored and several methods were
moved to the new class Machine, part of the code of run_command was
forgotten.
The system configuration data was moved to be stored in the slave
application, however for that the method _update_system_config has to be
called and that wasn't happening.
This commit fixes that. The fix also changes the behaviour of the
system_config command- it will not be running in the background anymore,
instead it is run in the main lnst-slave application, just like the
wait/intr/kill commands.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
Signed-off-by: Jiri Pirko <jiri(a)resnulli.us>
lnst/Common/NetTestCommand.py | 5 +++--
lnst/Slave/NetTestSlave.py | 11 +++++++++++
2 files changed, 14 insertions(+), 2 deletions(-)
---
diff --git a/lnst/Common/NetTestCommand.py b/lnst/Common/NetTestCommand.py
index 527764e..8dc9562 100644
--- a/lnst/Common/NetTestCommand.py
+++ b/lnst/Common/NetTestCommand.py
@@ -80,7 +80,8 @@ class NetTestCommand:
return self._finished
def run(self):
- if isinstance(self._cmd_cls, NetTestCommandControl):
+ if isinstance(self._cmd_cls, NetTestCommandControl) or \
+ isinstance(self._cmd_cls, NetTestCommandSystemConfig):
return self._cmd_cls.run()
self._read_pipe, self._write_pipe = multiprocessing.Pipe()
@@ -321,7 +322,7 @@ class NetTestCommandSystemConfig(NetTestCommandGeneric):
res = {"passed": True}
res["res_data"] = res_data
- self.set_result(res)
+ return res
class NetTestCommandControl(NetTestCommandGeneric):
def __init__(self, command_context, command):
diff --git a/lnst/Slave/NetTestSlave.py b/lnst/Slave/NetTestSlave.py
index 9b39c0a..d2dd484 100644
--- a/lnst/Slave/NetTestSlave.py
+++ b/lnst/Slave/NetTestSlave.py
@@ -207,6 +207,7 @@ class SlaveMethods:
logging.warn("Unable to restore '%s' config option!", option)
return False
+ self._system_config = {}
return True
def run_command(self, command):
@@ -218,6 +219,16 @@ class SlaveMethods:
res = cmd.run()
if not cmd.forked():
self._command_context.del_cmd(cmd)
+
+ if command["type"] == "system_config":
+ if res["passed"]:
+ self._update_system_config(res["res_data"]["options"],
+ command["persistent"])
+ else:
+ err = "Error occured while setting system "\
+ "configuration (%s)" % res["err_msg"]
+ logging.error(err)
+
return res
except:
log_exc_traceback()
10 years, 10 months
[lnst] lnst-ctl: use the new print_summary method
by Jiří Pírko
commit 33d1bfb2e360738bbf5e90198f4d871138897e02
Author: Ondrej Lichtner <olichtne(a)redhat.com>
Date: Fri May 31 11:06:40 2013 +0200
lnst-ctl: use the new print_summary method
This commit removes the old function that was used to print the summary
of test results. Instead the summary is printed via the use of the
NetTestResultSerializer method print_summary that was added in the
previous commit.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
Signed-off-by: Jiri Pirko <jiri(a)resnulli.us>
lnst-ctl | 12 +-----------
1 files changed, 1 insertions(+), 11 deletions(-)
---
diff --git a/lnst-ctl b/lnst-ctl
index 5701518..05f17c1 100755
--- a/lnst-ctl
+++ b/lnst-ctl
@@ -60,16 +60,6 @@ def process_recipe(action, file_path, cleanup, res_serializer,
logging.error("Unknown action \"%s\"" % action)
usage();
-def print_summary(summary):
- logging.info("====================== SUMMARY ======================")
- for recipe_file, res in summary:
- if res:
- res = "PASS"
- else:
- res = "FAIL"
- logging.info("*%s* %s" % (res, recipe_file))
- logging.info("=====================================================")
-
def get_recipe_result(args, file_path, cleanup, res_serializer, packet_capture,
config, log_ctl, pool_checks):
res_serializer.add_recipe(file_path)
@@ -178,7 +168,7 @@ def main():
log_ctl.set_recipe("", clean=False)
- print_summary(summary)
+ res_serializer.print_summary()
if result_path:
result_path = os.path.expanduser(result_path)
10 years, 10 months
[lnst] NetTestResultSerializer: add method print_summary
by Jiří Pírko
commit fecedc62ea3ac2b06edca660fc3f176913b44def
Author: Ondrej Lichtner <olichtne(a)redhat.com>
Date: Fri May 31 11:06:39 2013 +0200
NetTestResultSerializer: add method print_summary
This commit adds the method print_summary to the class
NetTestResultSerializer. The instances of this class contain recipe
results in DOM form. This was previously used to write results in XML
form to a file.
The test results can however be also used to provide a nice summary to
be printed at the end of lnst-ctl execution. This can now be done by
using the new method.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
Signed-off-by: Jiri Pirko <jiri(a)resnulli.us>
lnst/Controller/NetTestResultSerializer.py | 151 ++++++++++++++++++++++++++++
1 files changed, 151 insertions(+), 0 deletions(-)
---
diff --git a/lnst/Controller/NetTestResultSerializer.py b/lnst/Controller/NetTestResultSerializer.py
index 17b7f51..57577e7 100644
--- a/lnst/Controller/NetTestResultSerializer.py
+++ b/lnst/Controller/NetTestResultSerializer.py
@@ -13,6 +13,7 @@ jpirko(a)redhat.com (Jiri Pirko)
from xml.dom.minidom import getDOMImplementation
from lnst.Common.NetTestCommand import str_command
+import logging
def serialize_obj(obj, dom, el, upper_name="unnamed"):
if isinstance(obj, dict):
@@ -29,6 +30,13 @@ def serialize_obj(obj, dom, el, upper_name="unnamed"):
text = dom.createTextNode(str(obj))
el.appendChild(text)
+def get_node_val(node):
+ content = []
+ for child in node.childNodes:
+ if child.nodeType == child.TEXT_NODE:
+ content.append(child.nodeValue)
+ return str(''.join(content).strip())
+
class NetTestResultSerializer:
def __init__(self):
impl = getDOMImplementation()
@@ -86,3 +94,146 @@ class NetTestResultSerializer:
res_data_el = self._dom.createElement("result_data")
serialize_obj(cmd_res["res_data"], self._dom, res_data_el)
command_el.appendChild(res_data_el)
+
+ def print_summary(self):
+ output_pairs = []
+
+ for recipe in self._top_el.getElementsByTagName("recipe"):
+ recipe_name = recipe.getAttribute("name")
+ recipe_res = recipe.getAttribute("result")
+ output_pairs.append((recipe_name, recipe_res))
+
+ seq_num = 1
+ for cmd_seq in recipe.getElementsByTagName("command_sequence"):
+ command_sequence = 4*" "+"cmd_seq: %s" % seq_num
+ output_pairs.append((command_sequence, ""))
+
+ seq_num = seq_num + 1
+
+ for command in cmd_seq.getElementsByTagName("command"):
+ self._format_command(command, output_pairs)
+
+ self._print_pairs(output_pairs)
+
+ def _format_command(self, command, output_pairs):
+ cmd_type = command.getAttribute("type")
+ if cmd_type == "test":
+ self._format_test_command(command, output_pairs)
+ elif cmd_type == "wait":
+ self._format_wait_command(command, output_pairs)
+ elif cmd_type == "intr":
+ self._format_intr_command(command, output_pairs)
+ elif cmd_type == "kill":
+ self._format_kill_command(command, output_pairs)
+ elif cmd_type == "ctl_wait":
+ self._format_ctl_wait_command(command, output_pairs)
+ elif cmd_type == "exec":
+ self._format_exec_command(command, output_pairs)
+ elif cmd_type == "system_config":
+ self._format_system_config(command, output_pairs)
+
+ result_node = command.getElementsByTagName("result")[0]
+ cmd_res = result_node.getAttribute("result")
+
+ if cmd_res == "FAIL":
+ err_node = result_node.getElementsByTagName("error_message")
+ if len(err_node) != 0:
+ err_node = err_node[0]
+ text = get_node_val(err_node)
+ output_pairs.append((12*" "+"error message: "+text, ""))
+
+ def _format_test_command(self, command, output_pairs):
+ result_node = command.getElementsByTagName("result")[0]
+ cmd_res = result_node.getAttribute("result")
+
+ cmd_val = command.getAttribute("value")
+ cmd_type = command.getAttribute("type")
+ if command.hasAttribute("bg_id"):
+ bg_id = " bg_id: %s" % command.getAttribute("bg_id")
+ else:
+ bg_id = ""
+ cmd = 8*" "+"%-14s%s%s" %(cmd_type, cmd_val, bg_id)
+ output_pairs.append((cmd, cmd_res))
+
+ def _format_wait_command(self, command, output_pairs):
+ result_node = command.getElementsByTagName("result")[0]
+ cmd_res = result_node.getAttribute("result")
+
+ cmd_val = command.getAttribute("value")
+ cmd_type = command.getAttribute("type")
+ if command.hasAttribute("bg_id"):
+ bg_id = " bg_id: %s" % command.getAttribute("bg_id")
+ else:
+ bg_id = ""
+ cmd = 8*" "+"%-13s id: %s%s" %(cmd_type, cmd_val, bg_id)
+ output_pairs.append((cmd, cmd_res))
+
+ def _format_intr_command(self, command, output_pairs):
+ self._format_wait_command(command, output_pairs)
+
+ def _format_kill_command(self, command, output_pairs):
+ self._format_wait_command(command, output_pairs)
+
+ def _format_exec_command(self, command, output_pairs):
+ self._format_test_command(command, output_pairs)
+
+ def _format_ctl_wait_command(self, command, output_pairs):
+ result_node = command.getElementsByTagName("result")[0]
+ cmd_res = result_node.getAttribute("result")
+
+ cmd_val = command.getAttribute("value")
+ cmd_type = command.getAttribute("type")
+ cmd = 8*" "+"%-14s%ss" %(cmd_type, cmd_val)
+ output_pairs.append((cmd, cmd_res))
+
+ def _format_system_config(self, command, output_pairs):
+ result_node = command.getElementsByTagName("result")[0]
+ cmd_res = result_node.getAttribute("result")
+
+ cmd_type = command.getAttribute("type")
+ if command.hasAttribute("bg_id"):
+ bg_id = " bg_id: %s" % command.getAttribute("bg_id")
+ else:
+ bg_id = ""
+ cmd = 8*" "+"%-14s%s" %(cmd_type, bg_id)
+ output_pairs.append((cmd, cmd_res))
+
+ result_data_nodes = command.getElementsByTagName("result_data")
+ if len(result_data_nodes) != 0:
+ result_data_node = result_data_nodes[0]
+ options_nodes = result_data_node.getElementsByTagName("options")
+ for options_node in options_nodes:
+ for option in options_node.childNodes:
+ previous_node = option.getElementsByTagName("previous_val")[0]
+ current_node = option.getElementsByTagName("current_val")[0]
+ previous_val = get_node_val(previous_node)
+ current_val = get_node_val(current_node)
+ opt_left = 12*" "+"%s" % option.tagName
+ opt_right = "previous: %s current: %s" \
+ % (previous_val, current_val)
+ output_pairs.append((opt_left, opt_right))
+
+ def _print_pairs(self, output_pairs):
+ max_left = 0
+ max_right = 0
+ for left, right in output_pairs:
+ if len(left) > max_left and right != "":
+ max_left = len(left)
+ if len(right) > max_right:
+ max_right = len(right)
+
+ full_length = max_left + max_right
+ if full_length % 2:
+ full_length = full_length+2
+ else:
+ full_length = full_length+1
+
+ logging.info("="*((full_length-9)/2) + " SUMMARY " + "="*((full_length-9)/2))
+ for left, right in output_pairs:
+ if right != "":
+ space_fill = full_length - len(left) - len(right)
+ output = left + (space_fill)*" " + right
+ else:
+ output = left
+ logging.info(output)
+ logging.info("="*(full_length))
10 years, 10 months
[lnst] NetTestResultSerializer: add support for command_sequences
by Jiří Pírko
commit b720b424b695ec49dd41d6992cd82f6b317a2959
Author: Ondrej Lichtner <olichtne(a)redhat.com>
Date: Fri May 31 11:06:38 2013 +0200
NetTestResultSerializer: add support for command_sequences
This commit extends the xml format used by the result serializer to
include command sequences of the original recipe. I added this because
we use a lot of recipes with multiple command sequences and it can get
pretty confusing trying to figure out which commands are in the same
command sequence, when you're not directly looking at the recipe.
I also added a 'result' attribute to the <recipe> node, that contains
the cumulative result of the recipe. This is a little bit redundant
because you can deduce it from the results of individual commands. But
it's more convenient like this.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
Signed-off-by: Jiri Pirko <jiri(a)resnulli.us>
lnst/Controller/NetTestController.py | 1 +
lnst/Controller/NetTestResultSerializer.py | 15 ++++++++++++++-
2 files changed, 15 insertions(+), 1 deletions(-)
---
diff --git a/lnst/Controller/NetTestController.py b/lnst/Controller/NetTestController.py
index a43c299..3cf3f91 100644
--- a/lnst/Controller/NetTestController.py
+++ b/lnst/Controller/NetTestController.py
@@ -285,6 +285,7 @@ class NetTestController:
for sequence in self._recipe["sequences"]:
try:
+ self._res_serializer.add_command_sequence()
res = self._run_command_sequence(sequence)
except CommandException as exc:
logging.debug(exc)
diff --git a/lnst/Controller/NetTestResultSerializer.py b/lnst/Controller/NetTestResultSerializer.py
index 499a076..17b7f51 100644
--- a/lnst/Controller/NetTestResultSerializer.py
+++ b/lnst/Controller/NetTestResultSerializer.py
@@ -35,6 +35,7 @@ class NetTestResultSerializer:
self._dom = impl.createDocument(None, "results", None)
self._top_el = self._dom.documentElement
self._cur_recipe_el = None
+ self._cur_cmd_seq_el = None
def __str__(self):
return self._dom.toprettyxml()
@@ -42,12 +43,20 @@ class NetTestResultSerializer:
def add_recipe(self, name):
recipe_el = self._dom.createElement("recipe")
recipe_el.setAttribute("name", name)
+ recipe_el.setAttribute("result", "FAIL")
self._top_el.appendChild(recipe_el)
self._cur_recipe_el = recipe_el
+ self._cur_cmd_seq_el = None
+ self._first_command = True
+
+ def add_command_sequence(self):
+ cmd_seq_el = self._dom.createElement("command_sequence")
+ self._cur_recipe_el.appendChild(cmd_seq_el)
+ self._cur_cmd_seq_el = cmd_seq_el
def add_cmd_result(self, command, cmd_res):
command_el = self._dom.createElement("command")
- self._cur_recipe_el.appendChild(command_el)
+ self._cur_cmd_seq_el.appendChild(command_el)
for key in command:
if key == "options":
@@ -59,9 +68,13 @@ class NetTestResultSerializer:
if cmd_res["passed"]:
res = "PASS"
+ if self._first_command:
+ self._cur_recipe_el.setAttribute("result", "PASS")
else:
res = "FAIL"
+ self._cur_recipe_el.setAttribute("result", "FAIL")
result_el.setAttribute("result", res)
+ self._first_command = False
if "err_msg" in cmd_res:
err_el = self._dom.createElement("error_message")
10 years, 10 months
[lnst] Fix bracket typo
by Jiří Pírko
commit dffc2ad29f6126b5fdc6f1f37b84271111670baa
Author: Jan Tluka <jtluka(a)redhat.com>
Date: Wed May 29 15:46:48 2013 +0200
Fix bracket typo
I accidentally wrote incorrect brackets that results in crash of the
controller application. This commit fixes it.
Signed-off-by: Jan Tluka <jtluka(a)redhat.com>
Signed-off-by: Jiri Pirko <jiri(a)resnulli.us>
lnst-ctl | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
---
diff --git a/lnst-ctl b/lnst-ctl
index 1ed3515..5701518 100755
--- a/lnst-ctl
+++ b/lnst-ctl
@@ -145,7 +145,7 @@ def main():
action = args.pop()
- if not action in {'run', 'dump', 'config_only', 'match_setup'}:
+ if not action in ['run', 'dump', 'config_only', 'match_setup']:
logging.error("No action command passed")
usage();
10 years, 10 months
[lnst] Machine: fix timeout handling
by Jiří Pírko
commit 9cb6f1ce65ac294d08942fec38541bf9776c628a
Author: Ondrej Lichtner <olichtne(a)redhat.com>
Date: Mon May 27 15:53:32 2013 +0200
Machine: fix timeout handling
Before the reimplementation of controller <-> slave communication we
used socket timeouts to implement command timeouts. However since now we
are using select calls over all our connections this doesn't work
anymore. Furthermore using select timeout isn't very usefull as we are
continually recieving log messages from other slaves.
This commit implements the timeout mechanism by using the signal.alarm
call. The handler function raises an Exception that indicates a timeout
of a command.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
Signed-off-by: Jiri Pirko <jiri(a)resnulli.us>
lnst/Controller/Machine.py | 25 ++++++++++++++-----------
1 files changed, 14 insertions(+), 11 deletions(-)
---
diff --git a/lnst/Controller/Machine.py b/lnst/Controller/Machine.py
index d8162fc..006a5a0 100644
--- a/lnst/Controller/Machine.py
+++ b/lnst/Controller/Machine.py
@@ -17,6 +17,7 @@ import os
import re
import pickle
import tempfile
+import signal
from time import sleep
from xmlrpclib import Binary
from pprint import pprint, pformat
@@ -158,22 +159,24 @@ class Machine(object):
self._configured = False
+ def _timeout_handler(self, signum, frame):
+ msg = "RPC connection to machine %s timed out" % self.get_id()
+ raise MachineError(msg)
+
def run_command(self, command):
""" Run a command on the machine """
+ prev_handler = signal.signal(signal.SIGALRM, self._timeout_handler)
+
if "timeout" in command:
timeout = command["timeout"]
- logging.debug("Setting socket timeout to \"%d\"", timeout)
- socket.setdefaulttimeout(timeout)
- try:
- cmd_res = self._rpc_call("run_command", command)
- except socket.timeout:
- msg = "RPC connection to machine %s timed out" % self.get_id()
- raise Machine(msg)
- finally:
- if "timeout" in command:
- logging.debug("Setting socket timeout to default value")
- socket.setdefaulttimeout(None)
+ logging.debug("Setting timeout to \"%d\"", timeout)
+ signal.alarm(timeout)
+
+ cmd_res = self._rpc_call("run_command", command)
+
+ signal.alarm(0)
+ signal.signal(signal.SIGALRM, prev_handler)
return cmd_res
10 years, 10 months
[lnst] VirtUtils: bridge initialization adds iptables rules
by Jiří Pírko
commit b148b222281fd5c23cee7e38c853cd6584a22efa
Author: Ondrej Lichtner <olichtne(a)redhat.com>
Date: Mon May 27 15:53:23 2013 +0200
VirtUtils: bridge initialization adds iptables rules
When creating virtual networks we are using bridge interfaces on the
host machine. The default behaviour of these bridges is to filter
packets through iptables, which resulted in IPv6 communication being
blocked. This commit fixes that by adding iptable calls to the bridge
initialization. Every newly created bridge now works as an isolated
network.
From what I've seen these are the same rules added by libvirt when
creating an isolated network.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
Signed-off-by: Jiri Pirko <jiri(a)resnulli.us>
lnst/Common/VirtUtils.py | 28 ++++++++++++++++++++++++++++
1 files changed, 28 insertions(+), 0 deletions(-)
---
diff --git a/lnst/Common/VirtUtils.py b/lnst/Common/VirtUtils.py
index 71659ef..e13bfe2 100644
--- a/lnst/Common/VirtUtils.py
+++ b/lnst/Common/VirtUtils.py
@@ -36,6 +36,18 @@ def _brctl(cmd):
except ExecCmdFail as err:
raise VirtUtilsError("brctl error: %s" % err)
+def _iptables(cmd):
+ try:
+ exec_cmd("iptables %s" % cmd)
+ except ExecCmdFail as err:
+ raise VirtUtilsError("iptables error: %s" % err)
+
+def _ip6tables(cmd):
+ try:
+ exec_cmd("ip6tables %s" % cmd)
+ except ExecCmdFail as err:
+ raise VirtUtilsError("ip6tables error: %s" % err)
+
def _virsh(cmd):
try:
exec_cmd("virsh %s" % cmd, log_outputs=False)
@@ -233,6 +245,14 @@ class BridgeCtl(NetCtl):
def init(self):
if not self._exists():
_brctl("addbr %s" % self._name)
+ _iptables("-I FORWARD 1 -j REJECT -i %s -o any" % self._name)
+ _iptables("-I FORWARD 1 -j REJECT -i any -o %s" % self._name)
+ _iptables("-I FORWARD 1 -j ACCEPT -i %s -o %s" %
+ (self._name, self._name))
+ _ip6tables("-I FORWARD 1 -j REJECT -i %s -o any" % self._name)
+ _ip6tables("-I FORWARD 1 -j REJECT -i any -o %s" % self._name)
+ _ip6tables("-I FORWARD 1 -j ACCEPT -i %s -o %s" %
+ (self._name, self._name))
self._remove = True
_ip("link set %s up" % self._name)
@@ -241,3 +261,11 @@ class BridgeCtl(NetCtl):
if self._remove:
_ip("link set %s down" % self._name)
_brctl("delbr %s" % self._name)
+ _iptables("-D FORWARD -j REJECT -i %s -o any" % self._name)
+ _iptables("-D FORWARD -j REJECT -i any -o %s" % self._name)
+ _iptables("-D FORWARD -j ACCEPT -i %s -o %s" %
+ (self._name, self._name))
+ _ip6tables("-D FORWARD -j REJECT -i %s -o any" % self._name)
+ _ip6tables("-D FORWARD -j REJECT -i any -o %s" % self._name)
+ _ip6tables("-D FORWARD -j ACCEPT -i %s -o %s" %
+ (self._name, self._name))
10 years, 10 months