Ensure API not configured on volume-only units

COMMON_PACKAGES included haproxy and apache2. However, enabled-services
can request a unit to only run cinder-volume. Cinder API related
services should not run or get monitored.

func-test-pr: https://github.com/openstack-charmers/zaza-openstack-tests/pull/337

Change-Id: I69f15c3fd164f7114f5498d100b2832caf93fb00
Closes-Bug: #1779310
This commit is contained in:
Alvaro Uria 2020-06-26 15:38:40 +02:00
parent e5a0b4196a
commit 71f968faf1
5 changed files with 388 additions and 42 deletions

View File

@ -116,6 +116,8 @@ from charmhelpers.contrib.storage.linux.ceph import (
delete_keyring,
)
from charmhelpers.contrib.hahelpers.apache import install_ca_cert
from charmhelpers.contrib.hahelpers.cluster import (
is_clustered,
is_elected_leader,
@ -168,13 +170,15 @@ def install():
apt_update()
apt_install(determine_packages(), fatal=True)
if run_in_apache():
disable_package_apache_site()
# call the policy overrides handler which will install any policy overrides
maybe_do_policyd_overrides(
os_release('cinder-common'),
'cinder',
restart_handler=lambda: service_restart('cinder-api'))
if service_enabled('api'):
if run_in_apache():
disable_package_apache_site()
# call the policy overrides handler which will install any policy
# overrides
maybe_do_policyd_overrides(
os_release('cinder-common'),
'cinder',
restart_handler=lambda: service_restart('cinder-api'))
@hooks.hook('config-changed')
@ -220,9 +224,10 @@ def config_changed():
service_restart('cinder-volume')
CONFIGS.write_all()
configure_https()
if service_enabled('api'):
configure_https()
open_port(config('api-listening-port'))
update_nrpe_config()
open_port(config('api-listening-port'))
for rid in relation_ids('cluster'):
cluster_joined(relation_id=rid)
@ -236,11 +241,13 @@ def config_changed():
for rid in relation_ids('identity-service'):
identity_joined(rid=rid)
# call the policy overrides handler which will install any policy overrides
maybe_do_policyd_overrides_on_config_changed(
os_release('cinder-common'),
'cinder',
restart_handler=lambda: service_restart('cinder-api'))
if service_enabled('api'):
# call the policy overrides handler which will install any policy
# overrides
maybe_do_policyd_overrides_on_config_changed(
os_release('cinder-common'),
'cinder',
restart_handler=lambda: service_restart('cinder-api'))
@hooks.hook('storage.real')
@ -436,8 +443,9 @@ def identity_changed():
if 'identity-service' not in CONFIGS.complete_contexts():
juju_log('identity-service relation incomplete. Peer not ready?')
return
CONFIGS.write(CINDER_API_CONF)
configure_https()
if service_enabled('api'):
CONFIGS.write(CINDER_API_CONF)
configure_https()
@hooks.hook('ceph-relation-joined')
@ -602,11 +610,14 @@ def upgrade_charm():
juju_log("Package purge detected, restarting services")
for s in services():
service_restart(s)
# call the policy overrides handler which will install any policy overrides
maybe_do_policyd_overrides(
os_release('cinder-common'),
'cinder',
restart_handler=lambda: service_restart('cinder-api'))
if service_enabled('api'):
# call the policy overrides handler which will install any policy
# overrides
maybe_do_policyd_overrides(
os_release('cinder-common'),
'cinder',
restart_handler=lambda: service_restart('cinder-api'))
@hooks.hook('storage-backend-relation-changed')
@ -633,7 +644,11 @@ def update_nrpe_config():
nrpe_setup = nrpe.NRPE(hostname=hostname)
nrpe.copy_nrpe_checks()
nrpe.add_init_service_checks(nrpe_setup, services(), current_unit)
nrpe.add_haproxy_checks(nrpe_setup, current_unit)
if service_enabled('api'):
nrpe.add_haproxy_checks(nrpe_setup, current_unit)
else:
nrpe.remove_deprecated_check(nrpe_setup,
["haproxy_servers", "haproxy_queue"])
nrpe_setup.write()
@ -653,6 +668,13 @@ def certs_joined(relation_id=None):
@hooks.hook('certificates-relation-changed')
@restart_on_change(restart_map())
def certs_changed(relation_id=None, unit=None):
if not service_enabled('api'):
# Install CA cert to communicate with Keystone and Glance
data = relation_get(rid=relation_id, unit=unit)
ca = data.get('ca')
if ca:
install_ca_cert(ca.encode())
return
process_certificates('cinder', relation_id, unit)
configure_https()

View File

@ -118,10 +118,8 @@ import cinder_contexts
from cinder_contexts import ceph_config_file
COMMON_PACKAGES = [
'apache2',
'cinder-common',
'gdisk',
'haproxy',
'librbd1', # bug 1440948 vol-from-img
'python-jinja2',
'python-keystoneclient',
@ -137,10 +135,15 @@ PY3_PACKAGES = [
'python3-memcache',
'python3-rados',
'python3-rbd',
'libapache2-mod-wsgi-py3',
]
API_PACKAGES = ['cinder-api']
PY3_API_PACKAGES = ['libapache2-mod-wsgi-py3']
API_PACKAGES = [
'apache2',
'cinder-api',
'haproxy',
]
VOLUME_PACKAGES = ['cinder-volume']
SCHEDULER_PACKAGES = ['cinder-scheduler']
@ -156,6 +159,7 @@ CINDER_DB_INIT_ECHO_RKEY = 'cinder-db-initialised-echo'
class CinderCharmError(Exception):
pass
CINDER_CONF_DIR = "/etc/cinder"
CINDER_CONF = '%s/cinder.conf' % CINDER_CONF_DIR
CINDER_API_CONF = '%s/api-paste.ini' % CINDER_CONF_DIR
@ -320,7 +324,18 @@ def resource_map(release=None):
'contexts': [context.MemcacheContext()],
'services': ['memcached']}
if run_in_apache():
if not service_enabled('api'):
# haproxy and apache2 are related to cinder-api
cfg_files = {
CINDER_API_CONF,
HAPROXY_CONF,
APACHE_SITE_CONF,
APACHE_SITE_24_CONF,
APACHE_PORTS_CONF,
}
for cfg in cfg_files.intersection(resource_map.keys()):
resource_map.pop(cfg)
elif run_in_apache():
for cfile in resource_map:
svcs = resource_map[cfile]['services']
if 'cinder-api' in svcs:
@ -347,9 +362,13 @@ def filter_services(svcs):
@param svcs: List of services
@returns : List of enabled services
'''
deps = {
'haproxy': 'api',
'apache2': 'api',
}
return [s for s in svcs
if service_enabled(s.lstrip('cinder-')) or
not s.startswith('cinder')]
(deps.get(s) and service_enabled(deps[s]))]
def juju_log(msg):
@ -373,6 +392,8 @@ def determine_packages():
if CompareOpenStackReleases(os_release('cinder')) >= 'rocky':
pkgs = [p for p in pkgs if not p.startswith('python-')]
pkgs.extend(PY3_PACKAGES)
if service_enabled('api'):
pkgs.extend(PY3_API_PACKAGES)
return pkgs
@ -798,7 +819,7 @@ def do_openstack_upgrade(configs=None):
configs.set_release(openstack_release=new_os_rel)
configs.write_all()
if run_in_apache():
if service_enabled('api') and run_in_apache():
disable_package_apache_site()
# Stop/start services and migrate DB if leader

View File

@ -0,0 +1,293 @@
variables:
openstack-origin: &openstack-origin distro
series: focal
comment:
- 'machines section to decide order of deployment. database sooner = faster'
machines:
'0':
constraints: mem=3072M
'1':
constraints: mem=3072M
'2':
constraints: mem=3072M
'3':
'4':
'5':
'6':
'7':
'8':
'9':
'10':
'11':
'12':
'13':
'14':
applications:
nova-cloud-controller-mysql-router:
charm: cs:~openstack-charmers-next/mysql-router
placement-mysql-router:
charm: cs:~openstack-charmers-next/mysql-router
keystone-mysql-router:
charm: cs:~openstack-charmers-next/mysql-router
glance-mysql-router:
charm: cs:~openstack-charmers-next/mysql-router
neutron-api-mysql-router:
charm: cs:~openstack-charmers-next/mysql-router
cinder-mysql-router:
charm: cs:~openstack-charmers-next/mysql-router
mysql-innodb-cluster:
charm: cs:~openstack-charmers-next/mysql-innodb-cluster
num_units: 3
options:
source: *openstack-origin
to:
- '0'
- '1'
- '2'
rabbitmq-server:
charm: cs:~openstack-charmers-next/rabbitmq-server
num_units: 1
options:
source: *openstack-origin
to:
- '3'
nova-cloud-controller:
charm: cs:~openstack-charmers-next/nova-cloud-controller
num_units: 1
options:
network-manager: Neutron
debug: true
openstack-origin: *openstack-origin
to:
- '4'
placement:
charm: cs:~openstack-charmers-next/placement
num_units: 1
constraints: mem=1G
options:
openstack-origin: *openstack-origin
to:
- '5'
neutron-api:
charm: cs:~openstack-charmers-next/neutron-api
num_units: 1
options:
flat-network-providers: physnet1
neutron-security-groups: true
manage-neutron-plugin-legacy-mode: true
openstack-origin: *openstack-origin
to:
- '6'
keystone:
charm: cs:~openstack-charmers-next/keystone
num_units: 1
options:
openstack-origin: *openstack-origin
to:
- '7'
neutron-gateway:
charm: cs:~openstack-charmers-next/neutron-gateway
num_units: 1
options:
bridge-mappings: physnet1:br-ex
openstack-origin: *openstack-origin
to:
- '8'
glance:
charm: cs:~openstack-charmers-next/glance
num_units: 1
options:
openstack-origin: *openstack-origin
to:
- '9'
neutron-openvswitch:
charm: cs:~openstack-charmers-next/neutron-openvswitch
nova-compute:
charm: cs:~openstack-charmers-next/nova-compute
num_units: 1
constraints: mem=4G cores=4
storage:
ephemeral-device: '10G'
options:
config-flags: auto_assign_floating_ip=False
enable-live-migration: false
aa-profile-mode: enforce
#ephemeral-device: /dev/vdb
#ephemeral-unmount: /mnt
debug: true
openstack-origin: *openstack-origin
to:
- '10'
cinder:
num_units: 1
options:
openstack-origin: *openstack-origin
glance-api-version: 2
enabled-services: 'api,scheduler'
to:
- '11'
cinder-volume:
charm: ../../.
num_units: 2
storage:
block-devices: '40G'
options:
openstack-origin: *openstack-origin
glance-api-version: 2
block-device: None
overwrite: "true"
enabled-services: 'volume'
to:
- '12'
- '13'
vault-mysql-router:
charm: cs:~openstack-charmers-next/mysql-router
vault:
charm: cs:~openstack-charmers-next/vault
num_units: 1
to:
- '14'
relations:
- - 'nova-compute:image-service'
- 'glance:image-service'
- - 'nova-compute:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-cloud-controller:shared-db'
- 'nova-cloud-controller-mysql-router:shared-db'
- - 'nova-cloud-controller-mysql-router:db-router'
- 'mysql-innodb-cluster:db-router'
- - 'nova-cloud-controller:identity-service'
- 'keystone:identity-service'
- - 'nova-cloud-controller:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-cloud-controller:cloud-compute'
- 'nova-compute:cloud-compute'
- - 'nova-cloud-controller:image-service'
- 'glance:image-service'
- - 'placement:shared-db'
- 'placement-mysql-router:shared-db'
- - 'placement-mysql-router:db-router'
- 'mysql-innodb-cluster:db-router'
- - 'placement:identity-service'
- 'keystone:identity-service'
- - 'placement:placement'
- 'nova-cloud-controller:placement'
- - 'keystone:shared-db'
- 'keystone-mysql-router:shared-db'
- - 'keystone-mysql-router:db-router'
- 'mysql-innodb-cluster:db-router'
- - 'glance:identity-service'
- 'keystone:identity-service'
- - 'glance:shared-db'
- 'glance-mysql-router:shared-db'
- - 'glance-mysql-router:db-router'
- 'mysql-innodb-cluster:db-router'
- - 'glance:amqp'
- 'rabbitmq-server:amqp'
- - 'neutron-gateway:amqp'
- 'rabbitmq-server:amqp'
- - 'nova-cloud-controller:quantum-network-service'
- 'neutron-gateway:quantum-network-service'
- - 'neutron-api:shared-db'
- 'neutron-api-mysql-router:shared-db'
- - 'neutron-api-mysql-router:db-router'
- 'mysql-innodb-cluster:db-router'
- - 'neutron-api:amqp'
- 'rabbitmq-server:amqp'
- - 'neutron-api:neutron-api'
- 'nova-cloud-controller:neutron-api'
- - 'neutron-api:identity-service'
- 'keystone:identity-service'
- - 'nova-compute:neutron-plugin'
- 'neutron-openvswitch:neutron-plugin'
- - 'rabbitmq-server:amqp'
- 'neutron-openvswitch:amqp'
- - 'cinder:shared-db'
- 'cinder-mysql-router:shared-db'
- - 'cinder-mysql-router:db-router'
- 'mysql-innodb-cluster:db-router'
- - 'cinder:identity-service'
- 'keystone:identity-service'
- - 'cinder:amqp'
- 'rabbitmq-server:amqp'
- - 'cinder:image-service'
- 'glance:image-service'
- - 'cinder-volume:identity-service'
- 'keystone:identity-service'
- - 'cinder-volume:amqp'
- 'rabbitmq-server:amqp'
- - 'cinder-volume:image-service'
- 'glance:image-service'
- - 'cinder-volume:shared-db'
- 'cinder-mysql-router:shared-db'
- - 'vault-mysql-router:db-router'
- 'mysql-innodb-cluster:db-router'
- - 'vault:shared-db'
- 'vault-mysql-router:shared-db'
- - 'nova-cloud-controller:certificates'
- 'vault:certificates'
- - 'neutron-api:certificates'
- 'vault:certificates'
- - 'keystone:certificates'
- 'vault:certificates'
- - 'glance:certificates'
- 'vault:certificates'
- - 'cinder:certificates'
- 'vault:certificates'
- - 'cinder-volume:certificates'
- 'vault:certificates'

View File

@ -3,6 +3,7 @@ smoke_bundles:
- bionic-train
gate_bundles:
- focal-ussuri
- vault: focal-ussuri-volume-only
- bionic-ussuri
- bionic-train
- bionic-stein
@ -15,6 +16,10 @@ gate_bundles:
- trusty-mitaka
dev_bundles:
- focal-ussuri
target_deploy_status:
vault:
workload-status: blocked
workload-status-message: Vault needs to be initialized
configure:
- zaza.openstack.charm_tests.glance.setup.add_cirros_image
- zaza.openstack.charm_tests.glance.setup.add_lts_image
@ -22,6 +27,8 @@ configure:
- zaza.openstack.charm_tests.neutron.setup.basic_overcloud_network
- zaza.openstack.charm_tests.nova.setup.create_flavors
- zaza.openstack.charm_tests.nova.setup.manage_ssh_key
- vault:
- zaza.openstack.charm_tests.vault.setup.auto_initialize
tests:
- zaza.openstack.charm_tests.cinder.tests.CinderTests
- zaza.openstack.charm_tests.cinder.tests.SecurityTests
@ -29,5 +36,3 @@ tests:
tests_options:
policyd:
service: cinder
force_deploy:
- focal-ussuri

View File

@ -164,7 +164,8 @@ class TestCinderUtils(CharmTestCase):
cinder_utils.VOLUME_PACKAGES +
cinder_utils.API_PACKAGES +
cinder_utils.SCHEDULER_PACKAGES +
cinder_utils.PY3_PACKAGES))
cinder_utils.PY3_PACKAGES +
cinder_utils.PY3_API_PACKAGES))
@patch('cinder_utils.service_enabled')
def test_determine_packages_subset(self, service_enabled):
@ -236,12 +237,8 @@ class TestCinderUtils(CharmTestCase):
self.ceph_config_file.return_value = self.charm_ceph_conf
self.relation_ids.return_value = []
ex_map = OrderedDict([
('/etc/cinder/cinder.conf', ['cinder-volume', 'cinder-scheduler',
'haproxy']),
('/etc/cinder/api-paste.ini', []),
('/etc/haproxy/haproxy.cfg', ['haproxy']),
('/etc/apache2/sites-available/openstack_https_frontend.conf',
['apache2']),
('/etc/cinder/cinder.conf', ['cinder-volume',
'cinder-scheduler']),
])
for cfg in ex_map.keys():
self.assertEqual(cinder_utils.resource_map()[cfg]['services'],
@ -355,7 +352,7 @@ class TestCinderUtils(CharmTestCase):
self.assertEqual(
cinder_utils.filter_services(['cinder-api', 'cinder-volume',
'haproxy']),
['cinder-volume', 'haproxy']
['cinder-volume']
)
@patch('cinder_utils.service_enabled')
@ -763,12 +760,13 @@ class TestCinderUtils(CharmTestCase):
out.write('env CEPH_ARGS="--id %s"\n' % service)
"""
@patch.object(cinder_utils, 'service_enabled')
@patch.object(cinder_utils, 'register_configs')
@patch.object(cinder_utils, 'services')
@patch.object(cinder_utils, 'migrate_database')
@patch.object(cinder_utils, 'determine_packages')
def test_openstack_upgrade_leader(self, pkgs, migrate, services,
mock_register_configs):
mock_register_configs, service_enabled):
pkgs.return_value = ['mypackage']
self.os_release.return_value = 'havana'
self.config.side_effect = None
@ -777,6 +775,7 @@ class TestCinderUtils(CharmTestCase):
self.is_elected_leader.return_value = True
self.get_os_codename_install_source.return_value = 'havana'
configs = mock_register_configs.return_value
service_enabled.return_value = True
cinder_utils.do_openstack_upgrade(configs)
self.assertTrue(mock_register_configs.called)
self.assertTrue(configs.write_all.called)
@ -786,12 +785,14 @@ class TestCinderUtils(CharmTestCase):
configs.set_release.assert_called_with(openstack_release='havana')
self.assertTrue(migrate.called)
@patch.object(cinder_utils, 'service_enabled')
@patch.object(cinder_utils, 'register_configs')
@patch.object(cinder_utils, 'services')
@patch.object(cinder_utils, 'migrate_database')
@patch.object(cinder_utils, 'determine_packages')
def test_openstack_upgrade_not_leader(self, pkgs, migrate, services,
mock_register_configs):
mock_register_configs,
service_enabled):
pkgs.return_value = ['mypackage']
self.os_release.return_value = 'havana'
self.config.side_effect = None
@ -800,6 +801,7 @@ class TestCinderUtils(CharmTestCase):
self.is_elected_leader.return_value = False
self.get_os_codename_install_source.return_value = 'havana'
configs = mock_register_configs.return_value
service_enabled.return_value = True
cinder_utils.do_openstack_upgrade(configs)
self.assertTrue(mock_register_configs.called)
self.assertTrue(configs.write_all.called)
@ -809,12 +811,14 @@ class TestCinderUtils(CharmTestCase):
configs.set_release.assert_called_with(openstack_release='havana')
self.assertFalse(migrate.called)
@patch.object(cinder_utils, 'service_enabled')
@patch.object(cinder_utils, 'register_configs')
@patch.object(cinder_utils, 'services')
@patch.object(cinder_utils, 'migrate_database')
@patch.object(cinder_utils, 'determine_packages')
def test_openstack_upgrade_rocky(self, pkgs, migrate, services,
mock_register_configs):
mock_register_configs,
service_enabled):
pkgs.return_value = ['mypackage']
self.os_release.return_value = 'rocky'
self.config.side_effect = None
@ -823,6 +827,7 @@ class TestCinderUtils(CharmTestCase):
self.is_elected_leader.return_value = True
self.get_os_codename_install_source.return_value = 'rocky'
configs = mock_register_configs.return_value
service_enabled.return_value = True
self.filter_missing_packages.return_value = [
'python-cinder',
]