From: Ondrej Lichtner <olichtne(a)redhat.com>
Exceptions raised during execution of triggers are now catched and
transformed into XmlProcessing exceptions. This gives the user
additional information about where the problem occured during parsing of
the recipe.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
NetTest/NetTestParse.py | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/NetTest/NetTestParse.py b/NetTest/NetTestParse.py
index fbe5adc..4c46b0c 100644
--- a/NetTest/NetTestParse.py
+++ b/NetTest/NetTestParse.py
@@ -139,8 +139,11 @@ class NetMachineConfigParse(RecipeParser):
info["system_config"] = {}
- self._trigger_event("machine_info_ready",
- {"machine_id": self._machine_id})
+ try:
+ self._trigger_event("machine_info_ready",
+ {"machine_id": self._machine_id})
+ except Exception, exc:
+ raise XmlProcessingError(str(exc), node)
def _netdevices(self, node, params):
scheme = {"netdevice": self._netdevice,
@@ -179,8 +182,11 @@ class NetMachineConfigParse(RecipeParser):
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})
+ try:
+ self._trigger_event("netdevice_ready",
+ {"machine_id": self._machine_id, "dev_id":
phys_id})
+ except Exception, exc:
+ raise XmlProcessingError(str(exc), node)
class NetConfigParse(RecipeParser):
@@ -230,9 +236,12 @@ class NetConfigParse(RecipeParser):
self._process_child_nodes(node, scheme, params)
- self._trigger_event("interface_config_ready",
- {"machine_id": self._machine_id,
- "netdev_config_id": dev_id})
+ try:
+ self._trigger_event("interface_config_ready",
+ {"machine_id": self._machine_id,
+ "netdev_config_id": dev_id})
+ except Exception, exc:
+ raise XmlProcessingError(str(exc), node)
def _process_phys_id_attr(self, node, dev):
netconfig = self._netconfig
--
1.7.11.2
Show replies by thread
From: Ondrej Lichtner <olichtne(a)redhat.com>
Since machine preparation is done during recipe parsing, exceptions
result in a crash of the application without cleaning up the partial
changes.
This commit fixes that by calling cleanup functions after an exception
was raised.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
NetTest/NetTestController.py | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/NetTest/NetTestController.py b/NetTest/NetTestController.py
index 296150d..839d51c 100644
--- a/NetTest/NetTestController.py
+++ b/NetTest/NetTestController.py
@@ -276,7 +276,14 @@ class NetTestController:
def _prepare(self):
# All the perparations are made within the recipe parsing
# This is achieved by handling parser events (by registering
- self._ntparse.parse_recipe()
+ try:
+ self._ntparse.parse_recipe()
+ except Exception, exc:
+ logging.debug("Exception raised during recipe parsing. "\
+ "Deconfiguring machines.")
+ self._deconfigure_slaves()
+ self._disconnect_slaves()
+ raise exc
def _run_command(self, command):
machine_id = command["machine_id"]
--
1.7.11.2
From: Ondrej Lichtner <olichtne(a)redhat.com>
Currently cleanup expects that all the machines were configured without
problems. However, this isn't true when an error occured during recipe
parsing.
This commit fixes that by skipping parts that were not configured yet.
It skips machines that don't yet have an rpc connection initialized
because these couldn't have been configured previously.
It also introduces a new list info["created_devices"] which contains all
properly created dynamic devices that need to be removed.
Both of these were added because recipe parsing can fail after creating
data structures for the machine/devices but before actually storing data
in them. This can result in exceptions during cleanup which is again
unwanted behaviour.
I don't know if this is the best solution so if you have a better idea I
am open for discussion.
Signed-off-by: Ondrej Lichtner <olichtne(a)redhat.com>
---
NetTest/NetTestController.py | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/NetTest/NetTestController.py b/NetTest/NetTestController.py
index 839d51c..72233c5 100644
--- a/NetTest/NetTestController.py
+++ b/NetTest/NetTestController.py
@@ -136,6 +136,10 @@ class NetTestController:
% (dev_id, dev["hwaddr"], machine_id)
raise NetTestError(msg)
+ if 'created_devices' not in info:
+ info['created_devices'] = []
+ info['created_devices'].append((dev_id, dev))
+
phys_devs = rpc.get_devices_by_hwaddr(dev["hwaddr"])
if len(phys_devs) == 1:
pass
@@ -247,18 +251,20 @@ class NetTestController:
def _deconfigure_slaves(self):
for machine_id in self._recipe["machines"]:
info = self._get_machineinfo(machine_id)
+ if "rpc" not in info:
+ continue
rpc = self._get_machinerpc(machine_id)
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"])
+ if "created_devices" not in info:
+ continue
+ for dev_id, dev in reversed(info["created_devices"]):
+ 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"]
--
1.7.11.2