certs: async renewal via background task + status polling
- POST /acme/renew returns a request_id and spawns a background task (renew/deploy/refresh steps); dedups per-domain like issue - completes as "skipped" when acme.sh reports the renewal window has not been reached (no --force) - new GET /acme/renew/status endpoint (iface + handler + blueprint) - run acme.sh subprocesses off the event loop (asyncio.to_thread) in both issuance and renewal - ActionCell: busy/busyLabel props; certs page disables the Renew button and polls renewal status with toasts for success/skip/fail
This commit is contained in:
+38
-3
@@ -1333,11 +1333,46 @@ Returns HTTP `404` if the request ID is not found. The frontend uses `poll()` to
|
||||
POST /api/certs/<domain>/renew
|
||||
```
|
||||
|
||||
Force-renew an existing certificate.
|
||||
Start an async certificate renewal for an existing certificate. The renewal
|
||||
runs in the background and is polled via
|
||||
`GET /api/certs/renew/<request_id>`.
|
||||
|
||||
**Response:** `data` is `null` on success.
|
||||
**Request Body:** none (domain is taken from the path).
|
||||
|
||||
Returns HTTP `404` if the certificate is not found. Returns HTTP `500` if renewal fails.
|
||||
**Response (`data`):**
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `request_id` | `string` | Unique identifier for polling renewal status |
|
||||
| `domain` | `string` | Domain being renewed |
|
||||
| `status` | `string` | Only when a renewal for this domain is already in progress (`"existing"` — the existing `request_id` is returned) |
|
||||
|
||||
The renewal is a **no-op** when the certificate's renewal window (default:
|
||||
30 days before expiry) has not been reached — the request then completes with
|
||||
`status: "skipped"`.
|
||||
|
||||
Returns HTTP `400` if the domain is missing. Returns HTTP `500` when the
|
||||
renewal cannot be started (e.g. daemon unreachable).
|
||||
|
||||
---
|
||||
|
||||
#### Poll Certificate Renewal Status
|
||||
|
||||
```
|
||||
GET /api/certs/renew/<request_id>
|
||||
```
|
||||
|
||||
Poll the status of a certificate renewal started by
|
||||
`POST /api/certs/<domain>/renew`.
|
||||
|
||||
**Response (`data`):** Renewal status object containing `request_id`,
|
||||
`domain`, `status` (`"running"`, `"completed"`, `"skipped"`, or `"failed"`),
|
||||
a `steps` array (each with per-step status and error message), and
|
||||
timestamps.
|
||||
|
||||
Returns HTTP `404` if the request ID is not found. The frontend uses
|
||||
`poll()` to repeatedly fetch this endpoint until the renewal completes,
|
||||
is skipped, or fails.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user