summaryrefslogtreecommitdiffstats
path: root/qa/tasks/cephfs/filesystem.py
diff options
context:
space:
mode:
Diffstat (limited to 'qa/tasks/cephfs/filesystem.py')
-rw-r--r--qa/tasks/cephfs/filesystem.py161
1 files changed, 92 insertions, 69 deletions
diff --git a/qa/tasks/cephfs/filesystem.py b/qa/tasks/cephfs/filesystem.py
index 777ba8249..dc314efa8 100644
--- a/qa/tasks/cephfs/filesystem.py
+++ b/qa/tasks/cephfs/filesystem.py
@@ -17,8 +17,10 @@ from teuthology import misc
from teuthology.nuke import clear_firewall
from teuthology.parallel import parallel
from teuthology import contextutil
+
from tasks.ceph_manager import write_conf
-from tasks import ceph_manager
+from tasks.ceph_manager import CephManager
+from tasks.ceph_test_case import RunCephCmd
log = logging.getLogger(__name__)
@@ -66,16 +68,16 @@ class FSMissing(Exception):
def __str__(self):
return f"File system {self.ident} does not exist in the map"
-class FSStatus(object):
+class FSStatus(RunCephCmd):
"""
Operations on a snapshot of the FSMap.
"""
def __init__(self, mon_manager, epoch=None):
- self.mon = mon_manager
+ self.mon_manager = mon_manager
cmd = ["fs", "dump", "--format=json"]
if epoch is not None:
cmd.append(str(epoch))
- self.map = json.loads(self.mon.raw_cluster_cmd(*cmd))
+ self.map = json.loads(self.get_ceph_cmd_stdout(*cmd))
def __str__(self):
return json.dumps(self.map, indent = 2, sort_keys = True)
@@ -216,7 +218,7 @@ class FSStatus(object):
#all matching
return False
-class CephCluster(object):
+class CephCluster(RunCephCmd):
@property
def admin_remote(self):
first_mon = misc.get_first_mon(self._ctx, None)
@@ -225,7 +227,8 @@ class CephCluster(object):
def __init__(self, ctx) -> None:
self._ctx = ctx
- self.mon_manager = ceph_manager.CephManager(self.admin_remote, ctx=ctx, logger=log.getChild('ceph_manager'))
+ self.mon_manager = CephManager(self.admin_remote, ctx=ctx,
+ logger=log.getChild('ceph_manager'))
def get_config(self, key, service_type=None):
"""
@@ -261,8 +264,14 @@ class CephCluster(object):
"-Infinity": -float("inf")}
return c[value]
- j = json.loads(response_data.replace('inf', 'Infinity'),
- parse_constant=get_nonnumeric_values)
+
+ j = {}
+ try:
+ j = json.loads(response_data.replace('inf', 'Infinity'),
+ parse_constant=get_nonnumeric_values)
+ except json.decoder.JSONDecodeError:
+ raise RuntimeError(response_data) # assume it is an error message, pass it up
+
pretty = json.dumps(j, sort_keys=True, indent=2)
log.debug(f"_json_asok output\n{pretty}")
return j
@@ -271,7 +280,7 @@ class CephCluster(object):
return None
def is_addr_blocklisted(self, addr):
- blocklist = json.loads(self.mon_manager.raw_cluster_cmd(
+ blocklist = json.loads(self.get_ceph_cmd_stdout(
"osd", "dump", "--format=json"))['blocklist']
if addr in blocklist:
return True
@@ -350,7 +359,7 @@ class MDSCluster(CephCluster):
Inform MDSMonitor of the death of the daemon process(es). If it held
a rank, that rank will be relinquished.
"""
- self._one_or_all(mds_id, lambda id_: self.mon_manager.raw_cluster_cmd("mds", "fail", id_))
+ self._one_or_all(mds_id, lambda id_: self.get_ceph_cmd_stdout("mds", "fail", id_))
def mds_restart(self, mds_id=None):
self._one_or_all(mds_id, lambda id_: self.mds_daemons[id_].restart())
@@ -364,7 +373,7 @@ class MDSCluster(CephCluster):
"""
def _fail_restart(id_):
self.mds_daemons[id_].stop()
- self.mon_manager.raw_cluster_cmd("mds", "fail", id_)
+ self.run_ceph_cmd("mds", "fail", id_)
self.mds_daemons[id_].restart()
self._one_or_all(mds_id, _fail_restart)
@@ -468,7 +477,7 @@ class MDSCluster(CephCluster):
return FSStatus(self.mon_manager).get_mds(mds_id)
def is_pool_full(self, pool_name):
- pools = json.loads(self.mon_manager.raw_cluster_cmd("osd", "dump", "--format=json-pretty"))['pools']
+ pools = json.loads(self.get_ceph_cmd_stdout("osd", "dump", "--format=json-pretty"))['pools']
for pool in pools:
if pool['pool_name'] == pool_name:
return 'full' in pool['flags_names'].split(",")
@@ -575,21 +584,21 @@ class Filesystem(MDSCluster):
assert(mds_map['in'] == list(range(0, mds_map['max_mds'])))
def reset(self):
- self.mon_manager.raw_cluster_cmd("fs", "reset", str(self.name), '--yes-i-really-mean-it')
+ self.run_ceph_cmd("fs", "reset", str(self.name), '--yes-i-really-mean-it')
def fail(self):
- self.mon_manager.raw_cluster_cmd("fs", "fail", str(self.name))
+ self.run_ceph_cmd("fs", "fail", str(self.name))
def set_flag(self, var, *args):
a = map(lambda x: str(x).lower(), args)
- self.mon_manager.raw_cluster_cmd("fs", "flag", "set", var, *a)
+ self.run_ceph_cmd("fs", "flag", "set", var, *a)
def set_allow_multifs(self, yes=True):
self.set_flag("enable_multiple", yes)
def set_var(self, var, *args):
a = map(lambda x: str(x).lower(), args)
- self.mon_manager.raw_cluster_cmd("fs", "set", self.name, var, *a)
+ self.run_ceph_cmd("fs", "set", self.name, var, *a)
def set_down(self, down=True):
self.set_var("down", str(down).lower())
@@ -615,9 +624,12 @@ class Filesystem(MDSCluster):
def set_refuse_client_session(self, yes):
self.set_var("refuse_client_session", yes)
+ def set_refuse_standby_for_another_fs(self, yes):
+ self.set_var("refuse_standby_for_another_fs", yes)
+
def compat(self, *args):
a = map(lambda x: str(x).lower(), args)
- self.mon_manager.raw_cluster_cmd("fs", "compat", self.name, *a)
+ self.run_ceph_cmd("fs", "compat", self.name, *a)
def add_compat(self, *args):
self.compat("add_compat", *args)
@@ -633,7 +645,7 @@ class Filesystem(MDSCluster):
def required_client_features(self, *args, **kwargs):
c = ["fs", "required_client_features", self.name, *args]
- return self.mon_manager.run_cluster_cmd(args=c, **kwargs)
+ return self.run_ceph_cmd(args=c, **kwargs)
# Since v15.1.0 the pg autoscale mode has been enabled as default,
# will let the pg autoscale mode to calculate the pg_num as needed.
@@ -662,24 +674,23 @@ class Filesystem(MDSCluster):
log.debug("Creating filesystem '{0}'".format(self.name))
try:
- self.mon_manager.raw_cluster_cmd('osd', 'pool', 'create',
- self.metadata_pool_name,
- '--pg_num_min', str(self.pg_num_min))
-
- self.mon_manager.raw_cluster_cmd('osd', 'pool', 'create',
- data_pool_name, str(self.pg_num),
- '--pg_num_min', str(self.pg_num_min),
- '--target_size_ratio',
- str(self.target_size_ratio))
+ self.run_ceph_cmd('osd', 'pool', 'create',self.metadata_pool_name,
+ '--pg_num_min', str(self.pg_num_min))
+
+ self.run_ceph_cmd('osd', 'pool', 'create', data_pool_name,
+ str(self.pg_num),
+ '--pg_num_min', str(self.pg_num_min),
+ '--target_size_ratio',
+ str(self.target_size_ratio))
except CommandFailedError as e:
if e.exitstatus == 22: # nautilus couldn't specify --pg_num_min option
- self.mon_manager.raw_cluster_cmd('osd', 'pool', 'create',
- self.metadata_pool_name,
- str(self.pg_num_min))
+ self.run_ceph_cmd('osd', 'pool', 'create',
+ self.metadata_pool_name,
+ str(self.pg_num_min))
- self.mon_manager.raw_cluster_cmd('osd', 'pool', 'create',
- data_pool_name, str(self.pg_num),
- str(self.pg_num_min))
+ self.run_ceph_cmd('osd', 'pool', 'create',
+ data_pool_name, str(self.pg_num),
+ str(self.pg_num_min))
else:
raise
@@ -688,7 +699,7 @@ class Filesystem(MDSCluster):
args.append('--recover')
if metadata_overlay:
args.append('--allow-dangerous-metadata-overlay')
- self.mon_manager.raw_cluster_cmd(*args)
+ self.run_ceph_cmd(*args)
if not recover:
if self.ec_profile and 'disabled' not in self.ec_profile:
@@ -696,23 +707,22 @@ class Filesystem(MDSCluster):
log.debug("EC profile is %s", self.ec_profile)
cmd = ['osd', 'erasure-code-profile', 'set', ec_data_pool_name]
cmd.extend(self.ec_profile)
- self.mon_manager.raw_cluster_cmd(*cmd)
+ self.run_ceph_cmd(*cmd)
try:
- self.mon_manager.raw_cluster_cmd(
+ self.run_ceph_cmd(
'osd', 'pool', 'create', ec_data_pool_name,
'erasure', ec_data_pool_name,
'--pg_num_min', str(self.pg_num_min),
'--target_size_ratio', str(self.target_size_ratio_ec))
except CommandFailedError as e:
if e.exitstatus == 22: # nautilus couldn't specify --pg_num_min option
- self.mon_manager.raw_cluster_cmd(
+ self.run_ceph_cmd(
'osd', 'pool', 'create', ec_data_pool_name,
str(self.pg_num_min), 'erasure', ec_data_pool_name)
else:
raise
- self.mon_manager.raw_cluster_cmd(
- 'osd', 'pool', 'set',
- ec_data_pool_name, 'allow_ec_overwrites', 'true')
+ self.run_ceph_cmd('osd', 'pool', 'set', ec_data_pool_name,
+ 'allow_ec_overwrites', 'true')
self.add_data_pool(ec_data_pool_name, create=False)
self.check_pool_application(ec_data_pool_name)
@@ -723,7 +733,8 @@ class Filesystem(MDSCluster):
# Turn off spurious standby count warnings from modifying max_mds in tests.
try:
- self.mon_manager.raw_cluster_cmd('fs', 'set', self.name, 'standby_count_wanted', '0')
+ self.run_ceph_cmd('fs', 'set', self.name, 'standby_count_wanted',
+ '0')
except CommandFailedError as e:
if e.exitstatus == 22:
# standby_count_wanted not available prior to luminous (upgrade tests would fail otherwise)
@@ -756,17 +767,29 @@ class Filesystem(MDSCluster):
assert(isinstance(subvols['create'], int))
assert(subvols['create'] > 0)
+ self.mon_manager.raw_cluster_cmd('fs', 'subvolumegroup', 'create', self.name, 'qa')
+ subvol_options = self.fs_config.get('subvol_options', '')
+
for sv in range(0, subvols['create']):
sv_name = f'sv_{sv}'
- self.mon_manager.raw_cluster_cmd(
- 'fs', 'subvolume', 'create', self.name, sv_name,
- self.fs_config.get('subvol_options', ''))
+ cmd = [
+ 'fs',
+ 'subvolume',
+ 'create',
+ self.name,
+ sv_name,
+ '--group_name', 'qa',
+ ]
+ if subvol_options:
+ cmd.append(subvol_options)
+ self.run_ceph_cmd(cmd)
if self.name not in self._ctx.created_subvols:
self._ctx.created_subvols[self.name] = []
- subvol_path = self.mon_manager.raw_cluster_cmd(
- 'fs', 'subvolume', 'getpath', self.name, sv_name)
+ subvol_path = self.get_ceph_cmd_stdout(
+ 'fs', 'subvolume', 'getpath', self.name,
+ '--group_name', 'qa', sv_name)
subvol_path = subvol_path.strip()
self._ctx.created_subvols[self.name].append(subvol_path)
else:
@@ -858,7 +881,7 @@ class Filesystem(MDSCluster):
"""
Whether a filesystem exists in the mon's filesystem list
"""
- fs_list = json.loads(self.mon_manager.raw_cluster_cmd('fs', 'ls', '--format=json-pretty'))
+ fs_list = json.loads(self.get_ceph_cmd_stdout('fs', 'ls', '--format=json-pretty'))
return self.name in [fs['name'] for fs in fs_list]
def legacy_configured(self):
@@ -867,7 +890,7 @@ class Filesystem(MDSCluster):
the case, the caller should avoid using Filesystem.create
"""
try:
- out_text = self.mon_manager.raw_cluster_cmd('--format=json-pretty', 'osd', 'lspools')
+ out_text = self.get_ceph_cmd_stdout('--format=json-pretty', 'osd', 'lspools')
pools = json.loads(out_text)
metadata_pool_exists = 'metadata' in [p['poolname'] for p in pools]
if metadata_pool_exists:
@@ -883,7 +906,7 @@ class Filesystem(MDSCluster):
return metadata_pool_exists
def _df(self):
- return json.loads(self.mon_manager.raw_cluster_cmd("df", "--format=json-pretty"))
+ return json.loads(self.get_ceph_cmd_stdout("df", "--format=json-pretty"))
# may raise FSMissing
def get_mds_map(self, status=None):
@@ -901,15 +924,15 @@ class Filesystem(MDSCluster):
def add_data_pool(self, name, create=True):
if create:
try:
- self.mon_manager.raw_cluster_cmd('osd', 'pool', 'create', name,
- '--pg_num_min', str(self.pg_num_min))
+ self.run_ceph_cmd('osd', 'pool', 'create', name,
+ '--pg_num_min', str(self.pg_num_min))
except CommandFailedError as e:
if e.exitstatus == 22: # nautilus couldn't specify --pg_num_min option
- self.mon_manager.raw_cluster_cmd('osd', 'pool', 'create', name,
- str(self.pg_num_min))
+ self.run_ceph_cmd('osd', 'pool', 'create', name,
+ str(self.pg_num_min))
else:
raise
- self.mon_manager.raw_cluster_cmd('fs', 'add_data_pool', self.name, name)
+ self.run_ceph_cmd('fs', 'add_data_pool', self.name, name)
self.get_pool_names(refresh = True)
for poolid, fs_name in self.data_pools.items():
if name == fs_name:
@@ -962,9 +985,9 @@ class Filesystem(MDSCluster):
self.data_pool_name = name
def get_pool_pg_num(self, pool_name):
- pgs = json.loads(self.mon_manager.raw_cluster_cmd('osd', 'pool', 'get',
- pool_name, 'pg_num',
- '--format=json-pretty'))
+ pgs = json.loads(self.get_ceph_cmd_stdout('osd', 'pool', 'get',
+ pool_name, 'pg_num',
+ '--format=json-pretty'))
return int(pgs['pg_num'])
def get_namespace_id(self):
@@ -1095,13 +1118,13 @@ class Filesystem(MDSCluster):
self.mds_signal(name, signal)
def rank_freeze(self, yes, rank=0):
- self.mon_manager.raw_cluster_cmd("mds", "freeze", "{}:{}".format(self.id, rank), str(yes).lower())
+ self.run_ceph_cmd("mds", "freeze", "{}:{}".format(self.id, rank), str(yes).lower())
def rank_repaired(self, rank):
- self.mon_manager.raw_cluster_cmd("mds", "repaired", "{}:{}".format(self.id, rank))
+ self.run_ceph_cmd("mds", "repaired", "{}:{}".format(self.id, rank))
def rank_fail(self, rank=0):
- self.mon_manager.raw_cluster_cmd("mds", "fail", "{}:{}".format(self.id, rank))
+ self.run_ceph_cmd("mds", "fail", "{}:{}".format(self.id, rank))
def rank_is_running(self, rank=0, status=None):
name = self.get_rank(rank=rank, status=status)['name']
@@ -1240,15 +1263,15 @@ class Filesystem(MDSCluster):
if mds_id is None:
return self.rank_tell(command)
- return json.loads(self.mon_manager.raw_cluster_cmd("tell", f"mds.{mds_id}", *command))
+ return json.loads(self.get_ceph_cmd_stdout("tell", f"mds.{mds_id}", *command))
def rank_asok(self, command, rank=0, status=None, timeout=None):
info = self.get_rank(rank=rank, status=status)
return self.json_asok(command, 'mds', info['name'], timeout=timeout)
- def rank_tell(self, command, rank=0, status=None):
+ def rank_tell(self, command, rank=0, status=None, timeout=120):
try:
- out = self.mon_manager.raw_cluster_cmd("tell", f"mds.{self.id}:{rank}", *command)
+ out = self.get_ceph_cmd_stdout("tell", f"mds.{self.id}:{rank}", *command)
return json.loads(out)
except json.decoder.JSONDecodeError:
log.error("could not decode: {}".format(out))
@@ -1648,8 +1671,8 @@ class Filesystem(MDSCluster):
caps = tuple(x)
client_name = 'client.' + client_id
- return self.mon_manager.raw_cluster_cmd('fs', 'authorize', self.name,
- client_name, *caps)
+ return self.get_ceph_cmd_stdout('fs', 'authorize', self.name,
+ client_name, *caps)
def grow(self, new_max_mds, status=None):
oldmax = self.get_var('max_mds', status=status)
@@ -1663,11 +1686,11 @@ class Filesystem(MDSCluster):
self.set_max_mds(new_max_mds)
return self.wait_for_daemons()
- def run_scrub(self, cmd, rank=0):
- return self.rank_tell(["scrub"] + cmd, rank)
+ def run_scrub(self, cmd, rank=0, timeout=300):
+ return self.rank_tell(["scrub"] + cmd, rank=rank, timeout=timeout)
def get_scrub_status(self, rank=0):
- return self.run_scrub(["status"], rank)
+ return self.run_scrub(["status"], rank=rank, timeout=300)
def flush(self, rank=0):
return self.rank_tell(["flush", "journal"], rank=rank)
@@ -1679,7 +1702,7 @@ class Filesystem(MDSCluster):
result = "no active scrubs running"
with contextutil.safe_while(sleep=sleep, tries=timeout//sleep) as proceed:
while proceed():
- out_json = self.rank_tell(["scrub", "status"], rank=rank)
+ out_json = self.rank_tell(["scrub", "status"], rank=rank, timeout=timeout)
assert out_json is not None
if not reverse:
if result in out_json['status']: