From f3707f1ad43513c2a6df17e9dce756533c3b4a1d Mon Sep 17 00:00:00 2001 From: Andrew Schoen Date: Fri, 8 Mar 2019 09:53:08 -0600 Subject: [PATCH] ceph-volume: make systemctl.get_running_osds resilient to garbage output Makes systemd.systemctl.get_running_osds more resilient to output that doesn't match what we're expecting to parse. This also handles the case of a nonzero exit status by retuning an empty list. Signed-off-by: Andrew Schoen --- .../ceph_volume/systemd/systemctl.py | 17 ++++++++++++----- .../tests/systemd/test_systemctl.py | 18 +++++++++++++++--- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/ceph-volume/ceph_volume/systemd/systemctl.py b/src/ceph-volume/ceph_volume/systemd/systemctl.py index 280ddada7e9..778ad147917 100644 --- a/src/ceph-volume/ceph_volume/systemd/systemctl.py +++ b/src/ceph-volume/ceph_volume/systemd/systemctl.py @@ -1,8 +1,11 @@ """ Utilities to control systemd units """ +import logging + from ceph_volume import process +logger = logging.getLogger(__name__) def start(unit): process.run(['systemctl', 'start', unit]) @@ -44,11 +47,15 @@ def get_running_osd_ids(): 'ceph-osd@*', ]) osd_ids = [] - for line in out: - if line: - # example line looks like: Id=ceph-osd@1.service - osd_id = line.split("@")[1].split(".service")[0] - osd_ids.append(osd_id) + if rc == 0: + for line in out: + if line: + # example line looks like: Id=ceph-osd@1.service + try: + osd_id = line.split("@")[1].split(".service")[0] + osd_ids.append(osd_id) + except (IndexError, TypeError): + logger.warning("Failed to parse output from systemctl: %s", line) return osd_ids def start_osd(id_): diff --git a/src/ceph-volume/ceph_volume/tests/systemd/test_systemctl.py b/src/ceph-volume/ceph_volume/tests/systemd/test_systemctl.py index 76c8618a5bf..8eec4a3d441 100644 --- a/src/ceph-volume/ceph_volume/tests/systemd/test_systemctl.py +++ b/src/ceph-volume/ceph_volume/tests/systemd/test_systemctl.py @@ -1,9 +1,21 @@ +import pytest from ceph_volume.systemd import systemctl class TestSystemctl(object): - def test_get_running_osd_ids(self, stub_call): - stdout = ['Id=ceph-osd@1.service', '', 'Id=ceph-osd@2.service'] + @pytest.mark.parametrize("stdout,expected", [ + (['Id=ceph-osd@1.service', '', 'Id=ceph-osd@2.service'], ['1','2']), + (['Id=ceph-osd1.service',], []), + (['Id=ceph-osd@1'], ['1']), + ([], []), + ]) + def test_get_running_osd_ids(self, stub_call, stdout, expected): stub_call((stdout, [], 0)) osd_ids = systemctl.get_running_osd_ids() - assert osd_ids == ['1', '2'] + assert osd_ids == expected + + def test_returns_empty_list_on_nonzero_return_code(self, stub_call): + stdout = ['Id=ceph-osd@1.service', '', 'Id=ceph-osd@2.service'] + stub_call((stdout, [], 1)) + osd_ids = systemctl.get_running_osd_ids() + assert osd_ids == [] -- 2.39.5