Hello community,

here is the log from the commit of package targetcli-fb for openSUSE:Factory 
checked in at 2018-10-22 11:23:11
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/targetcli-fb (Old)
 and      /work/SRC/openSUSE:Factory/.targetcli-fb.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "targetcli-fb"

Mon Oct 22 11:23:11 2018 rev:10 rq:643051 version:2.1.49

Changes:
--------
--- /work/SRC/openSUSE:Factory/targetcli-fb/targetcli-fb.changes        
2018-04-22 14:40:49.226404083 +0200
+++ /work/SRC/openSUSE:Factory/.targetcli-fb.new/targetcli-fb.changes   
2018-10-22 11:23:14.883161582 +0200
@@ -1,0 +2,33 @@
+Thu Oct 18 19:50:11 UTC 2018 - opensuse-packag...@opensuse.org
+
+- Update to version 2.1.49:
+  * version 2.1.fb49
+  * targetcli-fb: Add support for media change
+  * fix the parameter of define_config_group_param
+  * saveconfig: handle backups with block-level delete
+  * saveconfig: way for block-level save with delete command
+  * create: add a way to set control string
+  * fix amount of backup files in backup dir
+  * config: add saveconfig command to StorageObject level
+  * Allow to customize a home directory
+  * Fix default max_backup_files in ui_command_saveconfig
+  * MappedLuns and Luns max number is not the same anymore
+  * Use signed char instead of char
+  * version 2.1.fb48
+  * remove wrong exit code from targetcli --version
+  * backup: global option to tune max no. of backup conf files
+  * config: rename key 'kept_backups' as 'max_backup_files'
+  * config: backup when current config is different from recent backup copy
+  * config: defend on '/etc/target/backup' directory
+  * Auto-detect readonly state for iblock devices
+  * Read number of backup files to keep from file
+  * skip refreshing user backed storage object when it is null
+  * Replace dbus-python with GObject Introspection
+ This replaces targetcli-fb-2.1.47.tar.xz with targetcli-fb-2.1.49.tar.xz,
+ and removes the following patches:
+ * Auto-detect-readonly-state-for-iblock-devices.patch
+ * Use-signed-char-instead-of-char.patch
+ * targetcli-only-save-old-config-if-present.patch
+ and updates the SPEC file.
+
+-------------------------------------------------------------------

Old:
----
  Auto-detect-readonly-state-for-iblock-devices.patch
  Use-signed-char-instead-of-char.patch
  targetcli-fb-2.1.47.tar.xz
  targetcli-only-save-old-config-if-present.patch

New:
----
  targetcli-fb-2.1.49.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ targetcli-fb.spec ++++++
--- /var/tmp/diff_new_pack.WQ4ImA/_old  2018-10-22 11:23:15.455161007 +0200
+++ /var/tmp/diff_new_pack.WQ4ImA/_new  2018-10-22 11:23:15.455161007 +0200
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           targetcli-fb
-Version:        2.1.47
+Version:        2.1.49
 Release:        0
 Summary:        A command shell for managing the Linux LIO kernel target
 License:        Apache-2.0
@@ -54,11 +54,8 @@
 Obsoletes:      targetcli-rbd < %{version}
 %endif
 %{?systemd_requires}
-Patch1:         Auto-detect-readonly-state-for-iblock-devices.patch
-Patch2:         Use-signed-char-instead-of-char.patch
-Patch3:         Split-out-blockdev-readonly-state-detection-helper.patch
-Patch4:         rbd-support.patch
-Patch5:         targetcli-only-save-old-config-if-present.patch
+Patch1:         Split-out-blockdev-readonly-state-detection-helper.patch
+Patch2:         rbd-support.patch
 
 %python_subpackages
 
@@ -84,13 +81,10 @@
 %prep
 %setup -q
 %patch1 -p1
-%patch2 -p1
-%patch3 -p1
 %if 0%{?sle_version} == 150000
 # RBD support is dependent on LIO changes present in the SLE/Leap kernel
-%patch4 -p1
+%patch2 -p1
 %endif
-%patch5 -p1
 
 %build
 %python_build

++++++ _service ++++++
--- /var/tmp/diff_new_pack.WQ4ImA/_old  2018-10-22 11:23:15.483160979 +0200
+++ /var/tmp/diff_new_pack.WQ4ImA/_new  2018-10-22 11:23:15.483160979 +0200
@@ -7,7 +7,7 @@
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="versionrewrite-pattern">v(\d*\.\d*\.)fb(\d*)</param>
     <param name="versionrewrite-replacement">\1\2</param>
-    <param name="revision">v2.1.fb47</param>
+    <param name="revision">v2.1.fb49</param>
     <param name="changesgenerate">enable</param>
   </service>
   <service name="recompress" mode="disabled">

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.WQ4ImA/_old  2018-10-22 11:23:15.499160963 +0200
+++ /var/tmp/diff_new_pack.WQ4ImA/_new  2018-10-22 11:23:15.499160963 +0200
@@ -1,4 +1,4 @@
 <servicedata>
 <service name="tar_scm">
                 <param 
name="url">https://github.com/open-iscsi/targetcli-fb.git</param>
-              <param 
name="changesrevision">ee32a2493eaccd9352cc596b9e3387960cca48fc</param></service></servicedata>
\ No newline at end of file
+              <param 
name="changesrevision">4d08771c0e6bf3cacba2ed3d3127dd10a86a7847</param></service></servicedata>
\ No newline at end of file

++++++ rbd-support.patch ++++++
--- /var/tmp/diff_new_pack.WQ4ImA/_old  2018-10-22 11:23:15.511160951 +0200
+++ /var/tmp/diff_new_pack.WQ4ImA/_new  2018-10-22 11:23:15.511160951 +0200
@@ -9,14 +9,12 @@
 [dd...@suse.de: accept and propagate wwn parameter]
 Reviewed-by: David Disseldorp <dd...@suse.de>
 ---
- targetcli/ui_backstore.py | 59 +++++++++++++++++++++++++++++++++++++++++++++++
+ targetcli/ui_backstore.py |   59 
++++++++++++++++++++++++++++++++++++++++++++++
  1 file changed, 59 insertions(+)
 
-diff --git a/targetcli/ui_backstore.py b/targetcli/ui_backstore.py
-index 57dedb1..d576122 100644
 --- a/targetcli/ui_backstore.py
 +++ b/targetcli/ui_backstore.py
-@@ -29,6 +29,7 @@ import dbus
+@@ -29,6 +29,7 @@ import stat
  from configshell_fb import ExecutionError
  from rtslib_fb import BlockStorageObject, FileIOStorageObject
  from rtslib_fb import PSCSIStorageObject, RDMCPStorageObject, 
UserBackedStorageObject
@@ -24,7 +22,7 @@
  from rtslib_fb import ALUATargetPortGroup
  from rtslib_fb import RTSLibError
  from rtslib_fb import RTSRoot
-@@ -269,6 +270,7 @@ class UIBackstores(UINode):
+@@ -281,6 +282,7 @@ class UIBackstores(UINode):
          UIRDMCPBackstore(self)
          UIFileIOBackstore(self)
          UIBlockBackstore(self)
@@ -32,7 +30,7 @@
  
          for name, iface, prop_dict in self._user_backstores():
              UIUserBackedBackstore(self, name, iface, prop_dict)
-@@ -572,6 +574,48 @@ class UIBlockBackstore(UIBackstore):
+@@ -589,6 +591,48 @@ class UIBlockBackstore(UIBackstore):
              completions = [completions[0] + ' ']
          return completions
  
@@ -81,7 +79,7 @@
  
  class UIUserBackedBackstore(UIBackstore):
      '''
-@@ -739,6 +783,21 @@ class UIBlockStorageObject(UIStorageObject):
+@@ -791,6 +835,21 @@ class UIBlockStorageObject(UIStorageObje
          return ("%s (%s) %s%s %s" % (so.udev_path, bytes_to_human(so.size),
                                     ro_str, wb_str, so.status), True)
  
@@ -103,6 +101,3 @@
  
  class UIUserBackedStorageObject(UIStorageObject):
      def summary(self):
--- 
-2.13.6
-

++++++ targetcli-fb-2.1.47.tar.xz -> targetcli-fb-2.1.49.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/targetcli-fb-2.1.47/scripts/targetcli 
new/targetcli-fb-2.1.49/scripts/targetcli
--- old/targetcli-fb-2.1.47/scripts/targetcli   2017-08-15 23:35:32.000000000 
+0200
+++ new/targetcli-fb-2.1.49/scripts/targetcli   2018-09-05 14:08:11.000000000 
+0200
@@ -20,7 +20,7 @@
 
 from __future__ import print_function
 
-from os import getuid
+from os import getuid, getenv
 from targetcli import UIRoot
 from rtslib_fb import RTSLibError
 from configshell_fb import ConfigShell, ExecutionError
@@ -49,6 +49,7 @@
                      'auto_add_mapped_luns': True,
                      'auto_cd_after_create': False,
                      'auto_save_on_exit': True,
+                     'max_backup_files': '10',
                      'auto_add_default_portal': True,
                     }
 
@@ -63,7 +64,7 @@
 
 def version():
     print("%s version %s" % (sys.argv[0], targetcli_version), file=err)
-    sys.exit(-1)
+    sys.exit(0)
 
 def main():
     '''
@@ -74,7 +75,7 @@
     else:
         is_root = False
 
-    shell = TargetCLI('~/.targetcli')
+    shell = TargetCLI(getenv("TARGETCLI_HOME", '~/.targetcli'))
 
     try:
         root_node = UIRoot(shell, as_root=is_root)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/targetcli-fb-2.1.47/targetcli/ui_backstore.py 
new/targetcli-fb-2.1.49/targetcli/ui_backstore.py
--- old/targetcli-fb-2.1.47/targetcli/ui_backstore.py   2017-08-15 
23:35:32.000000000 +0200
+++ new/targetcli-fb-2.1.49/targetcli/ui_backstore.py   2018-09-05 
14:08:11.000000000 +0200
@@ -17,11 +17,14 @@
 under the License.
 '''
 
+from gi.repository import Gio
 import glob
 import os
+import fcntl
+import array
+import struct
 import re
 import stat
-import dbus
 
 from configshell_fb import ExecutionError
 from rtslib_fb import BlockStorageObject, FileIOStorageObject
@@ -33,6 +36,8 @@
 
 from .ui_node import UINode, UIRTSLibNode
 
+default_save_file = "/etc/target/saveconfig.json"
+
 alua_rw_params = ['alua_access_state', 'alua_access_status',
                   'alua_write_metadata', 'alua_access_type', 'preferred',
                   'nonop_delay_msecs', 'trans_delay_msecs',
@@ -128,7 +133,7 @@
             self.define_config_group_param("alua", param, 'string')
 
         for param in alua_ro_params:
-            self.define_config_group_param("alua", param, 'string', False)
+            self.define_config_group_param("alua", param, 'string', 
writable=False)
 
     def ui_getgroup_alua(self, alua_attr):
         return getattr(self.rtsnode, alua_attr)
@@ -229,16 +234,26 @@
         tcmu-runner (or other daemon providing the same service) exposes a
         DBus ObjectManager-based iface to find handlers it supports.
         '''
-        bus = dbus.SystemBus()
+        bus = Gio.bus_get_sync(Gio.BusType.SYSTEM, None)
         try:
-            mgr_obj = bus.get_object('org.kernel.TCMUService1', 
'/org/kernel/TCMUService1')
-            mgr_iface = dbus.Interface(mgr_obj, 
'org.freedesktop.DBus.ObjectManager')
-
-            for k,v in mgr_iface.GetManagedObjects().items():
-                tcmu_obj = bus.get_object('org.kernel.TCMUService1', k)
-                tcmu_iface = dbus.Interface(tcmu_obj, 
dbus_interface='org.kernel.TCMUService1')
+            mgr_iface = Gio.DBusProxy.new_sync(bus,
+                                               Gio.DBusProxyFlags.NONE,
+                                               None,
+                                               'org.kernel.TCMUService1',
+                                               '/org/kernel/TCMUService1',
+                                               
'org.freedesktop.DBus.ObjectManager',
+                                               None)
+
+            for k, v in mgr_iface.GetManagedObjects().items():
+                tcmu_iface = Gio.DBusProxy.new_sync(bus,
+                                                    Gio.DBusProxyFlags.NONE,
+                                                    None,
+                                                    'org.kernel.TCMUService1',
+                                                    k,
+                                                    'org.kernel.TCMUService1',
+                                                    None)
                 yield (k[k.rfind("/")+1:], tcmu_iface, v)
-        except dbus.DBusException as e:
+        except Exception as e:
             return
 
     def refresh(self):
@@ -269,7 +284,7 @@
     def summary(self):
         return ("Storage Objects: %d" % len(self._children), None)
 
-    def ui_command_delete(self, name):
+    def ui_command_delete(self, name, save=None):
         '''
         Recursively deletes the storage object having the specified I{name}. If
         there are LUNs using this storage object, they will be deleted too.
@@ -286,7 +301,12 @@
         except ValueError:
             raise ExecutionError("No storage object named %s." % name)
 
-        child.rtsnode.delete()
+        save = self.ui_eval_param(save, 'bool', False)
+        if save:
+            rn = self.get_root()
+            rn._save_backups(default_save_file)
+
+        child.rtsnode.delete(save=save)
         self.remove_child(child)
         self.shell.log.info("Deleted storage object %s." % name)
 
@@ -516,6 +536,25 @@
         self.so_cls = UIBlockStorageObject
         UIBackstore.__init__(self, 'block', parent)
 
+    def _ui_block_ro_check(self, dev):
+        BLKROGET=0x0000125E
+        try:
+            f = os.open(dev, os.O_RDONLY)
+        except (OSError, IOError):
+            raise ExecutionError("Could not open %s" % dev)
+        # ioctl returns an int. Provision a buffer for it
+        buf = array.array('b', [0] * 4)
+        try:
+            fcntl.ioctl(f, BLKROGET, buf)
+        except (OSError, IOError):
+            os.close(f)
+            return False
+
+        os.close(f)
+        if struct.unpack('I', buf)[0] == 0:
+            return False
+        return True
+
     def ui_command_create(self, name, dev, readonly=None, wwn=None):
         '''
         Creates an Block Storage object. I{dev} is the path to the TYPE_DISK
@@ -523,7 +562,13 @@
         '''
         self.assert_root()
 
-        readonly = self.ui_eval_param(readonly, 'bool', False)
+        ro_string = self.ui_eval_param(readonly, 'string', None)
+        if ro_string == None:
+            # attempt to detect block device readonly state via ioctl
+            readonly = self._ui_block_ro_check(dev)
+        else:
+            readonly = self.ui_eval_param(readonly, 'bool', False)
+
         wwn = self.ui_eval_param(wwn, 'string', None)
 
         so = BlockStorageObject(name, dev, readonly=readonly, wwn=wwn)
@@ -559,7 +604,7 @@
     def refresh(self):
         self._children = set([])
         for so in RTSRoot().storage_objects:
-            if so.plugin == 'user':
+            if so.plugin == 'user' and so.config:
                 idx = so.config.find("/")
                 handler = so.config[:idx]
                 if handler == self.handler:
@@ -575,7 +620,7 @@
             print()
 
     def ui_command_create(self, name, size, cfgstring, wwn=None,
-                          hw_max_sectors=None):
+                          hw_max_sectors=None, control=None):
         '''
         Creates a User-backed storage object.
 
@@ -595,13 +640,14 @@
 
         config = self.handler + "/" + cfgstring
 
-        ok, errmsg = self.iface.CheckConfig(config)
+        ok, errmsg = self.iface.CheckConfig('(s)', config)
         if not ok:
             raise ExecutionError("cfgstring invalid: %s" % errmsg)
 
         try:
             so = UserBackedStorageObject(name, size=size, config=config,
-                                         wwn=wwn, 
hw_max_sectors=hw_max_sectors)
+                                         wwn=wwn, 
hw_max_sectors=hw_max_sectors,
+                                         control=control)
         except:
             raise ExecutionError("UserBackedStorageObject creation failed.")
 
@@ -610,6 +656,19 @@
                             % (name, size))
         return self.new_node(ui_so)
 
+    def ui_command_changemedium(self, name, size, cfgstring):
+        size = human_to_bytes(size)
+        config = self.handler + "/" + cfgstring
+
+        try:
+            rc, errmsg = self.iface.ChangeMedium('(sts)', name, size, config)
+        except Exception as e:
+            raise ExecutionError("ChangeMedium failed: %s" % e)
+        else:
+            if rc == 0:
+                self.shell.log.info("Medium Changed.")
+            else:
+                raise ExecutionError("ChangeMedium failed: %s" % errmsg)
 
 class UIStorageObject(UIRTSLibNode):
     '''
@@ -635,6 +694,7 @@
         'fabric_max_sectors': ('number', 'Maximum number of sectors the fabric 
can transfer at once.'),
         'hw_block_size': ('number', 'Hardware block size in bytes.'),
         'hw_max_sectors': ('number', 'Maximum number of sectors the hardware 
can transfer at once.'),
+        'control': ('string', 'Comma separated string of control=value tuples 
that will be passed to kernel control file.'),
         'hw_pi_prot_type': ('number', 'If non-zero, DIF protection is enabled 
on the underlying hardware.'),
         'hw_queue_depth': ('number', 'Hardware queue depth.'),
         'is_nonrot': ('number', 'If set to 1, the backstore is a non 
rotational device.'),
@@ -664,6 +724,26 @@
         self.shell.con.display("Backstore plugin %s %s"
                                % (self.rtsnode.plugin, self.rtsnode.version))
 
+    def ui_command_saveconfig(self, savefile=None):
+        '''
+        Save configuration of this StorageObject.
+        '''
+        so = self.rtsnode
+        rn = self.get_root()
+
+        if not savefile:
+            savefile = default_save_file
+
+        savefile = os.path.expanduser(savefile)
+
+        rn._save_backups(savefile)
+
+        rn.rtsroot.save_to_file(savefile,
+                                '/backstores/' + so.plugin  + '/' + so.name)
+
+        self.shell.log.info("Storage Object '%s:%s' config saved to %s."
+                            % (so.plugin, so.name, savefile))
+
 
 class UIPSCSIStorageObject(UIStorageObject):
     def summary(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/targetcli-fb-2.1.47/targetcli/ui_node.py 
new/targetcli-fb-2.1.49/targetcli/ui_node.py
--- old/targetcli-fb-2.1.47/targetcli/ui_node.py        2017-08-15 
23:35:32.000000000 +0200
+++ new/targetcli-fb-2.1.49/targetcli/ui_node.py        2018-09-05 
14:08:11.000000000 +0200
@@ -46,6 +46,9 @@
         self.define_config_group_param(
             'global', 'auto_add_default_portal', 'bool',
             'If true, adds a portal listening on all IPs to new targets.')
+        self.define_config_group_param(
+            'global', 'max_backup_files', 'string',
+            'Max no. of configurations to be backed up in /etc/target/backup/ 
directory.')
 
     def assert_root(self):
         '''
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/targetcli-fb-2.1.47/targetcli/ui_root.py 
new/targetcli-fb-2.1.49/targetcli/ui_root.py
--- old/targetcli-fb-2.1.47/targetcli/ui_root.py        2017-08-15 
23:35:32.000000000 +0200
+++ new/targetcli-fb-2.1.49/targetcli/ui_root.py        2018-09-05 
14:08:11.000000000 +0200
@@ -20,8 +20,10 @@
 from datetime import datetime
 from glob import glob
 import os
+import re
 import shutil
 import stat
+import filecmp
 
 from configshell_fb import ExecutionError
 from rtslib_fb import RTSRoot
@@ -32,7 +34,7 @@
 from .ui_target import UIFabricModule
 
 default_save_file = "/etc/target/saveconfig.json"
-kept_backups = 10
+universal_prefs_file = "/etc/target/targetcli.conf"
 
 class UIRoot(UINode):
     '''
@@ -60,40 +62,78 @@
             if fm.wwns == None or any(fm.wwns):
                 UIFabricModule(fm, self)
 
-    def ui_command_saveconfig(self, savefile=default_save_file):
+    def _save_backups(self, savefile):
         '''
-        Saves the current configuration to a file so that it can be restored
-        on next boot.
+        Take backup of config-file if needed.
         '''
-        self.assert_root()
+        # Only save backups if saving to default location
+        if savefile != default_save_file:
+            return
 
-        savefile = os.path.expanduser(savefile)
+        backup_dir = os.path.dirname(savefile) + "/backup/"
+        backup_name = "saveconfig-" + \
+                      datetime.now().strftime("%Y%m%d-%H:%M:%S") + ".json"
+        backupfile = backup_dir + backup_name
+        backup_error = None
 
-        # Only save backups if saving to default location
-        if savefile == default_save_file:
-            backup_dir = os.path.dirname(savefile) + "/backup"
-            backup_name = "saveconfig-" + \
-                datetime.now().strftime("%Y%m%d-%H:%M:%S") + ".json"
-            backupfile = backup_dir + "/" + backup_name
-            backup_error = None
+        if not os.path.exists(backup_dir):
+            try:
+                os.makedirs(backup_dir);
+            except OSError as exe:
+                raise ExecutionError("Cannot create backup directory [%s] %s."
+                                     % (backup_dir, exc.strerror))
+
+        # Only save backups if savefile exits
+        if not os.path.exists(savefile):
+            return
+
+        backed_files_list = sorted(glob(os.path.dirname(savefile) + \
+                                   "/backup/*.json"))
+
+        # Save backup if backup dir is empty, or savefile is differnt from 
recent backup copy
+        if not backed_files_list or not filecmp.cmp(backed_files_list[-1], 
savefile):
             try:
                 shutil.copy(savefile, backupfile)
+
             except IOError as ioe:
                 backup_error = ioe.strerror or "Unknown error"
 
             if backup_error == None:
-                # Kill excess backups
-                backups = sorted(glob(os.path.dirname(savefile) + 
"/backup/*.json"))
-                files_to_unlink = list(reversed(backups))[kept_backups:]
+                # remove excess backups
+                max_backup_files = int(self.shell.prefs['max_backup_files'])
+
+                try:
+                    with open(universal_prefs_file) as prefs:
+                        backups = [line for line in prefs.read().splitlines() 
if re.match('^max_backup_files\s*=', line)]
+                        if max_backup_files < 
int(backups[0].split('=')[1].strip()):
+                            max_backup_files = 
int(backups[0].split('=')[1].strip())
+                except:
+                    self.shell.log.debug("No universal prefs file '%s'." % 
universal_prefs_file)
+
+                files_to_unlink = 
list(reversed(backed_files_list))[max_backup_files - 1:]
                 for f in files_to_unlink:
                     with ignored(IOError):
                         os.unlink(f)
 
-                self.shell.log.info("Last %d configs saved in %s." % \
-                                        (kept_backups, backup_dir))
+                self.shell.log.info("Last %d configs saved in %s."
+                                    % (max_backup_files, backup_dir))
             else:
-                self.shell.log.warning("Could not create backup file %s: %s." 
% \
-                                           (backupfile, backup_error))
+                self.shell.log.warning("Could not create backup file %s: %s."
+                                       % (backupfile, backup_error))
+
+    def ui_command_saveconfig(self, savefile=default_save_file):
+        '''
+        Saves the current configuration to a file so that it can be restored
+        on next boot.
+        '''
+        self.assert_root()
+
+        if not savefile:
+            savefile = default_save_file
+
+        savefile = os.path.expanduser(savefile)
+
+        self._save_backups(savefile)
 
         self.rtsroot.save_to_file(savefile)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/targetcli-fb-2.1.47/targetcli/ui_target.py 
new/targetcli-fb-2.1.49/targetcli/ui_target.py
--- old/targetcli-fb-2.1.47/targetcli/ui_target.py      2017-08-15 
23:35:32.000000000 +0200
+++ new/targetcli-fb-2.1.49/targetcli/ui_target.py      2018-09-05 
14:08:11.000000000 +0200
@@ -1141,7 +1141,7 @@
                 existing_mluns = [mlun.mapped_lun for mlun in acl.mapped_luns]
                 if mapped_lun in existing_mluns:
                     mapped_lun = None
-                    for possible_mlun in six.moves.range(LUN.MAX_LUN):
+                    for possible_mlun in six.moves.range(MappedLUN.MAX_LUN):
                         if possible_mlun not in existing_mluns:
                             mapped_lun = possible_mlun
                             break
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/targetcli-fb-2.1.47/targetcli/version.py 
new/targetcli-fb-2.1.49/targetcli/version.py
--- old/targetcli-fb-2.1.47/targetcli/version.py        2017-08-15 
23:35:32.000000000 +0200
+++ new/targetcli-fb-2.1.49/targetcli/version.py        2018-09-05 
14:08:11.000000000 +0200
@@ -15,4 +15,4 @@
 under the License.
 '''
 
-__version__ = '2.1.fb47'
+__version__ = '2.1.fb49'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/targetcli-fb-2.1.47/targetcli.8 
new/targetcli-fb-2.1.49/targetcli.8
--- old/targetcli-fb-2.1.47/targetcli.8 2017-08-15 23:35:32.000000000 +0200
+++ new/targetcli-fb-2.1.49/targetcli.8 2018-09-05 14:08:11.000000000 +0200
@@ -456,6 +456,9 @@
 .B /etc/target/saveconfig.json
 .br
 .B /etc/target/backup/*
+.SH ENVIRONMENT
+.SS TARGETCLI_HOME
+If set, this variable points to a directory that should be used instead of 
~/.targetctl
 .SH SEE ALSO
 .BR targetctl (8),
 .BR tcmu-runner (8)


Reply via email to