Esempio n. 1
0
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'
Esempio n. 2
0
    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())
Esempio n. 3
0
 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')
Esempio n. 4
0
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']
Esempio n. 5
0
        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
Esempio n. 6
0
 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}')
Esempio n. 7
0
 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')
Esempio n. 8
0
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'
Esempio n. 9
0
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()
Esempio n. 10
0
def test_DriveGroup_fail():
    with pytest.raises(TypeError):
        DriveGroupSpec.from_json({})
Esempio n. 11
0
def test_DriveGroup_fail():
    with pytest.raises(DriveGroupValidationError):
        DriveGroupSpec.from_json({})
Esempio n. 12
0
def test_DriveGroup_fail(test_input):
    with pytest.raises(ServiceSpecValidationError):
        DriveGroupSpec.from_json(test_input)
Esempio n. 13
0
    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))