From: Andrew Schoen Date: Fri, 24 Apr 2020 17:11:52 +0000 (-0500) Subject: ceph-volume: handle idempotency with batch and explicit scenarios X-Git-Tag: v16.1.0~1906^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=9b8254edc8ee6c91809119120970b722edb100b7;p=ceph.git 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 --- 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"]