93 lines
3.3 KiB
Python
93 lines
3.3 KiB
Python
"""
|
|
Celery задачи для системных операций (бэкапы, очистка и т.д.)
|
|
"""
|
|
|
|
from celery import shared_task
|
|
import logging
|
|
from django.core.management import call_command
|
|
from django.conf import settings
|
|
import os
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
@shared_task
|
|
def backup_database():
|
|
"""
|
|
Автоматическое создание бэкапа базы данных.
|
|
Запускается через Celery Beat.
|
|
"""
|
|
try:
|
|
backup_dir = os.path.join(settings.BASE_DIR.parent, 'backups', 'database')
|
|
retention_days = int(os.getenv('BACKUP_RETENTION_DAYS', '30'))
|
|
|
|
logger.info(f'Starting database backup to {backup_dir}')
|
|
|
|
call_command(
|
|
'backup_database',
|
|
output_dir=backup_dir,
|
|
retention_days=retention_days,
|
|
compress=True,
|
|
)
|
|
|
|
logger.info('Database backup completed successfully')
|
|
return 'Database backup completed'
|
|
|
|
except Exception as e:
|
|
logger.error(f'Error creating database backup: {e}', exc_info=True)
|
|
raise
|
|
|
|
|
|
@shared_task
|
|
def cleanup_old_backups():
|
|
"""
|
|
Очистка старых бэкапов.
|
|
Удаляет бэкапы старше указанного количества дней.
|
|
"""
|
|
try:
|
|
from datetime import timedelta
|
|
from django.utils import timezone
|
|
import glob
|
|
|
|
backup_dir = os.path.join(settings.BASE_DIR.parent, 'backups', 'database')
|
|
retention_days = int(os.getenv('BACKUP_RETENTION_DAYS', '30'))
|
|
cutoff_date = timezone.now() - timedelta(days=retention_days)
|
|
|
|
if not os.path.exists(backup_dir):
|
|
logger.warning(f'Backup directory does not exist: {backup_dir}')
|
|
return 'Backup directory does not exist'
|
|
|
|
deleted_count = 0
|
|
total_size_freed = 0
|
|
|
|
# Ищем все файлы бэкапов
|
|
backup_patterns = [
|
|
os.path.join(backup_dir, 'db_backup_*.sql'),
|
|
os.path.join(backup_dir, 'db_backup_*.sql.gz'),
|
|
]
|
|
|
|
for pattern in backup_patterns:
|
|
for backup_file in glob.glob(pattern):
|
|
try:
|
|
file_mtime = os.path.getmtime(backup_file)
|
|
file_date = timezone.datetime.fromtimestamp(file_mtime, tz=timezone.utc)
|
|
|
|
if file_date < cutoff_date:
|
|
file_size = os.path.getsize(backup_file)
|
|
os.remove(backup_file)
|
|
deleted_count += 1
|
|
total_size_freed += file_size
|
|
logger.info(f'Deleted old backup: {os.path.basename(backup_file)}')
|
|
except Exception as e:
|
|
logger.error(f'Error deleting backup {backup_file}: {e}')
|
|
|
|
size_mb = total_size_freed / (1024 * 1024)
|
|
logger.info(f'Cleanup completed: {deleted_count} backups deleted, {size_mb:.2f} MB freed')
|
|
|
|
return f'Deleted {deleted_count} old backups, freed {size_mb:.2f} MB'
|
|
|
|
except Exception as e:
|
|
logger.error(f'Error cleaning up old backups: {e}', exc_info=True)
|
|
raise
|
|
|