@@ -102,10 +102,14 @@ def _can_unit_perform_backup(self) -> Tuple[bool, Optional[str]]:
102
102
103
103
tls_enabled = "tls" in self .charm .unit_peer_data
104
104
105
+ # Check if this unit is the primary (if it was not possible to retrieve that information,
106
+ # then show that the unit cannot perform a backup, because possibly the database is offline).
107
+ try :
108
+ is_primary = self .charm .is_primary
109
+ except RetryError :
110
+ return False , "Unit cannot perform backups as the database seems to be offline"
111
+
105
112
# Only enable backups on primary if there are replicas but TLS is not enabled.
106
- is_primary = self .charm .unit .name == self .charm ._patroni .get_primary (
107
- unit_name_pattern = True
108
- )
109
113
if is_primary and self .charm .app .planned_units () > 1 and tls_enabled :
110
114
return False , "Unit cannot perform backups as it is the cluster primary"
111
115
@@ -363,7 +367,7 @@ def _initialise_stanza(self) -> None:
363
367
located, how it will be backed up, archiving options, etc. (more info in
364
368
https://pgbackrest.org/user-guide.html#quickstart/configure-stanza).
365
369
"""
366
- if not self .charm .unit . is_leader () :
370
+ if not self .charm .is_primary :
367
371
return
368
372
369
373
# Enable stanza initialisation if the backup settings were fixed after being invalid
@@ -403,11 +407,18 @@ def _initialise_stanza(self) -> None:
403
407
self .start_stop_pgbackrest_service ()
404
408
405
409
# Store the stanza name to be used in configurations updates.
406
- self .charm .app_peer_data .update ({"stanza" : self .stanza_name , "init-pgbackrest" : "True" })
410
+ if self .charm .unit .is_leader ():
411
+ self .charm .app_peer_data .update (
412
+ {"stanza" : self .stanza_name , "init-pgbackrest" : "True" }
413
+ )
414
+ else :
415
+ self .charm .unit_peer_data .update (
416
+ {"stanza" : self .stanza_name , "init-pgbackrest" : "True" }
417
+ )
407
418
408
419
def check_stanza (self ) -> None :
409
420
"""Runs the pgbackrest stanza validation."""
410
- if not self .charm .unit . is_leader () or "init-pgbackrest" not in self .charm .app_peer_data :
421
+ if not self .charm .is_primary or "init-pgbackrest" not in self .charm .app_peer_data :
411
422
return
412
423
413
424
# Update the configuration to use pgBackRest as the archiving mechanism.
@@ -437,12 +448,37 @@ def check_stanza(self) -> None:
437
448
# and rollback the configuration.
438
449
self .charm .app_peer_data .update ({"stanza" : "" })
439
450
self .charm .app_peer_data .pop ("init-pgbackrest" , None )
451
+ self .charm .unit_peer_data .update ({"stanza" : "" , "init-pgbackrest" : "" })
440
452
self .charm .update_config ()
441
453
442
454
logger .exception (e )
443
455
self .charm .unit .status = BlockedStatus (FAILED_TO_INITIALIZE_STANZA_ERROR_MESSAGE )
444
456
445
- self .charm .app_peer_data .pop ("init-pgbackrest" , None )
457
+ if self .charm .unit .is_leader ():
458
+ self .charm .app_peer_data .pop ("init-pgbackrest" , None )
459
+ self .charm .unit_peer_data .pop ("init-pgbackrest" , None )
460
+
461
+ def coordinate_stanza_fields (self ) -> None :
462
+ """Coordinate the stanza name between the primary and the leader units."""
463
+ for unit , unit_data in self .charm ._peers .data .items ():
464
+ if "stanza" not in unit_data :
465
+ continue
466
+ # If the stanza name is not set in the application databag, then the primary is not
467
+ # the leader unit, and it's needed to set the stanza name in the application databag.
468
+ if "stanza" not in self .charm .app_peer_data and self .charm .unit .is_leader ():
469
+ self .charm .app_peer_data .update (
470
+ {"stanza" : self .stanza_name , "init-pgbackrest" : "True" }
471
+ )
472
+ break
473
+ # If the stanza was already checked and its name is still in the unit databag, mark
474
+ # the stanza as already checked in the application databag and remove it from the
475
+ # unit databag.
476
+ if "init-pgbackrest" not in unit_data :
477
+ if self .charm .unit .is_leader ():
478
+ self .charm .app_peer_data .pop ("init-pgbackrest" , None )
479
+ if "init-pgbackrest" not in self .charm .app_peer_data and unit == self .charm .unit :
480
+ self .charm .unit_peer_data .update ({"stanza" : "" })
481
+ break
446
482
447
483
@property
448
484
def _is_primary_pgbackrest_service_running (self ) -> bool :
@@ -469,8 +505,8 @@ def _on_s3_credential_changed(self, event: CredentialsChangedEvent):
469
505
logger .debug ("Cannot set pgBackRest configurations, missing configurations." )
470
506
return
471
507
472
- # Verify the s3 relation only on the leader
473
- if not self .charm .unit . is_leader () :
508
+ # Verify the s3 relation only on the primary.
509
+ if not self .charm .is_primary :
474
510
return
475
511
476
512
try :
@@ -487,6 +523,9 @@ def _on_s3_credential_changed(self, event: CredentialsChangedEvent):
487
523
self ._initialise_stanza ()
488
524
489
525
def _on_s3_credential_gone (self , _ ) -> None :
526
+ if self .charm .unit .is_leader ():
527
+ self .charm .app_peer_data .update ({"stanza" : "" , "init-pgbackrest" : "" })
528
+ self .charm .unit_peer_data .update ({"stanza" : "" , "init-pgbackrest" : "" })
490
529
if self .charm .is_blocked and self .charm .unit .status .message in S3_BLOCK_MESSAGES :
491
530
self .charm .unit .status = ActiveStatus ()
492
531
0 commit comments