Run aodh-api under mod_wsgi with apache2

This change aligns with the Ocata aodh package, which has
moved the aodh-api to run under mod_wsgi with apache2.

Change-Id: I4aa6a978eb719c955ad216326514d1175c86b4a7
This commit is contained in:
Corey Bryant 2017-01-06 20:48:01 +00:00
parent c8895a9ca5
commit ac1a668492
6 changed files with 124 additions and 63 deletions

View File

@ -3,3 +3,4 @@ options:
basic:
use_venv: True
include_system_packages: True
repo: https://github.com/openstack/charm-aodh

View File

@ -16,7 +16,6 @@ import collections
import os
import subprocess
import charmhelpers.contrib.openstack.utils as ch_utils
import charmhelpers.core.host as ch_host
import charms_openstack.charm
@ -28,6 +27,10 @@ AODH_CONF = os.path.join(AODH_DIR, 'aodh.conf')
AODH_API_SYSTEMD_CONF = (
'/etc/systemd/system/aodh-api.service.d/override.conf'
)
AODH_WSGI_CONF = '/etc/apache2/sites-available/aodh-api.conf'
charms_openstack.charm.use_defaults('charm.default-select-release')
class AodhAdapters(charms_openstack.adapters.OpenStackAPIRelationAdapters):
@ -105,14 +108,41 @@ class AodhCharm(charms_openstack.charm.HAOpenStackCharm):
]),
}
def __init__(self, release=None, **kwargs):
"""Custom initialiser for class
If no release is passed, then the charm determines the release from the
ch_utils.os_release() function.
"""
if release is None:
release = ch_utils.os_release('python-keystonemiddleware')
super(AodhCharm, self).__init__(release=release, **kwargs)
@staticmethod
def reload_and_restart():
if ch_host.init_is_systemd():
subprocess.check_call(['systemctl', 'daemon-reload'])
ch_host.service_restart('aodh-api')
class AodhCharmOcata(AodhCharm):
"""From ocata onwards there is no aodh-api service, as this is handled via
apache2 with a wsgi handler. Therefore, these specialisations are simple
to switch out the aodh-api.
"""
# This charms support Ocata and onward
release = 'ocata'
# Init services the charm manages
# Ocata onwards uses apache2 rather than aodh-api
services = ['aodh-evaluator', 'aodh-notifier',
'aodh-listener', 'apache2']
# The restart map defines which services should be restarted when a given
# file changes
# Ocata onwards doesn't require aodh-api and the AODH_API_SYSTEMD_CONF
# file.
restart_map = {
AODH_CONF: services,
AODH_WSGI_CONF: services,
}
@staticmethod
def reload_and_restart():
if ch_host.init_is_systemd():
subprocess.check_call(['systemctl', 'daemon-reload'])
# no need to restart aodh-api in ocata and onwards
def install():
@ -182,10 +212,7 @@ def upgrade_if_available(interfaces_list):
AodhCharm.singleton.upgrade_if_available(interfaces_list)
# TODO: drop once charm switches to apache+mod_wsgi
def reload_and_restart():
"""Reload systemd and restart aodh-api when override file changes
"""Reload systemd and restart aodh API when override file changes
"""
if ch_host.init_is_systemd():
subprocess.check_call(['systemctl', 'daemon-reload'])
ch_host.service_restart('aodh-api')
AodhCharm.singleton.reload_and_restart()

View File

@ -1,5 +1,6 @@
name: aodh
summary: OpenStack Telemetry - Alarming service
maintainer: OpenStack Charmers <openstack-charmers@lists.ubuntu.com>
description: |
Ceilometer aims to deliver a Single Point Of Contact for billing systems,
providing all the counters they need to establish customer billing, across
@ -9,10 +10,13 @@ description: |
overall system.
.
Aodh provides the Alarming service as part of OpenStack telemetry.
tags:
- openstack
series:
- xenial
- trusty
- yakkety
subordinate: false
requires:
mongodb:
interface: mongodb

View File

@ -0,0 +1,13 @@
Listen {{ options.service_listen_info.aodh_api.public_port }}
<VirtualHost *:{{ options.service_listen_info.aodh_api.public_port }}>
WSGIDaemonProcess aodh-api user=aodh group=aodh processes=2 threads=10 display-name=%{GROUP}
WSGIProcessGroup aodh-api
WSGIScriptAlias / /usr/share/aodh/app.wsgi
WSGIApplicationGroup %{GLOBAL}
<IfVersion >= 2.4>
ErrorLogFormat "%{cu}t %M"
</IfVersion>
ErrorLog /var/log/apache2/aodh_error.log
CustomLog /var/log/apache2/aodh_access.log combined
</VirtualHost>

View File

@ -157,11 +157,11 @@ class AodhBasicDeployment(OpenStackAmuletDeployment):
service units."""
u.log.debug('Checking system services on units...')
aodh_svcs = [
'aodh-api', 'aodh-evaluator',
'aodh-notifier', 'aodh-listener'
]
aodh_svcs = ['aodh-evaluator', 'aodh-notifier', 'aodh-listener']
if self._get_openstack_release() >= self.xenial_ocata:
aodh_svcs.append('apache2')
else:
aodh_svcs.append('aodh-api')
if self._get_openstack_release() < self.trusty_mitaka:
aodh_svcs.append('aodh-alarm-evaluator')
aodh_svcs.append('aodh-alarm-notifier')
@ -333,7 +333,14 @@ class AodhBasicDeployment(OpenStackAmuletDeployment):
# Services which are expected to restart upon config change,
# and corresponding config files affected by the change
conf_file = '/etc/aodh/aodh.conf'
if self._get_openstack_release() >= self.xenial_newton:
if self._get_openstack_release() >= self.xenial_ocata:
services = {
'apache2': conf_file,
'aodh-evaluator - AlarmEvaluationService(0)': conf_file,
'aodh-notifier - AlarmNotifierService(0)': conf_file,
'aodh-listener - EventAlarmEvaluationService(0)': conf_file,
}
elif self._get_openstack_release() >= self.xenial_newton:
services = {
('/usr/bin/python /usr/bin/aodh-api --port 8032 -- '
'--config-file=/etc/aodh/aodh.conf '

View File

@ -15,53 +15,38 @@
from __future__ import absolute_import
from __future__ import print_function
import unittest
import mock
import charm.openstack.aodh as aodh
import charms_openstack.test_utils as test_utils
class Helper(unittest.TestCase):
class Helper(test_utils.PatchHelper):
def setUp(self):
self._patches = {}
self._patches_start = {}
def tearDown(self):
for k, v in self._patches.items():
v.stop()
setattr(self, k, None)
self._patches = None
self._patches_start = None
def patch(self, obj, attr, return_value=None, **kwargs):
mocked = mock.patch.object(obj, attr, **kwargs)
self._patches[attr] = mocked
started = mocked.start()
started.return_value = return_value
self._patches_start[attr] = started
setattr(self, attr, started)
super().setUp()
self.patch_release(aodh.AodhCharm.release)
class TestOpenStackAodh(Helper):
def test_install(self):
self.patch(aodh.AodhCharm.singleton, 'install')
self.patch_object(aodh.AodhCharm.singleton, 'install')
aodh.install()
self.install.assert_called_once_with()
def test_setup_endpoint(self):
self.patch(aodh.AodhCharm, 'service_name',
new_callable=mock.PropertyMock)
self.patch(aodh.AodhCharm, 'region',
new_callable=mock.PropertyMock)
self.patch(aodh.AodhCharm, 'public_url',
new_callable=mock.PropertyMock)
self.patch(aodh.AodhCharm, 'internal_url',
new_callable=mock.PropertyMock)
self.patch(aodh.AodhCharm, 'admin_url',
new_callable=mock.PropertyMock)
self.patch_object(aodh.AodhCharm, 'service_name',
new_callable=mock.PropertyMock)
self.patch_object(aodh.AodhCharm, 'region',
new_callable=mock.PropertyMock)
self.patch_object(aodh.AodhCharm, 'public_url',
new_callable=mock.PropertyMock)
self.patch_object(aodh.AodhCharm, 'internal_url',
new_callable=mock.PropertyMock)
self.patch_object(aodh.AodhCharm, 'admin_url',
new_callable=mock.PropertyMock)
self.service_name.return_value = 'type1'
self.region.return_value = 'region1'
self.public_url.return_value = 'public_url'
@ -73,7 +58,7 @@ class TestOpenStackAodh(Helper):
'type1', 'region1', 'public_url', 'internal_url', 'admin_url')
def test_render_configs(self):
self.patch(aodh.AodhCharm.singleton, 'render_with_interfaces')
self.patch_object(aodh.AodhCharm.singleton, 'render_with_interfaces')
aodh.render_configs('interfaces-list')
self.render_with_interfaces.assert_called_once_with(
'interfaces-list')
@ -87,8 +72,9 @@ class TestAodhAdapters(Helper):
'keystone-api-version': '2',
}
config.side_effect = lambda: reply
self.patch(aodh.charms_openstack.adapters.APIConfigurationAdapter,
'get_network_addresses')
self.patch_object(
aodh.charms_openstack.adapters.APIConfigurationAdapter,
'get_network_addresses')
cluster_relation = mock.MagicMock()
cluster_relation.relation_name = 'cluster'
amqp_relation = mock.MagicMock()
@ -116,17 +102,40 @@ class TestAodhAdapters(Helper):
class TestAodhCharm(Helper):
def test__init__(self):
self.patch(aodh.ch_utils, 'os_release')
aodh.AodhCharm()
self.os_release.assert_called_once_with('python-keystonemiddleware')
def test_install(self):
b = aodh.AodhCharm()
self.patch(aodh.charms_openstack.charm.OpenStackCharm,
'configure_source')
self.patch(aodh.charms_openstack.charm.OpenStackCharm,
'install')
self.patch_object(aodh.charms_openstack.charm.OpenStackCharm,
'configure_source')
self.patch_object(aodh.charms_openstack.charm.OpenStackCharm,
'install')
b.install()
self.configure_source.assert_called_once_with()
self.install.assert_called_once_with()
def test_reload_and_restart(self):
self.patch('subprocess.check_call', name='check_call')
self.patch_object(aodh.ch_host, 'service_restart')
self.patch_object(aodh.ch_host, 'init_is_systemd', return_value=False)
aodh.AodhCharm.reload_and_restart()
self.init_is_systemd.assert_called_once_with()
self.check_call.assert_not_called()
self.service_restart.assert_not_called()
# now say it is systemd.
self.init_is_systemd.return_value = True
aodh.AodhCharm.reload_and_restart()
self.check_call.assert_called_once_with(['systemctl', 'daemon-reload'])
self.service_restart.assert_called_once_with('aodh-api')
class TestAodhCharmOcata(Helper):
def test_reload_and_restart(self):
self.patch('subprocess.check_call', name='check_call')
self.patch_object(aodh.ch_host, 'init_is_systemd', return_value=False)
aodh.AodhCharmOcata.reload_and_restart()
self.init_is_systemd.assert_called_once_with()
self.check_call.assert_not_called()
# now say it is systemd.
self.init_is_systemd.return_value = True
aodh.AodhCharmOcata.reload_and_restart()
self.check_call.assert_called_once_with(['systemctl', 'daemon-reload'])