Hello community, here is the log from the commit of package ceph-iscsi for openSUSE:Factory checked in at 2019-04-30 13:06:35 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ceph-iscsi (Old) and /work/SRC/openSUSE:Factory/.ceph-iscsi.new.5536 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "ceph-iscsi" Tue Apr 30 13:06:35 2019 rev:10 rq:699447 version:3.0+1556546618.g28a0e8a Changes: -------- --- /work/SRC/openSUSE:Factory/ceph-iscsi/ceph-iscsi.changes 2019-04-09 20:18:42.421844161 +0200 +++ /work/SRC/openSUSE:Factory/.ceph-iscsi.new.5536/ceph-iscsi.changes 2019-04-30 13:06:38.421556649 +0200 @@ -1,0 +2,9 @@ +Mon Apr 29 14:04:00 UTC 2019 - Nathan Cutler <ncutler@suse.com> + +- Update to 3.0+1556546618.g28a0e8a: + + Should be possible to export config without targets + + Prevent error getting the number of active sessions + + Fix race condition in '_targetauth' config update + + Fix error when trying to get client info from 'gwcli' + +------------------------------------------------------------------- Old: ---- ceph-iscsi-3.0+1554735444.g63aceaf.tar.gz New: ---- ceph-iscsi-3.0+1556546618.g28a0e8a.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ceph-iscsi.spec ++++++ --- /var/tmp/diff_new_pack.XyZkXH/_old 2019-04-30 13:06:38.937556304 +0200 +++ /var/tmp/diff_new_pack.XyZkXH/_new 2019-04-30 13:06:38.937556304 +0200 @@ -20,7 +20,7 @@ Name: ceph-iscsi -Version: 3.0+1554735444.g63aceaf +Version: 3.0+1556546618.g28a0e8a Release: 1%{?dist} Group: System/Filesystems Summary: Python modules for Ceph iSCSI gateway configuration management ++++++ ceph-iscsi-3.0+1554735444.g63aceaf.tar.gz -> ceph-iscsi-3.0+1556546618.g28a0e8a.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ceph-iscsi-3.0+1554735444.g63aceaf/ceph-iscsi.spec new/ceph-iscsi-3.0+1556546618.g28a0e8a/ceph-iscsi.spec --- old/ceph-iscsi-3.0+1554735444.g63aceaf/ceph-iscsi.spec 2019-04-08 16:57:24.610585206 +0200 +++ new/ceph-iscsi-3.0+1556546618.g28a0e8a/ceph-iscsi.spec 2019-04-29 16:03:38.399644158 +0200 @@ -20,7 +20,7 @@ Name: ceph-iscsi -Version: 3.0+1554735444.g63aceaf +Version: 3.0+1556546618.g28a0e8a Release: 1%{?dist} Group: System/Filesystems Summary: Python modules for Ceph iSCSI gateway configuration management diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ceph-iscsi-3.0+1554735444.g63aceaf/ceph_iscsi_config/target.py new/ceph-iscsi-3.0+1556546618.g28a0e8a/ceph_iscsi_config/target.py --- old/ceph-iscsi-3.0+1554735444.g63aceaf/ceph_iscsi_config/target.py 2019-04-08 16:57:24.310583510 +0200 +++ new/ceph-iscsi-3.0+1556546618.g28a0e8a/ceph_iscsi_config/target.py 2019-04-29 16:03:38.111642298 +0200 @@ -122,8 +122,12 @@ :return: boolean """ + return GWTarget._exists(self.iqn) + + @staticmethod + def _exists(target_iqn): return os.path.exists('/sys/kernel/config/target/iscsi/' - '{}'.format(self.iqn)) + '{}'.format(target_iqn)) def _get_portals(self, tpg): """ @@ -253,10 +257,9 @@ self.error = True self.error_msg = "Unable to delete target - {}".format(err) - def update_acl(self, config): - target_config = config.config["targets"][self.iqn] + def update_acl(self, acl_enabled): for tpg in self.tpg_list: - if target_config['acl_enabled']: + if acl_enabled: tpg.set_attribute('generate_node_acls', 0) tpg.set_attribute('demo_mode_write_protect', 1) else: @@ -563,7 +566,8 @@ # return to caller, with error state set return - self.update_acl(config) + target_config = config.config["targets"][self.iqn] + self.update_acl(target_config['acl_enabled']) discovery_auth_config = config.config['discovery_auth'] Discovery.set_discovery_auth_lio(discovery_auth_config['username'], @@ -574,7 +578,6 @@ discovery_auth_config[ 'mutual_password_encryption_enabled']) - target_config = config.config["targets"][self.iqn] gateway_group = config.config["gateways"].keys() if "ip_list" not in target_config: target_config['ip_list'] = self.gateway_ip_list @@ -630,7 +633,8 @@ self.map_luns(config) - self.update_acl(config) + target_config = config.config["targets"][self.iqn] + self.update_acl(target_config['acl_enabled']) else: self.error = True @@ -712,6 +716,8 @@ @staticmethod def get_num_sessions(target_iqn): + if not GWTarget._exists(target_iqn): + return 0 with open('/sys/kernel/config/target/iscsi/{}/fabric_statistics/iscsi_instance' '/sessions'.format(target_iqn)) as sessions_file: return int(sessions_file.read().rstrip('\n')) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ceph-iscsi-3.0+1554735444.g63aceaf/gwcli/client.py new/ceph-iscsi-3.0+1556546618.g28a0e8a/gwcli/client.py --- old/ceph-iscsi-3.0+1554735444.g63aceaf/gwcli/client.py 2019-04-08 16:57:24.314583532 +0200 +++ new/ceph-iscsi-3.0+1556546618.g28a0e8a/gwcli/client.py 2019-04-29 16:03:38.111642298 +0200 @@ -1,6 +1,6 @@ from gwcli.node import UIGroup, UINode -from gwcli.utils import response_message, APIRequest, get_config +from gwcli.utils import response_message, APIRequest, get_config, this_host from ceph_iscsi_config.client import CHAP, GWClient import ceph_iscsi_config.settings as settings @@ -690,10 +690,18 @@ @property def logged_in(self): target_iqn = self.parent.parent.name - client_info = GWClient.get_client_info(target_iqn, self.client_iqn) - self.alias = client_info['alias'] - self.ip_address = ','.join(client_info['ip_address']) - return client_info['state'] + gateways = self.parent.parent.get_child('gateways') + local_gw = this_host() + is_local_target = len([child for child in gateways.children if child.name == local_gw]) > 0 + if is_local_target: + client_info = GWClient.get_client_info(target_iqn, self.client_iqn) + self.alias = client_info['alias'] + self.ip_address = ','.join(client_info['ip_address']) + return client_info['state'] + else: + self.alias = '' + self.ip_address = '' + return '' class MappedLun(UINode): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ceph-iscsi-3.0+1554735444.g63aceaf/gwcli/gateway.py new/ceph-iscsi-3.0+1556546618.g28a0e8a/gwcli/gateway.py --- old/ceph-iscsi-3.0+1554735444.g63aceaf/gwcli/gateway.py 2019-04-08 16:57:24.314583532 +0200 +++ new/ceph-iscsi-3.0+1556546618.g28a0e8a/gwcli/gateway.py 2019-04-29 16:03:38.111642298 +0200 @@ -128,9 +128,6 @@ return current_config = self._get_config() - if not current_config.get('targets'): - self.logger.error("Export requested, but the config is empty") - return if mode == 'copy': self.export_copy(current_config) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ceph-iscsi-3.0+1554735444.g63aceaf/rbd-target-api.py new/ceph-iscsi-3.0+1556546618.g28a0e8a/rbd-target-api.py --- old/ceph-iscsi-3.0+1554735444.g63aceaf/rbd-target-api.py 2019-04-08 16:57:24.314583532 +0200 +++ new/ceph-iscsi-3.0+1556546618.g28a0e8a/rbd-target-api.py 2019-04-29 16:03:38.111642298 +0200 @@ -1597,22 +1597,24 @@ **RESTRICTED** """ + config.refresh() + local_gw = this_host() committing_host = request.form['committing_host'] action = request.form['action'] target = GWTarget(logger, target_iqn, []) - target_config = config.config['targets'][target_iqn] - if action in ['disable_acl', 'enable_acl']: - target_config['acl_enabled'] = (action == 'enable_acl') - config.update_item('targets', target_iqn, target_config) + acl_enabled = (action == 'enable_acl') if target.exists(): target.load_config() - target.update_acl(config) + target.update_acl(acl_enabled) if committing_host == local_gw: + target_config = config.config['targets'][target_iqn] + target_config['acl_enabled'] = acl_enabled + config.update_item('targets', target_iqn, target_config) config.commit("retain") return jsonify(message='OK'), 200 @@ -1634,6 +1636,10 @@ gateways = target_config['portals'] num_sessions = 0 for gateway in gateways.keys(): + target_state = target_ready([gateway]) + if target_state.get('status_api') == 'UP' and target_state.get('status_iscsi') == 'DOWN': + # If API is 'up' and iSCSI is 'down', there are no active sessions to count + continue resp_text, resp_code = call_api([gateway], '_targetinfo', target_iqn, http_method='get') if resp_code != 200: return jsonify(message="{}".format(resp_text)), resp_code @@ -1656,10 +1662,6 @@ """ if target_iqn not in config.config['targets']: return jsonify(message="Target {} does not exist".format(target_iqn)), 400 - target_config = config.config['targets'][target_iqn] - local_gw = this_host() - if local_gw not in target_config['portals']: - return jsonify(message="{} is not a portal of target {}".format(local_gw, target_iqn)), 400 num_sessions = GWTarget.get_num_sessions(target_iqn) return jsonify({ "num_sessions": num_sessions @@ -2485,6 +2487,8 @@ """ http_mode = 'https' if settings.config.api_secure else 'http' target_state = {"status": 'OK', + "status_iscsi": 'UP', + "status_api": 'UP', "summary": ''} for gw in gateway_list: @@ -2496,15 +2500,21 @@ api.get() except GatewayAPIError: target_state['status'] = 'NOTOK' + target_state['status_iscsi'] = 'UNKNOWN' + target_state['status_api'] = 'DOWN' target_state['summary'] += ',{}(iscsi Unknown, API down)'.format(gw) else: if api.response.status_code == 200: continue elif api.response.status_code == 503: target_state['status'] = 'NOTOK' + target_state['status_iscsi'] = 'DOWN' + target_state['status_api'] = 'UP' target_state['summary'] += ',{}(iscsi down, API up)'.format(gw) else: target_state['status'] = 'NOTOK' + target_state['status_iscsi'] = 'UNKNOWN' + target_state['status_api'] = 'UNKNOWN' target_state['summary'] += ',{}(UNKNOWN state)'.format(gw) target_state['summary'] = target_state['summary'][1:] # ignore 1st char