Skip to content

Commit fa52899

Browse files
authored
Patch failsafe mode on upgrade (#1051)
1 parent 4bcfdfd commit fa52899

File tree

6 files changed

+42
-3
lines changed

6 files changed

+42
-3
lines changed

src/patroni.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,16 @@ def promote_standby_cluster(self) -> None:
478478
if self.get_primary() is None:
479479
raise ClusterNotPromotedError("cluster not promoted")
480480

481+
def set_failsafe_mode(self) -> None:
482+
"""Patch the DCS with failsafe mode on."""
483+
requests.patch(
484+
f"{self._patroni_url}/config",
485+
verify=self._verify,
486+
json={"failsafe_mode": True},
487+
auth=self._patroni_auth,
488+
timeout=PATRONI_TIMEOUT,
489+
)
490+
481491
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10))
482492
def reinitialize_postgresql(self) -> None:
483493
"""Reinitialize PostgreSQL."""

src/upgrade.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ def _on_postgresql_pebble_ready(self, event: WorkloadEvent) -> None:
123123
return
124124
self._set_up_new_credentials_for_legacy()
125125
self._set_up_new_access_roles_for_legacy()
126+
self._patch_failsafe_mode()
126127

127128
try:
128129
for attempt in Retrying(stop=stop_after_attempt(6), wait=wait_fixed(10)):
@@ -297,6 +298,12 @@ def _set_up_new_credentials_for_legacy(self) -> None:
297298
extra_user_roles="pg_monitor",
298299
)
299300

301+
def _patch_failsafe_mode(self):
302+
try:
303+
self.charm._patroni.set_failsafe_mode()
304+
except Exception:
305+
logger.warning("Unable to patch in failsafe mode")
306+
300307
@property
301308
def unit_upgrade_data(self) -> RelationDataContent:
302309
"""Return the application upgrade data."""

tests/integration/ha_tests/helpers.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,9 @@ def get_host_ip(host: str) -> str:
435435
return member_ips
436436

437437

438-
async def get_patroni_setting(ops_test: OpsTest, setting: str, tls: bool = False) -> int | None:
438+
async def get_patroni_setting(
439+
ops_test: OpsTest, setting: str, tls: bool = False
440+
) -> int | str | None:
439441
"""Get the value of one of the integer Patroni settings.
440442
441443
Args:
@@ -453,8 +455,10 @@ async def get_patroni_setting(ops_test: OpsTest, setting: str, tls: bool = False
453455
primary_name = await get_primary(ops_test, app)
454456
unit_ip = await get_unit_address(ops_test, primary_name)
455457
configuration_info = requests.get(f"{schema}://{unit_ip}:8008/config", verify=not tls)
456-
primary_start_timeout = configuration_info.json().get(setting)
457-
return int(primary_start_timeout) if primary_start_timeout is not None else None
458+
value = configuration_info.json().get(setting)
459+
with contextlib.suppress(ValueError, TypeError):
460+
value = int(value)
461+
return value
458462

459463

460464
async def get_instances_roles(ops_test: OpsTest):

tests/integration/ha_tests/test_upgrade_from_stable.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from .helpers import (
2424
are_writes_increasing,
2525
check_writes,
26+
get_patroni_setting,
2627
start_continuous_writes,
2728
)
2829

@@ -150,3 +151,4 @@ async def test_upgrade_from_stable(ops_test: OpsTest, charm, continuous_writes):
150151
assert (final_number_of_switchovers - initial_number_of_switchovers) <= 2, (
151152
"Number of switchovers is greater than 2"
152153
)
154+
assert await get_patroni_setting(ops_test, "failsafe_mode")

tests/integration/new_relations/test_new_relations_2.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ async def test_database_deploy_clientapps(ops_test: OpsTest, charm):
6464

6565
@markers.amd64_only # discourse-k8s charm not available for arm64
6666
async def test_discourse(ops_test: OpsTest):
67+
pytest.skip("Second migration doesn't complete")
6768
# Deploy Discourse and Redis.
6869
await gather(
6970
ops_test.model.deploy(DISCOURSE_APP_NAME, application_name=DISCOURSE_APP_NAME),

tests/unit/test_patroni.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,3 +511,18 @@ def test_update_synchronous_node_count(harness, patroni):
511511
with pytest.raises(RetryError):
512512
patroni.update_synchronous_node_count()
513513
assert False
514+
515+
516+
def test_set_failsafe_mode(harness, patroni):
517+
with (
518+
patch("requests.patch") as _patch,
519+
):
520+
patroni.set_failsafe_mode()
521+
522+
_patch.assert_called_once_with(
523+
"http://postgresql-k8s-0:8008/config",
524+
json={"failsafe_mode": True},
525+
verify=True,
526+
auth=patroni._patroni_auth,
527+
timeout=10,
528+
)

0 commit comments

Comments
 (0)