@@ -87,14 +87,21 @@ def _can_unit_perform_backup(self) -> Tuple[bool, Optional[str]]:
8787
8888        tls_enabled  =  "tls"  in  self .charm .unit_peer_data 
8989
90+         # Check if this unit is the primary (if it was not possible to retrieve that information, 
91+         # then show that the unit cannot perform a backup, because possibly the database is offline). 
92+         try :
93+             is_primary  =  self .charm .is_primary 
94+         except  RetryError :
95+             return  False , "Unit cannot perform backups as the database seems to be offline" 
96+ 
9097        # Only enable backups on primary if there are replicas but TLS is not enabled. 
91-         if  self . charm . is_primary  and  self .charm .app .planned_units () >  1  and  tls_enabled :
98+         if  is_primary  and  self .charm .app .planned_units () >  1  and  tls_enabled :
9299            return  False , "Unit cannot perform backups as it is the cluster primary" 
93100
94101        # Can create backups on replicas only if TLS is enabled (it's needed to enable 
95102        # pgBackRest to communicate with the primary to request that missing WAL files 
96103        # are pushed to the S3 repo before the backup action is triggered). 
97-         if  not  self . charm . is_primary  and  not  tls_enabled :
104+         if  not  is_primary  and  not  tls_enabled :
98105            return  False , "Unit cannot perform backups as TLS is not enabled" 
99106
100107        if  not  self .charm ._patroni .member_started :
@@ -295,7 +302,7 @@ def _initialise_stanza(self) -> None:
295302        located, how it will be backed up, archiving options, etc. (more info in 
296303        https://pgbackrest.org/user-guide.html#quickstart/configure-stanza). 
297304        """ 
298-         if  not  self .charm .unit . is_leader () :
305+         if  not  self .charm .is_primary :
299306            return 
300307
301308        # Enable stanza initialisation if the backup settings were fixed after being invalid 
@@ -321,11 +328,18 @@ def _initialise_stanza(self) -> None:
321328        self .start_stop_pgbackrest_service ()
322329
323330        # Store the stanza name to be used in configurations updates. 
324-         self .charm .app_peer_data .update ({"stanza" : self .stanza_name , "init-pgbackrest" : "True" })
331+         if  self .charm .unit .is_leader ():
332+             self .charm .app_peer_data .update (
333+                 {"stanza" : self .stanza_name , "init-pgbackrest" : "True" }
334+             )
335+         else :
336+             self .charm .unit_peer_data .update (
337+                 {"stanza" : self .stanza_name , "init-pgbackrest" : "True" }
338+             )
325339
326340    def  check_stanza (self ) ->  None :
327341        """Runs the pgbackrest stanza validation.""" 
328-         if  not  self .charm .unit . is_leader ()  or  "init-pgbackrest"  not  in self .charm .app_peer_data :
342+         if  not  self .charm .is_primary  or  "init-pgbackrest"  not  in self .charm .app_peer_data :
329343            return 
330344
331345        # Update the configuration to use pgBackRest as the archiving mechanism. 
@@ -346,13 +360,38 @@ def check_stanza(self) -> None:
346360            # and rollback the configuration. 
347361            self .charm .app_peer_data .update ({"stanza" : "" })
348362            self .charm .app_peer_data .pop ("init-pgbackrest" , None )
363+             self .charm .unit_peer_data .update ({"stanza" : "" , "init-pgbackrest" : "" })
349364            self .charm .update_config ()
350365
351366            logger .exception (e )
352367            self .charm .unit .status  =  BlockedStatus (FAILED_TO_INITIALIZE_STANZA_ERROR_MESSAGE )
353368            return 
354369
355-         self .charm .app_peer_data .pop ("init-pgbackrest" , None )
370+         if  self .charm .unit .is_leader ():
371+             self .charm .app_peer_data .pop ("init-pgbackrest" , None )
372+         self .charm .unit_peer_data .pop ("init-pgbackrest" , None )
373+ 
374+     def  coordinate_stanza_fields (self ) ->  None :
375+         """Coordinate the stanza name between the primary and the leader units.""" 
376+         for  unit , unit_data  in  self .charm ._peers .data .items ():
377+             if  "stanza"  not  in unit_data :
378+                 continue 
379+             # If the stanza name is not set in the application databag, then the primary is not 
380+             # the leader unit, and it's needed to set the stanza name in the application databag. 
381+             if  "stanza"  not  in self .charm .app_peer_data  and  self .charm .unit .is_leader ():
382+                 self .charm .app_peer_data .update (
383+                     {"stanza" : self .stanza_name , "init-pgbackrest" : "True" }
384+                 )
385+                 break 
386+             # If the stanza was already checked and its name is still in the unit databag, mark 
387+             # the stanza as already checked in the application databag and remove it from the 
388+             # unit databag. 
389+             if  "init-pgbackrest"  not  in unit_data :
390+                 if  self .charm .unit .is_leader ():
391+                     self .charm .app_peer_data .pop ("init-pgbackrest" , None )
392+                 if  "init-pgbackrest"  not  in self .charm .app_peer_data  and  unit  ==  self .charm .unit :
393+                     self .charm .unit_peer_data .update ({"stanza" : "" })
394+                     break 
356395
357396    @property  
358397    def  _is_primary_pgbackrest_service_running (self ) ->  bool :
@@ -363,6 +402,10 @@ def _is_primary_pgbackrest_service_running(self) -> bool:
363402            logger .error (f"failed to get primary with error { str (e )}  )
364403            return  False 
365404
405+         if  primary  is  None :
406+             logger .debug ("the primary was not elected yet" )
407+             return  False 
408+ 
366409        primary_endpoint  =  self .charm ._get_hostname_from_unit (primary )
367410
368411        try :
@@ -388,8 +431,8 @@ def _on_s3_credential_changed(self, event: CredentialsChangedEvent):
388431            logger .debug ("Cannot set pgBackRest configurations, missing configurations." )
389432            return 
390433
391-         # Verify the s3 relation only on the leader  
392-         if  not  self .charm .unit . is_leader () :
434+         # Verify the s3 relation only on the primary.  
435+         if  not  self .charm .is_primary :
393436            return 
394437
395438        try :
@@ -526,6 +569,9 @@ def _on_create_backup_action(self, event) -> None:
526569        self .charm .unit .status  =  ActiveStatus ()
527570
528571    def  _on_s3_credential_gone (self , _ ) ->  None :
572+         if  self .charm .unit .is_leader ():
573+             self .charm .app_peer_data .update ({"stanza" : "" , "init-pgbackrest" : "" })
574+         self .charm .unit_peer_data .update ({"stanza" : "" , "init-pgbackrest" : "" })
529575        if  self .charm .is_blocked  and  self .charm .unit .status .message  in  S3_BLOCK_MESSAGES :
530576            self .charm .unit .status  =  ActiveStatus ()
531577
0 commit comments