diff --git a/bin/propolis-server/src/lib/migrate/destination.rs b/bin/propolis-server/src/lib/migrate/destination.rs index 068c8e8cd..24ac63a01 100644 --- a/bin/propolis-server/src/lib/migrate/destination.rs +++ b/bin/propolis-server/src/lib/migrate/destination.rs @@ -80,7 +80,8 @@ pub(crate) async fn initiate( info!(log, "negotiating migration as destination"); // Build upgrade request to the source instance - // (we do this by hand because it's hidden from the OpenAPI spec) + // (we do this by hand to avoid a dependency from propolis-server to + // propolis-client) // TODO(#165): https (wss) // TODO: We need to make sure the src_addr is a valid target let src_migrate_url = format!( diff --git a/crates/propolis-server-api/src/lib.rs b/crates/propolis-server-api/src/lib.rs index a32ed0eb2..9e0fb9484 100644 --- a/crates/propolis-server-api/src/lib.rs +++ b/crates/propolis-server-api/src/lib.rs @@ -83,6 +83,10 @@ pub trait PropolisServerApi { websock: WebsocketConnection, ) -> WebsocketChannelResult; + // See the note on instance_migrate_start below. /instance/vnc is not + // currently used (as of 2025-10), but before it's used we'll want to think + // about versioning considerations for the WebSocket protocol, similar to + // instance_migrate_start. #[channel { protocol = WEBSOCKETS, path = "/instance/vnc", @@ -94,14 +98,27 @@ pub trait PropolisServerApi { websock: WebsocketConnection, ) -> dropshot::WebsocketChannelResult; - // This endpoint is meant to only be called during a migration from the - // destination instance to the source instance as part of the HTTP connection - // upgrade used to establish the migration link. We don't actually want this - // exported via OpenAPI clients. + /// DO NOT USE THIS IF YOU'RE NOT PROPOLIS-SERVER. + /// + /// Internal API called during a migration from a destination instance to + /// the source instance as part of the HTTP connection upgrade used to + /// establish the migration link. This API is exported via OpenAPI purely + /// to verify that its shape hasn't changed. + // + // # Versioning notes + // + // This API is expected to work even if the source and destination + // propolis-server instances are on different versions. There are two parts + // to versioning: + // + // 1. The parameters passed into the initial request. + // 2. The protocol used for WebSocket communication. + // + // Part 1 is verified by the Dropshot API manager. For part 2, + // propolis-server has internal support for protocol negotiation. #[channel { protocol = WEBSOCKETS, path = "/instance/migrate/{migration_id}/start", - unpublished = true, }] async fn instance_migrate_start( rqctx: RequestContext, diff --git a/openapi/propolis-server.json b/openapi/propolis-server.json index f97b2341f..0bc7baf43 100644 --- a/openapi/propolis-server.json +++ b/openapi/propolis-server.json @@ -189,6 +189,35 @@ } } }, + "/instance/migrate/{migration_id}/start": { + "get": { + "summary": "DO NOT USE THIS IF YOU'RE NOT PROPOLIS-SERVER.", + "description": "Internal API called during a migration from a destination instance to the source instance as part of the HTTP connection upgrade used to establish the migration link. This API is exported via OpenAPI purely to verify that its shape hasn't changed.", + "operationId": "instance_migrate_start", + "parameters": [ + { + "in": "path", + "name": "migration_id", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "default": { + "description": "", + "content": { + "*/*": { + "schema": {} + } + } + } + }, + "x-dropshot-websocket": {} + } + }, "/instance/migration-status": { "get": { "operationId": "instance_migrate_status",