Skip to content

Commit b3d30d0

Browse files
authored
fixes for issue #447 (#451)
* make configure instance method idempotent * increase wait for connection time
1 parent ef8da8c commit b3d30d0

File tree

2 files changed

+35
-20
lines changed

2 files changed

+35
-20
lines changed

src/charm.py

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,16 @@
2424
BYTES_1MB,
2525
MySQLAddInstanceToClusterError,
2626
MySQLCharmBase,
27+
MySQLConfigureInstanceError,
28+
MySQLConfigureMySQLUsersError,
2729
MySQLCreateClusterError,
2830
MySQLGetClusterPrimaryAddressError,
2931
MySQLGetMemberStateError,
3032
MySQLGetMySQLVersionError,
3133
MySQLInitializeJujuOperationsTableError,
3234
MySQLLockAcquisitionError,
3335
MySQLRebootFromCompleteOutageError,
36+
MySQLServiceNotRunningError,
3437
MySQLSetClusterPrimaryError,
3538
)
3639
from charms.mysql.v0.tls import MySQLTLS
@@ -73,7 +76,7 @@
7376
)
7477
from k8s_helpers import KubernetesHelpers
7578
from log_rotate_manager import LogRotateManager
76-
from mysql_k8s_helpers import MySQL
79+
from mysql_k8s_helpers import MySQL, MySQLInitialiseMySQLDError
7780
from relations.mysql import MySQLRelation
7881
from relations.mysql_provider import MySQLProvider
7982
from relations.mysql_root import MySQLRootRelation
@@ -114,7 +117,7 @@ class MySQLOperatorCharm(MySQLCharmBase, TypedCharmBase[CharmConfig]):
114117
# RotateMySQLLogsCharmEvents needs to be defined on the charm object for
115118
# the log rotate manager process (which runs juju-run/juju-exec to dispatch
116119
# a custom event)
117-
on = RotateMySQLLogsCharmEvents() # pyright: ignore [reportAssignmentType]
120+
on = RotateMySQLLogsCharmEvents() # type: ignore
118121

119122
def __init__(self, *args):
120123
super().__init__(*args)
@@ -565,22 +568,34 @@ def _configure_instance(self, container) -> None:
565568
# Run mysqld for the first time to
566569
# bootstrap the data directory and users
567570
logger.debug("Initializing instance")
568-
self._mysql.fix_data_dir(container)
569-
self._mysql.initialise_mysqld()
570-
571-
# Add the pebble layer
572-
logger.debug("Adding pebble layer")
573-
container.add_layer(MYSQLD_SAFE_SERVICE, self._pebble_layer, combine=True)
574-
container.restart(MYSQLD_SAFE_SERVICE)
575-
576-
logger.debug("Waiting for instance to be ready")
577-
self._mysql.wait_until_mysql_connection(check_port=False)
578-
579-
logger.info("Configuring instance")
580-
# Configure all base users and revoke privileges from the root users
581-
self._mysql.configure_mysql_users(password_needed=False)
582-
# Configure instance as a cluster node
583-
self._mysql.configure_instance()
571+
try:
572+
self._mysql.fix_data_dir(container)
573+
self._mysql.initialise_mysqld()
574+
575+
# Add the pebble layer
576+
logger.debug("Adding pebble layer")
577+
container.add_layer(MYSQLD_SAFE_SERVICE, self._pebble_layer, combine=True)
578+
container.restart(MYSQLD_SAFE_SERVICE)
579+
580+
logger.debug("Waiting for instance to be ready")
581+
self._mysql.wait_until_mysql_connection(check_port=False)
582+
583+
logger.info("Configuring instance")
584+
# Configure all base users and revoke privileges from the root users
585+
self._mysql.configure_mysql_users(password_needed=False)
586+
# Configure instance as a cluster node
587+
self._mysql.configure_instance()
588+
except (
589+
MySQLInitialiseMySQLDError,
590+
MySQLServiceNotRunningError,
591+
MySQLConfigureMySQLUsersError,
592+
MySQLConfigureInstanceError,
593+
):
594+
# On any error, reset the data directory so hook is retried
595+
# on empty data directory
596+
# https://github.com/canonical/mysql-k8s-operator/issues/447
597+
self._mysql.reset_data_dir()
598+
raise
584599

585600
if self.has_cos_relation:
586601
if container.get_services(MYSQLD_EXPORTER_SERVICE)[

src/mysql_k8s_helpers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,11 @@ def initialise_mysqld(self) -> None:
218218
self.reset_data_dir()
219219
raise MySQLInitialiseMySQLDError
220220

221-
@retry(reraise=True, stop=stop_after_delay(30), wait=wait_fixed(5))
221+
@retry(reraise=True, stop=stop_after_delay(120), wait=wait_fixed(2))
222222
def wait_until_mysql_connection(self, check_port: bool = True) -> None:
223223
"""Wait until a connection to MySQL daemon is possible.
224224
225-
Retry every 5 seconds for 30 seconds if there is an issue obtaining a connection.
225+
Retry every 2 seconds for 120 seconds if there is an issue obtaining a connection.
226226
"""
227227
if not self.container.exists(MYSQLD_SOCK_FILE):
228228
raise MySQLServiceNotRunningError

0 commit comments

Comments
 (0)