Files
portainer/api/http/handler/settings
claude code agent b6ba9b46c7 feat(automation): inbound registry-push webhook for immediate auto-update (#32)
Adds POST /api/webhooks/container-automation/{token} which kicks a full
auto-update pass immediately, instead of waiting up to PollInterval (6h) for the
poll. Registry-agnostic 'general kick': the payload is not parsed; the pass
compares digests and updates only stale containers. Polling stays as a fallback.

- Service.TriggerUpdate(): a buffer-1 non-blocking kick channel + a worker
  goroutine on baseCtx that debounces ~10s (collapsing a multi-arch/multi-tag
  push burst into one pass). update() is split into runUpdatePass() bool, which
  returns false when the updateRunning CAS is not acquired; the worker backs off
  and re-runs so a kick landing during a scheduled pass is never lost. The poll
  timer keeps calling the same pass.
- Worker panics are recovered (poll parity — the poll path runs under the
  scheduler's cron.Recover), so a panic in the pass cannot crash the daemon from
  this bare goroutine. runUpdatePass also re-checks AutoUpdate.Enabled as
  defense-in-depth against a disable during the debounce window.
- Route via bouncer.PublicAccess (distinct from /webhooks/{token} by segment
  count); token compared with subtle.ConstantTimeCompare; empty/mismatched token
  -> 404, disabled auto-update -> 409, success -> 202. Token is server-generated
  (uuid) via RegenerateWebhookToken / ClearWebhookToken settings actions; never
  accepted from the client; excluded from /settings/public (present in admin GET
  for the UI).
- Frontend: an AutoUpdatePanel 'Update trigger webhook' section (readonly URL,
  copy, Generate/Regenerate, Clear, registry-setup hint).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 06:05:21 +03:00
..