]> git.proxmox.com Git - ceph.git/blob - ceph/src/ceph-volume/ceph_volume/tests/devices/lvm/test_migrate.py
import ceph 15.2.14
[ceph.git] / ceph / src / ceph-volume / ceph_volume / tests / devices / lvm / test_migrate.py
1 import pytest
2 from mock.mock import patch
3 from ceph_volume import process
4 from ceph_volume.api import lvm as api
5 from ceph_volume.devices.lvm import migrate
6 from ceph_volume.util.device import Device
7 from ceph_volume.util import system
8
9 class TestGetClusterName(object):
10
11 mock_volumes = []
12 def mock_get_lvs(self, *args, **kwargs):
13 return self.mock_volumes.pop(0)
14
15 def test_cluster_found(self, monkeypatch):
16 tags = 'ceph.osd_id=0,ceph.journal_uuid=x,ceph.type=data,ceph.osd_fsid=1234,ceph.cluster_name=name_of_the_cluster'
17 vol = api.Volume(lv_name='volume1', lv_uuid='y', vg_name='',
18 lv_path='/dev/VolGroup/lv1', lv_tags=tags)
19 self.mock_volumes = []
20 self.mock_volumes.append([vol])
21
22 monkeypatch.setattr(migrate.api, 'get_lvs', self.mock_get_lvs)
23 monkeypatch.setattr(process, 'call', lambda x, **kw: ('', '', 0))
24
25 result = migrate.get_cluster_name(osd_id='0', osd_fsid='1234')
26 assert "name_of_the_cluster" == result
27
28 def test_cluster_not_found(self, monkeypatch, capsys):
29 self.mock_volumes = []
30 self.mock_volumes.append([])
31
32 monkeypatch.setattr(migrate.api, 'get_lvs', self.mock_get_lvs)
33 monkeypatch.setattr(process, 'call', lambda x, **kw: ('', '', 0))
34
35 with pytest.raises(SystemExit) as error:
36 migrate.get_cluster_name(osd_id='0', osd_fsid='1234')
37 stdout, stderr = capsys.readouterr()
38 expected = 'Unexpected error, terminating'
39 assert expected in str(error.value)
40 expected = 'Unable to find any LV for source OSD: id:0 fsid:1234'
41 assert expected in stderr
42
43 class TestFindAssociatedDevices(object):
44
45 mock_volumes = []
46 def mock_get_lvs(self, *args, **kwargs):
47 return self.mock_volumes.pop(0)
48
49 mock_single_volumes = {}
50 def mock_get_first_lv(self, *args, **kwargs):
51 p = kwargs['filters']['lv_path']
52 return self.mock_single_volumes[p]
53
54 def test_lv_is_matched_id(self, monkeypatch):
55 tags = 'ceph.osd_id=0,ceph.journal_uuid=x,ceph.type=data,ceph.osd_fsid=1234'
56 vol = api.Volume(lv_name='volume1', lv_uuid='y', vg_name='',
57 lv_path='/dev/VolGroup/lv1', lv_tags=tags)
58 self.mock_volumes = []
59 self.mock_volumes.append([vol])
60 self.mock_volumes.append([vol])
61 self.mock_volumes.append([])
62 self.mock_volumes.append([])
63
64 self.mock_single_volumes = {'/dev/VolGroup/lv1': vol}
65
66 monkeypatch.setattr(migrate.api, 'get_lvs', self.mock_get_lvs)
67 monkeypatch.setattr(migrate.api, 'get_first_lv', self.mock_get_first_lv)
68 monkeypatch.setattr(process, 'call', lambda x, **kw: ('', '', 0))
69
70 result = migrate.find_associated_devices(osd_id='0', osd_fsid='1234')
71 assert len(result) == 1
72 assert result[0][0].abspath == '/dev/VolGroup/lv1'
73 assert result[0][0].lvs == [vol]
74 assert result[0][1] == 'block'
75
76 def test_lv_is_matched_id2(self, monkeypatch):
77 tags = 'ceph.osd_id=0,ceph.journal_uuid=x,ceph.type=data,ceph.osd_fsid=1234'
78 vol = api.Volume(lv_name='volume1', lv_uuid='y', vg_name='vg',
79 lv_path='/dev/VolGroup/lv1', lv_tags=tags)
80 tags2 = 'ceph.osd_id=0,ceph.journal_uuid=xx,ceph.type=wal,ceph.osd_fsid=1234'
81 vol2 = api.Volume(lv_name='volume2', lv_uuid='z', vg_name='vg',
82 lv_path='/dev/VolGroup/lv2', lv_tags=tags2)
83 self.mock_volumes = []
84 self.mock_volumes.append([vol])
85 self.mock_volumes.append([vol])
86 self.mock_volumes.append([])
87 self.mock_volumes.append([vol2])
88
89 self.mock_single_volumes = {'/dev/VolGroup/lv1': vol, '/dev/VolGroup/lv2': vol2}
90
91 monkeypatch.setattr(migrate.api, 'get_lvs', self.mock_get_lvs)
92 monkeypatch.setattr(migrate.api, 'get_first_lv', self.mock_get_first_lv)
93 monkeypatch.setattr(process, 'call', lambda x, **kw: ('', '', 0))
94
95 result = migrate.find_associated_devices(osd_id='0', osd_fsid='1234')
96 assert len(result) == 2
97 for d in result:
98 if d[1] == 'block':
99 assert d[0].abspath == '/dev/VolGroup/lv1'
100 assert d[0].lvs == [vol]
101 elif d[1] == 'wal':
102 assert d[0].abspath == '/dev/VolGroup/lv2'
103 assert d[0].lvs == [vol2]
104 else:
105 assert False
106
107 def test_lv_is_matched_id3(self, monkeypatch):
108 tags = 'ceph.osd_id=0,ceph.journal_uuid=x,ceph.type=data,ceph.osd_fsid=1234'
109 vol = api.Volume(lv_name='volume1', lv_uuid='y', vg_name='vg',
110 lv_path='/dev/VolGroup/lv1', lv_tags=tags)
111 tags2 = 'ceph.osd_id=0,ceph.journal_uuid=xx,ceph.type=wal,ceph.osd_fsid=1234'
112 vol2 = api.Volume(lv_name='volume2', lv_uuid='z', vg_name='vg',
113 lv_path='/dev/VolGroup/lv2', lv_tags=tags2)
114 tags3 = 'ceph.osd_id=0,ceph.journal_uuid=xx,ceph.type=db,ceph.osd_fsid=1234'
115 vol3 = api.Volume(lv_name='volume3', lv_uuid='z', vg_name='vg',
116 lv_path='/dev/VolGroup/lv3', lv_tags=tags3)
117
118 self.mock_volumes = []
119 self.mock_volumes.append([vol])
120 self.mock_volumes.append([vol])
121 self.mock_volumes.append([vol3])
122 self.mock_volumes.append([vol2])
123
124 self.mock_single_volumes = {'/dev/VolGroup/lv1': vol,
125 '/dev/VolGroup/lv2': vol2,
126 '/dev/VolGroup/lv3': vol3}
127
128 monkeypatch.setattr(migrate.api, 'get_lvs', self.mock_get_lvs)
129 monkeypatch.setattr(migrate.api, 'get_first_lv', self.mock_get_first_lv)
130 monkeypatch.setattr(process, 'call', lambda x, **kw: ('', '', 0))
131
132 result = migrate.find_associated_devices(osd_id='0', osd_fsid='1234')
133 assert len(result) == 3
134 for d in result:
135 if d[1] == 'block':
136 assert d[0].abspath == '/dev/VolGroup/lv1'
137 assert d[0].lvs == [vol]
138 elif d[1] == 'wal':
139 assert d[0].abspath == '/dev/VolGroup/lv2'
140 assert d[0].lvs == [vol2]
141 elif d[1] == 'db':
142 assert d[0].abspath == '/dev/VolGroup/lv3'
143 assert d[0].lvs == [vol3]
144 else:
145 assert False
146
147 def test_lv_is_not_matched(self, monkeypatch, capsys):
148 self.mock_volumes = [None]
149 monkeypatch.setattr(migrate.api, 'get_lvs', self.mock_get_lvs)
150 monkeypatch.setattr(process, 'call', lambda x, **kw: ('', '', 0))
151
152 with pytest.raises(SystemExit) as error:
153 migrate.find_associated_devices(osd_id='1', osd_fsid='1234')
154 stdout, stderr = capsys.readouterr()
155 expected = 'Unexpected error, terminating'
156 assert expected in str(error.value)
157 expected = 'Unable to find any LV for source OSD: id:1 fsid:1234'
158 assert expected in stderr
159
160 class TestVolumeTagTracker(object):
161 mock_single_volumes = {}
162 def mock_get_first_lv(self, *args, **kwargs):
163 p = kwargs['filters']['lv_path']
164 return self.mock_single_volumes[p]
165
166 mock_process_input = []
167 def mock_process(self, *args, **kwargs):
168 self.mock_process_input.append(args[0]);
169 return ('', '', 0)
170
171 def test_init(self, monkeypatch):
172 source_tags = 'ceph.osd_id=0,ceph.journal_uuid=x,ceph.type=data,ceph.osd_fsid=1234'
173 source_db_tags = 'ceph.osd_id=0,journal_uuid=x,ceph.type=db, osd_fsid=1234'
174 source_wal_tags = 'ceph.osd_id=0,ceph.journal_uuid=x,ceph.type=wal'
175 target_tags="ceph.a=1,ceph.b=2,c=3,ceph.d=4" # 'c' to be bypassed
176 devices=[]
177
178 data_vol = api.Volume(lv_name='volume1', lv_uuid='y', vg_name='vg',
179 lv_path='/dev/VolGroup/lv1', lv_tags=source_tags)
180 db_vol = api.Volume(lv_name='volume2', lv_uuid='y', vg_name='vg',
181 lv_path='/dev/VolGroup/lv2', lv_tags=source_db_tags)
182 wal_vol = api.Volume(lv_name='volume3', lv_uuid='y', vg_name='vg',
183 lv_path='/dev/VolGroup/lv3', lv_tags=source_wal_tags)
184
185 self.mock_single_volumes = {'/dev/VolGroup/lv1': data_vol,
186 '/dev/VolGroup/lv2': db_vol,
187 '/dev/VolGroup/lv3': wal_vol}
188 monkeypatch.setattr(migrate.api, 'get_first_lv', self.mock_get_first_lv)
189
190 self.mock_process_input = []
191 monkeypatch.setattr(process, 'call', self.mock_process)
192
193 data_device = Device(path = '/dev/VolGroup/lv1')
194 db_device = Device(path = '/dev/VolGroup/lv2')
195 wal_device = Device(path = '/dev/VolGroup/lv3')
196 devices.append([data_device, 'block'])
197 devices.append([db_device, 'db'])
198 devices.append([wal_device, 'wal'])
199
200 target = api.Volume(lv_name='target_name', lv_tags=target_tags,
201 lv_path='/dev/VolGroup/lv_target')
202 t = migrate.VolumeTagTracker(devices, target);
203
204 assert 3 == len(t.old_target_tags)
205
206 assert data_device == t.data_device
207 assert 4 == len(t.old_data_tags)
208 assert 'data' == t.old_data_tags['ceph.type']
209
210 assert db_device == t.db_device
211 assert 2 == len(t.old_db_tags)
212 assert 'db' == t.old_db_tags['ceph.type']
213
214 assert wal_device == t.wal_device
215 assert 3 == len(t.old_wal_tags)
216 assert 'wal' == t.old_wal_tags['ceph.type']
217
218 def test_update_tags_when_lv_create(self, monkeypatch):
219 source_tags = \
220 'ceph.osd_id=0,ceph.journal_uuid=x,' \
221 'ceph.type=data,ceph.osd_fsid=1234'
222 source_db_tags = \
223 'ceph.osd_id=0,journal_uuid=x,ceph.type=db,' \
224 'osd_fsid=1234'
225
226 devices=[]
227
228 data_vol = api.Volume(lv_name='volume1', lv_uuid='y', vg_name='vg',
229 lv_path='/dev/VolGroup/lv1', lv_tags=source_tags)
230 db_vol = api.Volume(lv_name='volume2', lv_uuid='y', vg_name='vg',
231 lv_path='/dev/VolGroup/lv2', lv_tags=source_db_tags)
232
233 self.mock_single_volumes = {'/dev/VolGroup/lv1': data_vol,
234 '/dev/VolGroup/lv2': db_vol}
235
236 monkeypatch.setattr(migrate.api, 'get_first_lv', self.mock_get_first_lv)
237
238 self.mock_process_input = []
239 monkeypatch.setattr(process, 'call', self.mock_process)
240
241 data_device = Device(path = '/dev/VolGroup/lv1')
242 db_device = Device(path = '/dev/VolGroup/lv2')
243 devices.append([data_device, 'block'])
244 devices.append([db_device, 'db'])
245
246 target = api.Volume(lv_name='target_name', lv_tags='',
247 lv_uuid='wal_uuid',
248 lv_path='/dev/VolGroup/lv_target')
249 t = migrate.VolumeTagTracker(devices, target);
250
251 self.mock_process_input = []
252 t.update_tags_when_lv_create('wal')
253
254 assert 3 == len(self.mock_process_input)
255
256 assert ['lvchange',
257 '--addtag', 'ceph.wal_uuid=wal_uuid',
258 '--addtag', 'ceph.wal_device=/dev/VolGroup/lv_target',
259 '/dev/VolGroup/lv1'] == self.mock_process_input[0]
260
261 assert self.mock_process_input[1].sort() == [
262 'lvchange',
263 '--addtag', 'ceph.osd_id=0',
264 '--addtag', 'ceph.journal_uuid=x',
265 '--addtag', 'ceph.type=wal',
266 '--addtag', 'ceph.osd_fsid=1234',
267 '--addtag', 'ceph.wal_uuid=wal_uuid',
268 '--addtag', 'ceph.wal_device=/dev/VolGroup/lv_target',
269 '/dev/VolGroup/lv_target'].sort()
270
271 assert ['lvchange',
272 '--addtag', 'ceph.wal_uuid=wal_uuid',
273 '--addtag', 'ceph.wal_device=/dev/VolGroup/lv_target',
274 '/dev/VolGroup/lv2'] == self.mock_process_input[2]
275
276 def test_remove_lvs(self, monkeypatch):
277 source_tags = \
278 'ceph.osd_id=0,ceph.journal_uuid=x,' \
279 'ceph.type=data,ceph.osd_fsid=1234,ceph.wal_uuid=aaaaa'
280 source_db_tags = \
281 'ceph.osd_id=0,journal_uuid=x,ceph.type=db,' \
282 'osd_fsid=1234,ceph.wal_device=aaaaa'
283 source_wal_tags = \
284 'ceph.wal_uuid=uuid,ceph.wal_device=device,' \
285 'ceph.osd_id=0,ceph.type=wal'
286
287 devices=[]
288
289 data_vol = api.Volume(lv_name='volume1', lv_uuid='y', vg_name='vg',
290 lv_path='/dev/VolGroup/lv1', lv_tags=source_tags)
291 db_vol = api.Volume(lv_name='volume2', lv_uuid='y', vg_name='vg',
292 lv_path='/dev/VolGroup/lv2', lv_tags=source_db_tags)
293 wal_vol = api.Volume(lv_name='volume3', lv_uuid='y', vg_name='vg',
294 lv_path='/dev/VolGroup/lv3', lv_tags=source_wal_tags)
295
296 self.mock_single_volumes = {'/dev/VolGroup/lv1': data_vol,
297 '/dev/VolGroup/lv2': db_vol,
298 '/dev/VolGroup/lv3': wal_vol}
299
300 monkeypatch.setattr(migrate.api, 'get_first_lv', self.mock_get_first_lv)
301
302 self.mock_process_input = []
303 monkeypatch.setattr(process, 'call', self.mock_process)
304
305 data_device = Device(path = '/dev/VolGroup/lv1')
306 db_device = Device(path = '/dev/VolGroup/lv2')
307 wal_device = Device(path = '/dev/VolGroup/lv3')
308 devices.append([data_device, 'block'])
309 devices.append([db_device, 'db'])
310 devices.append([wal_device, 'wal'])
311
312 target = api.Volume(lv_name='target_name', lv_tags='',
313 lv_path='/dev/VolGroup/lv_target')
314 t = migrate.VolumeTagTracker(devices, target);
315
316 device_to_remove = devices.copy()
317
318 self.mock_process_input = []
319 t.remove_lvs(device_to_remove, 'db')
320
321 assert 3 == len(self.mock_process_input)
322 assert ['lvchange',
323 '--deltag', 'ceph.wal_uuid=uuid',
324 '--deltag', 'ceph.wal_device=device',
325 '--deltag', 'ceph.osd_id=0',
326 '--deltag', 'ceph.type=wal',
327 '/dev/VolGroup/lv3'] == self.mock_process_input[0]
328 assert ['lvchange',
329 '--deltag', 'ceph.wal_uuid=aaaaa',
330 '/dev/VolGroup/lv1'] == self.mock_process_input[1]
331 assert ['lvchange',
332 '--deltag', 'ceph.wal_device=aaaaa',
333 '/dev/VolGroup/lv2'] == self.mock_process_input[2]
334
335 def test_replace_lvs(self, monkeypatch):
336 source_tags = \
337 'ceph.osd_id=0,ceph.type=data,ceph.osd_fsid=1234,'\
338 'ceph.wal_uuid=wal_uuid,ceph.db_device=/dbdevice'
339 source_db_tags = \
340 'ceph.osd_id=0,ceph.type=db,ceph.osd_fsid=1234'
341 source_wal_tags = \
342 'ceph.wal_uuid=uuid,ceph.wal_device=device,' \
343 'ceph.osd_id=0,ceph.type=wal'
344
345 devices=[]
346
347 data_vol = api.Volume(lv_name='volume1', lv_uuid='datauuid', vg_name='vg',
348 lv_path='/dev/VolGroup/lv1', lv_tags=source_tags)
349 db_vol = api.Volume(lv_name='volume2', lv_uuid='dbuuid', vg_name='vg',
350 lv_path='/dev/VolGroup/lv2', lv_tags=source_db_tags)
351 wal_vol = api.Volume(lv_name='volume3', lv_uuid='waluuid', vg_name='vg',
352 lv_path='/dev/VolGroup/lv3', lv_tags=source_wal_tags)
353
354 self.mock_single_volumes = {'/dev/VolGroup/lv1': data_vol,
355 '/dev/VolGroup/lv2': db_vol,
356 '/dev/VolGroup/lv3': wal_vol}
357
358 monkeypatch.setattr(migrate.api, 'get_first_lv', self.mock_get_first_lv)
359
360 self.mock_process_input = []
361 monkeypatch.setattr(process, 'call', self.mock_process)
362
363 data_device = Device(path = '/dev/VolGroup/lv1')
364 db_device = Device(path = '/dev/VolGroup/lv2')
365 wal_device = Device(path = '/dev/VolGroup/lv3')
366 devices.append([data_device, 'block'])
367 devices.append([db_device, 'db'])
368 devices.append([wal_device, 'wal'])
369
370 target = api.Volume(lv_name='target_name',
371 lv_uuid='ttt',
372 lv_tags='ceph.tag_to_remove=aaa',
373 lv_path='/dev/VolGroup/lv_target')
374 t = migrate.VolumeTagTracker(devices, target);
375
376 self.mock_process_input = []
377 t.replace_lvs(devices, 'db')
378
379 assert 5 == len(self.mock_process_input)
380
381 assert ['lvchange',
382 '--deltag', 'ceph.osd_id=0',
383 '--deltag', 'ceph.type=db',
384 '--deltag', 'ceph.osd_fsid=1234',
385 '/dev/VolGroup/lv2'] == self.mock_process_input[0]
386 assert ['lvchange',
387 '--deltag', 'ceph.wal_uuid=uuid',
388 '--deltag', 'ceph.wal_device=device',
389 '--deltag', 'ceph.osd_id=0',
390 '--deltag', 'ceph.type=wal',
391 '/dev/VolGroup/lv3'] == self.mock_process_input[1]
392 assert ['lvchange',
393 '--deltag', 'ceph.db_device=/dbdevice',
394 '--deltag', 'ceph.wal_uuid=wal_uuid',
395 '/dev/VolGroup/lv1'] == self.mock_process_input[2]
396
397 assert ['lvchange',
398 '--addtag', 'ceph.db_uuid=ttt',
399 '--addtag', 'ceph.db_device=/dev/VolGroup/lv_target',
400 '/dev/VolGroup/lv1'] == self.mock_process_input[3]
401
402 assert self.mock_process_input[4].sort() == [
403 'lvchange',
404 '--addtag', 'ceph.osd_id=0',
405 '--addtag', 'ceph.osd_fsid=1234',
406 '--addtag', 'ceph.type=db',
407 '--addtag', 'ceph.db_uuid=ttt',
408 '--addtag', 'ceph.db_device=/dev/VolGroup/lv_target',
409 '/dev/VolGroup/lv_target'].sort()
410
411 def test_undo(self, monkeypatch):
412 source_tags = 'ceph.osd_id=0,ceph.journal_uuid=x,ceph.type=data,ceph.osd_fsid=1234'
413 source_db_tags = 'ceph.osd_id=0,journal_uuid=x,ceph.type=db, osd_fsid=1234'
414 source_wal_tags = 'ceph.osd_id=0,ceph.journal_uuid=x,ceph.type=wal'
415 target_tags=""
416 devices=[]
417
418 data_vol = api.Volume(lv_name='volume1', lv_uuid='y', vg_name='vg',
419 lv_path='/dev/VolGroup/lv1', lv_tags=source_tags)
420 db_vol = api.Volume(lv_name='volume2', lv_uuid='y', vg_name='vg',
421 lv_path='/dev/VolGroup/lv2', lv_tags=source_db_tags)
422 wal_vol = api.Volume(lv_name='volume3', lv_uuid='y', vg_name='vg',
423 lv_path='/dev/VolGroup/lv3', lv_tags=source_wal_tags)
424
425 self.mock_single_volumes = {'/dev/VolGroup/lv1': data_vol,
426 '/dev/VolGroup/lv2': db_vol,
427 '/dev/VolGroup/lv3': wal_vol}
428
429 monkeypatch.setattr(migrate.api, 'get_first_lv', self.mock_get_first_lv)
430
431 self.mock_process_input = []
432 monkeypatch.setattr(process, 'call', self.mock_process)
433
434 data_device = Device(path = '/dev/VolGroup/lv1')
435 db_device = Device(path = '/dev/VolGroup/lv2')
436 wal_device = Device(path = '/dev/VolGroup/lv3')
437 devices.append([data_device, 'block'])
438 devices.append([db_device, 'db'])
439 devices.append([wal_device, 'wal'])
440
441 target = api.Volume(lv_name='target_name', lv_tags=target_tags,
442 lv_path='/dev/VolGroup/lv_target')
443 t = migrate.VolumeTagTracker(devices, target);
444
445 target.tags['ceph.a'] = 'aa';
446 target.tags['ceph.b'] = 'bb';
447
448 data_vol.tags['ceph.journal_uuid'] = 'z';
449
450 db_vol.tags.pop('ceph.type')
451
452 wal_vol.tags.clear()
453
454 assert 2 == len(target.tags)
455 assert 4 == len(data_vol.tags)
456 assert 1 == len(db_vol.tags)
457
458 self.mock_process_input = []
459 t.undo()
460
461 assert 0 == len(target.tags)
462 assert 4 == len(data_vol.tags)
463 assert 'x' == data_vol.tags['ceph.journal_uuid']
464
465 assert 2 == len(db_vol.tags)
466 assert 'db' == db_vol.tags['ceph.type']
467
468 assert 3 == len(wal_vol.tags)
469 assert 'wal' == wal_vol.tags['ceph.type']
470
471 assert 6 == len(self.mock_process_input)
472 assert 'lvchange' in self.mock_process_input[0]
473 assert '--deltag' in self.mock_process_input[0]
474 assert 'ceph.journal_uuid=z' in self.mock_process_input[0]
475 assert '/dev/VolGroup/lv1' in self.mock_process_input[0]
476
477 assert 'lvchange' in self.mock_process_input[1]
478 assert '--addtag' in self.mock_process_input[1]
479 assert 'ceph.journal_uuid=x' in self.mock_process_input[1]
480 assert '/dev/VolGroup/lv1' in self.mock_process_input[1]
481
482 assert 'lvchange' in self.mock_process_input[2]
483 assert '--deltag' in self.mock_process_input[2]
484 assert 'ceph.osd_id=0' in self.mock_process_input[2]
485 assert '/dev/VolGroup/lv2' in self.mock_process_input[2]
486
487 assert 'lvchange' in self.mock_process_input[3]
488 assert '--addtag' in self.mock_process_input[3]
489 assert 'ceph.type=db' in self.mock_process_input[3]
490 assert '/dev/VolGroup/lv2' in self.mock_process_input[3]
491
492 assert 'lvchange' in self.mock_process_input[4]
493 assert '--addtag' in self.mock_process_input[4]
494 assert 'ceph.type=wal' in self.mock_process_input[4]
495 assert '/dev/VolGroup/lv3' in self.mock_process_input[4]
496
497 assert 'lvchange' in self.mock_process_input[5]
498 assert '--deltag' in self.mock_process_input[5]
499 assert 'ceph.a=aa' in self.mock_process_input[5]
500 assert 'ceph.b=bb' in self.mock_process_input[5]
501 assert '/dev/VolGroup/lv_target' in self.mock_process_input[5]
502
503 class TestNew(object):
504
505 mock_volume = None
506 def mock_get_lv_by_fullname(self, *args, **kwargs):
507 return self.mock_volume
508
509 mock_process_input = []
510 def mock_process(self, *args, **kwargs):
511 self.mock_process_input.append(args[0]);
512 return ('', '', 0)
513
514 mock_single_volumes = {}
515 def mock_get_first_lv(self, *args, **kwargs):
516 p = kwargs['filters']['lv_path']
517 return self.mock_single_volumes[p]
518
519 mock_volumes = []
520 def mock_get_lvs(self, *args, **kwargs):
521 return self.mock_volumes.pop(0)
522
523 def test_newdb_non_root(self):
524 with pytest.raises(Exception) as error:
525 migrate.NewDB(argv=[
526 '--osd-id', '1',
527 '--osd-fsid', '55BD4219-16A7-4037-BC20-0F158EFCC83D',
528 '--target', 'vgname/new_db']).main()
529 expected = 'This command needs to be executed with sudo or as root'
530 assert expected in str(error.value)
531
532 @patch('os.getuid')
533 def test_newdb_not_target_lvm(self, m_getuid, capsys):
534 m_getuid.return_value = 0
535 with pytest.raises(SystemExit) as error:
536 migrate.NewDB(argv=[
537 '--osd-id', '1',
538 '--osd-fsid', '55BD4219-16A7-4037-BC20-0F158EFCC83D',
539 '--target', 'vgname/new_db']).main()
540 stdout, stderr = capsys.readouterr()
541 expected = 'Unable to attach new volume : vgname/new_db'
542 assert expected in str(error.value)
543 expected = 'Target path vgname/new_db is not a Logical Volume'
544 assert expected in stderr
545
546
547 @patch('os.getuid')
548 def test_newdb_already_in_use(self, m_getuid, monkeypatch, capsys):
549 m_getuid.return_value = 0
550
551 self.mock_volume = api.Volume(lv_name='volume1',
552 lv_uuid='y',
553 vg_name='vg',
554 lv_path='/dev/VolGroup/lv1',
555 lv_tags='ceph.osd_id=5') # this results in set used_by_ceph
556 monkeypatch.setattr(api, 'get_lv_by_fullname', self.mock_get_lv_by_fullname)
557
558 with pytest.raises(SystemExit) as error:
559 migrate.NewDB(argv=[
560 '--osd-id', '1',
561 '--osd-fsid', '55BD4219-16A7-4037-BC20-0F158EFCC83D',
562 '--target', 'vgname/new_db']).main()
563 stdout, stderr = capsys.readouterr()
564 expected = 'Unable to attach new volume : vgname/new_db'
565 assert expected in str(error.value)
566 expected = 'Target Logical Volume is already used by ceph: vgname/new_db'
567 assert expected in stderr
568
569 @patch('os.getuid')
570 def test_newdb(self, m_getuid, monkeypatch, capsys):
571 m_getuid.return_value = 0
572
573 source_tags = \
574 'ceph.osd_id=0,ceph.type=data,ceph.osd_fsid=1234,'\
575 'ceph.wal_uuid=wal_uuid,ceph.db_device=/dbdevice'
576 source_wal_tags = \
577 'ceph.wal_uuid=uuid,ceph.wal_device=device,' \
578 'ceph.osd_id=0,ceph.type=wal'
579
580 data_vol = api.Volume(lv_name='volume1', lv_uuid='datauuid',
581 vg_name='vg',
582 lv_path='/dev/VolGroup/lv1',
583 lv_tags=source_tags)
584 wal_vol = api.Volume(lv_name='volume3',
585 lv_uuid='waluuid',
586 vg_name='vg',
587 lv_path='/dev/VolGroup/lv3',
588 lv_tags=source_wal_tags)
589
590 self.mock_single_volumes = {'/dev/VolGroup/lv1': data_vol,
591 '/dev/VolGroup/lv3': wal_vol}
592
593 monkeypatch.setattr(migrate.api, 'get_first_lv',
594 self.mock_get_first_lv)
595
596 self.mock_process_input = []
597 monkeypatch.setattr(process, 'call', self.mock_process)
598
599 self.mock_volume = api.Volume(lv_name='target_volume1', lv_uuid='y',
600 vg_name='vg',
601 lv_path='/dev/VolGroup/target_volume',
602 lv_tags='')
603 monkeypatch.setattr(api, 'get_lv_by_fullname',
604 self.mock_get_lv_by_fullname)
605
606 monkeypatch.setattr("ceph_volume.systemd.systemctl.osd_is_active",
607 lambda id: False)
608
609 #find_associated_devices will call get_lvs() 4 times
610 # and it this needs results to be arranged that way
611 self.mock_volumes = []
612 self.mock_volumes.append([data_vol, wal_vol])
613 self.mock_volumes.append([data_vol])
614 self.mock_volumes.append([])
615 self.mock_volumes.append([wal_vol])
616
617 monkeypatch.setattr(migrate.api, 'get_lvs', self.mock_get_lvs)
618
619 monkeypatch.setattr(migrate, 'get_cluster_name',
620 lambda osd_id, osd_fsid: 'ceph_cluster')
621 monkeypatch.setattr(system, 'chown', lambda path: 0)
622
623 migrate.NewDB(argv=[
624 '--osd-id', '1',
625 '--osd-fsid', '55BD4219-16A7-4037-BC20-0F158EFCC83D',
626 '--target', 'vgname/new_db']).main()
627
628 n = len(self.mock_process_input)
629 assert n >= 5
630
631 assert self.mock_process_input[n - 5] == [
632 'lvchange',
633 '--deltag', 'ceph.db_device=/dbdevice',
634 '/dev/VolGroup/lv1']
635 assert self.mock_process_input[n - 4] == [
636 'lvchange',
637 '--addtag', 'ceph.db_uuid=y',
638 '--addtag', 'ceph.db_device=/dev/VolGroup/target_volume',
639 '/dev/VolGroup/lv1']
640
641 assert self.mock_process_input[n - 3].sort() == [
642 'lvchange',
643 '--addtag', 'ceph.wal_uuid=uuid',
644 '--addtag', 'ceph.osd_id=0',
645 '--addtag', 'ceph.type=db',
646 '--addtag', 'ceph.osd_fsid=1234',
647 '--addtag', 'ceph.db_uuid=y',
648 '--addtag', 'ceph.db_device=/dev/VolGroup/target_volume',
649 '/dev/VolGroup/target_volume'].sort()
650
651 assert self.mock_process_input[n - 2] == [
652 'lvchange',
653 '--addtag', 'ceph.db_uuid=y',
654 '--addtag', 'ceph.db_device=/dev/VolGroup/target_volume',
655 '/dev/VolGroup/lv3']
656
657 assert self.mock_process_input[n - 1] == [
658 'ceph-bluestore-tool',
659 '--path', '/var/lib/ceph/osd/ceph_cluster-1',
660 '--dev-target', '/dev/VolGroup/target_volume',
661 '--command', 'bluefs-bdev-new-db']
662
663 @patch('os.getuid')
664 def test_newwal(self, m_getuid, monkeypatch, capsys):
665 m_getuid.return_value = 0
666
667 source_tags = \
668 'ceph.osd_id=0,ceph.type=data,ceph.osd_fsid=1234'
669
670 data_vol = api.Volume(lv_name='volume1', lv_uuid='datauuid', vg_name='vg',
671 lv_path='/dev/VolGroup/lv1', lv_tags=source_tags)
672
673 self.mock_single_volumes = {'/dev/VolGroup/lv1': data_vol}
674
675 monkeypatch.setattr(migrate.api, 'get_first_lv', self.mock_get_first_lv)
676
677 self.mock_process_input = []
678 monkeypatch.setattr(process, 'call', self.mock_process)
679
680 self.mock_volume = api.Volume(lv_name='target_volume1', lv_uuid='y', vg_name='vg',
681 lv_path='/dev/VolGroup/target_volume',
682 lv_tags='')
683 monkeypatch.setattr(api, 'get_lv_by_fullname', self.mock_get_lv_by_fullname)
684
685 monkeypatch.setattr("ceph_volume.systemd.systemctl.osd_is_active", lambda id: False)
686
687 #find_associated_devices will call get_lvs() 4 times
688 # and it this needs results to be arranged that way
689 self.mock_volumes = []
690 self.mock_volumes.append([data_vol])
691 self.mock_volumes.append([data_vol])
692 self.mock_volumes.append([])
693 self.mock_volumes.append([])
694
695 monkeypatch.setattr(migrate.api, 'get_lvs', self.mock_get_lvs)
696
697 monkeypatch.setattr(migrate, 'get_cluster_name', lambda osd_id, osd_fsid: 'cluster')
698 monkeypatch.setattr(system, 'chown', lambda path: 0)
699
700 migrate.NewWAL(argv=[
701 '--osd-id', '2',
702 '--osd-fsid', '55BD4219-16A7-4037-BC20-0F158EFCC83D',
703 '--target', 'vgname/new_wal']).main()
704
705 n = len(self.mock_process_input)
706 assert n >= 3
707
708 assert self.mock_process_input[n - 3] == [
709 'lvchange',
710 '--addtag', 'ceph.wal_uuid=y',
711 '--addtag', 'ceph.wal_device=/dev/VolGroup/target_volume',
712 '/dev/VolGroup/lv1']
713
714 assert self.mock_process_input[n - 2].sort() == [
715 'lvchange',
716 '--addtag', 'ceph.osd_id=0',
717 '--addtag', 'ceph.type=wal',
718 '--addtag', 'ceph.osd_fsid=1234',
719 '--addtag', 'ceph.wal_uuid=y',
720 '--addtag', 'ceph.wal_device=/dev/VolGroup/target_volume',
721 '/dev/VolGroup/target_volume'].sort()
722
723 assert self.mock_process_input[n - 1] == [
724 'ceph-bluestore-tool',
725 '--path', '/var/lib/ceph/osd/cluster-2',
726 '--dev-target', '/dev/VolGroup/target_volume',
727 '--command', 'bluefs-bdev-new-wal']
728
729 class TestMigrate(object):
730
731 mock_volume = None
732 def mock_get_lv_by_fullname(self, *args, **kwargs):
733 return self.mock_volume
734
735 mock_process_input = []
736 def mock_process(self, *args, **kwargs):
737 self.mock_process_input.append(args[0]);
738 return ('', '', 0)
739
740 mock_single_volumes = {}
741 def mock_get_first_lv(self, *args, **kwargs):
742 p = kwargs['filters']['lv_path']
743 return self.mock_single_volumes[p]
744
745 mock_volumes = []
746 def mock_get_lvs(self, *args, **kwargs):
747 return self.mock_volumes.pop(0)
748
749 def test_get_source_devices(self, monkeypatch):
750
751 source_tags = 'ceph.osd_id=2,ceph.type=data,ceph.osd_fsid=1234'
752 source_db_tags = 'ceph.osd_id=2,ceph.type=db,ceph.osd_fsid=1234'
753 source_wal_tags = 'ceph.osd_id=2,ceph.type=wal,ceph.osd_fsid=1234'
754
755 data_vol = api.Volume(lv_name='volume1',
756 lv_uuid='datauuid',
757 vg_name='vg',
758 lv_path='/dev/VolGroup/lv1',
759 lv_tags=source_tags)
760 db_vol = api.Volume(lv_name='volume2',
761 lv_uuid='datauuid',
762 vg_name='vg',
763 lv_path='/dev/VolGroup/lv2',
764 lv_tags=source_db_tags)
765
766 wal_vol = api.Volume(lv_name='volume3',
767 lv_uuid='datauuid',
768 vg_name='vg',
769 lv_path='/dev/VolGroup/lv3',
770 lv_tags=source_wal_tags)
771
772 self.mock_single_volumes = {
773 '/dev/VolGroup/lv1': data_vol,
774 '/dev/VolGroup/lv2': db_vol,
775 '/dev/VolGroup/lv3': wal_vol,
776 }
777 monkeypatch.setattr(migrate.api, 'get_first_lv',
778 self.mock_get_first_lv)
779
780 self.mock_volume = api.Volume(lv_name='volume2', lv_uuid='y',
781 vg_name='vg',
782 lv_path='/dev/VolGroup/lv2',
783 lv_tags='ceph.osd_id=5,ceph.osd_type=db')
784 monkeypatch.setattr(api, 'get_lv_by_fullname',
785 self.mock_get_lv_by_fullname)
786
787 self.mock_process_input = []
788 monkeypatch.setattr(process, 'call', self.mock_process)
789
790 devices = []
791 devices.append([Device('/dev/VolGroup/lv1'), 'block'])
792 devices.append([Device('/dev/VolGroup/lv2'), 'db'])
793 devices.append([Device('/dev/VolGroup/lv3'), 'wal'])
794
795 monkeypatch.setattr(migrate, 'find_associated_devices',
796 lambda osd_id, osd_fsid: devices)
797
798
799 m = migrate.Migrate(argv=[
800 '--osd-id', '2',
801 '--osd-fsid', '55BD4219-16A7-4037-BC20-0F158EFCC83D',
802 '--from', 'data', 'wal',
803 '--target', 'vgname/new_wal'])
804 m.parse_argv()
805 res_devices = m.get_source_devices(devices)
806
807 assert 2 == len(res_devices)
808 assert devices[0] == res_devices[0]
809 assert devices[2] == res_devices[1]
810
811 m = migrate.Migrate(argv=[
812 '--osd-id', '2',
813 '--osd-fsid', '55BD4219-16A7-4037-BC20-0F158EFCC83D',
814 '--from', 'db', 'wal', 'data',
815 '--target', 'vgname/new_wal'])
816 m.parse_argv()
817 res_devices = m.get_source_devices(devices)
818
819 assert 3 == len(res_devices)
820 assert devices[0] == res_devices[0]
821 assert devices[1] == res_devices[1]
822 assert devices[2] == res_devices[2]
823
824
825 @patch('os.getuid')
826 def test_migrate_data_db_to_new_db(self, m_getuid, monkeypatch):
827 m_getuid.return_value = 0
828
829 source_tags = 'ceph.osd_id=2,ceph.type=data,ceph.osd_fsid=1234,' \
830 'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
831 source_db_tags = 'ceph.osd_id=2,ceph.type=db,ceph.osd_fsid=1234,' \
832 'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
833
834 data_vol = api.Volume(lv_name='volume1',
835 lv_uuid='datauuid',
836 vg_name='vg',
837 lv_path='/dev/VolGroup/lv1',
838 lv_tags=source_tags)
839 db_vol = api.Volume(lv_name='volume2',
840 lv_uuid='dbuuid',
841 vg_name='vg',
842 lv_path='/dev/VolGroup/lv2',
843 lv_tags=source_db_tags)
844
845 self.mock_single_volumes = {
846 '/dev/VolGroup/lv1': data_vol,
847 '/dev/VolGroup/lv2': db_vol,
848 }
849 monkeypatch.setattr(migrate.api, 'get_first_lv',
850 self.mock_get_first_lv)
851
852 self.mock_volume = api.Volume(lv_name='volume2_new', lv_uuid='new-db-uuid',
853 vg_name='vg',
854 lv_path='/dev/VolGroup/lv2_new',
855 lv_tags='')
856 monkeypatch.setattr(api, 'get_lv_by_fullname',
857 self.mock_get_lv_by_fullname)
858
859 self.mock_process_input = []
860 monkeypatch.setattr(process, 'call', self.mock_process)
861
862 devices = []
863 devices.append([Device('/dev/VolGroup/lv1'), 'block'])
864 devices.append([Device('/dev/VolGroup/lv2'), 'db'])
865
866 monkeypatch.setattr(migrate, 'find_associated_devices',
867 lambda osd_id, osd_fsid: devices)
868
869
870 monkeypatch.setattr("ceph_volume.systemd.systemctl.osd_is_active",
871 lambda id: False)
872
873 monkeypatch.setattr(migrate, 'get_cluster_name',
874 lambda osd_id, osd_fsid: 'ceph')
875 monkeypatch.setattr(system, 'chown', lambda path: 0)
876 m = migrate.Migrate(argv=[
877 '--osd-id', '2',
878 '--osd-fsid', '1234',
879 '--from', 'data', 'db', 'wal',
880 '--target', 'vgname/new_wal'])
881 m.main()
882
883 n = len(self.mock_process_input)
884 assert n >= 5
885
886 assert self. mock_process_input[n-5] == [
887 'lvchange',
888 '--deltag', 'ceph.osd_id=2',
889 '--deltag', 'ceph.type=db',
890 '--deltag', 'ceph.osd_fsid=1234',
891 '--deltag', 'ceph.cluster_name=ceph',
892 '--deltag', 'ceph.db_uuid=dbuuid',
893 '--deltag', 'ceph.db_device=db_dev',
894 '/dev/VolGroup/lv2']
895
896 assert self. mock_process_input[n-4] == [
897 'lvchange',
898 '--deltag', 'ceph.db_uuid=dbuuid',
899 '--deltag', 'ceph.db_device=db_dev',
900 '/dev/VolGroup/lv1']
901
902 assert self. mock_process_input[n-3] == [
903 'lvchange',
904 '--addtag', 'ceph.db_uuid=new-db-uuid',
905 '--addtag', 'ceph.db_device=/dev/VolGroup/lv2_new',
906 '/dev/VolGroup/lv1']
907
908 assert self. mock_process_input[n-2] == [
909 'lvchange',
910 '--addtag', 'ceph.osd_id=2',
911 '--addtag', 'ceph.type=db',
912 '--addtag', 'ceph.osd_fsid=1234',
913 '--addtag', 'ceph.cluster_name=ceph',
914 '--addtag', 'ceph.db_uuid=new-db-uuid',
915 '--addtag', 'ceph.db_device=/dev/VolGroup/lv2_new',
916 '/dev/VolGroup/lv2_new']
917
918 assert self. mock_process_input[n-1] == [
919 'ceph-bluestore-tool',
920 '--path', '/var/lib/ceph/osd/ceph-2',
921 '--dev-target', '/dev/VolGroup/lv2_new',
922 '--command', 'bluefs-bdev-migrate',
923 '--devs-source', '/var/lib/ceph/osd/ceph-2/block',
924 '--devs-source', '/var/lib/ceph/osd/ceph-2/block.db']
925
926 @patch('os.getuid')
927 def test_migrate_data_db_to_new_db_skip_wal(self, m_getuid, monkeypatch):
928 m_getuid.return_value = 0
929
930 source_tags = 'ceph.osd_id=2,ceph.type=data,ceph.osd_fsid=1234,' \
931 'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
932 source_db_tags = 'ceph.osd_id=2,ceph.type=db,ceph.osd_fsid=1234,' \
933 'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
934 source_wal_tags = 'ceph.osd_id=2,ceph.type=wal,ceph.osd_fsid=1234' \
935 'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
936
937 data_vol = api.Volume(lv_name='volume1',
938 lv_uuid='datauuid',
939 vg_name='vg',
940 lv_path='/dev/VolGroup/lv1',
941 lv_tags=source_tags)
942 db_vol = api.Volume(lv_name='volume2',
943 lv_uuid='dbuuid',
944 vg_name='vg',
945 lv_path='/dev/VolGroup/lv2',
946 lv_tags=source_db_tags)
947
948 wal_vol = api.Volume(lv_name='volume3',
949 lv_uuid='datauuid',
950 vg_name='vg',
951 lv_path='/dev/VolGroup/lv3',
952 lv_tags=source_wal_tags)
953
954 self.mock_single_volumes = {
955 '/dev/VolGroup/lv1': data_vol,
956 '/dev/VolGroup/lv2': db_vol,
957 '/dev/VolGroup/lv3': wal_vol,
958 }
959 monkeypatch.setattr(migrate.api, 'get_first_lv',
960 self.mock_get_first_lv)
961
962 self.mock_volume = api.Volume(lv_name='volume2_new', lv_uuid='new-db-uuid',
963 vg_name='vg',
964 lv_path='/dev/VolGroup/lv2_new',
965 lv_tags='')
966 monkeypatch.setattr(api, 'get_lv_by_fullname',
967 self.mock_get_lv_by_fullname)
968
969 self.mock_process_input = []
970 monkeypatch.setattr(process, 'call', self.mock_process)
971
972 devices = []
973 devices.append([Device('/dev/VolGroup/lv1'), 'block'])
974 devices.append([Device('/dev/VolGroup/lv2'), 'db'])
975 devices.append([Device('/dev/VolGroup/lv3'), 'wal'])
976
977 monkeypatch.setattr(migrate, 'find_associated_devices',
978 lambda osd_id, osd_fsid: devices)
979
980 monkeypatch.setattr("ceph_volume.systemd.systemctl.osd_is_active",
981 lambda id: False)
982
983 monkeypatch.setattr(migrate, 'get_cluster_name',
984 lambda osd_id, osd_fsid: 'ceph')
985 monkeypatch.setattr(system, 'chown', lambda path: 0)
986 m = migrate.Migrate(argv=[
987 '--osd-id', '2',
988 '--osd-fsid', '1234',
989 '--from', 'data', 'db',
990 '--target', 'vgname/new_wal'])
991 m.main()
992
993 n = len(self.mock_process_input)
994 assert n >= 7
995
996 assert self. mock_process_input[n-7] == [
997 'lvchange',
998 '--deltag', 'ceph.osd_id=2',
999 '--deltag', 'ceph.type=db',
1000 '--deltag', 'ceph.osd_fsid=1234',
1001 '--deltag', 'ceph.cluster_name=ceph',
1002 '--deltag', 'ceph.db_uuid=dbuuid',
1003 '--deltag', 'ceph.db_device=db_dev',
1004 '/dev/VolGroup/lv2']
1005
1006 assert self. mock_process_input[n-6] == [
1007 'lvchange',
1008 '--deltag', 'ceph.db_uuid=dbuuid',
1009 '--deltag', 'ceph.db_device=db_dev',
1010 '/dev/VolGroup/lv1']
1011
1012 assert self. mock_process_input[n-5] == [
1013 'lvchange',
1014 '--addtag', 'ceph.db_uuid=new-db-uuid',
1015 '--addtag', 'ceph.db_device=/dev/VolGroup/lv2_new',
1016 '/dev/VolGroup/lv1']
1017
1018 assert self. mock_process_input[n-4] == [
1019 'lvchange',
1020 '--deltag', 'ceph.db_uuid=dbuuid',
1021 '--deltag', 'ceph.db_device=db_dev',
1022 '/dev/VolGroup/lv3']
1023
1024 assert self. mock_process_input[n-3] == [
1025 'lvchange',
1026 '--addtag', 'ceph.db_uuid=new-db-uuid',
1027 '--addtag', 'ceph.db_device=/dev/VolGroup/lv2_new',
1028 '/dev/VolGroup/lv3']
1029
1030 assert self. mock_process_input[n-2] == [
1031 'lvchange',
1032 '--addtag', 'ceph.osd_id=2',
1033 '--addtag', 'ceph.type=db',
1034 '--addtag', 'ceph.osd_fsid=1234',
1035 '--addtag', 'ceph.cluster_name=ceph',
1036 '--addtag', 'ceph.db_uuid=new-db-uuid',
1037 '--addtag', 'ceph.db_device=/dev/VolGroup/lv2_new',
1038 '/dev/VolGroup/lv2_new']
1039
1040 assert self. mock_process_input[n-1] == [
1041 'ceph-bluestore-tool',
1042 '--path', '/var/lib/ceph/osd/ceph-2',
1043 '--dev-target', '/dev/VolGroup/lv2_new',
1044 '--command', 'bluefs-bdev-migrate',
1045 '--devs-source', '/var/lib/ceph/osd/ceph-2/block',
1046 '--devs-source', '/var/lib/ceph/osd/ceph-2/block.db']
1047
1048 @patch('os.getuid')
1049 def test_migrate_data_db_wal_to_new_db(self, m_getuid, monkeypatch):
1050 m_getuid.return_value = 0
1051
1052 source_tags = 'ceph.osd_id=2,ceph.type=data,ceph.osd_fsid=1234,' \
1053 'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
1054 'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
1055 source_db_tags = 'ceph.osd_id=2,ceph.type=db,ceph.osd_fsid=1234,' \
1056 'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
1057 source_wal_tags = 'ceph.osd_id=0,ceph.type=wal,ceph.osd_fsid=1234,' \
1058 'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
1059 'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
1060
1061 data_vol = api.Volume(lv_name='volume1',
1062 lv_uuid='datauuid',
1063 vg_name='vg',
1064 lv_path='/dev/VolGroup/lv1',
1065 lv_tags=source_tags)
1066 db_vol = api.Volume(lv_name='volume2',
1067 lv_uuid='dbuuid',
1068 vg_name='vg',
1069 lv_path='/dev/VolGroup/lv2',
1070 lv_tags=source_db_tags)
1071
1072 wal_vol = api.Volume(lv_name='volume3',
1073 lv_uuid='waluuid',
1074 vg_name='vg',
1075 lv_path='/dev/VolGroup/lv3',
1076 lv_tags=source_wal_tags)
1077
1078 self.mock_single_volumes = {
1079 '/dev/VolGroup/lv1': data_vol,
1080 '/dev/VolGroup/lv2': db_vol,
1081 '/dev/VolGroup/lv3': wal_vol,
1082 }
1083 monkeypatch.setattr(migrate.api, 'get_first_lv',
1084 self.mock_get_first_lv)
1085
1086 self.mock_volume = api.Volume(lv_name='volume2_new', lv_uuid='new-db-uuid',
1087 vg_name='vg',
1088 lv_path='/dev/VolGroup/lv2_new',
1089 lv_tags='')
1090 monkeypatch.setattr(api, 'get_lv_by_fullname',
1091 self.mock_get_lv_by_fullname)
1092
1093 self.mock_process_input = []
1094 monkeypatch.setattr(process, 'call', self.mock_process)
1095
1096 devices = []
1097 devices.append([Device('/dev/VolGroup/lv1'), 'block'])
1098 devices.append([Device('/dev/VolGroup/lv2'), 'db'])
1099 devices.append([Device('/dev/VolGroup/lv3'), 'wal'])
1100
1101 monkeypatch.setattr(migrate, 'find_associated_devices',
1102 lambda osd_id, osd_fsid: devices)
1103
1104 monkeypatch.setattr("ceph_volume.systemd.systemctl.osd_is_active",
1105 lambda id: False)
1106
1107 monkeypatch.setattr(migrate, 'get_cluster_name',
1108 lambda osd_id, osd_fsid: 'ceph')
1109 monkeypatch.setattr(system, 'chown', lambda path: 0)
1110 m = migrate.Migrate(argv=[
1111 '--osd-id', '2',
1112 '--osd-fsid', '1234',
1113 '--from', 'data', 'db', 'wal',
1114 '--target', 'vgname/new_wal'])
1115 m.main()
1116
1117 n = len(self.mock_process_input)
1118 assert n >= 6
1119
1120 assert self. mock_process_input[n-6] == [
1121 'lvchange',
1122 '--deltag', 'ceph.osd_id=2',
1123 '--deltag', 'ceph.type=db',
1124 '--deltag', 'ceph.osd_fsid=1234',
1125 '--deltag', 'ceph.cluster_name=ceph',
1126 '--deltag', 'ceph.db_uuid=dbuuid',
1127 '--deltag', 'ceph.db_device=db_dev',
1128 '/dev/VolGroup/lv2']
1129
1130 assert self. mock_process_input[n-5] == [
1131 'lvchange',
1132 '--deltag', 'ceph.osd_id=0',
1133 '--deltag', 'ceph.type=wal',
1134 '--deltag', 'ceph.osd_fsid=1234',
1135 '--deltag', 'ceph.cluster_name=ceph',
1136 '--deltag', 'ceph.db_uuid=dbuuid',
1137 '--deltag', 'ceph.db_device=db_dev',
1138 '--deltag', 'ceph.wal_uuid=waluuid',
1139 '--deltag', 'ceph.wal_device=wal_dev',
1140 '/dev/VolGroup/lv3']
1141
1142 assert self. mock_process_input[n-4] == [
1143 'lvchange',
1144 '--deltag', 'ceph.db_uuid=dbuuid',
1145 '--deltag', 'ceph.db_device=db_dev',
1146 '--deltag', 'ceph.wal_uuid=waluuid',
1147 '--deltag', 'ceph.wal_device=wal_dev',
1148 '/dev/VolGroup/lv1']
1149
1150 assert self. mock_process_input[n-3] == [
1151 'lvchange',
1152 '--addtag', 'ceph.db_uuid=new-db-uuid',
1153 '--addtag', 'ceph.db_device=/dev/VolGroup/lv2_new',
1154 '/dev/VolGroup/lv1']
1155
1156 assert self. mock_process_input[n-2] == [
1157 'lvchange',
1158 '--addtag', 'ceph.osd_id=2',
1159 '--addtag', 'ceph.type=db',
1160 '--addtag', 'ceph.osd_fsid=1234',
1161 '--addtag', 'ceph.cluster_name=ceph',
1162 '--addtag', 'ceph.db_uuid=new-db-uuid',
1163 '--addtag', 'ceph.db_device=/dev/VolGroup/lv2_new',
1164 '/dev/VolGroup/lv2_new']
1165
1166 assert self. mock_process_input[n-1] == [
1167 'ceph-bluestore-tool',
1168 '--path', '/var/lib/ceph/osd/ceph-2',
1169 '--dev-target', '/dev/VolGroup/lv2_new',
1170 '--command', 'bluefs-bdev-migrate',
1171 '--devs-source', '/var/lib/ceph/osd/ceph-2/block',
1172 '--devs-source', '/var/lib/ceph/osd/ceph-2/block.db',
1173 '--devs-source', '/var/lib/ceph/osd/ceph-2/block.wal']
1174
1175 @patch('os.getuid')
1176 def test_dont_migrate_data_db_wal_to_new_data(self,
1177 m_getuid,
1178 monkeypatch,
1179 capsys):
1180 m_getuid.return_value = 0
1181
1182 source_tags = 'ceph.osd_id=2,ceph.type=data,ceph.osd_fsid=1234,' \
1183 'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
1184 source_db_tags = 'ceph.osd_id=2,ceph.type=db,ceph.osd_fsid=1234,' \
1185 'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
1186
1187 data_vol = api.Volume(lv_name='volume1',
1188 lv_uuid='datauuid',
1189 vg_name='vg',
1190 lv_path='/dev/VolGroup/lv1',
1191 lv_tags=source_tags)
1192 db_vol = api.Volume(lv_name='volume2',
1193 lv_uuid='dbuuid',
1194 vg_name='vg',
1195 lv_path='/dev/VolGroup/lv2',
1196 lv_tags=source_db_tags)
1197
1198 self.mock_single_volumes = {
1199 '/dev/VolGroup/lv1': data_vol,
1200 '/dev/VolGroup/lv2': db_vol,
1201 }
1202 monkeypatch.setattr(migrate.api, 'get_first_lv',
1203 self.mock_get_first_lv)
1204
1205 self.mock_volume = api.Volume(lv_name='volume2_new', lv_uuid='new-db-uuid',
1206 vg_name='vg',
1207 lv_path='/dev/VolGroup/lv2_new',
1208 lv_tags='')
1209 monkeypatch.setattr(api, 'get_lv_by_fullname',
1210 self.mock_get_lv_by_fullname)
1211
1212 self.mock_process_input = []
1213 monkeypatch.setattr(process, 'call', self.mock_process)
1214
1215 devices = []
1216 devices.append([Device('/dev/VolGroup/lv1'), 'block'])
1217 devices.append([Device('/dev/VolGroup/lv2'), 'db'])
1218
1219 monkeypatch.setattr(migrate, 'find_associated_devices',
1220 lambda osd_id, osd_fsid: devices)
1221
1222 monkeypatch.setattr("ceph_volume.systemd.systemctl.osd_is_active",
1223 lambda id: False)
1224
1225 monkeypatch.setattr(migrate, 'get_cluster_name',
1226 lambda osd_id, osd_fsid: 'ceph')
1227 monkeypatch.setattr(system, 'chown', lambda path: 0)
1228 m = migrate.Migrate(argv=[
1229 '--osd-id', '2',
1230 '--osd-fsid', '1234',
1231 '--from', 'data',
1232 '--target', 'vgname/new_data'])
1233
1234 with pytest.raises(SystemExit) as error:
1235 m.main()
1236 stdout, stderr = capsys.readouterr()
1237 expected = 'Unable to migrate to : vgname/new_data'
1238 assert expected in str(error.value)
1239 expected = 'Unable to determine new volume type,'
1240 ' please use new-db or new-wal command before.'
1241 assert expected in stderr
1242
1243 @patch('os.getuid')
1244 def test_dont_migrate_db_to_wal(self,
1245 m_getuid,
1246 monkeypatch,
1247 capsys):
1248 m_getuid.return_value = 0
1249
1250 source_tags = 'ceph.osd_id=2,ceph.type=data,ceph.osd_fsid=1234,' \
1251 'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
1252 'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
1253 source_db_tags = 'ceph.osd_id=2,ceph.type=db,ceph.osd_fsid=1234,' \
1254 'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
1255 source_wal_tags = 'ceph.osd_id=2,ceph.type=wal,ceph.osd_fsid=1234,' \
1256 'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
1257 'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
1258
1259 data_vol = api.Volume(lv_name='volume1',
1260 lv_uuid='datauuid',
1261 vg_name='vg',
1262 lv_path='/dev/VolGroup/lv1',
1263 lv_tags=source_tags)
1264 db_vol = api.Volume(lv_name='volume2',
1265 lv_uuid='dbuuid',
1266 vg_name='vg',
1267 lv_path='/dev/VolGroup/lv2',
1268 lv_tags=source_db_tags)
1269
1270 wal_vol = api.Volume(lv_name='volume3',
1271 lv_uuid='waluuid',
1272 vg_name='vg',
1273 lv_path='/dev/VolGroup/lv3',
1274 lv_tags=source_wal_tags)
1275
1276 self.mock_single_volumes = {
1277 '/dev/VolGroup/lv1': data_vol,
1278 '/dev/VolGroup/lv2': db_vol,
1279 '/dev/VolGroup/lv3': wal_vol,
1280 }
1281 monkeypatch.setattr(migrate.api, 'get_first_lv',
1282 self.mock_get_first_lv)
1283
1284 self.mock_volume = wal_vol
1285 monkeypatch.setattr(api, 'get_lv_by_fullname',
1286 self.mock_get_lv_by_fullname)
1287
1288 self.mock_process_input = []
1289 monkeypatch.setattr(process, 'call', self.mock_process)
1290
1291 devices = []
1292 devices.append([Device('/dev/VolGroup/lv1'), 'block'])
1293 devices.append([Device('/dev/VolGroup/lv2'), 'db'])
1294 devices.append([Device('/dev/VolGroup/lv3'), 'wal'])
1295
1296 monkeypatch.setattr(migrate, 'find_associated_devices',
1297 lambda osd_id, osd_fsid: devices)
1298
1299 monkeypatch.setattr("ceph_volume.systemd.systemctl.osd_is_active",
1300 lambda id: False)
1301
1302 monkeypatch.setattr(migrate, 'get_cluster_name',
1303 lambda osd_id, osd_fsid: 'ceph')
1304 monkeypatch.setattr(system, 'chown', lambda path: 0)
1305 m = migrate.Migrate(argv=[
1306 '--osd-id', '2',
1307 '--osd-fsid', '1234',
1308 '--from', 'db',
1309 '--target', 'vgname/wal'])
1310
1311 with pytest.raises(SystemExit) as error:
1312 m.main()
1313 stdout, stderr = capsys.readouterr()
1314 expected = 'Unable to migrate to : vgname/wal'
1315 assert expected in str(error.value)
1316 expected = 'Migrate to WAL is not supported'
1317 assert expected in stderr
1318
1319 @patch('os.getuid')
1320 def test_migrate_data_db_to_db(self,
1321 m_getuid,
1322 monkeypatch,
1323 capsys):
1324 m_getuid.return_value = 0
1325
1326 source_tags = 'ceph.osd_id=2,ceph.type=data,ceph.osd_fsid=1234,' \
1327 'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
1328 'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
1329 source_db_tags = 'ceph.osd_id=2,ceph.type=db,ceph.osd_fsid=1234,' \
1330 'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
1331 source_wal_tags = 'ceph.osd_id=2,ceph.type=wal,ceph.osd_fsid=1234,' \
1332 'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
1333 'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
1334
1335 data_vol = api.Volume(lv_name='volume1',
1336 lv_uuid='datauuid',
1337 vg_name='vg',
1338 lv_path='/dev/VolGroup/lv1',
1339 lv_tags=source_tags)
1340 db_vol = api.Volume(lv_name='volume2',
1341 lv_uuid='dbuuid',
1342 vg_name='vg',
1343 lv_path='/dev/VolGroup/lv2',
1344 lv_tags=source_db_tags)
1345
1346 wal_vol = api.Volume(lv_name='volume3',
1347 lv_uuid='waluuid',
1348 vg_name='vg',
1349 lv_path='/dev/VolGroup/lv3',
1350 lv_tags=source_wal_tags)
1351
1352 self.mock_single_volumes = {
1353 '/dev/VolGroup/lv1': data_vol,
1354 '/dev/VolGroup/lv2': db_vol,
1355 '/dev/VolGroup/lv3': wal_vol,
1356 }
1357 monkeypatch.setattr(migrate.api, 'get_first_lv',
1358 self.mock_get_first_lv)
1359
1360 self.mock_volume = db_vol
1361 monkeypatch.setattr(api, 'get_lv_by_fullname',
1362 self.mock_get_lv_by_fullname)
1363
1364 self.mock_process_input = []
1365 monkeypatch.setattr(process, 'call', self.mock_process)
1366
1367 devices = []
1368 devices.append([Device('/dev/VolGroup/lv1'), 'block'])
1369 devices.append([Device('/dev/VolGroup/lv2'), 'db'])
1370 devices.append([Device('/dev/VolGroup/lv3'), 'wal'])
1371
1372 monkeypatch.setattr(migrate, 'find_associated_devices',
1373 lambda osd_id, osd_fsid: devices)
1374
1375 monkeypatch.setattr("ceph_volume.systemd.systemctl.osd_is_active",
1376 lambda id: False)
1377
1378 monkeypatch.setattr(migrate, 'get_cluster_name',
1379 lambda osd_id, osd_fsid: 'ceph')
1380 monkeypatch.setattr(system, 'chown', lambda path: 0)
1381 m = migrate.Migrate(argv=[
1382 '--osd-id', '2',
1383 '--osd-fsid', '1234',
1384 '--from', 'db', 'data',
1385 '--target', 'vgname/db'])
1386
1387 m.main()
1388
1389 n = len(self.mock_process_input)
1390 assert n >= 1
1391 for s in self.mock_process_input:
1392 print(s)
1393
1394 assert self. mock_process_input[n-1] == [
1395 'ceph-bluestore-tool',
1396 '--path', '/var/lib/ceph/osd/ceph-2',
1397 '--dev-target', '/var/lib/ceph/osd/ceph-2/block.db',
1398 '--command', 'bluefs-bdev-migrate',
1399 '--devs-source', '/var/lib/ceph/osd/ceph-2/block']
1400
1401 @patch('os.getuid')
1402 def test_migrate_data_wal_to_db(self,
1403 m_getuid,
1404 monkeypatch,
1405 capsys):
1406 m_getuid.return_value = 0
1407
1408 source_tags = 'ceph.osd_id=2,ceph.type=data,ceph.osd_fsid=1234,' \
1409 'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
1410 'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
1411 source_db_tags = 'ceph.osd_id=2,ceph.type=db,ceph.osd_fsid=1234,' \
1412 'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
1413 'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
1414 source_wal_tags = 'ceph.osd_id=2,ceph.type=wal,ceph.osd_fsid=1234,' \
1415 'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
1416 'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
1417
1418 data_vol = api.Volume(lv_name='volume1',
1419 lv_uuid='datauuid',
1420 vg_name='vg',
1421 lv_path='/dev/VolGroup/lv1',
1422 lv_tags=source_tags)
1423 db_vol = api.Volume(lv_name='volume2',
1424 lv_uuid='dbuuid',
1425 vg_name='vg',
1426 lv_path='/dev/VolGroup/lv2',
1427 lv_tags=source_db_tags)
1428
1429 wal_vol = api.Volume(lv_name='volume3',
1430 lv_uuid='waluuid',
1431 vg_name='vg',
1432 lv_path='/dev/VolGroup/lv3',
1433 lv_tags=source_wal_tags)
1434
1435 self.mock_single_volumes = {
1436 '/dev/VolGroup/lv1': data_vol,
1437 '/dev/VolGroup/lv2': db_vol,
1438 '/dev/VolGroup/lv3': wal_vol,
1439 }
1440 monkeypatch.setattr(migrate.api, 'get_first_lv',
1441 self.mock_get_first_lv)
1442
1443 self.mock_volume = db_vol
1444 monkeypatch.setattr(api, 'get_lv_by_fullname',
1445 self.mock_get_lv_by_fullname)
1446
1447 self.mock_process_input = []
1448 monkeypatch.setattr(process, 'call', self.mock_process)
1449
1450 devices = []
1451 devices.append([Device('/dev/VolGroup/lv1'), 'block'])
1452 devices.append([Device('/dev/VolGroup/lv2'), 'db'])
1453 devices.append([Device('/dev/VolGroup/lv3'), 'wal'])
1454
1455 monkeypatch.setattr(migrate, 'find_associated_devices',
1456 lambda osd_id, osd_fsid: devices)
1457
1458 monkeypatch.setattr("ceph_volume.systemd.systemctl.osd_is_active",
1459 lambda id: False)
1460
1461 monkeypatch.setattr(migrate, 'get_cluster_name',
1462 lambda osd_id, osd_fsid: 'ceph')
1463 monkeypatch.setattr(system, 'chown', lambda path: 0)
1464 m = migrate.Migrate(argv=[
1465 '--osd-id', '2',
1466 '--osd-fsid', '1234',
1467 '--from', 'db', 'data', 'wal',
1468 '--target', 'vgname/db'])
1469
1470 m.main()
1471
1472 n = len(self.mock_process_input)
1473 assert n >= 1
1474 for s in self.mock_process_input:
1475 print(s)
1476
1477 assert self. mock_process_input[n-4] == [
1478 'lvchange',
1479 '--deltag', 'ceph.osd_id=2',
1480 '--deltag', 'ceph.type=wal',
1481 '--deltag', 'ceph.osd_fsid=1234',
1482 '--deltag', 'ceph.cluster_name=ceph',
1483 '--deltag', 'ceph.db_uuid=dbuuid',
1484 '--deltag', 'ceph.db_device=db_dev',
1485 '--deltag', 'ceph.wal_uuid=waluuid',
1486 '--deltag', 'ceph.wal_device=wal_dev',
1487 '/dev/VolGroup/lv3']
1488 assert self. mock_process_input[n-3] == [
1489 'lvchange',
1490 '--deltag', 'ceph.wal_uuid=waluuid',
1491 '--deltag', 'ceph.wal_device=wal_dev',
1492 '/dev/VolGroup/lv1']
1493 assert self. mock_process_input[n-2] == [
1494 'lvchange',
1495 '--deltag', 'ceph.wal_uuid=waluuid',
1496 '--deltag', 'ceph.wal_device=wal_dev',
1497 '/dev/VolGroup/lv2']
1498 assert self. mock_process_input[n-1] == [
1499 'ceph-bluestore-tool',
1500 '--path', '/var/lib/ceph/osd/ceph-2',
1501 '--dev-target', '/var/lib/ceph/osd/ceph-2/block.db',
1502 '--command', 'bluefs-bdev-migrate',
1503 '--devs-source', '/var/lib/ceph/osd/ceph-2/block',
1504 '--devs-source', '/var/lib/ceph/osd/ceph-2/block.wal']