Hello community,

here is the log from the commit of package ceph-iscsi for openSUSE:Factory 
checked in at 2019-06-06 18:19:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ceph-iscsi (Old)
 and      /work/SRC/openSUSE:Factory/.ceph-iscsi.new.4811 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ceph-iscsi"

Thu Jun  6 18:19:07 2019 rev:13 rq:708099 version:3.0+1559815396.g7aa8f7f

Changes:
--------
--- /work/SRC/openSUSE:Factory/ceph-iscsi/ceph-iscsi.changes    2019-05-22 
11:17:46.154461201 +0200
+++ /work/SRC/openSUSE:Factory/.ceph-iscsi.new.4811/ceph-iscsi.changes  
2019-06-06 18:19:24.168649475 +0200
@@ -1,0 +2,11 @@
+Thu Jun  6 10:04:00 UTC 2019 - Nathan Cutler <ncut...@suse.com>
+
+- Update to 3.0+1559815396.g7aa8f7f:
+  + Set 'SUSE' SCSI vendor (bsc#1136769)
+  + Adds support for multiple IPs per gateway (bsc#1136757)
+  + Do not allow lrbd to be installed simultaneously with ceph-iscsi
+  + Temporary workaround to support ',' in configshell params (must be 
removed/reverted in the future, after configshell >= 1.1.f25 is available)
+  + Fix problem deleting target with clients/disks
+  + Removes the disk 'delete' command 
+
+-------------------------------------------------------------------

Old:
----
  ceph-iscsi-3.0+1558465738.g6a0a021.tar.gz

New:
----
  ceph-iscsi-3.0+1559815396.g7aa8f7f.tar.gz

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

Other differences:
------------------
++++++ ceph-iscsi.spec ++++++
--- /var/tmp/diff_new_pack.qSi1Cv/_old  2019-06-06 18:19:24.844649276 +0200
+++ /var/tmp/diff_new_pack.qSi1Cv/_new  2019-06-06 18:19:24.844649276 +0200
@@ -20,7 +20,7 @@
 
 
 Name:           ceph-iscsi
-Version:        3.0+1558465738.g6a0a021
+Version:        3.0+1559815396.g7aa8f7f
 Release:        1%{?dist}
 Group:          System/Filesystems
 Summary:        Python modules for Ceph iSCSI gateway configuration management
@@ -51,7 +51,7 @@
 Requires:       rpm-python >= 4.11
 Requires:       python-cryptography
 Requires:       python-flask >= 0.10.1
-Requires:       python-configshell
+Requires:       python-configshell >= 1.1.fb23
 %else
 BuildRequires:  python3-devel
 BuildRequires:  python3-setuptools
@@ -65,13 +65,17 @@
 BuildRequires:  python-rpm-macros
 BuildRequires:  fdupes
 Requires:       python3-Flask >= 0.10.1
-Requires:       python3-configshell-fb
+Requires:       python3-configshell-fb >= 1.1.23
 %else
 Requires:       python3-flask >= 0.10.1
-Requires:       python3-configshell
+Requires:       python3-configshell >= 1.1.fb23
 %endif
 %endif
 
+%if 0%{?suse_version}
+Conflicts: lrbd
+%endif
+
 BuildRequires: systemd-rpm-macros
 %{?systemd_requires}
 

++++++ ceph-iscsi-3.0+1558465738.g6a0a021.tar.gz -> 
ceph-iscsi-3.0+1559815396.g7aa8f7f.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ceph-iscsi-3.0+1558465738.g6a0a021/ceph-iscsi.spec 
new/ceph-iscsi-3.0+1559815396.g7aa8f7f/ceph-iscsi.spec
--- old/ceph-iscsi-3.0+1558465738.g6a0a021/ceph-iscsi.spec      2019-05-21 
21:08:58.372570734 +0200
+++ new/ceph-iscsi-3.0+1559815396.g7aa8f7f/ceph-iscsi.spec      2019-06-06 
12:03:16.636671848 +0200
@@ -20,7 +20,7 @@
 
 
 Name:           ceph-iscsi
-Version:        3.0+1558465738.g6a0a021
+Version:        3.0+1559815396.g7aa8f7f
 Release:        1%{?dist}
 Group:          System/Filesystems
 Summary:        Python modules for Ceph iSCSI gateway configuration management
@@ -51,7 +51,7 @@
 Requires:       rpm-python >= 4.11
 Requires:       python-cryptography
 Requires:       python-flask >= 0.10.1
-Requires:       python-configshell
+Requires:       python-configshell >= 1.1.fb23
 %else
 BuildRequires:  python3-devel
 BuildRequires:  python3-setuptools
@@ -65,13 +65,17 @@
 BuildRequires:  python-rpm-macros
 BuildRequires:  fdupes
 Requires:       python3-Flask >= 0.10.1
-Requires:       python3-configshell-fb
+Requires:       python3-configshell-fb >= 1.1.23
 %else
 Requires:       python3-flask >= 0.10.1
-Requires:       python3-configshell
+Requires:       python3-configshell >= 1.1.fb23
 %endif
 %endif
 
+%if 0%{?suse_version}
+Conflicts: lrbd
+%endif
+
 BuildRequires: systemd-rpm-macros
 %{?systemd_requires}
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ceph-iscsi-3.0+1558465738.g6a0a021/ceph_iscsi_config/gateway.py 
new/ceph-iscsi-3.0+1559815396.g7aa8f7f/ceph_iscsi_config/gateway.py
--- old/ceph-iscsi-3.0+1558465738.g6a0a021/ceph_iscsi_config/gateway.py 
2019-05-21 21:08:58.136569104 +0200
+++ new/ceph-iscsi-3.0+1559815396.g7aa8f7f/ceph_iscsi_config/gateway.py 
2019-06-06 12:03:16.060678398 +0200
@@ -160,7 +160,7 @@
         # 0, this is a boot time request
         self.logger.info("Setting up {}".format(target_iqn))
 
-        target = GWTarget(self.logger, target_iqn, gw_ip_list,
+        target = GWTarget(self.logger, self.config, target_iqn, gw_ip_list,
                           enable_portal=self.portals_active(target_iqn))
         if target.error:
             raise CephiSCSIError("Error initializing iSCSI target: "
@@ -241,7 +241,7 @@
 
     def delete_target(self, target_iqn):
 
-        target = GWTarget(self.logger, target_iqn, {})
+        target = GWTarget(self.logger, self.config, target_iqn, {})
         if target.error:
             raise CephiSCSIError("Could not initialize target: {}".
                                  format(target.error_msg))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ceph-iscsi-3.0+1558465738.g6a0a021/ceph_iscsi_config/lun.py 
new/ceph-iscsi-3.0+1559815396.g7aa8f7f/ceph_iscsi_config/lun.py
--- old/ceph-iscsi-3.0+1558465738.g6a0a021/ceph_iscsi_config/lun.py     
2019-05-21 21:08:58.136569104 +0200
+++ new/ceph-iscsi-3.0+1559815396.g7aa8f7f/ceph_iscsi_config/lun.py     
2019-06-06 12:03:16.060678398 +0200
@@ -555,7 +555,7 @@
 
             # Add the mapping for the lun to ensure the block device is
             # present on all TPG's
-            gateway = GWTarget(self.logger, target_iqn, ip_list)
+            gateway = GWTarget(self.logger, self.config, target_iqn, ip_list)
             gateway.map_lun(self.config, so)
             if gateway.error:
                 raise CephiSCSIError("LUN mapping failed - 
{}".format(gateway.error_msg))
@@ -981,6 +981,11 @@
             new_lun = RBDStorageObject(name=self.backstore_object_name,
                                        dev=dev,
                                        wwn=in_wwn)
+            path = 
glob.glob('/sys/kernel/config/target/core/rbd_*/{}/wwn/vendor_id'.format(
+                self.backstore_object_name))
+            if path:
+                with open(path[0], "w") as file_vendor:
+                    file_vendor.write("SUSE\n")
 
         except (RTSLibError, IOError) as err:
             self.error = True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ceph-iscsi-3.0+1558465738.g6a0a021/ceph_iscsi_config/target.py 
new/ceph-iscsi-3.0+1559815396.g7aa8f7f/ceph_iscsi_config/target.py
--- old/ceph-iscsi-3.0+1558465738.g6a0a021/ceph_iscsi_config/target.py  
2019-05-21 21:08:58.136569104 +0200
+++ new/ceph-iscsi-3.0+1559815396.g7aa8f7f/ceph_iscsi_config/target.py  
2019-06-06 12:03:16.064678352 +0200
@@ -48,7 +48,7 @@
     # gwcli to get/set all tpgs/clients under the target instead of per obj.
     SETTINGS = TPG_SETTINGS + TPG_KERNEL_SETTINGS + GWClient.SETTINGS
 
-    def __init__(self, logger, iqn, gateway_ip_list, enable_portal=True):
+    def __init__(self, logger, config, iqn, gateway_ip_list, 
enable_portal=True):
         """
         Instantiate the class
         :param iqn: iscsi iqn name for the gateway
@@ -62,6 +62,7 @@
 
         self.enable_portal = enable_portal  # boolean to trigger portal IP 
creation
         self.logger = logger                # logger object
+        self.config = config
 
         try:
             iqn, iqn_type = normalize_wwn(['iqn'], iqn)
@@ -106,6 +107,7 @@
         self.target = None
         self.tpg = None
         self.tpg_list = []
+        self.tpg_tag_by_gateway_name = {}
 
         try:
             super(GWTarget, self).__init__('targets', iqn, logger,
@@ -266,10 +268,27 @@
                 tpg.set_attribute('generate_node_acls', 1)
                 tpg.set_attribute('demo_mode_write_protect', 0)
 
+    def _get_gateway_name(self, ip):
+        if ip in self.active_portal_ips:
+            return this_host()
+        target_config = self.config.config['targets'][self.iqn]
+        for portal_name, portal_config in target_config['portals'].items():
+            if ip in portal_config['portal_ip_addresses']:
+                return portal_name
+        return None
+
     def create_tpg(self, ip):
 
         try:
-            tpg = TPG(self.target)
+            tpg = None
+            gateway_name = self._get_gateway_name(ip)
+            tpg_tag = self.tpg_tag_by_gateway_name.get(gateway_name)
+            if tpg_tag:
+                for tpg_item in self.tpg_list:
+                    if tpg_item.tag == tpg_tag:
+                        tpg = tpg_item
+            if not tpg:
+                tpg = TPG(self.target)
 
             # Use initiator name based ACL by default.
             tpg.set_attribute('authentication', '0')
@@ -293,6 +312,7 @@
                                   "portal ip {} as disabled".format(ip))
 
             self.tpg_list.append(tpg)
+            self.tpg_tag_by_gateway_name[gateway_name] = tpg.tag
 
         except RTSLibError as err:
             self.error_msg = err
@@ -359,10 +379,16 @@
             # clear list so we can rebuild with the current values below
             if self.tpg_list:
                 del self.tpg_list[:]
+            if self.tpg_tag_by_gateway_name:
+                self.tpg_tag_by_gateway_name = {}
 
             # there could/should be multiple tpg's for the target
             for tpg in self.target.tpgs:
                 self.tpg_list.append(tpg)
+                ip_address = list(tpg.network_portals)[0].ip_address
+                gateway_name = self._get_gateway_name(ip_address)
+                if gateway_name:
+                    self.tpg_tag_by_gateway_name[gateway_name] = tpg.tag
 
             # self.portal = self.tpg.network_portals.next()
 
@@ -410,7 +436,7 @@
         # they do not have a common gw the owning gw may not exist here.
         # The LUN will just have all ANO paths then.
         if gw_config:
-            if gw_config["portal_ip_addresses"][0] == tpg_ip_address:
+            if tpg_ip_address in gw_config["portal_ip_addresses"]:
                 is_owner = True
 
         try:
@@ -681,6 +707,8 @@
             if self.exists():
                 self.load_config()
                 self.clear_config(config)
+                if self.error:
+                    return
             target_config = config.config["targets"][self.iqn]
             if len(target_config['portals']) == 0:
                 config.del_item('targets', self.iqn)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ceph-iscsi-3.0+1558465738.g6a0a021/gwcli/gateway.py 
new/ceph-iscsi-3.0+1559815396.g7aa8f7f/gwcli/gateway.py
--- old/ceph-iscsi-3.0+1558465738.g6a0a021/gwcli/gateway.py     2019-05-21 
21:08:58.140569131 +0200
+++ new/ceph-iscsi-3.0+1559815396.g7aa8f7f/gwcli/gateway.py     2019-06-06 
12:03:16.068678307 +0200
@@ -657,15 +657,15 @@
             hosts_object = self.parent.get_child("hosts")
             hosts_object.reset()
 
-    def ui_command_create(self, gateway_name, ip_address, nosync=False,
+    def ui_command_create(self, gateway_name, ip_addresses, nosync=False,
                           skipchecks='false'):
         """
         Define a gateway to the gateway group for this iscsi target. The
         first host added should be the gateway running the command
 
         gateway_name ... should resolve to the hostname of the gateway
-        ip_address ..... is the IPv4/IPv6 address of the interface the iscsi
-                         portal should use
+        ip_addresses ... are the IPv4/IPv6 addresses of the interfaces the
+                         iSCSI portals should use
         nosync ......... by default new gateways are sync'd with the
                          existing configuration by cli. By specifying nosync
                          the sync step is bypassed - so the new gateway
@@ -678,10 +678,10 @@
                          to result in an unstable configuration.
         """
 
-        ip_address = normalize_ip_address(ip_address)
+        ip_addresses = [normalize_ip_address(ip_address) for ip_address in 
ip_addresses.split(',')]
         self.logger.debug("CMD: ../gateways/ create {} {} "
                           "nosync={} skipchecks={}".format(gateway_name,
-                                                           ip_address,
+                                                           ip_addresses,
                                                            nosync,
                                                            skipchecks))
 
@@ -730,7 +730,7 @@
         gw_rqst = gw_api + '/gateway/{}/{}'.format(target_iqn, gateway_name)
         gw_vars = {"nosync": nosync,
                    "skipchecks": skipchecks,
-                   "ip_address": ip_address}
+                   "ip_address": ','.join(ip_addresses)}
 
         api = APIRequest(gw_rqst, data=gw_vars)
         api.put()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ceph-iscsi-3.0+1558465738.g6a0a021/gwcli/storage.py 
new/ceph-iscsi-3.0+1559815396.g7aa8f7f/gwcli/storage.py
--- old/ceph-iscsi-3.0+1558465738.g6a0a021/gwcli/storage.py     2019-05-21 
21:08:58.140569131 +0200
+++ new/ceph-iscsi-3.0+1559815396.g7aa8f7f/gwcli/storage.py     2019-06-06 
12:03:16.068678307 +0200
@@ -467,25 +467,6 @@
         """
         self.delete_disk(image_id, True)
 
-    def ui_command_delete(self, image_id):
-        """
-        Delete a given rbd image from the configuration and ceph. This is a
-        destructive action that could lead to data loss, so please ensure
-        the rbd image name is correct!
-
-        > delete <disk_name>
-        e.g.
-        > delete rbd.disk_1
-
-        "disk_name" refers to the name of the disk as shown in the UI, for
-        example rbd.disk_1.
-
-        Also note that the delete process is a synchronous task, so the larger
-        the rbd image is, the longer the delete will take to run.
-
-        """
-        self.delete_disk(image_id, False)
-
     def delete_disk(self, image_id, preserve_image):
 
         all_disks = []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ceph-iscsi-3.0+1558465738.g6a0a021/gwcli/utils.py 
new/ceph-iscsi-3.0+1559815396.g7aa8f7f/gwcli/utils.py
--- old/ceph-iscsi-3.0+1558465738.g6a0a021/gwcli/utils.py       2019-05-21 
21:08:58.140569131 +0200
+++ new/ceph-iscsi-3.0+1559815396.g7aa8f7f/gwcli/utils.py       2019-06-06 
12:03:16.068678307 +0200
@@ -60,11 +60,11 @@
     return {}
 
 
-def valid_gateway(target_iqn, gw_name, gw_ip, config):
+def valid_gateway(target_iqn, gw_name, gw_ips, config):
     """
     validate the request for a new gateway
     :param gw_name: (str) host (shortname) of the gateway
-    :param gw_ip: (str) ip address on the gw that will be used for iSCSI
+    :param gw_ips: (str) ip addresses on the gw that will be used for iSCSI
     :param config: (dict) current config
     :return: (str) "ok" or error description
     """
@@ -76,17 +76,19 @@
     if gw_name in target_config['portals']:
         return "Gateway name {} already defined".format(gw_name)
 
-    if gw_ip in target_config.get('ip_list', []):
-        return "IP address already defined to the configuration"
+    for gw_ip in gw_ips:
+        if gw_ip in target_config.get('ip_list', []):
+            return "IP address already defined to the configuration"
 
     # validate the gateway name is resolvable
     if not resolve_ip_addresses(gw_name):
         return ("Gateway '{}' is not resolvable to an IP 
address".format(gw_name))
 
     # validate the ip_address is valid ip
-    if not resolve_ip_addresses(gw_ip):
-        return ("IP address provided is not usable (name doesn't"
-                " resolve, or not a valid IPv4/IPv6 address)")
+    for gw_ip in gw_ips:
+        if not resolve_ip_addresses(gw_ip):
+            return ("IP address provided is not usable (name doesn't"
+                    " resolve, or not a valid IPv4/IPv6 address)")
 
     # At this point the request seems reasonable, so lets check a bit deeper
 
@@ -108,11 +110,12 @@
     except Exception:
         return "Malformed REST API response"
 
-    if gw_ip not in target_ips:
-        return ("IP address of {} is not available on {}. Valid "
-                "IPs are :{}".format(gw_ip,
-                                     gw_name,
-                                     ','.join(target_ips)))
+    for gw_ip in gw_ips:
+        if gw_ip not in target_ips:
+            return ("IP address of {} is not available on {}. Valid "
+                    "IPs are :{}".format(gw_ip,
+                                         gw_name,
+                                         ','.join(target_ips)))
 
     # check that config file on the new gateway matches the local machine
     api = APIRequest(gw_api + '/sysinfo/checkconf')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ceph-iscsi-3.0+1558465738.g6a0a021/gwcli.py 
new/ceph-iscsi-3.0+1559815396.g7aa8f7f/gwcli.py
--- old/ceph-iscsi-3.0+1558465738.g6a0a021/gwcli.py     2019-05-21 
21:08:58.140569131 +0200
+++ new/ceph-iscsi-3.0+1559815396.g7aa8f7f/gwcli.py     2019-06-06 
12:03:16.064678352 +0200
@@ -11,7 +11,10 @@
 import argparse
 import signal
 
+from pyparsing import (alphanums, OneOrMore, Optional, Regex, Suppress, Word)
+
 from configshell_fb import ConfigShell, ExecutionError
+from configshell_fb.shell import locatedExpr
 from gwcli.gateway import ISCSIRoot
 
 import ceph_iscsi_config.settings as settings
@@ -39,6 +42,25 @@
                      }
 
 
+    def __init__(self, preferences_dir=None):
+        super(GatewayCLI, self).__init__(preferences_dir)
+        # Grammar of the command line
+        command = locatedExpr(Word(alphanums + '_'))('command')
+        var = Word(alphanums + ',=_\+/.<>()~@:-%[]')
+        value = var
+        keyword = Word(alphanums + '_\-')
+        kparam = locatedExpr(keyword + Suppress('=') + Optional(value, 
default=''))('kparams*')
+        pparam = locatedExpr(var)('pparams*')
+        parameter = kparam | pparam
+        parameters = OneOrMore(parameter)
+        bookmark = Regex('@([A-Za-z0-9:_.]|-)+')
+        pathstd = Regex('([A-Za-z0-9:_.\[\]]|-)*' + '/' + 
'([A-Za-z0-9:_.\[\]/]|-)*') \
+                | '..' | '.'
+        path = locatedExpr(bookmark | pathstd | '*')('path')
+        parser = Optional(path) + Optional(command) + Optional(parameters)
+        self._parser = parser
+
+
 def exception_handler(exception_type, exception, traceback,
                       debug_hook=sys.excepthook):
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ceph-iscsi-3.0+1558465738.g6a0a021/rbd-target-api.py 
new/ceph-iscsi-3.0+1559815396.g7aa8f7f/rbd-target-api.py
--- old/ceph-iscsi-3.0+1558465738.g6a0a021/rbd-target-api.py    2019-05-21 
21:08:58.140569131 +0200
+++ new/ceph-iscsi-3.0+1559815396.g7aa8f7f/rbd-target-api.py    2019-06-06 
12:03:16.068678307 +0200
@@ -280,6 +280,7 @@
 
         gateway_ip_list = []
         target = GWTarget(logger,
+                          config,
                           str(target_iqn),
                           gateway_ip_list)
 
@@ -368,7 +369,7 @@
 def local_target_reconfigure(target_iqn, tpg_controls, client_controls):
     config.refresh()
 
-    target = GWTarget(logger, str(target_iqn), [])
+    target = GWTarget(logger, config, str(target_iqn), [])
     if target.error:
         logger.error("Unable to create an instance of the GWTarget class")
         return target.error_msg
@@ -473,7 +474,7 @@
 
     else:
         # DELETE target request
-        target = GWTarget(logger, target_iqn, '')
+        target = GWTarget(logger, config, target_iqn, '')
         if target.error:
             return jsonify(message="Failed to access target"), 500
 
@@ -563,7 +564,7 @@
     required for PUT only.
     :param target_iqn: (str) target iqn
     :param gateway_name: (str) gateway name
-    :param ip_address: (str) IPv4/IPv6 address iSCSI should use
+    :param ip_address: (str) IPv4/IPv6 addresses iSCSI should use
     :param nosync: (bool) whether to sync the LIO objects to the new gateway
            default: FALSE
     :param skipchecks: (bool) whether to skip OS/software versions checks
@@ -592,7 +593,11 @@
     target_config = config.config['targets'][target_iqn]
 
     if request.method == 'PUT':
-        ip_address = request.form.get('ip_address')
+        if gateway_name in target_config['portals']:
+            err_str = "Gateway already exists in configuration"
+            logger.error(err_str)
+            return jsonify(message=err_str), 400
+        ip_address = request.form.get('ip_address').split(',')
         nosync = request.form.get('nosync', 'false')
         skipchecks = request.form.get('skipchecks', 'false')
 
@@ -620,7 +625,7 @@
             nosync = 'true'
 
         gateway_ip_list = target_config.get('ip_list', [])
-        gateway_ip_list.append(ip_address)
+        gateway_ip_list += ip_address
 
         op = 'creation'
         api_vars = {"gateway_ip_list": ",".join(gateway_ip_list),
@@ -842,6 +847,7 @@
         target_config = config.config['targets'][target_iqn]
         ip_list = target_config.get('ip_list', [])
         gateway = GWTarget(logger,
+                           config,
                            target_iqn,
                            ip_list)
 
@@ -1605,7 +1611,7 @@
     committing_host = request.form['committing_host']
     action = request.form['action']
 
-    target = GWTarget(logger, target_iqn, [])
+    target = GWTarget(logger, config, target_iqn, [])
 
     acl_enabled = (action == 'enable_acl')
 


Reply via email to