feat(api): expose async backup/restore job status (fixes #7)

Backup and restore only enqueue a cluster Job; a later failure left its
only trace in that Job object, invisible without kubectl. Add
GET /api/v1/servers/{name}/jobs (owner-or-admin) projecting the newest
20 managed Jobs (felis-backup / felis-restore) as
running|succeeded|failed with message and timestamps. Nil reader -> 503
jobs_unavailable, mirroring the backup/restore feature gates. RBAC gains
jobs:list; OpenAPI parity updated.
This commit is contained in:
Lemon-miaow committed 2026-09-22 20:36:36 +08:00
1 parent a2df2f242b
commit ff7c57cf9c
8 files changed
+365 -2

No files matched your search

+6
View File
@@ -63,6 +63,11 @@ type API struct {
// authorization boundary is exercised before the backup-Job executor is wired.
Backuper Backuper
// JobStatus reads the latest backup/restore Job outcomes for GET
// /servers/{name}/jobs — the status outlet for async failures (the enqueue
// endpoints only answer 202). Optional: nil → that route reports 503.
JobStatus JobStatusReader
// Files is the server file editor (list / read / write a file in a stopped
// server's world volume — the "one wrong line in server.properties" repair).
// Like Restorer and Backuper it is optional: when nil the file routes report
@@ -407,6 +412,7 @@ func (a *API) externalAPIRoutes() []apiRoute {
// owned), and restore is gated by owner-or-admin PLUS a former-owner match, so
// neither sits behind adminOnly.
{Method: "GET", Pattern: "/api/v1/backups", h: a.handleListBackups},
{Method: "GET", Pattern: "/api/v1/servers/{name}/jobs", h: a.handleServerJobs},
{Method: "POST", Pattern: "/api/v1/servers/{name}/restore-backup", h: a.handleRestoreBackup},
{Method: "POST", Pattern: "/api/v1/servers/{name}/backup", h: a.handleBackupNow},
// Server file editor: list / read / write a file in a STOPPED server's world