Phase 8: back up & restore remote (agent) stacks (0.8.0)

- Agent: GET /agent/stacks/{id}/backup + POST /agent/stacks/restore (reuse
  backup_service). backup_service gains backup_basename/backup_filename helpers.
- Main proxy streams agent <-> main <-> destination (creds stay central):
  agent_service download_to_file/upload_file; routers/agents.py backup download,
  backup/push, restore upload, restore-from.
- Schedules: BackupSchedule.agent_id; schedule_service downloads from the agent
  when set; per-host filename prefix isolates retention across hosts.
- Frontend: agents api backup/restore; BackupButton/RestoreButton agent-aware
  (Backup on remote stack detail, Restore per host section); schedule form host
  selector (local or an online agent) + host shown on schedule rows.

Rough-verified (per request): py_compile, frontend tsc build, image imports
(main 99 / agent 16 routes). Full live agent round-trip to be tested post-deploy.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
menzelj
2026-06-07 22:26:20 +00:00
co-authored by Claude Opus 4.8
parent 84ef3df59e
commit 5cd55382ed
16 changed files with 561 additions and 59 deletions
+20
View File
@@ -38,6 +38,26 @@ class BackupError(Exception):
pass
# --------------------------------------------------------------------------- #
# Backup filename convention
# --------------------------------------------------------------------------- #
def backup_basename(stack_id: str, prefix: Optional[str] = None) -> str:
"""Filename stem used to group a stack's backups (and match for retention).
``prefix`` (e.g. a remote host slug) keeps backups of same-named stacks on
different hosts from colliding / pruning each other on a shared destination.
"""
return f"backup-{prefix}-{stack_id}" if prefix else f"backup-{stack_id}"
def backup_filename(stack_id: str, include_volumes: bool, prefix: Optional[str] = None) -> str:
date = now().strftime("%Y%m%d-%H%M%S")
suffix = "full" if include_volumes else "config"
return f"{backup_basename(stack_id, prefix)}-{suffix}-{date}.tar.gz"
# --------------------------------------------------------------------------- #
# Helper container for volume I/O
# --------------------------------------------------------------------------- #