Change in vdsm[master]: net: native ovs [5]: rollback manager

phoracek at redhat.com phoracek at redhat.com
Sun Mar 27 14:45:59 UTC 2016


Petr Horáček has uploaded a new change for review.

Change subject: net: native ovs [5]: rollback manager
......................................................................

net: native ovs [5]: rollback manager

Introduce rollback manager for OVS switch. This context manager keeps
running config. After a successful setup it saves running config,
after failed one, it triggers unified rollback via RollbackIncomplete
exception.

Change-Id: I5bceae0aada964c47aacfcfdbe93ca19eb8f3d15
Bug-Url: https://bugzilla.redhat.com/1195208
Signed-off-by: Petr Horáček <phoracek at redhat.com>
---
M lib/vdsm/network/ovs/switch.py
M tests/network/ovs_test.py
2 files changed, 72 insertions(+), 4 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/12/55312/1

diff --git a/lib/vdsm/network/ovs/switch.py b/lib/vdsm/network/ovs/switch.py
index f5059f4..53d8380 100644
--- a/lib/vdsm/network/ovs/switch.py
+++ b/lib/vdsm/network/ovs/switch.py
@@ -19,11 +19,14 @@
 from __future__ import absolute_import
 
 from contextlib import contextmanager
+import logging
+import sys
 
 import six
 
 from vdsm.netconfpersistence import RunningConfig
 from vdsm.netinfo.cache import CachingNetInfo
+from vdsm.network.api import RollbackIncomplete
 
 from . import utils
 from . import validator
@@ -50,12 +53,22 @@
 
 @contextmanager
 def rollback_manager(in_rollback):
+    """Keep running_config and in case of an exception, trigger rollback."""
+    running_config = RunningConfig()
     try:
-        yield
+        yield running_config
     except:
-        pass
-    finally:
-        pass
+        type, value, traceback = sys.exc_info()
+        if in_rollback:
+            logging.error('Failed rollback transaction to last known good '
+                          'network.', exc_info=(type, value, traceback))
+            raise
+        else:
+            config_diff = RunningConfig().diffFrom(running_config)
+            if config_diff:
+                raise RollbackIncomplete(config_diff, type, value)
+    else:
+        running_config.save()
 
 
 def setup(nets, bonds, running_config):
diff --git a/tests/network/ovs_test.py b/tests/network/ovs_test.py
index 0b2874e..527644b 100644
--- a/tests/network/ovs_test.py
+++ b/tests/network/ovs_test.py
@@ -20,8 +20,12 @@
 
 from copy import deepcopy
 
+from vdsm import netconfpersistence
+from vdsm.network.api import RollbackIncomplete
+from vdsm.network.ovs import switch as ovs_switch
 from vdsm.network.ovs import utils as ovs_utils
 
+from monkeypatch import MonkeyPatch
 from testlib import VdsmTestCase as TestCaseBase
 
 
@@ -81,3 +85,54 @@
             gathered_ovs_nets[net] = attrs
 
         self.assertEquals(gathered_ovs_nets, ovs_nets)
+
+
+class RollbackManagerTests(TestCaseBase):
+    """
+    Test if successfull run saves running config (override it)
+    Test if failed reutrns correct exception
+    Test if in_rollback=True returns real cause
+    """
+
+    class FakeRunningConfig(netconfpersistence.BaseConfig):
+        def __init__(self, *args, **kwargs):
+            self.networks = {'net1': {'nic': 'eth0'}}
+            self.bonds = {}
+            self.saved = False
+
+        def save(self):
+            self.saved = True
+
+    @MonkeyPatch(netconfpersistence, 'RunningConfig', FakeRunningConfig)
+    def test_successful_setup(self):
+        with ovs_switch.rollback_manager(in_rollback=False) as running_config:
+            running_config.setNetwork('net1', {'nic': 'eth1'})
+
+        self.assertTrue(running_config.saved)
+        self.assertEquals(running_config.networks['net1']['nic'], 'eth1')
+
+    @MonkeyPatch(netconfpersistence, 'RunningConfig', FakeRunningConfig)
+    def test_failed_setup(self):
+        try:
+            with ovs_switch.rollback_manager(in_rollback=False) as \
+                    running_config:
+                running_config.setNetwork('net1', {'nic': 'eth1'})
+                running_config.setNetwork('net2', {'nic': 'eth2'})
+                raise Exception('This is not a test.')
+        except RollbackIncomplete as roi:
+            self.assertEquals(
+                roi.diff.networks,
+                {'net1': {'nic': 'eth0'}, 'net2': {'remove': True}})
+        else:
+            raise
+
+        self.assertFalse(running_config.saved)
+
+    @MonkeyPatch(netconfpersistence, 'RunningConfig', FakeRunningConfig)
+    def test_failed_setup_in_rollback(self):
+        with self.assertRaises(OSError):
+            with ovs_switch.rollback_manager(in_rollback=True) as \
+                    running_config:
+                raise OSError()
+
+        self.assertFalse(running_config.saved)


-- 
To view, visit https://gerrit.ovirt.org/55312
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I5bceae0aada964c47aacfcfdbe93ca19eb8f3d15
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Petr Horáček <phoracek at redhat.com>


More information about the vdsm-patches mailing list