Blame SOURCES/0008-save_to_file-support-saveconfig-at-storage-object-le.patch

4959d3
From 7cc8531b03f5391f8c2fa1208c4f6b6e7b030b66 Mon Sep 17 00:00:00 2001
4959d3
From: Maurizio Lombardi <mlombard@redhat.com>
4959d3
Date: Tue, 10 Apr 2018 15:18:37 +0200
4959d3
Subject: [PATCH] save_to_file: support saveconfig at storage object level
4959d3
4959d3
Added an option to update configuration for single storage object at a time.
4959d3
As of today changes done for one storage object needs the whole configuration
4959d3
update. This option will enable us to save changes done to a give storage object.
4959d3
4959d3
$ targetcli /backstores/user:glfs/block1 help
4959d3
[...]
4959d3
AVAILABLE COMMANDS
4959d3
[...]
4959d3
    - saveconfig [savefile]
4959d3
    - set [group] [parameter=value...]
4959d3
    - status
4959d3
    - version
4959d3
4959d3
$ targetcli /backstores/user:glfs/block1 saveconfig
4959d3
Storage Object 'user:block1' config saved to /etc/target/saveconfig.json
4959d3
4959d3
Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
4959d3
Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
4959d3
---
4959d3
 rtslib/root.py | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
4959d3
 1 file changed, 84 insertions(+), 2 deletions(-)
4959d3
4959d3
diff --git a/rtslib/root.py b/rtslib/root.py
4959d3
index 99a25b7..c6697cf 100644
4959d3
--- a/rtslib/root.py
4959d3
+++ b/rtslib/root.py
4959d3
@@ -148,6 +148,83 @@ class RTSRoot(CFSNode):
4959d3
     def __str__(self):
4959d3
         return "rtslib"
4959d3
 
4959d3
+    def _get_saveconf(self, so_path, save_file):
4959d3
+        '''
4959d3
+        Fetch the configuration of all the blocks and return conf with
4959d3
+        updated storageObject info and its related target configuraion of
4959d3
+        given storage object path
4959d3
+        '''
4959d3
+        current = self.dump()
4959d3
+
4959d3
+        with open(save_file, "r") as f:
4959d3
+            saveconf = json.loads(f.read())
4959d3
+            f.close()
4959d3
+
4959d3
+        fetch_cur_so = False
4959d3
+        fetch_cur_tg = False
4959d3
+        # Get the given block current storageObj configuration
4959d3
+        for sidx, sobj in enumerate(current.get('storage_objects', [])):
4959d3
+            if '/backstores/' + sobj['plugin'] + '/' + sobj['name'] == so_path:
4959d3
+                current_so = current['storage_objects'][sidx]
4959d3
+                fetch_cur_so = True
4959d3
+                break
4959d3
+
4959d3
+        # Get the given block current target configuration
4959d3
+        if fetch_cur_so:
4959d3
+            for tidx, tobj in enumerate(current.get('targets', [])):
4959d3
+                if fetch_cur_tg:
4959d3
+                    break
4959d3
+                for luns in tobj.get('tpgs', []):
4959d3
+                    if fetch_cur_tg:
4959d3
+                        break
4959d3
+                    for lun in luns.get('luns', []):
4959d3
+                        if lun['storage_object'] == so_path:
4959d3
+                            current_tg = current['targets'][tidx]
4959d3
+                            fetch_cur_tg = True
4959d3
+                            break
4959d3
+
4959d3
+        fetch_sav_so = False
4959d3
+        fetch_sav_tg = False
4959d3
+        # Get the given block storageObj from saved configuration
4959d3
+        for sidx, sobj in enumerate(saveconf.get('storage_objects', [])):
4959d3
+            if '/backstores/' + sobj['plugin'] + '/' + sobj['name'] == so_path:
4959d3
+                # Merge StorageObj
4959d3
+                if fetch_cur_so:
4959d3
+                    saveconf['storage_objects'][sidx] = current_so;
4959d3
+                # Remove StorageObj
4959d3
+                else:
4959d3
+                    saveconf['storage_objects'].remove(saveconf['storage_objects'][sidx])
4959d3
+                fetch_sav_so = True
4959d3
+                break
4959d3
+
4959d3
+        # Get the given block target from saved configuration
4959d3
+        if fetch_sav_so:
4959d3
+            for tidx, tobj in enumerate(saveconf.get('targets', [])):
4959d3
+                if fetch_sav_tg:
4959d3
+                    break
4959d3
+                for luns in tobj.get('tpgs', []):
4959d3
+                    if fetch_sav_tg:
4959d3
+                        break
4959d3
+                    for lun in luns.get('luns', []):
4959d3
+                        if lun['storage_object'] == so_path:
4959d3
+                            # Merge target
4959d3
+                            if fetch_cur_tg:
4959d3
+                                saveconf['targets'][tidx] = current_tg;
4959d3
+                            # Remove target
4959d3
+                            else:
4959d3
+                                saveconf['targets'].remove(saveconf['targets'][tidx])
4959d3
+                            fetch_sav_tg = True
4959d3
+                            break
4959d3
+
4959d3
+        # Insert storageObj
4959d3
+        if fetch_cur_so and not fetch_sav_so:
4959d3
+            saveconf['storage_objects'].append(current_so)
4959d3
+        # Insert target
4959d3
+        if fetch_cur_tg and not fetch_sav_tg:
4959d3
+            saveconf['targets'].append(current_tg)
4959d3
+
4959d3
+        return saveconf
4959d3
+
4959d3
     # RTSRoot public stuff
4959d3
 
4959d3
     def dump(self):
4959d3
@@ -257,7 +334,7 @@ class RTSRoot(CFSNode):
4959d3
 
4959d3
         return errors
4959d3
 
4959d3
-    def save_to_file(self, save_file=None):
4959d3
+    def save_to_file(self, save_file=None, so_path=None):
4959d3
         '''
4959d3
         Write the configuration in json format to a file.
4959d3
         Save file defaults to '/etc/targets/saveconfig.json'.
4959d3
@@ -265,9 +342,14 @@ class RTSRoot(CFSNode):
4959d3
         if not save_file:
4959d3
             save_file = default_save_file
4959d3
 
4959d3
+        if so_path:
4959d3
+            saveconf = self._get_saveconf(so_path, save_file)
4959d3
+        else:
4959d3
+            saveconf = self.dump()
4959d3
+
4959d3
         with open(save_file+".temp", "w+") as f:
4959d3
             os.fchmod(f.fileno(), stat.S_IRUSR | stat.S_IWUSR)
4959d3
-            f.write(json.dumps(self.dump(), sort_keys=True, indent=2))
4959d3
+            f.write(json.dumps(saveconf, sort_keys=True, indent=2))
4959d3
             f.write("\n")
4959d3
             f.flush()
4959d3
             os.fsync(f.fileno())
4959d3
-- 
4959d3
1.8.3.1
4959d3