Skip to content

Commit 1b7f8dc

Browse files
authored
Migrating to Rock OCI image (#118)
* Initial switch * Use stable tls-certificates-operator * Temporarily manually installing ca-certs * Revert "Temporarily manually installing ca-certs" This reverts commit 2fd47db. * Read version from the Rock image * Switch to GHCR Rock
1 parent 9a23f1d commit 1b7f8dc

File tree

8 files changed

+43
-11
lines changed

8 files changed

+43
-11
lines changed

metadata.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ containers:
1919
resources:
2020
postgresql-image:
2121
type: oci-image
22-
description: OCI image for PostgreSQL (dataplatformoci/postgres-patroni)
23-
upstream-source: dataplatformoci/postgres-patroni
22+
description: OCI image for PostgreSQL
23+
upstream-source: ghcr.io/canonical/charmed-postgresql:14.7-22.04_edge
2424

2525
peers:
2626
database-peers:
@@ -47,4 +47,4 @@ requires:
4747
storage:
4848
pgdata:
4949
type: filesystem
50-
location: /var/lib/postgresql/data
50+
location: /var/lib/postgresql/data

src/charm.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,7 @@ def _set_primary_status_message(self) -> None:
729729
def _patroni(self):
730730
"""Returns an instance of the Patroni object."""
731731
return Patroni(
732+
self,
732733
self._endpoint,
733734
self._endpoints,
734735
self.primary_endpoint,
@@ -814,7 +815,7 @@ def _postgresql_layer(self) -> Layer:
814815
self._postgresql_service: {
815816
"override": "replace",
816817
"summary": "entrypoint of the postgresql + patroni image",
817-
"command": f"/usr/bin/python3 /usr/local/bin/patroni {self._storage_path}/patroni.yml",
818+
"command": f"patroni {self._storage_path}/patroni.yml",
818819
"startup": "enabled",
819820
"user": WORKLOAD_OS_USER,
820821
"group": WORKLOAD_OS_GROUP,

src/patroni.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from typing import List, Optional
1111

1212
import requests
13+
import yaml
1314
from jinja2 import Template
1415
from tenacity import (
1516
AttemptManager,
@@ -40,6 +41,7 @@ class Patroni:
4041

4142
def __init__(
4243
self,
44+
charm,
4345
endpoint: str,
4446
endpoints: List[str],
4547
primary_endpoint: str,
@@ -50,6 +52,7 @@ def __init__(
5052
rewind_password: str,
5153
tls_enabled: bool,
5254
):
55+
self._charm = charm
5356
self._endpoint = endpoint
5457
self._endpoints = endpoints
5558
self._primary_endpoint = primary_endpoint
@@ -70,6 +73,16 @@ def _patroni_url(self) -> str:
7073
"""Patroni REST API URL."""
7174
return f"{'https' if self._tls_enabled else 'http'}://{self._endpoint}:8008"
7275

76+
@property
77+
def rock_postgresql_version(self) -> Optional[str]:
78+
"""Version of Postgresql installed in the Rock image."""
79+
container = self._charm.unit.get_container("postgresql")
80+
if not container.can_connect():
81+
logger.debug("Cannot get Postgresql version from Rock. Container inaccessible")
82+
return
83+
snap_meta = container.pull("/meta.charmed-postgresql/snap.yaml")
84+
return yaml.safe_load(snap_meta)["version"]
85+
7386
def _get_alternative_patroni_url(self, attempt: AttemptManager) -> str:
7487
"""Get an alternative REST API URL from another member each time.
7588
@@ -231,6 +244,7 @@ def render_patroni_yml_file(
231244
restoring_backup=backup_id is not None,
232245
backup_id=backup_id,
233246
stanza=stanza,
247+
version=self.rock_postgresql_version.split(".")[0],
234248
)
235249
self._render_file(f"{self._storage_path}/patroni.yml", rendered, 0o644)
236250

templates/patroni.yml.j2

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ bootstrap:
44
use_pg_rewind: true
55
remove_data_directory_on_rewind_failure: true
66
remove_data_directory_on_diverged_timelines: true
7+
bin_dir: /usr/lib/postgresql/{{ version }}/bin
78
parameters:
89
{%- if enable_pgbackrest %}
910
archive_command: 'pgbackrest --stanza={{ stanza }} archive-push %p'
@@ -24,7 +25,6 @@ bootstrap:
2425
- auth-host: md5
2526
- auth-local: trust
2627
- encoding: UTF8
27-
- locale: en_US.UTF-8
2828
- data-checksums
2929
{%- endif %}
3030
pg_hba:
@@ -52,6 +52,7 @@ postgresql:
5252
connect_address: '{{ endpoint }}:5432'
5353
custom_conf: {{ storage_path }}/postgresql-k8s-operator.conf
5454
data_dir: {{ storage_path }}/pgdata
55+
bin_dir: /usr/lib/postgresql/{{ version }}/bin
5556
listen: 0.0.0.0:5432
5657
parameters:
5758
{%- if enable_pgbackrest %}

tests/integration/test_backups.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ async def test_backup_and_restore(ops_test: OpsTest, cloud_configs: Tuple[Dict,
3030
# Deploy S3 Integrator and TLS Certificates Operator.
3131
await ops_test.model.deploy(S3_INTEGRATOR_APP_NAME, channel="edge")
3232
config = {"generate-self-signed-certificates": "true", "ca-common-name": "Test CA"}
33-
await ops_test.model.deploy(TLS_CERTIFICATES_APP_NAME, channel="beta", config=config)
33+
await ops_test.model.deploy(TLS_CERTIFICATES_APP_NAME, config=config)
3434

3535
for cloud, config in cloud_configs[0].items():
3636
# Deploy and relate PostgreSQL to S3 integrator (one database app for each cloud for now

tests/integration/test_tls.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ async def test_mattermost_db(ops_test: OpsTest) -> None:
4545
async with ops_test.fast_forward():
4646
# Deploy TLS Certificates operator.
4747
config = {"generate-self-signed-certificates": "true", "ca-common-name": "Test CA"}
48-
await ops_test.model.deploy(TLS_CERTIFICATES_APP_NAME, channel="beta", config=config)
48+
await ops_test.model.deploy(TLS_CERTIFICATES_APP_NAME, config=config)
4949
# Relate it to the PostgreSQL to enable TLS.
5050
await ops_test.model.relate(DATABASE_APP_NAME, TLS_CERTIFICATES_APP_NAME)
5151
await ops_test.model.wait_for_idle(status="active", timeout=1000)

tests/unit/test_charm.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ def test_postgresql_layer(self, _, __, ___, ____):
423423
self._postgresql_service: {
424424
"override": "replace",
425425
"summary": "entrypoint of the postgresql + patroni image",
426-
"command": "/usr/bin/python3 /usr/local/bin/patroni /var/lib/postgresql/data/patroni.yml",
426+
"command": "patroni /var/lib/postgresql/data/patroni.yml",
427427
"startup": "enabled",
428428
"user": "postgres",
429429
"group": "postgres",

tests/unit/test_patroni.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,30 @@
33
# See LICENSE file for licensing details.
44

55
import unittest
6-
from unittest.mock import mock_open, patch
6+
from unittest.mock import PropertyMock, mock_open, patch
77

88
from jinja2 import Template
9+
from ops.testing import Harness
910
from tenacity import RetryError
1011

12+
from charm import PostgresqlOperatorCharm
1113
from constants import REWIND_USER
1214
from patroni import Patroni
13-
from tests.helpers import STORAGE_PATH
15+
from tests.helpers import STORAGE_PATH, patch_network_get
1416

1517

1618
class TestPatroni(unittest.TestCase):
19+
@patch("charm.KubernetesServicePatch", lambda x, y: None)
20+
@patch_network_get(private_address="1.1.1.1")
1721
def setUp(self):
22+
self.harness = Harness(PostgresqlOperatorCharm)
23+
self.addCleanup(self.harness.cleanup)
24+
self.harness.begin()
25+
self.charm = self.harness.charm
26+
1827
# Setup Patroni wrapper.
1928
self.patroni = Patroni(
29+
self.charm,
2030
"postgresql-k8s-0",
2131
["postgresql-k8s-0"],
2232
"postgresql-k8s-primary.dev.svc.cluster.local",
@@ -77,8 +87,11 @@ def test_render_file(self, _temp_file, _pwnam, _chown, _chmod):
7787
# Ensure the file is chown'd correctly.
7888
_chown.assert_called_with(filename, uid=35, gid=35)
7989

90+
@patch("charm.Patroni.rock_postgresql_version", new_callable=PropertyMock)
8091
@patch("charm.Patroni._render_file")
81-
def test_render_patroni_yml_file(self, _render_file):
92+
def test_render_patroni_yml_file(self, _render_file, _rock_postgresql_version):
93+
_rock_postgresql_version.return_value = "14.7"
94+
8295
# Get the expected content from a file.
8396
with open("templates/patroni.yml.j2") as file:
8497
template = Template(file.read())
@@ -92,6 +105,7 @@ def test_render_patroni_yml_file(self, _render_file):
92105
replication_password=self.patroni._replication_password,
93106
rewind_user=REWIND_USER,
94107
rewind_password=self.patroni._rewind_password,
108+
version="14",
95109
)
96110

97111
# Setup a mock for the `open` method, set returned data to postgresql.conf template.
@@ -125,6 +139,7 @@ def test_render_patroni_yml_file(self, _render_file):
125139
replication_password=self.patroni._replication_password,
126140
rewind_user=REWIND_USER,
127141
rewind_password=self.patroni._rewind_password,
142+
version="14",
128143
)
129144
self.assertNotEqual(expected_content_with_tls, expected_content)
130145

@@ -180,6 +195,7 @@ def test_render_postgresql_conf_file(self, _render_file):
180195

181196
# Also test with multiple planned units (synchronous_commit is turned on).
182197
self.patroni = Patroni(
198+
self.charm,
183199
"postgresql-k8s-0",
184200
["postgresql-k8s-0", "postgresql-k8s-1"],
185201
"postgresql-k8s-primary.dev.svc.cluster.local",

0 commit comments

Comments
 (0)