Add an action to report utilization

Using swift-recon -d, report disk-utilization in GB.

Change-Id: I02f9b85106046fc038a66c7059c23c8a89fd32b1
Closes-Bug: 1720258
This commit is contained in:
Jill Rouleau 2017-09-28 16:53:35 -07:00
parent 727aff428b
commit dcec924d47
5 changed files with 108 additions and 2 deletions

View File

@ -31,3 +31,5 @@ openstack-upgrade:
description: |
Perform openstack upgrades. Config option action-managed-upgrade must be
set to True.
diskusage:
description: Run swift-recon -d on the specified unit. Returns values in GB.

View File

@ -22,7 +22,11 @@ import yaml
sys.path.append('hooks/')
from charmhelpers.core.host import service_pause, service_resume
from charmhelpers.core.hookenv import action_fail
from charmhelpers.core.hookenv import (
action_fail,
action_set,
)
from charmhelpers.contrib.openstack.utils import (
set_unit_paused,
clear_unit_paused,
@ -30,6 +34,11 @@ from charmhelpers.contrib.openstack.utils import (
from lib.swift_utils import assess_status, services
from swift_hooks import CONFIGS
from subprocess import (
check_output,
CalledProcessError,
)
def get_action_parser(actions_yaml_path, action_name,
get_services=services):
@ -73,9 +82,32 @@ def resume(args):
assess_status(CONFIGS, args.services)
def diskusage(args):
"""Runs 'swift-recon -d' and returns values in GB.
@raises CalledProcessError on check_output failure
@raises Exception on any other failure
"""
try:
raw_output = check_output(['swift-recon', '-d'])
recon_result = list(line.strip().split(' ')
for line in raw_output.splitlines()
if 'Disk' in line)
for line in recon_result:
if 'space' in line:
line[4] = str(int(line[4]) / 1024 / 1024 / 1024) + 'GB'
line[6] = str(int(line[6]) / 1024 / 1024 / 1024) + 'GB'
result = [' '.join(x) for x in recon_result]
action_set({'output': result})
except CalledProcessError as e:
action_set({'output': e.output})
action_fail('Failed to run swift-recon -d')
except:
raise
# A dictionary of all the defined actions to callables (which take
# parsed arguments).
ACTIONS = {"pause": pause, "resume": resume}
ACTIONS = {"pause": pause, "resume": resume, 'diskusage': diskusage}
def main(argv):

1
actions/diskusage Symbolic link
View File

@ -0,0 +1 @@
actions.py

View File

@ -755,3 +755,11 @@ class SwiftProxyBasicDeployment(OpenStackAmuletDeployment):
u.log.debug('Checking pause/resume actions...')
self._test_pause()
self._test_resume()
def test_903_disk_usage_action(self):
"""diskusage action can be run"""
u.log.info("Testing diskusage action")
action_id = u.run_action(self.swift_proxy_sentry, "diskusage")
assert u.wait_on_action(action_id), "diskusage action failed."
u.log.info('OK')

View File

@ -247,3 +247,66 @@ class AddUserTestCase(CharmTestCase):
self.action_fail.assert_called_once_with(
'Adding user test failed with: ""')
class DiskUsageTestCase(CharmTestCase):
TEST_RECON_OUTPUT = '===================================================' \
'============================\n--> Starting ' \
'reconnaissance on 9 hosts\n========================' \
'===================================================' \
'====\n[2017-11-03 21:50:30] Checking disk usage now' \
'\nDistribution Graph:\n 40% 108 ******************' \
'***************************************************' \
'\n 41% 15 *********\n 42% 50 ******************' \
'*************\n 43% 5 ***\n 44% 1 \n 45% ' \
'1 \nDisk usage: space used: 89358060716032 of ' \
'215829411840000\nDisk usage: space free: ' \
'126471351123968 of 215829411840000\nDisk usage: ' \
'lowest: 40.64%, highest: 45.63%, avg: ' \
'41.4021703318%\n===================================' \
'============================================\n'
TEST_RESULT = ['Disk usage: space used: 83221GB of 201006GB',
'Disk usage: space free: 117785GB of 201006GB',
'Disk usage: lowest: 40.64%, highest: 45.63%, avg: '
'41.4021703318%']
def setUp(self):
super(DiskUsageTestCase, self).setUp(
actions.actions, ["check_output", "action_set", "action_fail"])
def test_success(self):
"""Ensure that the action_set is called on success."""
self.check_output.return_value = 'Swift recon ran OK'
actions.actions.diskusage([])
self.check_output.assert_called_once_with(['swift-recon', '-d'])
self.action_set.assert_called()
self.action_fail.not_called()
def test_check_output_failure(self):
"""Ensure that action_fail and action_set are called on
check_output failure."""
self.check_output.side_effect = actions.actions.CalledProcessError(
1, "Failure")
actions.actions.diskusage([])
self.check_output.assert_called_once_with(['swift-recon', '-d'])
self.action_set.assert_called()
self.action_fail.assert_called()
def test_failure(self):
"""Ensure that action_fail is called on any other failure."""
self.check_output.side_effect = Exception("Failure")
with self.assertRaises(Exception):
actions.actions.diskusage([])
self.check_output.assert_called_once_with(['swift-recon', '-d'])
def test_recon_result(self):
"""Ensure the data ultimately returned is the right format
"""
self.check_output.return_value = self.TEST_RECON_OUTPUT
actions.actions.diskusage([])
self.action_set.assert_called_once_with({'output': self.TEST_RESULT})