From 6caa776748834452a2131e84e1873054ba8514a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20C=2E=20Mass=C3=B3n?= <939888+Abuelodelanada@users.noreply.github.com> Date: Tue, 26 Mar 2024 14:50:45 -0300 Subject: [PATCH] configure database path (#314) --- src/charm.py | 15 ++++++++-- tests/integration/helpers.py | 38 ++++++++++++++++++++++++ tests/integration/test_kubectl_delete.py | 8 +++++ tests/integration/workload.py | 26 ++++++++++++++++ 4 files changed, 85 insertions(+), 2 deletions(-) diff --git a/src/charm.py b/src/charm.py index cfed7b83..1433a75c 100755 --- a/src/charm.py +++ b/src/charm.py @@ -112,6 +112,7 @@ DATABASE = "database" PEER = "grafana" PORT = 3000 +DATABASE_PATH = "/var/lib/grafana/grafana.db" # Template for storing trusted certificate in a file. TRUSTED_CA_TEMPLATE = string.Template( @@ -378,7 +379,7 @@ def _configure_replication(self) -> None: ): restart = True - litestream_config = {"addr": ":9876", "dbs": [{"path": "/var/lib/grafana/grafana.db"}]} + litestream_config = {"addr": ":9876", "dbs": [{"path": DATABASE_PATH}]} if not leader: litestream_config["dbs"][0].update({"upstream": {"url": "http://${LITESTREAM_UPSTREAM_URL}"}}) # type: ignore @@ -754,6 +755,16 @@ def _generate_grafana_config(self) -> str: configs = [] if self.has_db: configs.append(self._generate_database_config()) + else: + with StringIO() as data: + config_ini = configparser.ConfigParser() + config_ini["database"] = { + "type": "sqlite3", + "path": DATABASE_PATH, + } + config_ini.write(data) + data.seek(0) + configs.append(data.read()) return "\n".join(configs) @@ -874,7 +885,7 @@ def restart_grafana(self) -> None: pragma = self.containers["workload"].exec( [ "/usr/local/bin/sqlite3", - "/var/lib/grafana/grafana.db", + DATABASE_PATH, "pragma journal_mode=wal;", ] ) diff --git a/tests/integration/helpers.py b/tests/integration/helpers.py index 84720067..ea33ee50 100644 --- a/tests/integration/helpers.py +++ b/tests/integration/helpers.py @@ -74,6 +74,44 @@ async def check_grafana_is_ready(ops_test: OpsTest, app_name: str, unit_num: int return is_ready +async def create_org(ops_test: OpsTest, app_name: str, unit_num: int, org_name: str) -> dict: + """Create Organisation. + + Args: + ops_test: pytest-operator plugin + app_name: string name of Grafana application + unit_num: integer number of a Grafana juju unit + org_name: string name of Org. + + Returns: + Oranisation created. + """ + host = await unit_address(ops_test, app_name, unit_num) + pw = await grafana_password(ops_test, app_name) + grafana = Grafana(host=host, pw=pw) + org = await grafana.create_org(name=org_name) + return org + + +async def get_org(ops_test: OpsTest, app_name: str, unit_num: int, org_name: str) -> dict: + """Fetch Organisation. + + Args: + ops_test: pytest-operator plugin + app_name: string name of Grafana application + unit_num: integer number of a Grafana juju unit + org_name: string name of Org. + + Returns: + Oranisation. + """ + host = await unit_address(ops_test, app_name, unit_num) + pw = await grafana_password(ops_test, app_name) + grafana = Grafana(host=host, pw=pw) + org = await grafana.fetch_org(name=org_name) + return org + + async def get_grafana_settings(ops_test: OpsTest, app_name: str, unit_num: int) -> dict: """Fetch Grafana settings. diff --git a/tests/integration/test_kubectl_delete.py b/tests/integration/test_kubectl_delete.py index 45bd8a21..ec871333 100644 --- a/tests/integration/test_kubectl_delete.py +++ b/tests/integration/test_kubectl_delete.py @@ -8,10 +8,12 @@ import pytest from helpers import ( check_grafana_is_ready, + create_org, get_config_values, get_dashboard_by_search, get_datasource_for, get_grafana_datasources, + get_org, oci_image, uk8s_group, ) @@ -84,6 +86,9 @@ async def test_create_and_check_datasource_and_dashboard_before_delete(ops_test) async def test_config_values_are_retained_after_pod_deleted_and_restarted(ops_test): + org_name = "D10S" + await create_org(ops_test, grafana_app_name, 0, org_name) + pod_name = f"{grafana_app_name}-0" cmd = [ @@ -108,6 +113,9 @@ async def test_config_values_are_retained_after_pod_deleted_and_restarted(ops_te await check_grafana_is_ready(ops_test, grafana_app_name, 0) assert (await get_config_values(ops_test, grafana_app_name)).items() >= config.items() + org = await get_org(ops_test, grafana_app_name, 0, "D10S") + assert org["name"] == org_name + async def test_dashboards_and_datasources_are_retained_after_pod_deleted_and_restarted(ops_test): await check_grafana_is_ready(ops_test, grafana_app_name, 0) diff --git a/tests/integration/workload.py b/tests/integration/workload.py index 2e4d4ba5..db40c9fd 100644 --- a/tests/integration/workload.py +++ b/tests/integration/workload.py @@ -119,3 +119,29 @@ async def fetch_dashboard(self, dashboard_uid: str) -> dict: async with session.get(uri) as response: result = await response.json() return result if response.status == 200 else {} + + async def fetch_org(self, name: str) -> dict: + """Get the JSON representation of orgs. + + Returns: + Organisation. + """ + api_path = f"/api/orgs/name/{name}" + uri = f"{self.base_uri}{api_path}" + async with aiohttp.ClientSession(headers=self.headers) as session: + async with session.get(uri) as response: + result = await response.json() + return result if response.status == 200 else {} + + async def create_org(self, name: str) -> dict: + """Create org. + + Returns: + Dict containing the orgId. + """ + api_path = "/api/orgs" + uri = f"{self.base_uri}{api_path}" + async with aiohttp.ClientSession(headers=self.headers) as session: + async with session.post(uri, json={"name": name}) as response: + result = await response.json() + return result if response.status == 200 else {}