Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions nexus/src/app/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -517,4 +517,26 @@ impl super::Nexus {
.await?;
Ok(())
}

/// Remove a read only parent from a disk.
/// This is just a wrapper around the volume operation of the same
/// name, but we provide this interface when all the caller has is
/// the disk UUID as the internal volume_id is not exposed.
pub async fn disk_remove_read_only_parent(
self: &Arc<Self>,
opctx: &OpContext,
disk_id: Uuid,
) -> DeleteResult {
// First get the internal volume ID that is stored in the disk
// database entry, once we have that just call the volume method
// to remove the read only parent.
let (.., db_disk) = LookupPath::new(opctx, &self.db_datastore)
.disk_id(disk_id)
.fetch()
.await?;

self.volume_remove_read_only_parent(db_disk.volume_id).await?;

Ok(())
}
}
26 changes: 26 additions & 0 deletions nexus/src/internal_api/http_entrypoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub fn internal_api() -> NexusApiDescription {
api.register(cpapi_instances_put)?;
api.register(cpapi_disks_put)?;
api.register(cpapi_volume_remove_read_only_parent)?;
api.register(cpapi_disk_remove_read_only_parent)?;
api.register(cpapi_producers_post)?;
api.register(cpapi_collectors_post)?;
api.register(cpapi_metrics_collect)?;
Expand Down Expand Up @@ -226,6 +227,31 @@ async fn cpapi_volume_remove_read_only_parent(
apictx.internal_latencies.instrument_dropshot_handler(&rqctx, handler).await
}

/// Request removal of a read_only_parent from a disk
/// This is a thin wrapper around the volume_remove_read_only_parent saga.
/// All we are doing here is, given a disk UUID, figure out what the
/// volume_id is for that disk, then use that to call the
/// volume_remove_read_only_parent saga on it.
#[endpoint {
method = POST,
path = "/disk/{disk_id}/remove-read-only-parent",
}]
async fn cpapi_disk_remove_read_only_parent(
rqctx: Arc<RequestContext<Arc<ServerContext>>>,
path_params: Path<DiskPathParam>,
) -> Result<HttpResponseUpdatedNoContent, HttpError> {
let apictx = rqctx.context();
let nexus = &apictx.nexus;
let path = path_params.into_inner();

let handler = async {
let opctx = OpContext::for_internal_api(&rqctx).await;
nexus.disk_remove_read_only_parent(&opctx, path.disk_id).await?;
Ok(HttpResponseUpdatedNoContent())
};
apictx.internal_latencies.instrument_dropshot_handler(&rqctx, handler).await
}

/// Accept a registration from a new metric producer
#[endpoint {
method = POST,
Expand Down
29 changes: 29 additions & 0 deletions openapi/nexus-internal.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,35 @@
}
}
},
"/disk/{disk_id}/remove-read-only-parent": {
"post": {
"summary": "Request removal of a read_only_parent from a disk",
"description": "This is a thin wrapper around the volume_remove_read_only_parent saga. All we are doing here is, given a disk UUID, figure out what the volume_id is for that disk, then use that to call the volume_remove_read_only_parent saga on it.",
"operationId": "cpapi_disk_remove_read_only_parent",
"parameters": [
{
"in": "path",
"name": "disk_id",
"required": true,
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"204": {
"description": "resource updated"
},
"4XX": {
"$ref": "#/components/responses/Error"
},
"5XX": {
"$ref": "#/components/responses/Error"
}
}
}
},
"/disks/{disk_id}": {
"put": {
"summary": "Report updated state for a disk.",
Expand Down