From 9d91c7d1fea223b778c740c0d0f6d1a799f7b50d Mon Sep 17 00:00:00 2001 From: Liam Young Date: Tue, 12 Jan 2021 08:03:24 +0000 Subject: [PATCH] Add support for Trilio 4.1 Change-Id: Ic2870144f1e64b1f3c51f8ec9180a77008b1b145 --- src/lib/charm/openstack/dmapi.py | 56 ++++++++++++++++++++++++++----- src/reactive/dmapi_handlers.py | 15 +++++++++ src/templates/dmapi.conf | 5 +++ src/tests/tests.yaml | 5 ++- unit_tests/test_dmapi_handlers.py | 8 +++-- 5 files changed, 77 insertions(+), 12 deletions(-) diff --git a/src/lib/charm/openstack/dmapi.py b/src/lib/charm/openstack/dmapi.py index a1a2d9b..b7205d5 100644 --- a/src/lib/charm/openstack/dmapi.py +++ b/src/lib/charm/openstack/dmapi.py @@ -16,6 +16,7 @@ import os import charms_openstack.adapters as adapters import charms_openstack.ip as os_ip import charms_openstack.plugins as plugins +import charmhelpers.contrib.openstack.utils as os_utils import charmhelpers.contrib.openstack.utils as ch_utils import charmhelpers.core.hookenv as hookenv @@ -23,6 +24,8 @@ import charmhelpers.core.hookenv as hookenv DMAPI_DIR = "/etc/dmapi" DMAPI_CONF = os.path.join(DMAPI_DIR, "dmapi.conf") +plugins.trilio.make_trilio_handlers() + class DmapiDBAdapter(adapters.DatabaseRelationAdapter): """Get database URIs for the two nova databases""" @@ -37,6 +40,11 @@ class DmapiDBAdapter(adapters.DatabaseRelationAdapter): """URI for nova_api DB""" return self.get_uri(prefix="dmapinovaapi") + @property + def dmapi_uri(self): + """URI for dmapi DB""" + return self.get_uri(prefix="dmapi") + class DmapiAdapters(adapters.OpenStackAPIRelationAdapters): """ @@ -59,6 +67,7 @@ class DmapiCharm(plugins.TrilioVaultCharm): # First release supported release = "queens" + trilio_release = "4.0" # Init services the charm manages services = ["tvault-datamover-api"] @@ -102,15 +111,18 @@ class DmapiCharm(plugins.TrilioVaultCharm): "python3-dmapi": collections.OrderedDict( [("3", "stein"), ("4", "train")] ), + "nova-common": os_utils.PACKAGE_CODENAMES["nova-common"], } + os_release_pkg = 'nova-common' + 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") + release = ch_utils.os_release("nova-common") super(DmapiCharm, self).__init__(release=release, **kwargs) def get_amqp_credentials(self): @@ -124,6 +136,11 @@ class DmapiCharm(plugins.TrilioVaultCharm): "username": "nova", "prefix": "dmapinovaapi", }, + { + "database": "dmapi", + "username": "dmapi", + "prefix": "dmapi", + }, ] @property @@ -138,18 +155,39 @@ class DmapiCharm(plugins.TrilioVaultCharm): def internal_url(self): return "{}/v2".format(super().internal_url) + @classmethod + def trilio_version_package(cls): + pkg = "dmapi" + if hookenv.config("python-version") == 3: + pkg = "python3-dmapi" + return pkg + @property def packages(self): if hookenv.config("python-version") == 3: return ["python3-nova", "python3-dmapi"] return ["python-nova", "dmapi"] - @property - def version_package(self): - if hookenv.config("python-version") == 3: - return "python3-dmapi" - return "dmapi" - @property - def release_pkg(self): - return self.version_package +class DmapiCharmQueens41(DmapiCharm): + + # First release supported + release = "queens" + trilio_release = "4.1" + sync_cmd = ['dmapi-dbsync'] + + def __init__(self, release=None, **kwargs): + """Custom initialiser for class + """ + if release is None: + release = ch_utils.os_release("python-keystonemiddleware") + super().__init__(release=release, **kwargs) + + def get_database_setup(self): + return [ + { + "database": "dmapi", + "username": "dmapi", + "prefix": "dmapi", + }, + ] diff --git a/src/reactive/dmapi_handlers.py b/src/reactive/dmapi_handlers.py index 933de52..7aafcf1 100644 --- a/src/reactive/dmapi_handlers.py +++ b/src/reactive/dmapi_handlers.py @@ -30,6 +30,7 @@ charm.use_defaults( ) +@reactive.when("dmapi-db.ready") @reactive.when("shared-db.available") @reactive.when("identity-service.available") @reactive.when("amqp.available") @@ -39,6 +40,7 @@ def render_config(*args): """ with charm.provide_charm_instance() as charm_class: charm_class.upgrade_if_available(args) + with charm.provide_charm_instance() as charm_class: charm_class.render_with_interfaces(args) charm_class.assess_status() reactive.set_state("config.rendered") @@ -59,6 +61,19 @@ def cluster_connected(hacluster): charm_class.assess_status() +@reactive.when("shared-db.available") +@reactive.when_not("dmapi-db.ready") +def check_dmapi_db(): + db_ep = reactive.endpoint_from_flag('shared-db.available') + if db_ep: + if db_ep.password(prefix='dmapi'): + reactive.set_state("dmapi-db.ready") + else: + with charm.provide_charm_instance() as instance: + for db in instance.get_database_setup(): + db_ep.configure(**db) + + @reactive.when_any("config.changed.triliovault-pkg-source", "config.changed.openstack-origin") def install_source_changed(): diff --git a/src/templates/dmapi.conf b/src/templates/dmapi.conf index 99e78e2..9eccd8a 100644 --- a/src/templates/dmapi.conf +++ b/src/templates/dmapi.conf @@ -21,11 +21,16 @@ ssl_cert_file = {{ amqp.ssl_cert_file }} ssl_key_file = {{ amqp.ssl_key_file }} api_paste_config = /etc/dmapi/api-paste.ini +{% if options.trilio_properties.db_type == "legacy" %} [database] connection = {{ shared_db.dmapi_nova_uri }} [api_database] connection = {{ shared_db.dmapi_nova_api_uri }} +{% else %} +[database] +connection = {{ shared_db.dmapi_uri }} +{% endif %} {% include "parts/section-keystone-authtoken" %} region_name = {{ options.region }} diff --git a/src/tests/tests.yaml b/src/tests/tests.yaml index f129239..a48c353 100644 --- a/src/tests/tests.yaml +++ b/src/tests/tests.yaml @@ -27,10 +27,13 @@ target_deploy_status: workload-status-message: "Monitor bootstrapped but waiting for number of OSDs to reach expected-osd-count (3)" cinder-ceph: workload-status: waiting - workload-status-message: "Incomplete relations: ceph" + workload-status-message: "Ceph broker request incomplete" trilio-wlm: workload-status: blocked workload-status-message: "nfs-shares configuration not set" trilio-data-mover: workload-status: blocked workload-status-message: "nfs-shares configuration not set" + glance: + workload-status: waiting + workload-status-message: "Incomplete relations: storage-backend" diff --git a/unit_tests/test_dmapi_handlers.py b/unit_tests/test_dmapi_handlers.py index 0ec9b93..c99ce93 100644 --- a/unit_tests/test_dmapi_handlers.py +++ b/unit_tests/test_dmapi_handlers.py @@ -106,18 +106,22 @@ class TestDmapiHandlers(test_utils.PatchHelper): when_patterns = { "render_config": ( "shared-db.available", + "dmapi-db.ready", "identity-service.available", "amqp.available", ), "init_db": ("config.rendered",), "cluster_connected": ("ha.connected",), + "check_dmapi_db": ("shared-db.available",), + } + when_not_patterns = { + "check_dmapi_db": ("dmapi-db.ready",), } - when_not_patterns = {} when_any_patterns = { "install_source_changed": ( "config.changed.triliovault-pkg-source", "config.changed.openstack-origin" - ) + ), } # check the when hooks are attached to the expected functions for t, p in [