Skip to content

Commit 7626c12

Browse files
committed
ceph-volume: refactor LvmBlueStore.setup_device()
This refactores redundant device setup calls in LvmBlueStore class: Calling the same function twice with different arguments for WAL and DB devices was inefficient and unnecessary. The new implementation simplifies the logic by directly accessing `self.args`, it removes the need for passing arguments manually. Signed-off-by: Guillaume Abrioux <[email protected]>
1 parent 4034cae commit 7626c12

File tree

3 files changed

+155
-215
lines changed

3 files changed

+155
-215
lines changed

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

Lines changed: 71 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from ceph_volume.devices.lvm.common import rollback_osd
1111
from ceph_volume.devices.lvm.listing import direct_report
1212
from .bluestore import BlueStore
13-
from typing import Dict, Any, Optional, List, Tuple, TYPE_CHECKING
13+
from typing import Dict, Any, Optional, List, TYPE_CHECKING
1414

1515
if TYPE_CHECKING:
1616
import argparse
@@ -131,21 +131,10 @@ def prepare(self) -> None:
131131
self.pre_prepare()
132132

133133
# 2/
134-
self.wal_device_path, wal_uuid, tags = self.setup_device(
135-
'wal',
136-
self.args.block_wal,
137-
self.tags,
138-
self.args.block_wal_size,
139-
self.args.block_wal_slots)
140-
self.db_device_path, db_uuid, tags = self.setup_device(
141-
'db',
142-
self.args.block_db,
143-
self.tags,
144-
self.args.block_db_size,
145-
self.args.block_db_slots)
146-
134+
self.setup_metadata_devices()
147135
self.tags['ceph.type'] = 'block'
148-
self.block_lv.set_tags(self.tags) # type: ignore
136+
if self.block_lv is not None:
137+
self.block_lv.set_tags(self.tags)
149138

150139
# 3/ encryption-only operations
151140
if self.encrypted:
@@ -205,12 +194,7 @@ def luks_format_and_open(self,
205194

206195
return '/dev/mapper/%s' % uuid
207196

208-
def setup_device(self,
209-
device_type: str,
210-
device_name: str,
211-
tags: Dict[str, Any],
212-
size: int,
213-
slots: int) -> Tuple[str, str, Dict[str, Any]]:
197+
def setup_metadata_devices(self) -> None:
214198
"""
215199
Check if ``device`` is an lv, if so, set the tags, making sure to
216200
update the tags with the lv_uuid and lv_path which the incoming tags
@@ -219,57 +203,73 @@ def setup_device(self,
219203
If the device is not a logical volume, then retrieve the partition UUID
220204
by querying ``blkid``
221205
"""
222-
if device_name is None:
223-
return '', '', tags
224-
tags['ceph.type'] = device_type
225-
tags['ceph.vdo'] = api.is_vdo(device_name)
226-
227-
try:
228-
vg_name, lv_name = device_name.split('/')
229-
lv = api.get_single_lv(filters={'lv_name': lv_name,
230-
'vg_name': vg_name})
231-
except ValueError:
232-
lv = None
233-
234-
if lv:
235-
lv_uuid = lv.lv_uuid
236-
path = lv.lv_path
237-
tags['ceph.%s_uuid' % device_type] = lv_uuid
238-
tags['ceph.%s_device' % device_type] = path
239-
lv.set_tags(tags)
240-
elif disk.is_partition(device_name) or disk.is_device(device_name):
241-
# We got a disk or a partition, create an lv
242-
lv_type = "osd-{}".format(device_type)
243-
name_uuid = system.generate_uuid()
244-
kwargs = {
245-
'name_prefix': lv_type,
246-
'uuid': name_uuid,
247-
'vg': None,
248-
'device': device_name,
249-
'slots': slots,
250-
'extents': None,
251-
'size': None,
252-
'tags': tags,
206+
s: Dict[str, Any] = {
207+
'db': {
208+
'attr_map': 'db_device_path',
209+
'device_name': self.args.block_db,
210+
'device_size': self.args.block_db_size,
211+
'device_slots': self.args.block_db_slots,
212+
},
213+
'wal': {
214+
'attr_map': 'wal_device_path',
215+
'device_name': self.args.block_wal,
216+
'device_size': self.args.block_wal_size,
217+
'device_slots': self.args.block_wal_slots,
218+
}
253219
}
254-
# TODO use get_block_db_size and co here to get configured size in
255-
# conf file
256-
if size != 0:
257-
kwargs['size'] = size
258-
lv = api.create_lv(**kwargs)
259-
if lv is not None:
260-
path = lv.lv_path
261-
lv_uuid = lv.lv_uuid
262-
tags['ceph.{}_device'.format(device_type)] = path
263-
tags['ceph.{}_uuid'.format(device_type)] = lv_uuid
264-
lv.set_tags(tags)
265-
else:
266-
# otherwise assume this is a regular disk partition
267-
name_uuid = self.get_ptuuid(device_name)
268-
path = device_name
269-
tags['ceph.%s_uuid' % device_type] = name_uuid
270-
tags['ceph.%s_device' % device_type] = path
271-
lv_uuid = name_uuid
272-
return path, lv_uuid, tags
220+
for device_type, device_args in s.items():
221+
device_name: str = device_args.get('device_name', None)
222+
size: int = device_args.get('device_size')
223+
slots: int = device_args.get('device_slots')
224+
if device_name is None:
225+
continue
226+
_tags: Dict[str, Any] = self.tags.copy()
227+
_tags['ceph.type'] = device_type
228+
_tags['ceph.vdo'] = api.is_vdo(device_name)
229+
230+
try:
231+
vg_name, lv_name = device_name.split('/')
232+
lv = api.get_single_lv(filters={'lv_name': lv_name,
233+
'vg_name': vg_name})
234+
except ValueError:
235+
lv = None
236+
237+
if lv:
238+
_tags['ceph.%s_uuid' % device_type] = lv.lv_uuid
239+
_tags['ceph.%s_device' % device_type] = lv.lv_path
240+
lv.set_tags(_tags)
241+
elif disk.is_partition(device_name) or disk.is_device(device_name):
242+
# We got a disk or a partition, create an lv
243+
path = device_name
244+
lv_type = "osd-{}".format(device_type)
245+
name_uuid = system.generate_uuid()
246+
kwargs = {
247+
'name_prefix': lv_type,
248+
'uuid': name_uuid,
249+
'vg': None,
250+
'device': device_name,
251+
'slots': slots,
252+
'extents': None,
253+
'size': None,
254+
'tags': _tags,
255+
}
256+
# TODO use get_block_db_size and co here to get configured size in
257+
# conf file
258+
if size != 0:
259+
kwargs['size'] = size
260+
# We do not create LV if this is a partition
261+
if not disk.is_partition(device_name):
262+
lv = api.create_lv(**kwargs)
263+
if lv is not None:
264+
path, lv_uuid = lv.lv_path, lv.lv_uuid
265+
for key, value in {
266+
f"ceph.{device_type}_uuid": lv_uuid,
267+
f"ceph.{device_type}_device": path,
268+
}.items():
269+
_tags[key] = value
270+
self.tags[key] = value
271+
lv.set_tags(_tags)
272+
setattr(self, f'{device_type}_device_path', path)
273273

274274
def get_osd_device_path(self,
275275
osd_lvs: List["Volume"],

src/ceph-volume/ceph_volume/tests/devices/lvm/test_prepare.py

Lines changed: 0 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
import pytest
22
from ceph_volume.devices import lvm
3-
from ceph_volume.api import lvm as api
43
from unittest.mock import patch
5-
from ceph_volume import objectstore
6-
74

85
class TestLVM(object):
96

@@ -25,35 +22,6 @@ def test_main_shows_prepare_subcommands(self, capsys):
2522
assert 'Format an LVM device' in stdout
2623

2724

28-
@patch('ceph_volume.util.prepare.create_key', return_value='fake-secret')
29-
class TestPrepareDevice(object):
30-
31-
def test_cannot_use_device(self, m_create_key, factory):
32-
args = factory(data='/dev/var/foo')
33-
with pytest.raises(RuntimeError) as error:
34-
p = lvm.prepare.Prepare([])
35-
p.objectstore = objectstore.lvmbluestore.LvmBlueStore(args=args)
36-
p.objectstore.prepare_data_device( 'data', '0')
37-
assert 'Cannot use device (/dev/var/foo)' in str(error.value)
38-
assert 'A vg/lv path or an existing device is needed' in str(error.value)
39-
40-
@patch('ceph_volume.util.prepare.create_key', return_value='fake-secret')
41-
class TestGetClusterFsid(object):
42-
def setup_method(self):
43-
self.p = lvm.prepare.Prepare([])
44-
45-
def test_fsid_is_passed_in(self, m_create_key, factory):
46-
args = factory(cluster_fsid='aaaa-1111')
47-
self.p.objectstore = objectstore.lvmbluestore.LvmBlueStore(args)
48-
assert self.p.objectstore.get_cluster_fsid() == 'aaaa-1111'
49-
50-
def test_fsid_is_read_from_ceph_conf(self, m_create_key, factory, conf_ceph_stub):
51-
conf_ceph_stub('[global]\nfsid = bbbb-2222')
52-
args = factory(cluster_fsid='')
53-
self.p.objectstore = objectstore.lvmbluestore.LvmBlueStore(args)
54-
assert self.p.objectstore.get_cluster_fsid() == 'bbbb-2222'
55-
56-
5725
@patch('ceph_volume.util.prepare.create_key', return_value='fake-secret')
5826
class TestPrepare(object):
5927

@@ -72,56 +40,6 @@ def test_main_shows_full_help(self, m_create_key, capsys):
7240
assert 'Use the bluestore objectstore' in stdout
7341
assert 'A physical device or logical' in stdout
7442

75-
def test_setup_device_device_name_is_none(self, m_create_key):
76-
self.p.objectstore = objectstore.lvmbluestore.LvmBlueStore(args=[])
77-
result = self.p.objectstore.setup_device(device_type='data',
78-
device_name=None,
79-
tags={'ceph.type': 'data'},
80-
size=0,
81-
slots=None)
82-
assert result == ('', '', {'ceph.type': 'data'})
83-
84-
@patch('ceph_volume.api.lvm.Volume.set_tags')
85-
@patch('ceph_volume.api.lvm.get_single_lv')
86-
def test_setup_device_lv_passed(self, m_get_single_lv, m_set_tags, m_create_key):
87-
fake_volume = api.Volume(lv_name='lv_foo', lv_path='/fake-path', vg_name='vg_foo', lv_tags='', lv_uuid='fake-uuid')
88-
m_get_single_lv.return_value = fake_volume
89-
self.p.objectstore = objectstore.lvmbluestore.LvmBlueStore(args=[])
90-
result = self.p.objectstore.setup_device(device_type='data', device_name='vg_foo/lv_foo', tags={'ceph.type': 'data'}, size=0, slots=None)
91-
92-
assert result == ('/fake-path', 'fake-uuid', {'ceph.type': 'data',
93-
'ceph.vdo': '0',
94-
'ceph.data_uuid': 'fake-uuid',
95-
'ceph.data_device': '/fake-path'})
96-
97-
@patch('ceph_volume.api.lvm.create_lv')
98-
@patch('ceph_volume.api.lvm.Volume.set_tags')
99-
@patch('ceph_volume.util.disk.is_device')
100-
def test_setup_device_device_passed(self, m_is_device, m_set_tags, m_create_lv, m_create_key):
101-
fake_volume = api.Volume(lv_name='lv_foo', lv_path='/fake-path', vg_name='vg_foo', lv_tags='', lv_uuid='fake-uuid')
102-
m_is_device.return_value = True
103-
m_create_lv.return_value = fake_volume
104-
self.p.objectstore = objectstore.lvmbluestore.LvmBlueStore(args=[])
105-
result = self.p.objectstore.setup_device(device_type='data', device_name='/dev/sdx', tags={'ceph.type': 'data'}, size=0, slots=None)
106-
107-
assert result == ('/fake-path', 'fake-uuid', {'ceph.type': 'data',
108-
'ceph.vdo': '0',
109-
'ceph.data_uuid': 'fake-uuid',
110-
'ceph.data_device': '/fake-path'})
111-
112-
@patch('ceph_volume.objectstore.baseobjectstore.BaseObjectStore.get_ptuuid')
113-
@patch('ceph_volume.api.lvm.get_single_lv')
114-
def test_setup_device_partition_passed(self, m_get_single_lv, m_get_ptuuid, m_create_key):
115-
m_get_single_lv.side_effect = ValueError()
116-
m_get_ptuuid.return_value = 'fake-uuid'
117-
self.p.objectstore = objectstore.lvmbluestore.LvmBlueStore(args=[])
118-
result = self.p.objectstore.setup_device(device_type='data', device_name='/dev/sdx', tags={'ceph.type': 'data'}, size=0, slots=None)
119-
120-
assert result == ('/dev/sdx', 'fake-uuid', {'ceph.type': 'data',
121-
'ceph.vdo': '0',
122-
'ceph.data_uuid': 'fake-uuid',
123-
'ceph.data_device': '/dev/sdx'})
124-
12543
def test_invalid_osd_id_passed(self, m_create_key):
12644
with pytest.raises(SystemExit):
12745
lvm.prepare.Prepare(argv=['--osd-id', 'foo']).main()

0 commit comments

Comments
 (0)