134 lines
4.2 KiB
Python
134 lines
4.2 KiB
Python
"""
|
|
IGNY8 Daily Backup Task - Celery Scheduled Task
|
|
Creates daily application package backups at midnight
|
|
"""
|
|
from celery import shared_task
|
|
from celery.utils.log import get_task_logger
|
|
import subprocess
|
|
import os
|
|
from datetime import datetime
|
|
|
|
logger = get_task_logger(__name__)
|
|
|
|
@shared_task(name='backup.create_daily_app_package')
|
|
def create_daily_app_package():
|
|
"""
|
|
Daily scheduled task to create IGNY8 application package backup.
|
|
Runs at 00:00 UTC daily via Celery Beat.
|
|
|
|
This creates a portable package containing only source code,
|
|
excluding node_modules, .venv, dist, and other generated files.
|
|
|
|
Returns:
|
|
dict: Status information about the backup operation
|
|
"""
|
|
logger.info("🚀 Starting daily IGNY8 application package backup...")
|
|
|
|
script_path = "/data/app/igny8/scripts/package_app.sh"
|
|
|
|
try:
|
|
# Check if script exists
|
|
if not os.path.exists(script_path):
|
|
error_msg = f"Packaging script not found at {script_path}"
|
|
logger.error(f"❌ {error_msg}")
|
|
return {
|
|
'success': False,
|
|
'error': error_msg,
|
|
'timestamp': datetime.now().isoformat()
|
|
}
|
|
|
|
# Execute packaging script
|
|
logger.info(f"📦 Executing packaging script: {script_path}")
|
|
result = subprocess.run(
|
|
['/bin/bash', script_path],
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=300 # 5 minute timeout
|
|
)
|
|
|
|
if result.returncode == 0:
|
|
logger.info("✅ Daily application package created successfully!")
|
|
logger.info(f"Output: {result.stdout}")
|
|
|
|
return {
|
|
'success': True,
|
|
'message': 'Application package created successfully',
|
|
'output': result.stdout,
|
|
'timestamp': datetime.now().isoformat()
|
|
}
|
|
else:
|
|
error_msg = f"Packaging script failed with code {result.returncode}"
|
|
logger.error(f"❌ {error_msg}")
|
|
logger.error(f"Error output: {result.stderr}")
|
|
|
|
return {
|
|
'success': False,
|
|
'error': error_msg,
|
|
'stderr': result.stderr,
|
|
'timestamp': datetime.now().isoformat()
|
|
}
|
|
|
|
except subprocess.TimeoutExpired:
|
|
error_msg = "Packaging script timed out after 5 minutes"
|
|
logger.error(f"⏱️ {error_msg}")
|
|
return {
|
|
'success': False,
|
|
'error': error_msg,
|
|
'timestamp': datetime.now().isoformat()
|
|
}
|
|
|
|
except Exception as e:
|
|
error_msg = f"Unexpected error during packaging: {str(e)}"
|
|
logger.error(f"💥 {error_msg}")
|
|
return {
|
|
'success': False,
|
|
'error': error_msg,
|
|
'timestamp': datetime.now().isoformat()
|
|
}
|
|
|
|
|
|
@shared_task(name='backup.cleanup_old_packages')
|
|
def cleanup_old_packages():
|
|
"""
|
|
Cleanup old package backups (older than 30 days).
|
|
Runs weekly.
|
|
|
|
Returns:
|
|
dict: Status information about cleanup operation
|
|
"""
|
|
logger.info("🧹 Starting cleanup of old application packages...")
|
|
|
|
backup_dir = "/data/backups/igny8"
|
|
|
|
try:
|
|
# Find and delete packages older than 30 days
|
|
result = subprocess.run(
|
|
['find', backup_dir, '-name', 'igny8-app-*.tar.gz', '-type', 'f', '-mtime', '+30', '-delete'],
|
|
capture_output=True,
|
|
text=True
|
|
)
|
|
|
|
# Also delete old checksum files
|
|
subprocess.run(
|
|
['find', backup_dir, '-name', 'igny8-app-*.sha256', '-type', 'f', '-mtime', '+30', '-delete'],
|
|
capture_output=True,
|
|
text=True
|
|
)
|
|
|
|
logger.info("✅ Old packages cleaned up successfully")
|
|
|
|
return {
|
|
'success': True,
|
|
'message': 'Old packages cleaned up (30+ days)',
|
|
'timestamp': datetime.now().isoformat()
|
|
}
|
|
|
|
except Exception as e:
|
|
error_msg = f"Error during cleanup: {str(e)}"
|
|
logger.error(f"❌ {error_msg}")
|
|
return {
|
|
'success': False,
|
|
'error': error_msg,
|
|
'timestamp': datetime.now().isoformat()
|
|
}
|