Files
Frobot-OTA-Agent/ota_agent/mysql_backup.py
2026-04-23 14:40:29 +08:00

60 lines
2.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from __future__ import annotations
import asyncio
import logging
from datetime import datetime
from pathlib import Path
from .compose_manager import ComposeManager
from .models import CommandResult
logger = logging.getLogger(__name__)
class MysqlBackupManager:
def __init__(self, *, enabled: bool, backup_dir: str, dump_command: str, timeout_seconds: int, compose_manager: ComposeManager) -> None:
self.enabled = enabled
self.backup_dir = Path(backup_dir)
self.dump_command = dump_command
self.timeout_seconds = timeout_seconds
self.compose_manager = compose_manager
if self.enabled:
self.backup_dir.mkdir(parents=True, exist_ok=True)
async def backup_before_upgrade(self, target_release: str) -> CommandResult:
if not self.enabled:
return CommandResult(success=True, stdout="mysql backup skipped", returncode=0)
timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
backup_file = self.backup_dir / f"mysql-backup-{target_release}-{timestamp}.sql"
command = self.dump_command.replace("{backup_file}", str(backup_file))
logger.info("开始执行MySQL备份目标文件: %s", backup_file)
result = await self._run_shell_command(command)
if result.success:
logger.info("MySQL备份完成: %s", backup_file)
result.stdout = str(backup_file)
else:
logger.error("MySQL备份失败: %s", result.stderr or result.stdout)
return result
async def _run_shell_command(self, command: str) -> CommandResult:
process = await asyncio.create_subprocess_shell(
command,
cwd=str(self.compose_manager.working_dir),
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
try:
stdout, stderr = await asyncio.wait_for(process.communicate(), timeout=self.timeout_seconds)
except asyncio.TimeoutError:
process.kill()
await process.wait()
return CommandResult(success=False, stderr=f"mysql backup timeout after {self.timeout_seconds}s", returncode=-1)
return CommandResult(
success=process.returncode == 0,
stdout=stdout.decode("utf-8", errors="ignore"),
stderr=stderr.decode("utf-8", errors="ignore"),
returncode=process.returncode or 0,
)