From d3d2efbf50a84a83c20a0bedc2b731b4c455c565 Mon Sep 17 00:00:00 2001
From: "A. Wilcox" <AWilcox@Wilcox-Tech.com>
Date: Tue, 8 Dec 2020 19:02:46 -0600
Subject: NMSA: Add rollback() and transaction() methods

---
 doc/network.rst                   | 13 +++++++++++++
 ncserver/module/nms_ifupdownng.py | 24 ++++++++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git a/doc/network.rst b/doc/network.rst
index 7291249..eef0e68 100644
--- a/doc/network.rst
+++ b/doc/network.rst
@@ -174,6 +174,19 @@ Saves all queued operations to configuration storage and configures
 network interfaces.
 
 
+``rollback()``
+~~~~~~~~~~~~~~
+
+Erases all queued operations and restores the configuration from when
+the transaction began.
+
+
+``transaction()``
+~~~~~~~~~~~~~~~~~
+
+A Python context manager designed to be used with the ``with`` keyword.
+
+
 
 Parameters
 ----------
diff --git a/ncserver/module/nms_ifupdownng.py b/ncserver/module/nms_ifupdownng.py
index 8c92717..0c03fd9 100644
--- a/ncserver/module/nms_ifupdownng.py
+++ b/ncserver/module/nms_ifupdownng.py
@@ -10,6 +10,8 @@ with this source distribution for more information.
 SPDX-License-Identifier: NCSA
 """
 
+from contextlib import contextmanager
+
 import logging
 import pathlib
 import socket
@@ -573,6 +575,28 @@ def commit():
     _TRANSACTION = False
 
 
+def rollback():
+    """Roll back outstanding operations."""
+    global _TRANSACTION  # pylint: disable=W0603
+
+    _load_config()
+    _load_sysctl_cfg()
+
+    _TRANSACTION = False
+
+
+@contextmanager
+def transaction():
+    begin_transaction()
+    try:
+        yield None
+    except:
+        rollback()
+        raise
+    else:
+        commit()
+
+
 def get_param(iface: str, parameter: str):
     """Retrieve the parameter for the specified interface."""
     _load_config()
-- 
cgit v1.2.3-70-g09d2