Add get-quorum-status action
Adds a new get-quorum-status action to return some distilled info from 'ceph quorum_status', primarily for verification of which mon units are online. Partial-Bug: #1917690 Change-Id: I608832d849ee3e4f5d150082c328b63c6ab43de7
This commit is contained in:

committed by
Robert Gildein

parent
ab0ccb2450
commit
282e23416f
10
actions.yaml
10
actions.yaml
@@ -395,3 +395,13 @@ change-osd-weight:
|
|||||||
required:
|
required:
|
||||||
- osd
|
- osd
|
||||||
- weight
|
- weight
|
||||||
|
get-quorum-status:
|
||||||
|
description: "Return lists of the known mons, and online mons, to determine if there is quorum."
|
||||||
|
params:
|
||||||
|
format:
|
||||||
|
type: string
|
||||||
|
default: text
|
||||||
|
enum:
|
||||||
|
- text
|
||||||
|
- json
|
||||||
|
description: Specify output format (text|json).
|
||||||
|
@@ -12,12 +12,16 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import json
|
||||||
from subprocess import CalledProcessError, check_output
|
from subprocess import CalledProcessError, check_output
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
sys.path.append('hooks')
|
sys.path.append('hooks')
|
||||||
|
|
||||||
from charmhelpers.core.hookenv import action_get, action_fail
|
from charmhelpers.core.hookenv import (
|
||||||
|
action_get,
|
||||||
|
action_fail,
|
||||||
|
)
|
||||||
from charmhelpers.contrib.storage.linux.ceph import pool_set, \
|
from charmhelpers.contrib.storage.linux.ceph import pool_set, \
|
||||||
set_pool_quota, snapshot_pool, remove_pool_snapshot
|
set_pool_quota, snapshot_pool, remove_pool_snapshot
|
||||||
|
|
||||||
@@ -143,3 +147,26 @@ def snapshot_ceph_pool():
|
|||||||
snapshot_pool(service='ceph',
|
snapshot_pool(service='ceph',
|
||||||
pool_name=pool_name,
|
pool_name=pool_name,
|
||||||
snapshot_name=snapshot_name)
|
snapshot_name=snapshot_name)
|
||||||
|
|
||||||
|
|
||||||
|
def get_quorum_status(format_type="text"):
|
||||||
|
"""
|
||||||
|
Return the output of 'ceph quorum_status'.
|
||||||
|
|
||||||
|
On error, function_fail() is called with the exception info.
|
||||||
|
"""
|
||||||
|
ceph_output = check_output(['ceph', 'quorum_status'],
|
||||||
|
timeout=60).decode("utf-8")
|
||||||
|
ceph_output_json = json.loads(ceph_output)
|
||||||
|
|
||||||
|
if format_type == "json":
|
||||||
|
return {"message": json.dumps(ceph_output_json)}
|
||||||
|
else:
|
||||||
|
return {
|
||||||
|
"election-epoch": ceph_output_json.get("election_epoch"),
|
||||||
|
"quorum-age": ceph_output_json.get("quorum_age"),
|
||||||
|
"quorum-leader-name": ceph_output_json.get("quorum_leader_name",
|
||||||
|
"unknown"),
|
||||||
|
"quorum-names": ", ".join(ceph_output_json.get("quorum_names",
|
||||||
|
[])),
|
||||||
|
}
|
||||||
|
1
actions/get-quorum-status
Symbolic link
1
actions/get-quorum-status
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
get_quorum_status.py
|
37
actions/get_quorum_status.py
Executable file
37
actions/get_quorum_status.py
Executable file
@@ -0,0 +1,37 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# Copyright 2021 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.
|
||||||
|
|
||||||
|
"""Run action to collect Ceph quorum_status output."""
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from subprocess import CalledProcessError
|
||||||
|
|
||||||
|
sys.path.append('hooks')
|
||||||
|
|
||||||
|
from ceph_ops import get_quorum_status
|
||||||
|
from charmhelpers.core.hookenv import function_fail, function_get, function_set
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
"""Run action to collect Ceph quorum_status output."""
|
||||||
|
try:
|
||||||
|
function_set(get_quorum_status(function_get("format")))
|
||||||
|
except CalledProcessError as error:
|
||||||
|
function_fail("Failed to run ceph quorum_status, {}".format(error))
|
||||||
|
except (json.decoder.JSONDecodeErro, KeyError) as error:
|
||||||
|
function_fail(
|
||||||
|
"Failed to parse ceph quorum_status output. {}".format(error)
|
||||||
|
)
|
@@ -10,9 +10,9 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
import json
|
||||||
from mock import mock
|
|
||||||
import sys
|
import sys
|
||||||
|
from mock import mock
|
||||||
|
|
||||||
from test_utils import CharmTestCase
|
from test_utils import CharmTestCase
|
||||||
|
|
||||||
@@ -52,3 +52,44 @@ class OpsTestCase(CharmTestCase):
|
|||||||
actions.get_health()
|
actions.get_health()
|
||||||
cmd = ['ceph', 'health']
|
cmd = ['ceph', 'health']
|
||||||
self.check_output.assert_called_once_with(cmd)
|
self.check_output.assert_called_once_with(cmd)
|
||||||
|
|
||||||
|
@mock.patch('socket.gethostname')
|
||||||
|
def test_get_quorum_status(self, mock_hostname):
|
||||||
|
mock_hostname.return_value = 'mockhost'
|
||||||
|
cmd_out = (
|
||||||
|
'{"election_epoch":4,"quorum":[0,1,2],"quorum_names":["juju-18410c'
|
||||||
|
'-zaza-b7061340ed19-1","juju-18410c-zaza-b7061340ed19-0","juju-184'
|
||||||
|
'10c-zaza-b7061340ed19-2"],"quorum_leader_name":"juju-18410c-zaza-'
|
||||||
|
'b7061340ed19-1","quorum_age":97785,"monmap":{"epoch":1,"fsid":"4f'
|
||||||
|
'9dd22a-1b71-11ec-a02a-fa163ee765d3","modified":"2021-09-22 06:51:'
|
||||||
|
'10.975225","created":"2021-09-22 06:51:10.975225","min_mon_releas'
|
||||||
|
'e":14,"min_mon_release_name":"nautilus","features":{"persistent":'
|
||||||
|
'["kraken","luminous","mimic","osdmap-prune","nautilus"],"optional'
|
||||||
|
'":[]},"mons":[{"rank":0,"name":"juju-18410c-zaza-b7061340ed19-1",'
|
||||||
|
'"public_addrs":{"addrvec":[{"type":"v2","addr":"10.5.0.122:3300",'
|
||||||
|
'"nonce":0},{"type":"v1","addr":"10.5.0.122:6789","nonce":0}]},"ad'
|
||||||
|
'dr":"10.5.0.122:6789/0","public_addr":"10.5.0.122:6789/0"},{"rank'
|
||||||
|
'":1,"name":"juju-18410c-zaza-b7061340ed19-0","public_addrs":{"add'
|
||||||
|
'rvec":[{"type":"v2","addr":"10.5.2.239:3300","nonce":0},{"type":"'
|
||||||
|
'v1","addr":"10.5.2.239:6789","nonce":0}]},"addr":"10.5.2.239:6789'
|
||||||
|
'/0","public_addr":"10.5.2.239:6789/0"},{"rank":2,"name":"juju-184'
|
||||||
|
'10c-zaza-b7061340ed19-2","public_addrs":{"addrvec":[{"type":"v2",'
|
||||||
|
'"addr":"10.5.3.201:3300","nonce":0},{"type":"v1","addr":"10.5.3.2'
|
||||||
|
'01:6789","nonce":0}]},"addr":"10.5.3.201:6789/0","public_addr":"1'
|
||||||
|
'0.5.3.201:6789/0"}]}}'
|
||||||
|
)
|
||||||
|
self.check_output.return_value = cmd_out.encode()
|
||||||
|
|
||||||
|
result = actions.get_quorum_status()
|
||||||
|
self.assertDictEqual(result, {
|
||||||
|
"election-epoch": 4,
|
||||||
|
"quorum-age": 97785,
|
||||||
|
"quorum-names": "juju-18410c-zaza-b7061340ed19-1, "
|
||||||
|
"juju-18410c-zaza-b7061340ed19-0, "
|
||||||
|
"juju-18410c-zaza-b7061340ed19-2",
|
||||||
|
"quorum-leader-name": "juju-18410c-zaza-b7061340ed19-1",
|
||||||
|
})
|
||||||
|
|
||||||
|
result = actions.get_quorum_status(format_type="json")
|
||||||
|
self.assertDictEqual(json.loads(result["message"]),
|
||||||
|
json.loads(cmd_out))
|
||||||
|
Reference in New Issue
Block a user