Skip to content

Commit c5f7951

Browse files
authored
Merge pull request #258 from frappe/mergify/bp/master/pr-242
2 parents 8cbdad2 + 39f07fa commit c5f7951

5 files changed

Lines changed: 466 additions & 0 deletions

File tree

agent/bench.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,9 @@ def _update_runtime_limits(self, memory_high, memory_max, memory_swap, vcpu):
797797
cmd += f" --cpus={vcpu}"
798798
return self.execute(cmd)
799799

800+
def _update_database_host(self, db_host: str):
801+
self._update_config({"db_host": db_host})
802+
800803
@property
801804
def job_record(self):
802805
return self.server.job_record

agent/database_server.py

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,24 @@ def __init__(self, directory=None):
3131
self.job = None
3232
self.step = None
3333

34+
def ping(self, private_ip, mariadb_root_password):
35+
"""Ping the MariaDB server to check if it is reachable."""
36+
try:
37+
mariadb = MySQLDatabase(
38+
"mysql",
39+
user="root",
40+
password=mariadb_root_password,
41+
host=private_ip,
42+
port=3306,
43+
)
44+
mariadb.connect(reuse_if_open=True)
45+
mariadb.execute_sql("SELECT 1;")
46+
# Close the connection to avoid leaving it open
47+
mariadb.close()
48+
return True
49+
except Exception:
50+
return False
51+
3452
def search_binary_log(
3553
self,
3654
log,
@@ -87,6 +105,162 @@ def binary_logs(self):
87105
)
88106
return sorted(files, key=lambda x: x["name"])
89107

108+
def get_slave_status(self, private_ip, mariadb_root_password):
109+
"""Get the slave status of the MariaDB server."""
110+
try:
111+
mariadb = MySQLDatabase(
112+
"mysql",
113+
user="root",
114+
password=mariadb_root_password,
115+
host=private_ip,
116+
port=3306,
117+
)
118+
gtid_binlog_pos = self.sql(mariadb, "SELECT @@GLOBAL.gtid_binlog_pos;")[0][
119+
"@@GLOBAL.gtid_binlog_pos"
120+
]
121+
gtid_current_pos = self.sql(mariadb, "SELECT @@GLOBAL.gtid_current_pos;")[0][
122+
"@@GLOBAL.gtid_current_pos"
123+
]
124+
gtid_slave_pos = self.sql(mariadb, "SELECT @@GLOBAL.gtid_slave_pos;")
125+
if len(gtid_slave_pos) > 0:
126+
gtid_slave_pos = gtid_slave_pos[0].get("@@GLOBAL.gtid_slave_pos", "")
127+
else:
128+
gtid_slave_pos = ""
129+
130+
rows = self.sql(mariadb, "SHOW SLAVE STATUS;")
131+
return {
132+
"success": True,
133+
"message": "Slave status retrieved successfully.",
134+
"data": {
135+
"gtid_binlog_pos": gtid_binlog_pos,
136+
"gtid_current_pos": gtid_current_pos,
137+
"gtid_slave_pos": gtid_slave_pos,
138+
"slave_status": rows[0] if rows else {},
139+
},
140+
}
141+
except Exception:
142+
import traceback
143+
144+
return {
145+
"success": False,
146+
"message": "Failed to retrieve slave status.",
147+
"error": traceback.format_exc(),
148+
}
149+
150+
def configure_replication(
151+
self,
152+
private_ip,
153+
mariadb_root_password,
154+
master_private_ip,
155+
master_mariadb_root_password,
156+
gtid_slave_pos=None,
157+
):
158+
try:
159+
"""Configure replication on the MariaDB server."""
160+
mariadb = MySQLDatabase(
161+
"mysql",
162+
user="root",
163+
password=mariadb_root_password,
164+
host=private_ip,
165+
port=3306,
166+
)
167+
mariadb.execute_sql("STOP SLAVE;")
168+
mariadb.execute_sql("RESET SLAVE ALL;")
169+
if gtid_slave_pos:
170+
mariadb.execute_sql(f"SET GLOBAL gtid_slave_pos = '{gtid_slave_pos}';")
171+
mariadb.execute_sql(f"""CHANGE MASTER TO
172+
MASTER_HOST = '{master_private_ip}',
173+
MASTER_PORT = 3306,
174+
MASTER_USER = 'root',
175+
MASTER_PASSWORD = '{master_mariadb_root_password}',
176+
MASTER_USE_GTID=slave_pos;
177+
""")
178+
return {
179+
"success": True,
180+
"message": "Replication configured successfully.",
181+
}
182+
except Exception:
183+
import traceback
184+
185+
return {
186+
"success": False,
187+
"message": "Failed to configure replication.",
188+
"error": traceback.format_exc(),
189+
}
190+
191+
def reset_replication(self, private_ip, mariadb_root_password):
192+
"""Reset the replication configuration on the MariaDB server."""
193+
try:
194+
mariadb = MySQLDatabase(
195+
"mysql",
196+
user="root",
197+
password=mariadb_root_password,
198+
host=private_ip,
199+
port=3306,
200+
)
201+
mariadb.execute_sql("STOP SLAVE;")
202+
mariadb.execute_sql("RESET SLAVE ALL;")
203+
return {
204+
"success": True,
205+
"message": "Slave configuration reset successfully.",
206+
}
207+
except Exception:
208+
import traceback
209+
210+
return {
211+
"success": False,
212+
"message": "Failed to reset replication configuration.",
213+
"error": traceback.format_exc(),
214+
}
215+
216+
def start_replication(self, private_ip, mariadb_root_password):
217+
"""Start replication on the MariaDB server."""
218+
try:
219+
mariadb = MySQLDatabase(
220+
"mysql",
221+
user="root",
222+
password=mariadb_root_password,
223+
host=private_ip,
224+
port=3306,
225+
)
226+
mariadb.execute_sql("START SLAVE;")
227+
return {
228+
"success": True,
229+
"message": "Replication resumed successfully.",
230+
}
231+
except Exception:
232+
import traceback
233+
234+
return {
235+
"success": False,
236+
"message": "Failed to resume replication.",
237+
"error": traceback.format_exc(),
238+
}
239+
240+
def stop_replication(self, private_ip, mariadb_root_password) -> bool:
241+
"""Stop replication on the MariaDB server."""
242+
try:
243+
mariadb = MySQLDatabase(
244+
"mysql",
245+
user="root",
246+
password=mariadb_root_password,
247+
host=private_ip,
248+
port=3306,
249+
)
250+
mariadb.execute_sql("STOP SLAVE;")
251+
return {
252+
"success": True,
253+
"message": "Replication stopped successfully.",
254+
}
255+
except Exception:
256+
import traceback
257+
258+
return {
259+
"success": False,
260+
"message": "Failed to stop replication.",
261+
"error": traceback.format_exc(),
262+
}
263+
90264
def processes(self, private_ip, mariadb_root_password):
91265
try:
92266
mariadb = MySQLDatabase(

agent/server.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,15 @@ def reload_nginx(self):
457457
def update_supervisor(self):
458458
return self._update_supervisor()
459459

460+
@job("Update Database Host", priority="high")
461+
def update_database_host_job(self, db_host: str):
462+
self.update_database_host_step(db_host)
463+
464+
@step("Update Database Host")
465+
def update_database_host_step(self, db_host: str):
466+
for b in self.benches.values():
467+
b._update_database_host(db_host)
468+
460469
def setup_authentication(self, password):
461470
self.update_config({"access_token": pbkdf2.hash(password)})
462471

0 commit comments

Comments
 (0)