diff --git a/actions.yaml b/actions.yaml index 2d2f1729..84259dbd 100644 --- a/actions.yaml +++ b/actions.yaml @@ -230,6 +230,12 @@ crushmap-update: additionalProperties: false show-disk-free: description: Show disk utilization by host and OSD. + params: + format: + type: string + enum: [json, json-pretty, xml, xml-pretty, plain] + default: "plain" + description: Output format, either json, json-pretty, xml, xml-pretty, plain; defaults to plain additionalProperties: false set-noout: description: Set ceph noout across the cluster. diff --git a/actions/show-disk-free.py b/actions/show-disk-free.py index 2ba7894f..1f38f094 100755 --- a/actions/show-disk-free.py +++ b/actions/show-disk-free.py @@ -18,12 +18,14 @@ import sys sys.path.append('hooks') from subprocess import check_output, CalledProcessError -from charmhelpers.core.hookenv import log, action_set, action_fail +from charmhelpers.core.hookenv import log, action_get, action_set, action_fail if __name__ == '__main__': + # constrained to enum: json,json-pretty,xml,xml-pretty,plain + fmt = action_get("format") try: out = check_output(['ceph', '--id', 'admin', - 'osd', 'df', 'tree']).decode('UTF-8') + 'osd', 'df', 'tree', '-f', fmt]).decode('UTF-8') action_set({'message': out}) except CalledProcessError as e: log(e) diff --git a/tests/basic_deployment.py b/tests/basic_deployment.py index 2aeaa2a8..a15d7b01 100644 --- a/tests/basic_deployment.py +++ b/tests/basic_deployment.py @@ -17,6 +17,7 @@ import amulet import re import time +import json from charmhelpers.contrib.openstack.amulet.deployment import ( OpenStackAmuletDeployment @@ -117,7 +118,7 @@ class CephBasicDeployment(OpenStackAmuletDeployment): # Include a non-existent device as osd-devices is a whitelist, # and this will catch cases where proposals attempt to change that. ceph_osd_config = { - 'osd-reformat': 'yes', + 'osd-reformat': True, 'ephemeral-unmount': '/mnt', 'osd-devices': '/dev/vdb /srv/ceph /dev/test-non-existent' } @@ -716,6 +717,27 @@ class CephBasicDeployment(OpenStackAmuletDeployment): action_id = u.run_action(sentry_unit, 'get-health') assert u.wait_on_action(action_id), "HEALTH_OK" + def test_420_show_disk_free_action(self): + """Verify show-disk-free""" + u.log.debug("Testing show-disk-free") + if self._get_openstack_release() < self.trusty_kilo: + u.log.info( + "show-disk-free only supported in >=kilo, skipping") + return + sentry_unit = self.ceph0_sentry + action_id = u.run_action(sentry_unit, + 'show-disk-free', + params={'format': 'json'}) + assert u.wait_on_action(action_id), "Show-disk-free action failed." + data = amulet.actions.get_action_output(action_id, full_output=True) + assert data.get(u"status") == "completed", "Show-disk-free failed" + message = data.get(u"results").get(u"message") + assert message is not None + jsonout = json.loads(message.strip()) + nodes = jsonout.get(u"nodes") + assert nodes is not None, "Show-disk-free: no 'nodes' elem" + assert len(nodes) > 0, "Show-disk-free action: 0 nodes" + def test_499_ceph_cmds_exit_zero(self): """Check basic functionality of ceph cli commands against all ceph units."""