service: updates nova-api-os-compute service to use apache wsgi

Due to an issue in python3 oslo_cache+eventlet when using
memcached. As workaroud for Rocky it has been decided to run service
nova-api-os-compute from systemd to apache2.

Closes-Bug: #1812672
Depends-On: https://review.openstack.org/#/c/633218
Depends-On: https://review.openstack.org/#/c/633482
Change-Id: I3bf279638c5decf1020345f3d2e876e379144997
Signed-off-by: Sahid Orentino Ferdjaoui <sahid.ferdjaoui@canonical.com>
This commit is contained in:
Sahid Orentino Ferdjaoui 2019-01-28 11:37:40 +01:00 committed by Corey Bryant
parent fc68571c51
commit 13eca55803
7 changed files with 106 additions and 19 deletions

View File

@ -219,6 +219,15 @@ class PlacementAPIHAProxyContext(HAProxyContext):
return ctxt
class ComputeAPIHAProxyContext(HAProxyContext):
"""Context for the nova os compute api service."""
def __call__(self):
ctxt = super(ComputeAPIHAProxyContext, self).__call__()
ctxt['port'] = ctxt['listen_ports']['osapi_compute_listen_port']
return ctxt
class MetaDataHAProxyContext(HAProxyContext):
"""Context for the nova metadata service."""

View File

@ -192,8 +192,8 @@ def install():
ch_fetch.apt_update()
ch_fetch.apt_install(ncc_utils.determine_packages(), fatal=True)
if ncc_utils.placement_api_enabled():
ncc_utils.disable_package_apache_site()
ncc_utils.disable_package_apache_site()
ncc_utils.stop_deprecated_services()
_files = os.path.join(hookenv.charm_dir(), 'files')
if os.path.isdir(_files):
@ -902,6 +902,7 @@ def upgrade_charm():
# charm only we need ensure to not end-up with the old
# 'wsgi-openstack-api' and the new 'wsgi-placement-api' apache
# configurations installed at the same time.
ncc_utils.stop_deprecated_services()
ncc_utils.disable_package_apache_site(service_reload=True)
for r_id in hookenv.relation_ids('amqp'):

View File

@ -113,6 +113,10 @@ OLD_WSGI_NOVA_PLACEMENT_API_CONF = \
'/etc/apache2/sites-enabled/wsgi-openstack-api.conf'
WSGI_NOVA_METADATA_API_CONF = \
'/etc/apache2/sites-enabled/wsgi-openstack-metadata.conf'
PACKAGE_NOVA_API_OS_COMPUTE_CONF = \
'/etc/apache2/sites-available/nova-api-os-compute.conf'
WSGI_NOVA_API_OS_COMPUTE_CONF = \
'/etc/apache2/sites-enabled/wsgi-api-os-compute.conf'
VENDORDATA_FILE = '/etc/nova/vendor_data.json'
@ -216,6 +220,26 @@ SERIAL_CONSOLE = {
}
def _replace_service_with_apache2(service, wsgi_script, wsgi_config,
resource_map, context):
for cfile in resource_map:
svcs = resource_map[cfile]['services']
if service in svcs:
svcs.remove(service)
if 'apache2' not in svcs:
svcs.append('apache2')
resource_map[wsgi_config] = {
'contexts': [
ch_context.WSGIWorkerConfigContext(
name=service,
script=wsgi_script,
user='nova',
group='nova'
),
context],
'services': ['apache2']}
def resource_map(actual_services=True):
'''
Dynamically generate a map of resources that will be managed for a single
@ -273,24 +297,24 @@ def resource_map(actual_services=True):
'contexts': [ch_context.MemcacheContext()],
'services': ['memcached']}
if (actual_services and
ch_utils.CompareOpenStackReleases(release) >= 'rocky'):
# For Rocky we decided to switch from systemd to use apache2
# wsgi mod for the service nova-api-os-compute.
_replace_service_with_apache2(
'nova-api-os-compute',
'/usr/bin/nova-api-wsgi',
WSGI_NOVA_API_OS_COMPUTE_CONF,
_resource_map,
nova_cc_context.ComputeAPIHAProxyContext())
if actual_services and placement_api_enabled():
for cfile in _resource_map:
svcs = _resource_map[cfile]['services']
if 'nova-placement-api' in svcs:
svcs.remove('nova-placement-api')
if 'apache2' not in svcs:
svcs.append('apache2')
wsgi_script = "/usr/bin/nova-placement-api"
_resource_map[WSGI_NOVA_PLACEMENT_API_CONF] = {
'contexts': [
ch_context.WSGIWorkerConfigContext(
name="nova_placement",
user="nova",
group="nova",
script=wsgi_script),
nova_cc_context.PlacementAPIHAProxyContext()],
'services': ['apache2']
}
_replace_service_with_apache2(
'nova-placement-api',
'/usr/bin/nova-placement-api',
WSGI_NOVA_PLACEMENT_API_CONF,
_resource_map,
nova_cc_context.PlacementAPIHAProxyContext())
elif not placement_api_enabled():
for cfile in _resource_map:
svcs = _resource_map[cfile]['services']
@ -570,6 +594,7 @@ def _do_openstack_upgrade(new_src):
disable_package_apache_site()
disable_policy_rcd()
stop_deprecated_services()
# NOTE(jamespage) upgrade with existing config files as the
# havana->icehouse migration enables new service_plugins which
@ -1480,11 +1505,27 @@ def disable_package_apache_site(service_reload=False):
# "file" that is not symlink from sites-available.
os.remove(OLD_WSGI_NOVA_PLACEMENT_API_CONF)
site_changed = True
if os.path.exists(PACKAGE_NOVA_API_OS_COMPUTE_CONF):
# Even if using systemd or apache for the service we want
# remove the conf created by the package installed if exists
subprocess.check_call(['a2dissite', 'nova-api-os-compute'])
site_changed = True
if site_changed and service_reload:
ch_host.service_reload('apache2', restart_on_failure=True)
def stop_deprecated_services():
"""Stop services that are not used anymore.
Note: It may be important to also disable the service, see:
resource_map.
"""
release = ch_utils.os_release('nova-common')
if ch_utils.CompareOpenStackReleases(release) >= 'rocky':
ch_host.service_pause('nova-api-os-compute')
def get_shared_metadatasecret():
"""Return the shared metadata secret."""
return hookenv.leader_get(SHARED_METADATA_SECRET_KEY)

View File

@ -0,0 +1 @@
../charmhelpers/contrib/openstack/templates/wsgi-openstack-api.conf

View File

@ -81,6 +81,8 @@ class NovaCCBasicDeployment(OpenStackAmuletDeployment):
)
if cmp_os_release >= 'newton':
services.remove('nova-cert')
if cmp_os_release >= 'rocky':
services.remove('nova-api-os-compute')
u.get_unit_process_ids(
{self.nova_cc_sentry: services},
expect_success=should_run)
@ -325,6 +327,10 @@ class NovaCCBasicDeployment(OpenStackAmuletDeployment):
services[self.nova_compute_sentry].remove('nova-network')
services[self.nova_compute_sentry].remove('nova-api')
if self._get_openstack_release() >= self.bionic_rocky:
services[self.nova_cc_sentry].remove('nova-api-os-compute')
services[self.nova_cc_sentry].append('apache2')
ret = u.validate_services_by_name(services)
if ret:
amulet.raise_status(amulet.FAIL, msg=ret)
@ -819,6 +825,10 @@ class NovaCCBasicDeployment(OpenStackAmuletDeployment):
if cmp_os_release >= 'newton':
del services['nova-cert']
if cmp_os_release >= 'rocky':
del services['nova-api-os-compute']
services['apache2'] = conf_file
if self._get_openstack_release() >= self.xenial_ocata:
# nova-placement-api is run under apache2 with mod_wsgi
services['apache2'] = conf_file

View File

@ -111,6 +111,7 @@ class NovaCCHooksTests(CharmTestCase):
super(NovaCCHooksTests, self).tearDown()
def test_install_hook(self):
self.os_release.return_value = 'rocky'
self.determine_packages.return_value = [
'nova-scheduler', 'nova-api-ec2']
self.determine_ports.return_value = [80, 81, 82]

View File

@ -153,6 +153,17 @@ RESTART_MAP_OCATA_BASE = OrderedDict([
('/etc/haproxy/haproxy.cfg', ['haproxy']),
('/etc/apache2/sites-available/openstack_https_frontend', ['apache2'])
])
RESTART_MAP_ROCKY_ACTUAL = OrderedDict([
('/etc/nova/nova.conf', [
'nova-scheduler', 'nova-conductor', 'apache2',
]),
('/etc/nova/api-paste.ini', ['apache2']),
('/etc/haproxy/haproxy.cfg', ['haproxy']),
('/etc/apache2/sites-available/openstack_https_frontend', ['apache2']),
('/etc/apache2/sites-enabled/wsgi-api-os-compute.conf', ['apache2']),
('/etc/apache2/sites-enabled/wsgi-placement-api.conf', ['apache2']),
('/etc/apache2/sites-enabled/wsgi-openstack-metadata.conf', ['apache2']),
])
DPKG_OPTS = [
@ -352,6 +363,19 @@ class NovaCCUtilsTests(CharmTestCase):
self.assertIsInstance(_map, OrderedDict)
self.assertEqual(_map, RESTART_MAP_OCATA_ACTUAL)
@patch('charmhelpers.contrib.openstack.neutron.os_release')
@patch('os.path.exists')
@patch('charmhelpers.contrib.openstack.context.SubordinateConfigContext')
def test_restart_map_api_actual_rocky(
self, subcontext, _exists, _os_release):
_os_release.return_value = 'rocky'
self.os_release.return_value = 'rocky'
_exists.return_value = False
self.enable_memcache.return_value = False
_map = utils.restart_map()
self.assertIsInstance(_map, OrderedDict)
self.assertEqual(_map, RESTART_MAP_ROCKY_ACTUAL)
@patch('charmhelpers.contrib.openstack.neutron.os_release')
@patch('os.path.exists')
@patch('charmhelpers.contrib.openstack.context.SubordinateConfigContext')