Skip to content

Commit 1ce8ae6

Browse files
committed
add update start and stop without deciding what their responses are
1 parent 468a263 commit 1ce8ae6

File tree

4 files changed

+121
-3
lines changed

4 files changed

+121
-3
lines changed

nexus/src/external_api/http_entrypoints.rs

+51
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,8 @@ pub fn external_api() -> NexusApiDescription {
280280
api.register(system_component_version_list)?;
281281
api.register(system_update_list)?;
282282
api.register(system_update_view)?;
283+
api.register(system_update_start)?;
284+
api.register(system_update_stop)?;
283285
api.register(system_update_components_list)?;
284286

285287
api.register(user_list)?;
@@ -5120,6 +5122,9 @@ async fn system_update_list(
51205122
/// Path parameters for SystemUpdate requests
51215123
#[derive(Deserialize, JsonSchema)]
51225124
struct SystemUpdatePathParam {
5125+
// TODO: do updates have names? Should this therefore be NameOrId? Do we
5126+
// allow access by some other string identifier (like version) which, like
5127+
// Name, is disjoint with the set of Uuids? NameOrVersion?
51235128
update_id: Uuid,
51245129
}
51255130

@@ -5166,6 +5171,52 @@ async fn system_update_components_list(
51665171
apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await
51675172
}
51685173

5174+
// TODO: 204 isn't the right response
5175+
5176+
/// Start system update
5177+
#[endpoint {
5178+
method = POST,
5179+
path = "/v1/system/update/updates/{update_id}/start",
5180+
tags = ["system"],
5181+
}]
5182+
async fn system_update_start(
5183+
rqctx: Arc<RequestContext<Arc<ServerContext>>>,
5184+
path_params: Path<SystemUpdatePathParam>,
5185+
) -> Result<HttpResponseUpdatedNoContent, HttpError> {
5186+
let apictx = rqctx.context();
5187+
let _nexus = &apictx.nexus;
5188+
let _path = path_params.into_inner();
5189+
let handler = async {
5190+
let _opctx = OpContext::for_external_api(&rqctx).await?;
5191+
Ok(HttpResponseUpdatedNoContent())
5192+
};
5193+
apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await
5194+
}
5195+
5196+
// TODO: since there can only be one system update going at a time, does /stop
5197+
// even need to hang off the detail endpoint? `POST /system/update/stop` would
5198+
// be sufficient, and if the system is currently steady, it would be a noop
5199+
5200+
/// Stop system update
5201+
#[endpoint {
5202+
method = POST,
5203+
path = "/v1/system/update/updates/{update_id}/stop",
5204+
tags = ["system"],
5205+
}]
5206+
async fn system_update_stop(
5207+
rqctx: Arc<RequestContext<Arc<ServerContext>>>,
5208+
path_params: Path<SystemUpdatePathParam>,
5209+
) -> Result<HttpResponseUpdatedNoContent, HttpError> {
5210+
let apictx = rqctx.context();
5211+
let _nexus = &apictx.nexus;
5212+
let _path = path_params.into_inner();
5213+
let handler = async {
5214+
let _opctx = OpContext::for_external_api(&rqctx).await?;
5215+
Ok(HttpResponseUpdatedNoContent())
5216+
};
5217+
apictx.external_latencies.instrument_dropshot_handler(&rqctx, handler).await
5218+
}
5219+
51695220
// Sagas
51705221

51715222
/// List sagas

nexus/tests/output/nexus_tags.txt

+2
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,8 @@ system_image_view /system/images/{image_name}
181181
system_image_view_by_id /system/by-id/images/{id}
182182
system_update_components_list /v1/system/update/updates/{update_id}/components
183183
system_update_list /v1/system/update/updates
184+
system_update_start /v1/system/update/updates/{update_id}/start
185+
system_update_stop /v1/system/update/updates/{update_id}/stop
184186
system_update_view /v1/system/update/updates/{update_id}
185187
system_user_list /system/user
186188
system_user_view /system/user/{user_name}

nexus/types/src/external_api/views.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,8 @@ pub enum VersionStatus {
479479
pub struct SystemVersion {
480480
pub version_range: VersionRange,
481481
pub status: VersionStatus,
482+
// TODO: time_released? time_last_applied? I got a fever and the only
483+
// prescription is more timestamps
482484
}
483485

484486
#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)]
@@ -502,8 +504,9 @@ pub struct ComponentUpdate {
502504
pub device_id: String,
503505
pub device_type: DeviceType,
504506
pub version: SemverVersion,
505-
/// ID of the parent component, e.g., the sled a disk belongs to. Value will
506-
/// be `None` for top-level components whose "parent" is the rack.
507+
// TODO: parent ID doesn't need to be optional if we say top-level
508+
// components have the rack as their parent
509+
/// ID of the parent component. Not present for top-level components.
507510
pub parent_id: Option<Uuid>,
508511
}
509512

openapi/nexus.json

+63-1
Original file line numberDiff line numberDiff line change
@@ -8598,6 +8598,68 @@
85988598
}
85998599
}
86008600
},
8601+
"/v1/system/update/updates/{update_id}/start": {
8602+
"post": {
8603+
"tags": [
8604+
"system"
8605+
],
8606+
"summary": "Start system update",
8607+
"operationId": "system_update_start",
8608+
"parameters": [
8609+
{
8610+
"in": "path",
8611+
"name": "update_id",
8612+
"required": true,
8613+
"schema": {
8614+
"type": "string",
8615+
"format": "uuid"
8616+
}
8617+
}
8618+
],
8619+
"responses": {
8620+
"204": {
8621+
"description": "resource updated"
8622+
},
8623+
"4XX": {
8624+
"$ref": "#/components/responses/Error"
8625+
},
8626+
"5XX": {
8627+
"$ref": "#/components/responses/Error"
8628+
}
8629+
}
8630+
}
8631+
},
8632+
"/v1/system/update/updates/{update_id}/stop": {
8633+
"post": {
8634+
"tags": [
8635+
"system"
8636+
],
8637+
"summary": "Stop system update",
8638+
"operationId": "system_update_stop",
8639+
"parameters": [
8640+
{
8641+
"in": "path",
8642+
"name": "update_id",
8643+
"required": true,
8644+
"schema": {
8645+
"type": "string",
8646+
"format": "uuid"
8647+
}
8648+
}
8649+
],
8650+
"responses": {
8651+
"204": {
8652+
"description": "resource updated"
8653+
},
8654+
"4XX": {
8655+
"$ref": "#/components/responses/Error"
8656+
},
8657+
"5XX": {
8658+
"$ref": "#/components/responses/Error"
8659+
}
8660+
}
8661+
}
8662+
},
86018663
"/v1/system/update/version": {
86028664
"get": {
86038665
"tags": [
@@ -8858,7 +8920,7 @@
88588920
},
88598921
"parent_id": {
88608922
"nullable": true,
8861-
"description": "ID of the parent component, e.g., the sled a disk belongs to. Value will be `None` for top-level components whose \"parent\" is the rack.",
8923+
"description": "ID of the parent component. Not present for top-level components.",
88628924
"type": "string",
88638925
"format": "uuid"
88648926
},

0 commit comments

Comments
 (0)