Sync from main server - 2026-05-16 00:38:48
This commit is contained in:
@@ -74,7 +74,7 @@ def get_vm_backups():
|
||||
f"-o StrictHostKeyChecking=no -o ConnectTimeout=10 "
|
||||
f"-o BatchMode=yes "
|
||||
f"{VM_USER}@{VM_HOST} "
|
||||
f"'ls -t /backups/main-server/myapps-backup-*.tar.gz 2>/dev/null | head -20'"
|
||||
f"'ls -t /backups/cloudproject/myapps-backup-*.tar.gz 2>/dev/null | head -20'"
|
||||
)
|
||||
stdout, _ = _run(cmd, timeout=25)
|
||||
if stdout:
|
||||
@@ -85,7 +85,7 @@ def get_vm_backups():
|
||||
except Exception as e:
|
||||
print(f"[backups] VM backup fetch error: {e}")
|
||||
else:
|
||||
backup_dir = '/backups/main-server'
|
||||
backup_dir = '/backups/cloudproject'
|
||||
if os.path.exists(backup_dir):
|
||||
files = glob.glob(f'{backup_dir}/myapps-backup-*.tar.gz')
|
||||
files.sort(key=os.path.getmtime, reverse=True)
|
||||
@@ -109,7 +109,7 @@ def audit_backup(backup_file, source='local'):
|
||||
if source == 'local':
|
||||
archive_path = f"/root/backups/{backup_file}"
|
||||
else:
|
||||
archive_path = f"/backups/main-server/{backup_file}"
|
||||
archive_path = f"/backups/cloudproject/{backup_file}"
|
||||
|
||||
if not RUNNING_ON_MAIN_SERVER and source == 'local':
|
||||
tmp_path = f"/tmp/audit_{backup_file}"
|
||||
@@ -381,7 +381,7 @@ def delete_backup(backup_file, source='local'):
|
||||
return True, f'Deleted {backup_file} from main server'
|
||||
|
||||
elif source == 'vm':
|
||||
archive_path = f"/backups/main-server/{backup_file}"
|
||||
archive_path = f"/backups/cloudproject/{backup_file}"
|
||||
if not RUNNING_ON_MAIN_SERVER:
|
||||
if not os.path.exists(archive_path):
|
||||
return False, f'File not found: {archive_path}'
|
||||
@@ -395,8 +395,8 @@ def delete_backup(backup_file, source='local'):
|
||||
f"-o StrictHostKeyChecking=no -o ConnectTimeout=10 "
|
||||
f"-o BatchMode=yes "
|
||||
f"{VM_USER}@{VM_HOST} "
|
||||
f"'rm -f /backups/main-server/{backup_file} "
|
||||
f"/backups/main-server/{backup_file}.sha256'"
|
||||
f"'rm -f /backups/cloudproject/{backup_file} "
|
||||
f"/backups/cloudproject/{backup_file}.sha256'"
|
||||
)
|
||||
out, err = _run(cmd, timeout=30)
|
||||
if err and 'No such file' not in err:
|
||||
|
||||
@@ -81,7 +81,6 @@ def r2_test_connection() -> dict:
|
||||
except Exception as e:
|
||||
return {"success": False, "message": str(e), "bucket_exists": False}
|
||||
|
||||
|
||||
def r2_ensure_bucket() -> tuple[bool, str]:
|
||||
cfg = _get_r2_config()
|
||||
bucket = cfg["bucket_name"]
|
||||
@@ -125,6 +124,35 @@ def r2_list_backups() -> list[dict]:
|
||||
except Exception:
|
||||
return []
|
||||
|
||||
def r2_enforce_retention(max_backups: int = 5) -> list[str]:
|
||||
"""Keep only the latest max_backups in R2, delete the rest. Returns list of deleted keys."""
|
||||
if not r2_is_configured():
|
||||
return []
|
||||
cfg = _get_r2_config()
|
||||
bucket = cfg["bucket_name"]
|
||||
deleted = []
|
||||
try:
|
||||
client = _get_r2_client()
|
||||
resp = client.list_objects_v2(Bucket=bucket, Prefix="backups/")
|
||||
# Only count real archives, not .sha256 files
|
||||
objects = sorted(
|
||||
[o for o in resp.get("Contents", []) if not o["Key"].endswith(".sha256")],
|
||||
key=lambda x: x["LastModified"],
|
||||
reverse=True # newest first
|
||||
)
|
||||
to_delete = objects[max_backups:] # everything beyond the 5 latest
|
||||
for obj in to_delete:
|
||||
key = obj["Key"]
|
||||
client.delete_object(Bucket=bucket, Key=key)
|
||||
# Also delete the sha256 companion if it exists
|
||||
try:
|
||||
client.delete_object(Bucket=bucket, Key=key + ".sha256")
|
||||
except Exception:
|
||||
pass
|
||||
deleted.append(key)
|
||||
except Exception as e:
|
||||
print(f"R2 retention error: {e}")
|
||||
return deleted
|
||||
|
||||
def r2_delete_backup(key: str) -> tuple[bool, str]:
|
||||
cfg = _get_r2_config()
|
||||
@@ -227,6 +255,10 @@ def r2_upload_async(local_path: str, job_id: str) -> None:
|
||||
_upload_jobs[job_id]["log"].append(
|
||||
f"Upload complete in {elapsed}s — r2://{bucket}/{object_key}"
|
||||
)
|
||||
# Enforce R2 retention — keep only 5 latest
|
||||
deleted = r2_enforce_retention(max_backups=5)
|
||||
for dk in deleted:
|
||||
_upload_jobs[job_id]["log"].append(f"🗑️ Pruned old R2 backup: {dk.replace('backups/', '')}")
|
||||
_upload_jobs[job_id]["status"] = "done"
|
||||
_upload_jobs[job_id]["progress"] = 100
|
||||
_upload_jobs[job_id]["object_key"] = object_key
|
||||
|
||||
1
platform/requirements.txt
Normal file
1
platform/requirements.txt
Normal file
@@ -0,0 +1 @@
|
||||
boto3==1.43.5
|
||||
Reference in New Issue
Block a user