Add get-health action to the Ceph mon charm
* get-health - outputs `ceph health` output Including unit and functional tests for the above actions. Change-Id: Id4c0a89f2068a6f30025d4a165f84ad112b62cf7 Closes-Bug: #1720099
This commit is contained in:
parent
91d6885e50
commit
001ac4786f
@ -2,6 +2,8 @@ pause-health:
|
||||
description: Pause ceph health operations across the entire ceph cluster
|
||||
resume-health:
|
||||
description: Resume ceph health operations across the entire ceph cluster
|
||||
get-health:
|
||||
description: Output the current cluster health reported by `ceph health`
|
||||
create-cache-tier:
|
||||
description: Create a new cache tier
|
||||
params:
|
||||
|
@ -13,11 +13,11 @@
|
||||
# limitations under the License.
|
||||
|
||||
from subprocess import CalledProcessError, check_output
|
||||
import rados
|
||||
import sys
|
||||
|
||||
sys.path.append('hooks')
|
||||
|
||||
import rados
|
||||
from charmhelpers.core.hookenv import log, action_get, action_fail
|
||||
from charmhelpers.contrib.storage.linux.ceph import pool_set, \
|
||||
set_pool_quota, snapshot_pool, remove_pool_snapshot
|
||||
@ -25,6 +25,7 @@ from charmhelpers.contrib.storage.linux.ceph import pool_set, \
|
||||
|
||||
# Connect to Ceph via Librados and return a connection
|
||||
def connect():
|
||||
"""Creates a connection to Ceph using librados."""
|
||||
try:
|
||||
cluster = rados.Rados(conffile='/etc/ceph/ceph.conf')
|
||||
cluster.connect()
|
||||
@ -38,11 +39,13 @@ def connect():
|
||||
|
||||
|
||||
def create_crush_rule():
|
||||
"""Stub function."""
|
||||
# Shell out
|
||||
pass
|
||||
|
||||
|
||||
def list_pools():
|
||||
"""Return a list of all Ceph pools."""
|
||||
try:
|
||||
cluster = connect()
|
||||
pool_list = cluster.list_pools()
|
||||
@ -56,7 +59,31 @@ def list_pools():
|
||||
action_fail(str(e))
|
||||
|
||||
|
||||
def get_health():
|
||||
"""
|
||||
Returns the output of 'ceph health'.
|
||||
|
||||
On error, 'unknown' is returned.
|
||||
"""
|
||||
try:
|
||||
value = check_output(['ceph', 'health'])
|
||||
return value
|
||||
except CalledProcessError as e:
|
||||
action_fail(e.message)
|
||||
return 'Getting health failed, health unknown'
|
||||
|
||||
|
||||
def pool_get():
|
||||
"""
|
||||
Returns a key from a pool using 'ceph osd pool get'.
|
||||
|
||||
The key is provided via the 'key' action parameter and the
|
||||
pool provided by the 'pool_name' parameter. These are used when
|
||||
running 'ceph osd pool get <pool_name> <key>', the result of
|
||||
which is returned.
|
||||
|
||||
On failure, 'unknown' will be returned.
|
||||
"""
|
||||
key = action_get("key")
|
||||
pool_name = action_get("pool_name")
|
||||
try:
|
||||
@ -65,9 +92,18 @@ def pool_get():
|
||||
return value
|
||||
except CalledProcessError as e:
|
||||
action_fail(str(e))
|
||||
return 'unknown'
|
||||
|
||||
|
||||
def set_pool():
|
||||
"""
|
||||
Sets an arbitrary key key in a Ceph pool.
|
||||
|
||||
Sets the key specified by the action parameter 'key' to the value
|
||||
specified in the action parameter 'value' for the pool specified
|
||||
by the action parameter 'pool_name' using the charmhelpers
|
||||
'pool_set' function.
|
||||
"""
|
||||
key = action_get("key")
|
||||
value = action_get("value")
|
||||
pool_name = action_get("pool_name")
|
||||
@ -75,6 +111,11 @@ def set_pool():
|
||||
|
||||
|
||||
def pool_stats():
|
||||
"""
|
||||
Returns statistics for a pool.
|
||||
|
||||
The pool name is provided by the action parameter 'pool-name'.
|
||||
"""
|
||||
try:
|
||||
pool_name = action_get("pool-name")
|
||||
cluster = connect()
|
||||
@ -93,6 +134,13 @@ def pool_stats():
|
||||
|
||||
|
||||
def delete_pool_snapshot():
|
||||
"""
|
||||
Delete a pool snapshot.
|
||||
|
||||
Deletes a snapshot from the pool provided by the action
|
||||
parameter 'pool-name', with the snapshot name provided by
|
||||
action parameter 'snapshot-name'
|
||||
"""
|
||||
pool_name = action_get("pool-name")
|
||||
snapshot_name = action_get("snapshot-name")
|
||||
remove_pool_snapshot(service='ceph',
|
||||
@ -102,6 +150,13 @@ def delete_pool_snapshot():
|
||||
|
||||
# Note only one or the other can be set
|
||||
def set_pool_max_bytes():
|
||||
"""
|
||||
Sets the max bytes quota for a pool.
|
||||
|
||||
Sets the pool quota maximum bytes for the pool specified by
|
||||
the action parameter 'pool-name' to the value specified by
|
||||
the action parameter 'max'
|
||||
"""
|
||||
pool_name = action_get("pool-name")
|
||||
max_bytes = action_get("max")
|
||||
set_pool_quota(service='ceph',
|
||||
@ -110,6 +165,13 @@ def set_pool_max_bytes():
|
||||
|
||||
|
||||
def snapshot_ceph_pool():
|
||||
"""
|
||||
Snapshots a Ceph pool.
|
||||
|
||||
Snapshots the pool provided in action parameter 'pool-name' and
|
||||
uses the parameter provided in the action parameter 'snapshot-name'
|
||||
as the name for the snapshot.
|
||||
"""
|
||||
pool_name = action_get("pool-name")
|
||||
snapshot_name = action_get("snapshot-name")
|
||||
snapshot_pool(service='ceph',
|
||||
|
6
actions/get-health
Executable file
6
actions/get-health
Executable file
@ -0,0 +1,6 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
from ceph_ops import get_health
|
||||
|
||||
if __name__ == '__main__':
|
||||
get_health()
|
@ -708,6 +708,14 @@ class CephBasicDeployment(OpenStackAmuletDeployment):
|
||||
if ret:
|
||||
amulet.raise_status(amulet.FAIL, msg=ret)
|
||||
|
||||
def test_414_get_health_action(self):
|
||||
"""Verify that getting health works"""
|
||||
u.log.debug("Testing get-health")
|
||||
|
||||
sentry_unit = self.ceph0_sentry
|
||||
action_id = u.run_action(sentry_unit, 'get-health')
|
||||
assert u.wait_on_action(action_id), "HEALTH_OK"
|
||||
|
||||
def test_499_ceph_cmds_exit_zero(self):
|
||||
"""Check basic functionality of ceph cli commands against
|
||||
all ceph units."""
|
||||
|
@ -16,3 +16,4 @@ import sys
|
||||
sys.path.append('hooks')
|
||||
sys.path.append('lib')
|
||||
sys.path.append('unit_tests')
|
||||
sys.path.append('actions')
|
||||
|
54
unit_tests/test_actions_mon.py
Normal file
54
unit_tests/test_actions_mon.py
Normal file
@ -0,0 +1,54 @@
|
||||
# Copyright 2016 Canonical Ltd
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from mock import mock
|
||||
import sys
|
||||
|
||||
from test_utils import CharmTestCase
|
||||
|
||||
# python-apt is not installed as part of test-requirements but is imported by
|
||||
# some charmhelpers modules so create a fake import.
|
||||
mock_apt = mock.MagicMock()
|
||||
sys.modules['apt'] = mock_apt
|
||||
mock_apt.apt_pkg = mock.MagicMock()
|
||||
|
||||
# mocking for rados
|
||||
mock_rados = mock.MagicMock()
|
||||
sys.modules['rados'] = mock_rados
|
||||
mock_rados.connect = mock.MagicMock()
|
||||
|
||||
# mocking for psutil
|
||||
mock_psutil = mock.MagicMock()
|
||||
sys.modules['psutil'] = mock_psutil
|
||||
mock_psutil.disks = mock.MagicMock()
|
||||
|
||||
with mock.patch('charmhelpers.contrib.hardening.harden.harden') as mock_dec:
|
||||
mock_dec.side_effect = (lambda *dargs, **dkwargs: lambda f:
|
||||
lambda *args, **kwargs: f(*args, **kwargs))
|
||||
# import health actions as actions
|
||||
import ceph_ops as actions
|
||||
|
||||
|
||||
class OpsTestCase(CharmTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(OpsTestCase, self).setUp(
|
||||
actions, ["check_output",
|
||||
"action_get",
|
||||
"action_fail",
|
||||
"open"])
|
||||
|
||||
def test_get_health(self):
|
||||
actions.get_health()
|
||||
cmd = ['ceph', 'health']
|
||||
self.check_output.assert_called_once_with(cmd)
|
Loading…
Reference in New Issue
Block a user