v0.335.0: no app stop for a tier the agent will refuse because its host is busy (host_busy pre-check, R-921)
gates / gates (push) Successful in 53s

This commit is contained in:
2026-10-19 20:05:52 +02:00
parent db980ff2cc
commit 15ea002458
9 changed files with 282 additions and 13 deletions
+16 -1
View File
@@ -132,7 +132,7 @@ func (c *Client) BackupStatusFor(ctx context.Context, target string) (StatusResp
// tier is the agent's first reason to refuse POST /backup (HTTP 409), so the controller asks this BEFORE it
// stops any app. It reads only GET /backup/tiers and GET /backup/status?target= (both agent >= v0.97.0); a
// pre-R-82 agent (no /backup/tiers) answers nil, nil. Any other error is returned — the caller fails toward
// backing up. It does NOT see the agent's host-wide heavy-operation gate: no endpoint serves it.
// backing up. It does NOT see the agent's host-wide heavy-operation gate; HostBusy does (newer agents).
func (c *Client) BackupJobsInFlight(ctx context.Context) ([]string, error) {
tiers, err := c.BackupTiers(ctx)
if errors.Is(err, ErrTiersUnsupported) {
@@ -154,6 +154,21 @@ func (c *Client) BackupJobsInFlight(ctx context.Context) ([]string, error) {
return out, nil
}
// HostBusy (R-921) reads GET /backup/status's host_busy: whether the agent's host-wide heavy-operation gate is held
// right now (another guest's backup, the restore test, a night OS step …) — the agent's second reason to refuse
// POST /backup. known=false: the agent does not serve the field (older than the agent release that adds it) — no
// information, never „free". An error is returned; the caller fails toward backing up.
func (c *Client) HostBusy(ctx context.Context) (busy bool, what string, known bool, err error) {
st, err := c.BackupStatusFor(ctx, "")
if err != nil {
return false, "", false, err
}
if st.HostBusy == nil {
return false, "", false, nil
}
return st.HostBusy.Busy, st.HostBusy.What, true, nil
}
// SetBackupTargetResponse mirrors POST /backup/target (agent >= v0.113.0).
type SetBackupTargetResponse struct {
Target string `json:"target"`