From 8aa2f4745adff0ba3c7a0731cf48ccc1c85b33f3 Mon Sep 17 00:00:00 2001 From: Guillaume Abrioux Date: Wed, 23 Mar 2022 10:04:45 +0100 Subject: [PATCH] orchestrator: support complex osd creation This adds the support of complex OSD creation with command `orch daemon add osd`. Any argument supported by `DriveGroupSpec()` can be passed on the command line. Usage: ``` ceph orch daemon add osd host:data_devices=device1,device2,db_devices=device3,osds_per_device=2,... ``` Signed-off-by: Guillaume Abrioux --- doc/cephadm/services/osd.rst | 6 +++++ src/pybind/mgr/orchestrator/module.py | 33 +++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/doc/cephadm/services/osd.rst b/doc/cephadm/services/osd.rst index c96d8a510860f..c4260b84d90a4 100644 --- a/doc/cephadm/services/osd.rst +++ b/doc/cephadm/services/osd.rst @@ -138,6 +138,12 @@ There are a few ways to create new OSDs: ceph orch daemon add osd host1:/dev/sdb + Advanced OSD creation from specific devices on a specific host: + + .. prompt:: bash # + + ceph orch daemon add osd host1:data_devices=/dev/sda,/dev/sdb,db_devices=/dev/sdc,osds_per_device=2 + * You can use :ref:`drivegroups` to categorize device(s) based on their properties. This might be useful in forming a clearer picture of which devices are available to consume. Properties include device type (SSD or diff --git a/src/pybind/mgr/orchestrator/module.py b/src/pybind/mgr/orchestrator/module.py index e7a3b20be50fb..633c55908eb36 100644 --- a/src/pybind/mgr/orchestrator/module.py +++ b/src/pybind/mgr/orchestrator/module.py @@ -792,17 +792,42 @@ class OrchestratorCli(OrchestratorClientMixin, MgrModule, usage = """ Usage: ceph orch daemon add osd host:device1,device2,... + ceph orch daemon add osd host:data_devices=device1,device2,db_devices=device3,osds_per_device=2,... """ if not svc_arg: return HandleCommandResult(-errno.EINVAL, stderr=usage) try: - host_name, block_device = svc_arg.split(":") - block_devices = block_device.split(',') - devs = DeviceSelection(paths=block_devices) + host_name, raw = svc_arg.split(":") + drive_group_spec = { + 'data_devices': [] + } # type: Dict + drv_grp_spec_arg = None + values = raw.split(',') + while values: + v = values[0].split(',', 1)[0] + if '=' in v: + drv_grp_spec_arg, value = v.split('=') + if drv_grp_spec_arg in ['data_devices', + 'db_devices', + 'wal_devices', + 'journal_devices']: + drive_group_spec[drv_grp_spec_arg] = [] + drive_group_spec[drv_grp_spec_arg].append(value) + else: + drive_group_spec[drv_grp_spec_arg] = value + elif drv_grp_spec_arg is not None: + drive_group_spec[drv_grp_spec_arg].append(v) + else: + drive_group_spec['data_devices'].append(v) + values.remove(v) + + for dev_type in ['data_devices', 'db_devices', 'wal_devices', 'journal_devices']: + drive_group_spec[dev_type] = DeviceSelection(paths=drive_group_spec[dev_type]) if drive_group_spec.get(dev_type) else None + drive_group = DriveGroupSpec( placement=PlacementSpec(host_pattern=host_name), - data_devices=devs, method=method, + **drive_group_spec, ) except (TypeError, KeyError, ValueError) as e: msg = f"Invalid 'host:device' spec: '{svc_arg}': {e}" + usage -- 2.39.5