@@ -130,7 +130,7 @@ def wait_until_mysql_connection(self) -> None:
130
130
131
131
# Increment this PATCH version before using `charmcraft publish-lib` or reset
132
132
# to 0 if you are raising the major API version
133
- LIBPATCH = 61
133
+ LIBPATCH = 62
134
134
135
135
UNIT_TEARDOWN_LOCKNAME = "unit-teardown"
136
136
UNIT_ADD_LOCKNAME = "unit-add"
@@ -402,6 +402,10 @@ class MySQLRejoinClusterError(Error):
402
402
"""Exception raised when there is an issue trying to rejoin a cluster to the cluster set."""
403
403
404
404
405
+ class MySQLGetClusterNameError (Error ):
406
+ """Exception raised when there is an issue getting cluster name."""
407
+
408
+
405
409
@dataclasses .dataclass
406
410
class RouterUser :
407
411
"""MySQL Router user."""
@@ -1792,7 +1796,10 @@ def is_instance_in_cluster(self, unit_label: str) -> bool:
1792
1796
logger .debug (f"Checking existence of unit { unit_label } in cluster { self .cluster_name } " )
1793
1797
1794
1798
output = self ._run_mysqlsh_script ("\n " .join (commands ))
1795
- return MySQLMemberState .ONLINE in output .lower ()
1799
+ return (
1800
+ MySQLMemberState .ONLINE in output .lower ()
1801
+ or MySQLMemberState .RECOVERING in output .lower ()
1802
+ )
1796
1803
except MySQLClientError :
1797
1804
# confirmation can fail if the clusteradmin user does not yet exist on the instance
1798
1805
logger .debug (
@@ -1805,7 +1812,9 @@ def is_instance_in_cluster(self, unit_label: str) -> bool:
1805
1812
stop = stop_after_attempt (3 ),
1806
1813
retry = retry_if_exception_type (TimeoutError ),
1807
1814
)
1808
- def get_cluster_status (self , extended : Optional [bool ] = False ) -> Optional [dict ]:
1815
+ def get_cluster_status (
1816
+ self , from_instance : Optional [str ] = None , extended : Optional [bool ] = False
1817
+ ) -> Optional [dict ]:
1809
1818
"""Get the cluster status.
1810
1819
1811
1820
Executes script to retrieve cluster status.
@@ -1817,7 +1826,7 @@ def get_cluster_status(self, extended: Optional[bool] = False) -> Optional[dict]
1817
1826
"""
1818
1827
options = {"extended" : extended }
1819
1828
status_commands = (
1820
- f"shell.connect('{ self .cluster_admin_user } :{ self .cluster_admin_password } @{ self .instance_address } ')" ,
1829
+ f"shell.connect('{ self .cluster_admin_user } :{ self .cluster_admin_password } @{ from_instance or self .instance_address } ')" ,
1821
1830
f"cluster = dba.get_cluster('{ self .cluster_name } ')" ,
1822
1831
f"print(cluster.status({ options } ))" ,
1823
1832
)
@@ -2265,6 +2274,34 @@ def get_cluster_set_global_primary_address(
2265
2274
2266
2275
return matches .group (1 )
2267
2276
2277
+ def get_cluster_name (self , connect_instance_address : Optional [str ]) -> Optional [str ]:
2278
+ """Get the cluster name from instance.
2279
+
2280
+ Uses the mysql_innodb_cluster_metadata.clusters table in case instance connecting
2281
+ to is offline and thus cannot use mysqlsh.dba.get_cluster().
2282
+ """
2283
+ if not connect_instance_address :
2284
+ connect_instance_address = self .instance_address
2285
+
2286
+ logger .debug (f"Getting cluster name from { connect_instance_address } " )
2287
+ get_cluster_name_commands = (
2288
+ f"shell.connect('{ self .cluster_admin_user } :{ self .cluster_admin_password } @{ connect_instance_address } ')" ,
2289
+ 'cluster_name = session.run_sql("SELECT cluster_name FROM mysql_innodb_cluster_metadata.clusters;")' ,
2290
+ "print(f'<CLUSTER_NAME>{cluster_name.fetch_one()[0]}</CLUSTER_NAME>')" ,
2291
+ )
2292
+
2293
+ try :
2294
+ output = self ._run_mysqlsh_script ("\n " .join (get_cluster_name_commands ))
2295
+ except MySQLClientError as e :
2296
+ logger .warning ("Failed to get cluster name" )
2297
+ raise MySQLGetClusterNameError (e .message )
2298
+
2299
+ matches = re .search (r"<CLUSTER_NAME>(.+)</CLUSTER_NAME>" , output )
2300
+ if not matches :
2301
+ return None
2302
+
2303
+ return matches .group (1 )
2304
+
2268
2305
def get_primary_label (self ) -> Optional [str ]:
2269
2306
"""Get the label of the cluster's primary."""
2270
2307
status = self .get_cluster_status ()
0 commit comments