Status blocked until ceilometer-upgrade action

Currently it is unclear that ceilometer is not actually ready when it
is related to gnocchi until the ceilometer-upgrade action has run. The
status will show active Unit is ready when it is not.

When gnocchi is related, check that the ceilometer-upgrade action has
been run. If not set workload status to prompt the administator to run
the action.

Please merge the charm-helpers change first:
https://github.com/juju/charm-helpers/pull/270

Partial-Bug: #1811108
Change-Id: Id778ed3f59e4bcde9c6586aad46be2b5b9ccb531
This commit is contained in:
David Ames 2019-01-29 23:16:23 +00:00
parent 36b8e9a8bd
commit e2ca8f06de
5 changed files with 95 additions and 8 deletions

View File

@ -22,6 +22,7 @@ from charmhelpers.core.hookenv import (
action_set,
)
from ceilometer_utils import (
assess_status,
ceilometer_upgrade_helper,
pause_unit_helper,
register_configs,
@ -59,6 +60,7 @@ def ceilometer_upgrade(args):
if e.trace:
action_set({'traceback': e.trace})
raise Exception(str(e.message))
assess_status(register_configs())
# A dictionary of all the defined actions to callables (which take

View File

@ -83,7 +83,8 @@ from charmhelpers.fetch import (
add_source as fetch_add_source,
SourceConfigError,
GPGKeyError,
get_upstream_version
get_upstream_version,
filter_missing_packages
)
from charmhelpers.fetch.snap import (
@ -309,6 +310,15 @@ def error_out(msg):
sys.exit(1)
def get_installed_semantic_versioned_packages():
'''Get a list of installed packages which have OpenStack semantic versioning
:returns List of installed packages
:rtype: [pkg1, pkg2, ...]
'''
return filter_missing_packages(PACKAGE_CODENAMES.keys())
def get_os_codename_install_source(src):
'''Derive OpenStack release codename from a given installation source.'''
ubuntu_rel = lsb_release()['DISTRIB_CODENAME']
@ -972,7 +982,9 @@ def _ows_check_charm_func(state, message, charm_func_with_configs):
"""
if charm_func_with_configs:
charm_state, charm_message = charm_func_with_configs()
if charm_state != 'active' and charm_state != 'unknown':
if (charm_state != 'active' and
charm_state != 'unknown' and
charm_state is not None):
state = workload_state_compare(state, charm_state)
if message:
charm_message = charm_message.replace("Incomplete relations: ",

View File

@ -19,6 +19,8 @@ import traceback
from collections import OrderedDict
from charmhelpers.core.unitdata import kv
from charmhelpers.contrib.openstack import (
templating,
context,
@ -75,6 +77,7 @@ POLLING_CONF = "%s/polling.yaml" % CEILOMETER_CONF_DIR
CEILOMETER_API_SYSTEMD_CONF = (
'/etc/systemd/system/ceilometer-api.service.d/override.conf'
)
CEILOMETER_UPGRADED = "ceilometer-upgrade-run"
HTTPS_APACHE_CONF = "/etc/apache2/sites-available/openstack_https_frontend"
HTTPS_APACHE_24_CONF = "/etc/apache2/sites-available/" \
"openstack_https_frontend.conf"
@ -545,6 +548,7 @@ def assess_status_func(configs):
"""
return make_assess_status_func(
configs, resolve_required_interfaces(),
charm_func=check_ceilometer_upgraded,
services=services(), ports=determine_ports())
@ -655,6 +659,10 @@ def ceilometer_upgrade_helper(CONFIGS):
'unexpected error: {}'.format(e.message),
outcome='ceilometer-upgrade failed, see traceback.',
trace=traceback.format_exc())
kvstore = kv()
if not kvstore.get(CEILOMETER_UPGRADED, False):
kvstore.set(key=CEILOMETER_UPGRADED, value=True)
kvstore.flush()
def ceilometer_upgrade(action=False):
@ -669,3 +677,25 @@ def ceilometer_upgrade(action=False):
log("Running ceilomter-upgrade: {}".format(" ".join(cmd)), DEBUG)
subprocess.check_call(cmd)
log("ceilometer-upgrade succeeded", DEBUG)
def check_ceilometer_upgraded(configs):
"""Assess status check if ceilometer-upgrade action has run
When related to gnocchi check that the ceilometer-upgrade action has been
run. Set blocked when action run is still required. Set None None when no
action is required.
:param configs: The charms main OSConfigRenderer object.
:return: str, str tuple or None, None
"""
if relation_ids("metric-service"):
kvstore = kv()
if not kvstore.get(CEILOMETER_UPGRADED, False):
log("Action ceilometer-upgrade not yet run, setting status "
"blocked")
return "blocked", ("Run the ceilometer-upgrade action to "
"initialize ceilometer and gnocchi")
# Avoid changing status check
return None, None

View File

@ -45,8 +45,12 @@ class CeilometerBasicDeployment(OpenStackAmuletDeployment):
self._deploy()
u.log.info('Waiting on extended status checks...')
exclude_services = ['mongodb', 'memcached']
self._auto_wait_for_status(exclude_services=exclude_services)
self.exclude_services = ['mongodb', 'memcached']
if self._get_openstack_release() >= self.xenial_pike:
# Ceilometer will come up blocked until the ceilometer-upgrade
# action is run
self.exclude_services.append("ceilometer")
self._auto_wait_for_status(exclude_services=self.exclude_services)
self.d.sentry.wait()
self._initialize_tests()
@ -163,6 +167,7 @@ class CeilometerBasicDeployment(OpenStackAmuletDeployment):
self.nova_sentry = self.d.sentry['nova-compute'][0]
if self._get_openstack_release() >= self.xenial_pike:
self.gnocchi_sentry = self.d.sentry['gnocchi'][0]
self.run_ceilometer_upgrade_action()
else:
self.mongodb_sentry = self.d.sentry['mongodb'][0]
u.log.debug('openstack release val: {}'.format(
@ -681,8 +686,13 @@ class CeilometerBasicDeployment(OpenStackAmuletDeployment):
assert u.status_get(unit)[0] == "active"
u.log.debug('OK')
def test_920_ceilometer_upgrade(self):
"""Run ceilometer-upgrade"""
def run_ceilometer_upgrade_action(self):
"""Run ceilometer-upgrade
This action will be run early to initialize ceilometer
when gnocchi is related.
Ceilometer will be in a blocked state until this runs.
"""
if self._get_openstack_release() < self.xenial_pike:
u.log.debug('Not checking ceilometer-upgrade')
return
@ -691,4 +701,7 @@ class CeilometerBasicDeployment(OpenStackAmuletDeployment):
action_id = unit.run_action("ceilometer-upgrade")
assert u.wait_on_action(action_id), "ceilometer-upgrade action failed"
# Wait for acivte Unit is ready on ceilometer
self.exclude_services.remove('ceilometer')
self._auto_wait_for_status(exclude_services=self.exclude_services)
u.log.debug('OK')

View File

@ -270,6 +270,7 @@ class CeilometerUtilsTest(CharmTestCase):
utils.VERSION_PACKAGE
)
@patch.object(utils, 'check_ceilometer_upgraded')
@patch.object(utils, 'resolve_required_interfaces')
@patch.object(utils, 'services')
@patch.object(utils, 'determine_ports')
@ -278,13 +279,16 @@ class CeilometerUtilsTest(CharmTestCase):
make_assess_status_func,
determine_ports,
services,
resolve_required_interfaces):
resolve_required_interfaces,
check_ceilometer_upgraded):
check_ceilometer_upgraded.return_value = None, None
services.return_value = 's1'
determine_ports.return_value = 'p1'
resolve_required_interfaces.return_value = {'a': ['b']}
utils.assess_status_func('test-config')
make_assess_status_func.assert_called_once_with(
'test-config', {'a': ['b']}, services='s1', ports='p1')
'test-config', {'a': ['b']}, charm_func=check_ceilometer_upgraded,
services='s1', ports='p1')
def test_pause_unit_helper(self):
with patch.object(utils, '_pause_resume_helper') as prh:
@ -433,3 +437,29 @@ class CeilometerUtilsTest(CharmTestCase):
with self.assertRaises(utils.FailedAction):
utils.ceilometer_upgrade_helper(self.CONFIGS)
mock_ceilometer_upgrade.assert_called_once_with(action=True)
@patch.object(utils, 'kv')
def test_check_ceilometer_upgraded(self, mock_kv):
self.CONFIGS = MagicMock()
_kv = MagicMock()
mock_kv.return_value = _kv
# Not related
self.relation_ids.return_value = []
self.assertEqual(
(None, None),
utils.check_ceilometer_upgraded(self.CONFIGS))
# Related not ready
self.relation_ids.return_value = ['metric:1']
_kv.get.return_value = False
self.assertEqual(
("blocked", "Run the ceilometer-upgrade action to initialize "
"ceilometer and gnocchi"),
utils.check_ceilometer_upgraded(self.CONFIGS))
# Related ready
_kv.get.return_value = True
self.assertEqual(
(None, None),
utils.check_ceilometer_upgraded(self.CONFIGS))