From f244e3e68ed176ff6636894a67e5c08fbbaeaefc Mon Sep 17 00:00:00 2001 From: Andrew Schoen Date: Fri, 24 Apr 2020 12:11:52 -0500 Subject: [PATCH] ceph-volume: handle idempotency with batch and explicit scenarios If you used --wal-devices or --db-devices with batch and too many devices are filtered out then a RuntimeError was raised. However, if --report and --format=json is used then we should return valid json indicating that no OSDS will be created so that ceph-ansible and other systems can use that for idempotency checks. Resolves: rhbz#1827349 Signed-off-by: Andrew Schoen (cherry picked from commit 9b8254edc8ee6c91809119120970b722edb100b7) --- .../ceph_volume/devices/lvm/batch.py | 6 ++++ .../tests/devices/lvm/test_batch.py | 30 +++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/ceph-volume/ceph_volume/devices/lvm/batch.py b/src/ceph-volume/ceph_volume/devices/lvm/batch.py index b7a4b35b2fd2..a83c8680bf33 100644 --- a/src/ceph-volume/ceph_volume/devices/lvm/batch.py +++ b/src/ceph-volume/ceph_volume/devices/lvm/batch.py @@ -1,5 +1,6 @@ import argparse import logging +import json from textwrap import dedent from ceph_volume import terminal, decorators from ceph_volume.util import disk, prompt_bool @@ -376,6 +377,11 @@ class Batch(object): # filtered if self.args.yes and dev_list and self.usable and devs != usable: err = '{} devices were filtered in non-interactive mode, bailing out' + if self.args.format == "json" and self.args.report: + # if a json report is requested, report unchanged so idempotency checks + # in ceph-ansible will work + print(json.dumps({"changed": False, "osds": [], "vgs": []})) + raise SystemExit(0) raise RuntimeError(err.format(len(devs) - len(usable))) diff --git a/src/ceph-volume/ceph_volume/tests/devices/lvm/test_batch.py b/src/ceph-volume/ceph_volume/tests/devices/lvm/test_batch.py index 1c3c25f67e31..06a37c4906c2 100644 --- a/src/ceph-volume/ceph_volume/tests/devices/lvm/test_batch.py +++ b/src/ceph-volume/ceph_volume/tests/devices/lvm/test_batch.py @@ -1,4 +1,5 @@ import pytest +import json from ceph_volume.devices.lvm import batch @@ -133,7 +134,7 @@ class TestFilterDevices(object): abspath="/dev/sda", rotational=True, is_lvm_member=False, - available=True + available=True, ) ssd1 = factory( used_by_ceph=True, @@ -143,9 +144,34 @@ class TestFilterDevices(object): available=False ) args = factory(devices=[hdd1], db_devices=[ssd1], filtered_devices={}, - yes=True) + yes=True, format="", report=False) b = batch.Batch([]) b.args = args with pytest.raises(RuntimeError) as ex: b._filter_devices() assert '1 devices were filtered in non-interactive mode, bailing out' in str(ex.value) + + def test_no_auto_prints_json_on_unavailable_device_and_report(self, factory, capsys): + hdd1 = factory( + used_by_ceph=False, + abspath="/dev/sda", + rotational=True, + is_lvm_member=False, + available=True, + ) + ssd1 = factory( + used_by_ceph=True, + abspath="/dev/nvme0n1", + rotational=False, + is_lvm_member=True, + available=False + ) + captured = capsys.readouterr() + args = factory(devices=[hdd1], db_devices=[ssd1], filtered_devices={}, + yes=True, format="json", report=True) + b = batch.Batch([]) + b.args = args + with pytest.raises(SystemExit): + b._filter_devices() + result = json.loads(captured.out) + assert not result["changed"] -- 2.47.3