Skip to content

Commit f6d2b20

Browse files
committed
ceph-volume: lvm.Lvm.setup_metadata_devices refactor
This commit refactors setup_metadata_devices into smaller helper methods. It keeps the distinction between existing logical volumes and raw devices explicit, centralizes tag handling and path assignment to make the control flow obvious and separates responsibilities for checking, creating, and tagging devices. Fixes: https://tracker.ceph.com/issues/73445 Signed-off-by: Guillaume Abrioux <[email protected]>
1 parent 01510d1 commit f6d2b20

File tree

1 file changed

+82
-75
lines changed
  • src/ceph-volume/ceph_volume/objectstore

1 file changed

+82
-75
lines changed

src/ceph-volume/ceph_volume/objectstore/lvm.py

Lines changed: 82 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
if TYPE_CHECKING:
1616
import argparse
17-
from ceph_volume.api.lvm import Volume
1817

1918
logger = logging.getLogger(__name__)
2019

@@ -69,7 +68,7 @@ def pre_prepare(self) -> None:
6968

7069
def prepare_data_device(self,
7170
device_type: str,
72-
osd_uuid: str) -> Optional["Volume"]:
71+
osd_uuid: str) -> Optional[api.Volume]:
7372
"""
7473
Check if ``arg`` is a device or partition to create an LV out of it
7574
with a distinct volume group name, assigning LV tags on it and
@@ -198,84 +197,92 @@ def luks_format_and_open(self,
198197
return '/dev/mapper/%s' % uuid
199198

200199
def setup_metadata_devices(self) -> None:
201-
"""
202-
Check if ``device`` is an lv, if so, set the tags, making sure to
203-
update the tags with the lv_uuid and lv_path which the incoming tags
204-
will not have.
205-
206-
If the device is not a logical volume, then retrieve the partition UUID
207-
by querying ``blkid``
208-
"""
209-
s: Dict[str, Any] = {
210-
'db': {
211-
'attr_map': 'db_device_path',
212-
'device_name': self.args.block_db,
213-
'device_size': self.args.block_db_size,
214-
'device_slots': self.args.block_db_slots,
215-
},
216-
'wal': {
217-
'attr_map': 'wal_device_path',
218-
'device_name': self.args.block_wal,
219-
'device_size': self.args.block_wal_size,
220-
'device_slots': self.args.block_wal_slots,
221-
}
222-
}
223-
for device_type, device_args in s.items():
224-
device_name: str = device_args.get('device_name', None)
225-
size: int = device_args.get('device_size')
226-
slots: int = device_args.get('device_slots')
227-
if device_name is None:
200+
for device_type in ("db", "wal"):
201+
device_name: Optional[str] = getattr(self.args, f"block_{device_type}")
202+
if not device_name:
228203
continue
229-
_tags: Dict[str, Any] = self.tags.copy()
230-
_tags['ceph.type'] = device_type
231-
_tags['ceph.vdo'] = api.is_vdo(device_name)
232204

233-
try:
234-
vg_name, lv_name = device_name.split('/')
235-
lv = api.get_single_lv(filters={'lv_name': lv_name,
236-
'vg_name': vg_name})
237-
except ValueError:
238-
lv = None
205+
size: int = getattr(self.args, f"block_{device_type}_size")
206+
slots: int = getattr(self.args, f"block_{device_type}_slots")
207+
208+
tags: Dict[str, Any] = self._prepare_tags(device_type, device_name)
209+
lv = self._get_existing_lv(device_name)
239210

240211
if lv:
241-
_tags['ceph.%s_uuid' % device_type] = lv.lv_uuid
242-
_tags['ceph.%s_device' % device_type] = lv.lv_path
243-
lv.set_tags(_tags)
244-
elif disk.is_partition(device_name) or disk.is_device(device_name):
245-
# We got a disk or a partition, create an lv
246-
path = device_name
247-
lv_type = "osd-{}".format(device_type)
248-
name_uuid = system.generate_uuid()
249-
kwargs = {
250-
'name_prefix': lv_type,
251-
'uuid': name_uuid,
252-
'vg': None,
253-
'device': device_name,
254-
'slots': slots,
255-
'extents': None,
256-
'size': None,
257-
'tags': _tags,
212+
self._apply_tags_to_existing_lv(lv, device_type, tags)
213+
path = lv.lv_path
214+
else:
215+
path = self._handle_physical_device(
216+
device_name, device_type, size, slots, tags
217+
)
218+
if path is None:
219+
raise RuntimeError(f"Invalid device: {device_name}")
220+
221+
setattr(self, f"{device_type}_device_path", path)
222+
223+
def _prepare_tags(self, device_type: str, device_name: str) -> Dict[str, Any]:
224+
tags: Dict[str, Any] = self.tags.copy()
225+
tags["ceph.type"] = device_type
226+
tags["ceph.vdo"] = api.is_vdo(device_name)
227+
return tags
228+
229+
def _get_existing_lv(self, device_name: str) -> Optional[api.Volume]:
230+
try:
231+
vg_name, lv_name = device_name.split("/")
232+
return api.get_single_lv(filters={"lv_name": lv_name, "vg_name": vg_name})
233+
except ValueError:
234+
return None
235+
236+
def _apply_tags_to_existing_lv(
237+
self, lv: api.Volume, device_type: str, tags: Dict[str, Any]
238+
) -> None:
239+
tags[f"ceph.{device_type}_uuid"] = lv.lv_uuid
240+
tags[f"ceph.{device_type}_device"] = lv.lv_path
241+
lv.set_tags(tags)
242+
self.tags.update(tags)
243+
244+
def _handle_physical_device(
245+
self,
246+
device_name: str,
247+
device_type: str,
248+
size: int,
249+
slots: int,
250+
tags: Dict[str, Any],
251+
) -> Optional[str]:
252+
if not (disk.is_partition(device_name) or disk.is_device(device_name)):
253+
return None
254+
255+
lv_type = f"osd-{device_type}"
256+
name_uuid = system.generate_uuid()
257+
258+
kwargs: Dict[str, Any] = {
259+
"name_prefix": lv_type,
260+
"uuid": name_uuid,
261+
"vg": None,
262+
"device": device_name,
263+
"slots": slots,
264+
"extents": None,
265+
"size": size if size != 0 else None,
266+
"tags": tags,
267+
}
268+
269+
lv = None if disk.is_partition(device_name) else api.create_lv(**kwargs)
270+
271+
if lv is not None:
272+
tags.update(
273+
{
274+
f"ceph.{device_type}_uuid": lv.lv_uuid,
275+
f"ceph.{device_type}_device": lv.lv_path,
258276
}
259-
# TODO use get_block_db_size and co here to get configured size in
260-
# conf file
261-
if size != 0:
262-
kwargs['size'] = size
263-
# We do not create LV if this is a partition
264-
if not disk.is_partition(device_name):
265-
lv = api.create_lv(**kwargs)
266-
if lv is not None:
267-
path, lv_uuid = lv.lv_path, lv.lv_uuid
268-
for key, value in {
269-
f"ceph.{device_type}_uuid": lv_uuid,
270-
f"ceph.{device_type}_device": path,
271-
}.items():
272-
_tags[key] = value
273-
self.tags[key] = value
274-
lv.set_tags(_tags)
275-
setattr(self, f'{device_type}_device_path', path)
277+
)
278+
self.tags.update(tags)
279+
lv.set_tags(tags)
280+
return lv.lv_path
281+
282+
return device_name
276283

277284
def get_osd_device_path(self,
278-
osd_lvs: List["Volume"],
285+
osd_lvs: List[api.Volume],
279286
device_type: str,
280287
dmcrypt_secret: str = '') -> Optional[str]:
281288
"""
@@ -301,7 +308,7 @@ def get_osd_device_path(self,
301308
if not device_uuid:
302309
return None
303310

304-
device_lv: Optional["Volume"] = None
311+
device_lv: Optional[api.Volume] = None
305312
for lv in osd_lvs:
306313
if lv.tags.get('ceph.type') == device_type:
307314
device_lv = lv
@@ -328,7 +335,7 @@ def get_osd_device_path(self,
328335
device_uuid))
329336

330337
def _activate(self,
331-
osd_lvs: List["Volume"],
338+
osd_lvs: List[api.Volume],
332339
no_systemd: bool = False,
333340
no_tmpfs: bool = False) -> None:
334341
for lv in osd_lvs:

0 commit comments

Comments
 (0)