diff --git a/src/pybind/mgr/cephadm/services/osd.py b/src/pybind/mgr/cephadm/services/osd.py index 94cb6fa076d..775d296911f 100644 --- a/src/pybind/mgr/cephadm/services/osd.py +++ b/src/pybind/mgr/cephadm/services/osd.py @@ -204,12 +204,14 @@ class OSDService(CephService): [ {'data': {}, 'osdspec': , - 'host': + 'host': , + 'notes': }, {'data': ..., 'osdspec': .., - 'host': .. + 'host': ..., + 'notes': ... } ] @@ -246,10 +248,16 @@ class OSDService(CephService): except ValueError: logger.exception('Cannot decode JSON: \'%s\'' % ' '.join(out)) concat_out = {} - + notes = [] + if osdspec.data_devices is not None and osdspec.data_devices.limit and len(concat_out) < osdspec.data_devices.limit: + found = len(concat_out) + limit = osdspec.data_devices.limit + notes.append( + f'NOTE: Did not find enough disks matching filter on host {host} to reach data device limit (Found: {found} | Limit: {limit})') ret_all.append({'data': concat_out, 'osdspec': osdspec.service_id, - 'host': host}) + 'host': host, + 'notes': notes}) return ret_all def resolve_hosts_for_osdspecs(self, diff --git a/src/pybind/mgr/cephadm/tests/test_cephadm.py b/src/pybind/mgr/cephadm/tests/test_cephadm.py index 2d1f4a9a342..f93ededbdee 100644 --- a/src/pybind/mgr/cephadm/tests/test_cephadm.py +++ b/src/pybind/mgr/cephadm/tests/test_cephadm.py @@ -665,6 +665,28 @@ class TestCephadm(object): out = wait(cephadm_module, c) assert out == "Created no osd(s) on host test; already created?" + @mock.patch("cephadm.serve.CephadmServe._run_cephadm", _run_cephadm('{}')) + @mock.patch('cephadm.services.osd.OSDService._run_ceph_volume_command') + @mock.patch('cephadm.services.osd.OSDService.driveselection_to_ceph_volume') + @mock.patch('cephadm.services.osd.OsdIdClaims.refresh', lambda _: None) + @mock.patch('cephadm.services.osd.OsdIdClaims.get', lambda _: {}) + def test_limit_not_reached(self, d_to_cv, _run_cv_cmd, cephadm_module): + with with_host(cephadm_module, 'test'): + dg = DriveGroupSpec(placement=PlacementSpec(host_pattern='test'), + data_devices=DeviceSelection(limit=5, rotational=1), + service_id='not_enough') + + disks_found = [ + '[{"data": "/dev/vdb", "data_size": "50.00 GB", "encryption": "None"}, {"data": "/dev/vdc", "data_size": "50.00 GB", "encryption": "None"}]'] + d_to_cv.return_value = 'foo' + _run_cv_cmd.return_value = (disks_found, '', 0) + preview = cephadm_module.osd_service.generate_previews([dg], 'test') + + for osd in preview: + assert 'notes' in osd + assert osd['notes'] == [ + 'NOTE: Did not find enough disks matching filter on host test to reach data device limit (Found: 2 | Limit: 5)'] + @mock.patch("cephadm.serve.CephadmServe._run_cephadm", _run_cephadm('{}')) def test_prepare_drivegroup(self, cephadm_module): with with_host(cephadm_module, 'test'): diff --git a/src/pybind/mgr/orchestrator/module.py b/src/pybind/mgr/orchestrator/module.py index 6d28d59fc7c..dde3397ce60 100644 --- a/src/pybind/mgr/orchestrator/module.py +++ b/src/pybind/mgr/orchestrator/module.py @@ -158,6 +158,7 @@ def preview_table_osd(data: List) -> str: table.align = 'l' table.left_padding_width = 0 table.right_padding_width = 2 + notes = '' for osd_data in data: if osd_data.get('service_type') != 'osd': continue @@ -166,6 +167,8 @@ def preview_table_osd(data: List) -> str: if spec.get('error'): return spec.get('message') dg_name = spec.get('osdspec') + if spec.get('notes', []): + notes += '\n'.join(spec.get('notes')) + '\n' for osd in spec.get('data', []): db_path = osd.get('block_db', '-') wal_path = osd.get('block_wal', '-') @@ -173,7 +176,7 @@ def preview_table_osd(data: List) -> str: if not block_data: continue table.add_row(('osd', dg_name, host, block_data, db_path, wal_path)) - return table.get_string() + return notes + table.get_string() def preview_table_services(data: List) -> str: