Change in vdsm[master]: net: add rollback_trigger to Config()

phoracek at redhat.com phoracek at redhat.com
Thu Apr 14 13:22:02 UTC 2016


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

Change subject: net: add rollback_trigger to Config()
......................................................................

net: add rollback_trigger to Config()

This patch introduces rollback_trigger() method to Config().
Is will be used as a rollback trigger for OVS switch and could
also replace unified rollback mechanism from legacy switch.

Change-Id: Iab1dcf346a5d5de15f01148a58abc4ae6e0ab97d
Bug-Url: https://bugzilla.redhat.com/1195208
Signed-off-by: Petr Horáček <phoracek at redhat.com>
---
M lib/vdsm/netconfpersistence.py
M tests/network/conf_persistence_test.py
2 files changed, 52 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/49/56149/1

diff --git a/lib/vdsm/netconfpersistence.py b/lib/vdsm/netconfpersistence.py
index 6397a7c..7bda855 100644
--- a/lib/vdsm/netconfpersistence.py
+++ b/lib/vdsm/netconfpersistence.py
@@ -19,11 +19,14 @@
 #
 
 from __future__ import absolute_import
+from contextlib import contextmanager
+from copy import deepcopy
 import errno
 import json
 import logging
 import os
 import pwd
+import sys
 
 from .config import config
 from .tool.restore_nets import restore
@@ -31,6 +34,7 @@
 from . import constants
 from . import utils
 from vdsm.network.canonicalize import canonicalize_networks
+from vdsm.network import errors as ne
 
 CONF_RUN_DIR = constants.P_VDSM_RUN + 'netconf/'
 # The persistent path is inside of an extra "persistence" dir in order to get
@@ -195,6 +199,22 @@
         _clear_dir(self.networksPath)
         _clear_dir(self.bondingsPath)
 
+    @contextmanager
+    def rollback_trigger(self, in_rollback):
+        self._backup = deepcopy(self)
+        try:
+            yield
+        except:
+            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 = self.diffFrom(self.backup)
+                if config_diff:
+                    raise ne.RollbackIncomplete(config_diff, type, value)
+
 
 class RunningConfig(Config):
     def __init__(self):
diff --git a/tests/network/conf_persistence_test.py b/tests/network/conf_persistence_test.py
index 4f52557..0646bb6 100644
--- a/tests/network/conf_persistence_test.py
+++ b/tests/network/conf_persistence_test.py
@@ -29,6 +29,7 @@
 from nose.plugins.attrib import attr
 
 from vdsm.netconfpersistence import Config
+from vdsm.network import errors as ne
 from vdsm.utils import rmFile
 
 from testlib import VdsmTestCase as TestCaseBase
@@ -114,3 +115,34 @@
         configB.removeNetwork(NETWORK)
         diff = configA.diffFrom(configB)
         self.assertIn(NETWORK, diff.networks)
+
+    def test_rollback_successful_setup(self):
+        config = Config(self.tempdir)
+        with self.assertNotRaises():
+            with config.rollback_trigger(in_rollback=False):
+                pass
+
+    def test_rollback_failed_setup(self):
+        config = Config(self.tempdir)
+        config.setNetwork('to-stay', {'nic': 'eth0'})
+        config.setNetwork('to-edit', {'nic': 'eth1'})
+        config.setNetwork('to-remove', {'nic': 'eth2'})
+
+        try:
+            with config.rollback_trigger(in_rollback=False):
+                config.setNetwork('to-add', {'nic': 'eth3'})
+                config.setNetwork('to-edit', {'nic': 'eth4'})
+                config.removeNetwork('to-remove')
+                raise Exception('Setup failed, rollback please.')
+        except ne.RollbackIncomplete as roi:
+            diff, _, _ = roi
+            self.assertEquals(diff.networks['to-remove']['nic'], 'eth2')
+            self.assertEquals(diff.networks['to-add'], {'remove': True})
+        else:
+            raise
+
+    def test_rollback_failed_setup_in_rollback(self):
+        config = Config(self.tempdir)
+        with self.assertRaises(RuntimeError):
+            with config.rollback_trigger(in_rollback=True):
+                raise RuntimeError()


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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iab1dcf346a5d5de15f01148a58abc4ae6e0ab97d
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