From 3b14648a32e060c490dcd558d0d58ca507a45206 Mon Sep 17 00:00:00 2001 From: Guillaume Abrioux Date: Mon, 20 Jul 2020 15:43:38 +0200 Subject: [PATCH] ceph-volume: filter by osd-id or osd-fsid when zapping 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 (cherry picked from commit e94aef6f96189648d0f204d8118501577dde5f52) --- src/ceph-volume/ceph_volume/devices/lvm/zap.py | 13 +++++++------ .../ceph_volume/tests/devices/lvm/test_zap.py | 11 +++++++++++ src/ceph-volume/ceph_volume/util/__init__.py | 8 ++++++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/ceph-volume/ceph_volume/devices/lvm/zap.py b/src/ceph-volume/ceph_volume/devices/lvm/zap.py index 0e51d1edb706f..63624e55f5bd2 100644 --- a/src/ceph-volume/ceph_volume/devices/lvm/zap.py +++ b/src/ceph-volume/ceph_volume/devices/lvm/zap.py @@ -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')] diff --git a/src/ceph-volume/ceph_volume/tests/devices/lvm/test_zap.py b/src/ceph-volume/ceph_volume/tests/devices/lvm/test_zap.py index 0284a0b8fe2cf..9dde5f576a2ac 100644 --- a/src/ceph-volume/ceph_volume/tests/devices/lvm/test_zap.py +++ b/src/ceph-volume/ceph_volume/tests/devices/lvm/test_zap.py @@ -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): diff --git a/src/ceph-volume/ceph_volume/util/__init__.py b/src/ceph-volume/ceph_volume/util/__init__.py index 43c9c9d6835d1..1b5afe97040fb 100644 --- a/src/ceph-volume/ceph_volume/util/__init__.py +++ b/src/ceph-volume/ceph_volume/util/__init__.py @@ -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 -- 2.39.5