--- /dev/null
+overrides:
+ ceph:
+ log-ignorelist:
+ - FS_DEGRADED
+ - fs.*is degraded
+ - filesystem is degraded
+ - FS_INLINE_DATA_DEPRECATED
+ - FS_WITH_FAILED_MDS
+ - MDS_ALL_DOWN
+ - filesystem is offline
+ - is offline because no MDS
+ - MDS_DAMAGE
+ - MDS_DEGRADED
+ - MDS_FAILED
+ - MDS_INSUFFICIENT_STANDBY
+ - insufficient standby MDS daemons available
+ - MDS_UP_LESS_THAN_MAX
+ - online, but wants
+ - filesystem is online with fewer MDS than max_mds
+ - POOL_APP_NOT_ENABLED
+ - do not have an application enabled
+ - overall HEALTH_
+ - Replacing daemon
+ - deprecated feature inline_data
+ - BLUESTORE_SLOW_OP_ALERT
+ - slow operation indications in BlueStore
+ - experiencing slow operations in BlueStore
+ - MGR_MODULE_ERROR
+ - OSD_NEARFULL
--- /dev/null
+"""
+reconfigure a ganesha server
+"""
+import logging
+
+from teuthology.task import Task
+
+log = logging.getLogger(__name__)
+
+class GaneshaClient(Task):
+ def __init__(self, ctx, config):
+ super(GaneshaClient, self).__init__(ctx, config)
+ self.log = log
+
+ def setup(self):
+ super(GaneshaClient, self).setup()
+
+ def begin(self):
+ super(GaneshaClient, self).begin()
+
+ log.info('mounting ganesha client')
+ log.info(f'config is {self.config}')
+
+ def end(self):
+ super(GaneshaClient, self).end()
+
+task = GaneshaClient
--- /dev/null
+"""
+reconfigure a ganesha server
+"""
+
+import json
+import logging
+from io import StringIO
+
+from teuthology.misc import deep_merge
+from teuthology.task import Task
+from teuthology import misc
+
+log = logging.getLogger(__name__)
+
+class GaneshaReconf(Task):
+ def __init__(self, ctx, config):
+ super(GaneshaReconf, self).__init__(ctx, config)
+ self.log = log
+
+ def setup(self):
+ super(GaneshaReconf, self).setup()
+
+ def begin(self):
+ super(GaneshaReconf, self).begin()
+ log.info('reconfiguring ganesha server')
+
+ ganesha_config = self.config
+ log.info(f'ganesha_config is {ganesha_config}')
+ overrides = self.ctx.config.get('overrides', {}).get('ganesha-reconf', {})
+ log.info(f'overrides is {overrides}')
+
+ deep_merge(ganesha_config, overrides)
+ log.info(f'ganesha_config is {ganesha_config}')
+
+ try:
+ first_mon = misc.get_first_mon(self.ctx, None)
+ (mon0_remote,) = self.ctx.cluster.only(first_mon).remotes.keys()
+
+ cluster_id = ganesha_config['cluster_id']
+ pseudo_path = ganesha_config['pseudo_path']
+
+ proc = mon0_remote.run(args=['ceph', 'nfs', 'export', 'info', cluster_id, pseudo_path],
+ stdout=StringIO(), wait=True)
+ res = proc.stdout.getvalue()
+ log.debug(f'res: {res} type {type(res)}')
+ export_json = json.loads(res)
+ log.debug(f'export_json: {export_json} type {type(export_json)}')
+
+ is_async = ganesha_config.get('async', False)
+ if is_async:
+ export_json.setdefault("ceph", {})
+ export_json["ceph"]["async"] = True
+ is_zerocopy = ganesha_config.get('zerocopy', False)
+ if is_async:
+ export_json.setdefault("ceph", {})
+ export_json["ceph"]["zerocopy"] = True
+
+ if is_async or is_zerocopy:
+ log.debug(f'export_json is {json.dumps(export_json)}')
+ mon0_remote.run(args=['ceph', 'nfs', 'export', 'apply', cluster_id, "-i", "-"],
+ stdin=json.dumps(export_json))
+
+ proc = mon0_remote.run(args=['ceph', 'nfs', 'export', 'info', cluster_id, pseudo_path],
+ stdout=StringIO(), wait=True)
+ res = proc.stdout.getvalue()
+ log.debug(f'verify res: {res} type {type(res)}')
+ export_json = json.loads(res)
+ log.debug(f'verify export_json: {export_json} type {type(export_json)}')
+ except Exception as e:
+ log.error(f'failed: {e}')
+
+ def end(self):
+ super(GaneshaReconf, self).end()
+
+task = GaneshaReconf