]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph-volume: filter by osd-id or osd-fsid when zapping 35900/head
authorGuillaume Abrioux <gabrioux@redhat.com>
Mon, 20 Jul 2020 13:43:38 +0000 (15:43 +0200)
committerRishabh Dave <ridave@redhat.com>
Mon, 10 Aug 2020 08:18:42 +0000 (13:48 +0530)
2f5c10c12c37e6865ce54bb4940d3779353cba4f introduced a bug:

`ceph-volume lvm zap` command fails under certain conditions.

when passing `--osd-id` or `--osd-fsid` to `ceph-volume lvm zap` command
it tries to zap additionnal devices that have nothing to do with the osd
being zapped.

When calling `api.get_lvs()` in `ensure_associated_lvs()` we have to
pass the osd-id/osd-fsid information so only related devices are
returned by `get_lvs()` method

Closes: https://tracker.ceph.com/issues/46627
Signed-off-by: Guillaume Abrioux <gabrioux@redhat.com>
(cherry picked from commit e94aef6f96189648d0f204d8118501577dde5f52)

src/ceph-volume/ceph_volume/devices/lvm/zap.py
src/ceph-volume/ceph_volume/tests/devices/lvm/test_zap.py
src/ceph-volume/ceph_volume/util/__init__.py

index 0e51d1edb706fce9b14d7618e1a7d2dda5f94679..63624e55f5bd228b912bc5eaf09fa39944ea115f 100644 (file)
@@ -7,7 +7,7 @@ from textwrap import dedent
 
 from ceph_volume import decorators, terminal, process
 from ceph_volume.api import lvm as api
-from ceph_volume.util import system, encryption, disk, arg_validators, str_to_int
+from ceph_volume.util import system, encryption, disk, arg_validators, str_to_int, merge_dict
 from ceph_volume.util.device import Device
 from ceph_volume.systemd import systemctl
 
@@ -87,11 +87,11 @@ def find_associated_devices(osd_id=None, osd_fsid=None):
         raise RuntimeError('Unable to find any LV for zapping OSD: '
                            '%s' % osd_id or osd_fsid)
 
-    devices_to_zap = ensure_associated_lvs(lvs)
+    devices_to_zap = ensure_associated_lvs(lvs, lv_tags)
     return [Device(path) for path in set(devices_to_zap) if path]
 
 
-def ensure_associated_lvs(lvs):
+def ensure_associated_lvs(lvs, lv_tags={}):
     """
     Go through each LV and ensure if backing devices (journal, wal, block)
     are LVs or partitions, so that they can be accurately reported.
@@ -100,9 +100,10 @@ def ensure_associated_lvs(lvs):
     # receive a filtering for osd.1, and have multiple failed deployments
     # leaving many journals with osd.1 - usually, only a single LV will be
     # returned
-    journal_lvs = api.get_lvs(tags={'ceph.type': 'journal'})
-    db_lvs = api.get_lvs(tags={'ceph.type': 'db'})
-    wal_lvs = api.get_lvs(tags={'ceph.type': 'wal'})
+
+    journal_lvs = api.get_lvs(tags=merge_dict(lv_tags, {'ceph.type': 'journal'}))
+    db_lvs = api.get_lvs(tags=merge_dict(lv_tags, {'ceph.type': 'db'}))
+    wal_lvs = api.get_lvs(tags=merge_dict(lv_tags, {'ceph.type': 'wal'}))
     backing_devices = [(journal_lvs, 'journal'), (db_lvs, 'db'),
                        (wal_lvs, 'wal')]
 
index 0284a0b8fe2cff31d396aa3c81f7fafd57323bd3..9dde5f576a2ac988e05f36ef515b689d5715c814 100644 (file)
@@ -1,6 +1,7 @@
 import os
 import pytest
 from copy import deepcopy
+from mock.mock import patch, call
 from ceph_volume.api import lvm as api
 from ceph_volume.devices.lvm import zap
 
@@ -184,6 +185,16 @@ class TestEnsureAssociatedLVs(object):
         assert '/dev/VolGroup/lvwal' in result
         assert '/dev/VolGroup/lvdb' in result
 
+    @patch('ceph_volume.devices.lvm.zap.api.get_lvs')
+    def test_ensure_associated_lvs(self, m_get_lvs):
+        zap.ensure_associated_lvs([], lv_tags={'ceph.osd_id': '1'})
+        calls = [
+            call(tags={'ceph.type': 'journal', 'ceph.osd_id': '1'}),
+            call(tags={'ceph.type': 'db', 'ceph.osd_id': '1'}),
+            call(tags={'ceph.type': 'wal', 'ceph.osd_id': '1'})
+        ]
+        m_get_lvs.assert_has_calls(calls, any_order=True)
+
 
 class TestWipeFs(object):
 
index 43c9c9d6835d11b53070ac6b7386364b9f637a30..1b5afe97040fbb83812c9a3fc3316ded206c7cbf 100644 (file)
@@ -98,3 +98,11 @@ def prompt_bool(question, input_=None):
         terminal.error('Valid false responses are: n, no')
         terminal.error('That response was invalid, please try again')
         return prompt_bool(question, input_=input_prompt)
+
+def merge_dict(x, y):
+    """
+    Return two dicts merged
+    """
+    z = x.copy()
+    z.update(y)
+    return z
\ No newline at end of file