def test_DriveGroup(test_input): dg = [DriveGroupSpec.from_json(inp) for inp in test_input][0] assert dg.placement.filter_matching_hostspecs([HostSpec('hostname') ]) == ['hostname'] assert dg.service_id == 'testing_drivegroup' assert all([isinstance(x, Device) for x in dg.data_devices.paths]) assert dg.data_devices.paths[0].path == '/dev/sda'
def _create_osd(self, svc_arg=None, inbuf=None): # type: (str, str) -> HandleCommandResult """Create one or more OSDs""" usage = """ Usage: ceph orchestrator osd create -i <json_file> ceph orchestrator osd create host:device1,device2,... """ if inbuf: try: drive_group = DriveGroupSpec.from_json(json.loads(inbuf)) except ValueError as e: msg = 'Failed to read JSON input: {}'.format(str(e)) + usage return HandleCommandResult(-errno.EINVAL, stderr=msg) elif svc_arg: try: node_name, block_device = svc_arg.split(":") block_devices = block_device.split(',') except (TypeError, KeyError, ValueError): msg = "Invalid host:device spec: '{}'".format(svc_arg) + usage return HandleCommandResult(-errno.EINVAL, stderr=msg) devs = DeviceSelection(paths=block_devices) drive_group = DriveGroupSpec(node_name, data_devices=devs) else: return HandleCommandResult(-errno.EINVAL, stderr=usage) completion = self.create_osds(drive_group) self._orchestrator_wait([completion]) orchestrator.raise_if_exception(completion) self.log.warning(str(completion.result)) return HandleCommandResult(stdout=completion.result_str())
def _create_with_drive_groups(self, drive_group): """Create OSDs with DriveGroups.""" orch = OrchClient.instance() try: orch.osds.create(DriveGroupSpec.from_json(drive_group)) except (ValueError, TypeError, DriveGroupValidationError) as e: raise DashboardException(e, component='osd')
def test_DriveGroup(): dg_json = { 'host_pattern': 'hostname', 'data_devices': {'paths': ['/dev/sda']} } dg = DriveGroupSpec.from_json(dg_json) assert dg.hosts(['hostname']) == ['hostname'] assert dg.data_devices.paths == ['/dev/sda']
def make_sample_data(empty=empty, data_limit=0, wal_limit=0, db_limit=0, osds_per_device='', disk_format='bluestore'): raw_sample_bluestore = { 'host_pattern': 'data*', 'data_devices': { 'size': '30G:50G', 'model': '42-RGB', 'vendor': 'samsung', 'limit': data_limit }, 'wal_devices': { 'model': 'fast', 'limit': wal_limit }, 'db_devices': { 'size': ':20G', 'limit': db_limit }, 'db_slots': 5, 'wal_slots': 5, 'block_wal_size': '5G', 'block_db_size': '10G', 'objectstore': disk_format, 'osds_per_device': osds_per_device, 'encrypted': True, } raw_sample_filestore = { 'host_pattern': 'data*', 'objectstore': 'filestore', 'data_devices': { 'size': '30G:50G', 'model': 'foo', 'vendor': '1x', 'limit': data_limit }, 'journal_devices': { 'size': ':20G' }, 'journal_size': '5G', 'osds_per_device': osds_per_device, 'encrypted': True, } if disk_format == 'filestore': raw_sample = raw_sample_filestore else: raw_sample = raw_sample_bluestore if empty: raw_sample = {'host_pattern': 'data*'} dgo = DriveGroupSpec.from_json(raw_sample) return dgo
def _load_drive_groups(self) -> None: stored_drive_group = self.get_store("drive_group_map") self._drive_group_map: Dict[str, DriveGroupSpec] = {} if stored_drive_group: for name, dg in json.loads(stored_drive_group).items(): try: self._drive_group_map[name] = DriveGroupSpec.from_json(dg) except ValueError as e: self.log.error( f'Failed to load drive group {name} ({dg}): {e}')
def _create_predefined_drive_group(self, data): orch = OrchClient.instance() option = OsdDeploymentOptions(data[0]['option']) if option in list(OsdDeploymentOptions): try: predefined_drive_groups[option]['encrypted'] = data[0][ 'encrypted'] orch.osds.create([ DriveGroupSpec.from_json(predefined_drive_groups[option]) ]) except (ValueError, TypeError, KeyError, DriveGroupValidationError) as e: raise DashboardException(e, component='osd')
def test_DriveGroup(test_input): dg = DriveGroupSpec.from_json(yaml.safe_load(test_input)) assert dg.service_id == 'testing_drivegroup' assert all([isinstance(x, Device) for x in dg.data_devices.paths]) assert dg.data_devices.paths[0].path == '/dev/sda'
def test_DriveGroup_fail(match, test_input): with pytest.raises(SpecValidationError, match=match): osd_spec = DriveGroupSpec.from_json(yaml.safe_load(test_input)) osd_spec.validate()
def test_DriveGroup_fail(): with pytest.raises(TypeError): DriveGroupSpec.from_json({})
def test_DriveGroup_fail(): with pytest.raises(DriveGroupValidationError): DriveGroupSpec.from_json({})
def test_DriveGroup_fail(test_input): with pytest.raises(ServiceSpecValidationError): DriveGroupSpec.from_json(test_input)
def _apply_osd(self, all_available_devices: bool = False, preview: bool = False, service_name: Optional[str] = None, unmanaged: Optional[bool] = None, format: Optional[str] = 'plain', inbuf: Optional[str] = None) -> HandleCommandResult: """Apply DriveGroupSpecs to create OSDs""" usage = """ Usage: ceph orch apply osd -i <json_file/yaml_file> ceph orch apply osd --all-available-devices ceph orch apply osd --service-name <service_name> --preview ceph orch apply osd --service-name <service_name> --unmanaged=True|False """ def print_preview(prev, format): if format != 'plain': return to_format(prev, format) else: table = PrettyTable(['NAME', 'HOST', 'DATA', 'DB', 'WAL'], border=False) table.align = 'l' table.left_padding_width = 0 table.right_padding_width = 1 for data in prev: dg_name = data.get('drivegroup') hostname = data.get('host') for osd in data.get('data', {}).get('osds', []): db_path = '-' wal_path = '-' block_db = osd.get('block.db', {}).get('path') block_wal = osd.get('block.wal', {}).get('path') block_data = osd.get('data', {}).get('path', '') if not block_data: continue if block_db: db_path = data.get('data', {}).get('vg', {}).get('devices', []) if block_wal: wal_path = data.get('data', {}).get('wal_vg', {}).get('devices', []) table.add_row( (dg_name, hostname, block_data, db_path, wal_path)) out = table.get_string() if not out: out = "No pending deployments." return out if (inbuf or all_available_devices) and service_name: # mutually exclusive return HandleCommandResult(-errno.EINVAL, stderr=usage) if preview and not (service_name or all_available_devices or inbuf): # get all stored drivegroups and print prev = self.preview_drivegroups() return HandleCommandResult(stdout=print_preview(prev, format)) if service_name and preview: # get specified drivegroup and print prev = self.preview_drivegroups(service_name) return HandleCommandResult(stdout=print_preview(prev, format)) if service_name and unmanaged is not None: return self.set_unmanaged_flag(service_name, unmanaged) if not inbuf and not all_available_devices: return HandleCommandResult(-errno.EINVAL, stderr=usage) if inbuf: if all_available_devices: raise OrchestratorError( '--all-available-devices cannot be combined with an osd spec' ) try: drivegroups = yaml.load_all(inbuf) dg_specs = [DriveGroupSpec.from_json(dg) for dg in drivegroups] except ValueError as e: msg = 'Failed to read JSON/YAML input: {}'.format( str(e)) + usage return HandleCommandResult(-errno.EINVAL, stderr=msg) else: dg_specs = [ DriveGroupSpec( service_id='all-available-devices', placement=PlacementSpec(host_pattern='*'), data_devices=DeviceSelection(all=True), ) ] if not preview: completion = self.apply_drivegroups(dg_specs) self._orchestrator_wait([completion]) raise_if_exception(completion) ret = self.preview_drivegroups(dg_specs=dg_specs) return HandleCommandResult(stdout=print_preview(ret, format))