Recover a protection group
POST/v1/protection-groups/:id/recover
Brings the group's workload up here, in the region that holds its standby copy. A planned recover acts only on a release the other region recorded: the newest record for the group must be a release from the region this group recovers from, at the custody epoch held here or above, with no recovery above it. It brings each member back from exactly the final backup the release took, so nothing written there is lost, and it never acts because time passed: with wait_for_release it waits up to that long for the record, and is refused with release_not_observed if none arrives. Without a release it can verify it is refused with release_not_observed, saying where to release. An unplanned recover, for when the group's home is lost or cannot be reached, needs no release. Only an operator can start one, and only by confirming with confirm_primary_may_be_serving_writes that the home may still be running the workload; the confirmation is audited with who gave it.
At a group's home, a recover is a failback. A planned one acts on the recovery region's release and writes its final backup back into each original server, in place, from the point the server held when it was released: instance ids, ports and addresses, and the home's plans carry on unchanged. Before a byte is written, each original's disks are compared with the snapshot of the point it holds, and an original that changed is refused with return_target_diverged — unless an operator asks for overwrite_diverged, which keeps what the original holds as a divergence point and then writes the whole backup over it. A member whose original no longer exists is rebuilt from the recovery region's backup as a new server, resolved through the group's own recovery profile and accepted gaps. The originals are then unlocked and started, and the plans the release paused resume. An unplanned recover at home takes back a group released here by starting the originals as they are, without the recovery region's consent.
The run restores each member of a cold group from a backup adopted here, or clones each member's standby for a warm one, into the group's project. It then takes custody: the group's custody here becomes active and its custody epoch goes up by one, which is the run's point of no return. Before it, a failure or a cancel removes everything the run built; after it, nothing is removed. It boots the members tier by tier in boot order, on the networks the group's network_map and recovery profile resolve, and starts a tier only once every member of the tier before it passed its health check. Last, it records the recovery in the repository for the group's home to read, and puts the recovered servers under a new backup plan with the group's policy, which the group names as reprotect_plan_id. The group ends protected.
With dry_run=true the request answers 200 with the plan the run would follow and starts nothing. Otherwise it answers 202 with the admitted run; follow it at GET /v1/protection-groups/{id}/runs/{run_id}. Everything that would refuse the run is checked before it is admitted, and again by the run itself before it acts: a run that finds a refusal then ends failed with that code in error_code. A refusal about members names each in fields as members.<instance id>.
The hot rung is refused in this release. GET /v1/capabilities says under dr and dr_reason whether recovery runs on this cloud.
Any member of the project the token is scoped to.
Request
Responses
- 200
- 202
- 400
- 401
- 403
- 404
- 409
- 413
- 415
- 422
- 503
- default
OK.
With dry_run=true, the plan the run would follow. Nothing was started.
Accepted
Bad Request.
invalid_request: The body is not a single JSON object, names a field this operation does not take, or gives a value of the wrong type.
Unauthorized.
unauthenticated: The token is missing, expired or not valid.
Forbidden.
forbidden: The token may not recover this group. An unplanned recover needs a system-scoped admin token.
Not Found.
not_found: No group with this id exists in the token's project.
group_document_not_found: The group's repository no longer shows the document its home writes.
Conflict.
group_busy: A run is acting on the group.
custody_not_standby: This region does not hold the group's standby copy, because its custody here is active or released.
split_brain_risk: The group is in split_brain_risk, which only a resync or an acknowledgement clears.
standby_advanced: A member's standby moved to a newer backup while the recover was being worked out. Asking again works from the newer one.
release_not_observed: A planned recover finds no release it can verify, and no wait_for_release was asked: nothing was released, the newest record is not a release, it came from a region this group does not recover from, or a recovery was recorded above it. The detail says where to release.
release_epoch_mismatch: The other region released at a custody epoch below the one held here, so it is not the release this region takes the workload from.
Request Entity Too Large.
body_too_large: The body is larger than the service accepts.
Unsupported Media Type.
unsupported_media_type: The body is not sent as application/json.
Unprocessable Entity.
validation_failed: mode is missing or is neither planned nor unplanned. recovery_point is neither aligned nor newest, or is sent with a planned recover. max_point_age is not a positive duration, or is sent with a planned recover. wait_for_release is sent with an unplanned recover, or is not a positive duration of at most 30 minutes. fields names each.
unplanned_failover_unconfirmed: An unplanned recover is sent without confirm_primary_may_be_serving_writes set to true.
group_has_no_policy: The group names no protection policy, so nothing says how it recovers.
policy_has_no_recovery: The group's policy states no recovery section.
member_not_mirrored: For a hot group, a member's disk is not a mirrored volume here.
image_not_found_by_global_id: For a hot group, no image here carries a member's disk's mirror global id.
mirror_unavailable: The group promises the hot rung and this region cannot reach its own mirrored images.
member_never_synced: No standby holds a member of a warm group yet, or a mirrored image of a hot group holds no complete mirror snapshot.
member_has_no_recoverable_state: No backup of a member has been adopted here, or the group has no member.
domain_key_missing: A member's backups are encrypted under a dedup domain whose key this cloud lacks.
member_not_ready: A member's readiness reports something else that refuses a recovery, such as binding_missing; fields gives it as <issue code>: <detail>. Or a member's backup cannot be read, or describes no server to build.
standby_has_no_applied_snapshot: A member's standby holds no snapshot taken when an update finished, so nothing it holds is known to be a whole backup.
recovery_point_too_old: A member's recovery point is older than max_point_age, or its age is unknown.
partial_coverage_unaccepted: A member's backup does not hold every disk of the server, and the group's registration does not accept partial_coverage.
no_probe_origin: Members declare health checks, and this region has neither a probe image to run them from nor a route to the project's networks. A check is never reduced to the server merely being up.
recovery_delegation_missing: Nothing can be built in the group's project: the group is not armed or its delegation has expired, and the service holds no role there.
mapping_unresolved: A member's server cannot be rebuilt here as it stands: an element such as a flavor or network does not map, and the group's accept_gaps does not accept it: the registration's, or at a group's home its own, for a member a failback rebuilds because its original is gone. fields names each member's elements.
return_target_diverged: With dry_run=true, a failback finds an original server whose disks changed after the point it holds, one that is running, or one that cannot be compared and is no longer locked by the release. A started failback that finds it ends failed with this error_code before anything is written. Fail back again with overwrite_diverged, which keeps what each such original holds as a backup first; a resync does not apply, since it runs where the workload runs.
failback_binding_missing: With dry_run=true, a failback finds a member whose final backup from the recovery region has not been adopted here: confirm the failback bindings first. A started failback waits for it, and ends failed with this error_code if it does not arrive.
unplanned_needs_originals: An unplanned recover at the group's home finds a member whose original server no longer exists.
Service Unavailable.
dr_not_enabled: Disaster recovery is not enabled here, or this cloud lacks something the recover needs, which the detail names.
An error, as an RFC 7807 problem document.