Skip to content

Commit 6817d9c

Browse files
author
lif
committed
WIP: start making nexus-side glue
1 parent efb04a8 commit 6817d9c

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

nexus/src/app/instance.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,10 @@ impl super::Nexus {
955955
//
956956
// If the operation failed, kick the sled agent error back up to
957957
// the caller to let it decide how to handle it.
958+
//
959+
// When creating the zone for the first time, we just get
960+
// Ok(None) here, which is a no-op. We later asynchronously get
961+
// a cpapi call invoking Self::write_returned_instance_state
958962
match instance_put_result {
959963
Ok(state) => self
960964
.write_returned_instance_state(&instance_id, state)
@@ -967,6 +971,38 @@ impl super::Nexus {
967971
}
968972
}
969973

974+
/// TODO describe how this relates to [Self::instance_request_state] (above)
975+
pub(crate) async fn instance_handle_creation_result(
976+
&self,
977+
opctx: &OpContext,
978+
instance_id: &Uuid,
979+
result: Result<
980+
Option<nexus::SledInstanceState>,
981+
sled_agent_client::types::Error,
982+
>,
983+
) -> Result<(), Error> {
984+
let (.., authz_instance, db_instance) =
985+
LookupPath::new(&opctx, &self.db_datastore)
986+
.instance_id(*instance_id)
987+
.lookup_for(authz::Action::Modify)
988+
.await?;
989+
990+
let state = self
991+
.db_datastore
992+
.instance_fetch_with_vmm(opctx, &authz_instance)
993+
.await?;
994+
995+
// TODO: add param for sled-agent to show its 'previous' and compare with this
996+
let prev_instance_runtime = &state.instance().runtime_state;
997+
998+
self.handle_instance_put_result(
999+
instance_id,
1000+
prev_instance_runtime,
1001+
result.map_err(Into::into), // TODO: this isn't real
1002+
).await?;
1003+
todo!()
1004+
}
1005+
9701006
/// Modifies the runtime state of the Instance as requested. This generally
9711007
/// means booting or halting the Instance.
9721008
pub(crate) async fn instance_ensure_registered(

nexus/src/internal_api/http_entrypoints.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,34 @@ async fn cpapi_instances_put(
269269
apictx.internal_latencies.instrument_dropshot_handler(&rqctx, handler).await
270270
}
271271

272+
/// Asynchronously report the result of a potentially long-running
273+
/// instance_put call to sled-agent made during instance creation.
274+
#[endpoint {
275+
method = PUT,
276+
path = "/instances/{instance_id}/creation-result",
277+
}]
278+
async fn cpapi_handle_instance_put_result(
279+
rqctx: RequestContext<Arc<ServerContext>>,
280+
path_params: Path<InstancePathParam>,
281+
result: TypedBody<Result<
282+
Option<SledInstanceState>,
283+
sled_agent_client::types::Error
284+
>>,
285+
) -> Result<HttpResponseUpdatedNoContent, HttpError> {
286+
let apictx = rqctx.context();
287+
let nexus = &apictx.nexus;
288+
let path = path_params.into_inner();
289+
let result = result.into_inner();
290+
let opctx = crate::context::op_context_for_internal_api(&rqctx).await;
291+
let handler = async {
292+
nexus
293+
.instance_handle_creation_result(&opctx, &path.instance_id, result)
294+
.await?;
295+
Ok(HttpResponseUpdatedNoContent())
296+
};
297+
apictx.internal_latencies.instrument_dropshot_handler(&rqctx, handler).await
298+
}
299+
272300
/// Path parameters for Disk requests (internal API)
273301
#[derive(Deserialize, JsonSchema)]
274302
struct DiskPathParam {

0 commit comments

Comments
 (0)