From ba427960259ccbb3592f229d491dccee48ee1c77 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Tue, 1 Apr 2025 10:15:07 -0700 Subject: [PATCH 01/32] [ereport] index ereport ingestion by SP type/slot Currently, the initial ereport ingestion API I added in #7833 proposed a single dropshot API that would be implemented by both sled-agent and MGS. This was possible because the initial design would have indexed all ereport producers (reporters) by a UUID. However, per recent conversations with @cbiffle and @jgallagher, we've determined that Nexus will instead request ereports from service processors indexed by SP physical topology (e.g. type and slot), like the rest of the MGS HTTP API. Therefore, we can no longer have a single HTTP API for ereporters that's implemented by both MGS and sled-agents, and instead, SP ereport ingestion should be a new endpoint on the MGS API. This commit does that, moving the ereport query params into `ereport-types`, eliminating the separate `ereport-api` and `ereport-client` crates, and adding an ereport-ingestion-by-SP-location endpoint to the management gateway API. --- Cargo.lock | 41 +--- Cargo.toml | 6 - clients/ereport-client/Cargo.toml | 22 -- clients/ereport-client/src/lib.rs | 23 -- dev-tools/ls-apis/api-manifest.toml | 12 - dev-tools/openapi-manager/Cargo.toml | 1 - dev-tools/openapi-manager/src/omicron.rs | 12 - ereport/api/Cargo.toml | 19 -- ereport/api/src/lib.rs | 116 --------- ereport/types/Cargo.toml | 3 +- ereport/types/src/lib.rs | 44 ++++ gateway-api/Cargo.toml | 1 + gateway-api/src/lib.rs | 15 ++ gateway/Cargo.toml | 1 - gateway/src/http_entrypoints.rs | 14 ++ nexus/Cargo.toml | 1 - openapi/ereport/ereport-1.0.0-e41934.json | 272 ---------------------- openapi/ereport/ereport-latest.json | 1 - openapi/gateway.json | 232 ++++++++++++++++++ sled-agent/Cargo.toml | 1 - 20 files changed, 310 insertions(+), 527 deletions(-) delete mode 100644 clients/ereport-client/Cargo.toml delete mode 100644 clients/ereport-client/src/lib.rs delete mode 100644 ereport/api/Cargo.toml delete mode 100644 ereport/api/src/lib.rs delete mode 100644 openapi/ereport/ereport-1.0.0-e41934.json delete mode 120000 openapi/ereport/ereport-latest.json diff --git a/Cargo.lock b/Cargo.lock index 4a4684ef720..300f85ff92c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3032,45 +3032,11 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" -[[package]] -name = "ereport-api" -version = "0.1.0" -dependencies = [ - "dropshot 0.16.0", - "ereport-types", - "omicron-workspace-hack", - "openapi-manager-types", - "schemars", - "semver 1.0.25", - "serde", - "serde_json", - "thiserror 1.0.69", - "uuid", -] - -[[package]] -name = "ereport-client" -version = "0.1.0" -dependencies = [ - "chrono", - "ereport-types", - "expectorate", - "http", - "omicron-uuid-kinds", - "omicron-workspace-hack", - "progenitor 0.9.1", - "reqwest", - "schemars", - "serde", - "serde_json", - "slog", - "uuid", -] - [[package]] name = "ereport-types" version = "0.1.0" dependencies = [ + "dropshot 0.16.0", "omicron-uuid-kinds", "omicron-workspace-hack", "schemars", @@ -3474,6 +3440,7 @@ name = "gateway-api" version = "0.1.0" dependencies = [ "dropshot 0.16.0", + "ereport-types", "gateway-types", "omicron-common", "omicron-uuid-kinds", @@ -6975,7 +6942,6 @@ dependencies = [ "chrono", "clap", "dropshot 0.16.0", - "ereport-api", "expectorate", "futures", "gateway-api", @@ -7096,7 +7062,6 @@ dependencies = [ "dns-service-client", "dpd-client", "dropshot 0.16.0", - "ereport-client", "expectorate", "fatfs", "futures", @@ -7446,7 +7411,6 @@ dependencies = [ "dns-service-client", "dpd-client", "dropshot 0.16.0", - "ereport-api", "expectorate", "flate2", "flume", @@ -7809,7 +7773,6 @@ dependencies = [ "debug-ignore", "dns-server-api", "dropshot 0.16.0", - "ereport-api", "fs-err", "gateway-api", "hex", diff --git a/Cargo.toml b/Cargo.toml index fa683135868..350e0fb6263 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,6 @@ members = [ "clients/ddm-admin-client", "clients/dns-service-client", "clients/dpd-client", - "clients/ereport-client", "clients/gateway-client", "clients/installinator-client", "clients/nexus-client", @@ -50,7 +49,6 @@ members = [ "dns-server", "dns-server-api", "end-to-end-tests", - "ereport/api", "ereport/types", "gateway", "gateway-api", @@ -154,7 +152,6 @@ default-members = [ "clients/ddm-admin-client", "clients/dns-service-client", "clients/dpd-client", - "clients/ereport-client", "clients/gateway-client", "clients/installinator-client", "clients/nexus-client", @@ -192,7 +189,6 @@ default-members = [ "dns-server", "dns-server-api", "end-to-end-tests", - "ereport/api", "ereport/types", "gateway", "gateway-api", @@ -393,8 +389,6 @@ dpd-client = { path = "clients/dpd-client" } dropshot = { version = "0.16.0", features = [ "usdt-probes" ] } dyn-clone = "1.0.19" either = "1.14.0" -ereport-api = { path = "ereport/api" } -ereport-client = { path = "clients/ereport-client" } ereport-types = { path = "ereport/types" } expectorate = "1.1.0" fatfs = "0.3.6" diff --git a/clients/ereport-client/Cargo.toml b/clients/ereport-client/Cargo.toml deleted file mode 100644 index 5cc61ab5974..00000000000 --- a/clients/ereport-client/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "ereport-client" -version = "0.1.0" -edition = "2024" - -[lints] -workspace = true - -[dependencies] -chrono.workspace = true -expectorate.workspace = true -ereport-types.workspace = true -http.workspace = true -progenitor.workspace = true -reqwest = { workspace = true, features = ["json", "rustls-tls", "stream"] } -schemars.workspace = true -serde.workspace = true -serde_json.workspace = true -slog.workspace = true -omicron-uuid-kinds.workspace = true -omicron-workspace-hack.workspace = true -uuid.workspace = true diff --git a/clients/ereport-client/src/lib.rs b/clients/ereport-client/src/lib.rs deleted file mode 100644 index 6b890ee2517..00000000000 --- a/clients/ereport-client/src/lib.rs +++ /dev/null @@ -1,23 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -progenitor::generate_api!( - spec = "../../openapi/ereport/ereport-latest.json", - inner_type = slog::Logger, - derives = [schemars::JsonSchema, Clone, Eq, PartialEq], - pre_hook = (|log: &slog::Logger, request: &reqwest::Request| { - slog::debug!(log, "client request"; - "method" => %request.method(), - "uri" => %request.url(), - "body" => ?&request.body(), - ); - }), - post_hook = (|log: &slog::Logger, result: &Result<_, _>| { - slog::debug!(log, "client response"; "result" => ?result); - }), - replace = { - Ena = ereport_types::Ena, - TypedUuidForEreporterGenerationKind = omicron_uuid_kinds::EreporterGenerationUuid, - } -); diff --git a/dev-tools/ls-apis/api-manifest.toml b/dev-tools/ls-apis/api-manifest.toml index 7762d531436..67030ef01e5 100644 --- a/dev-tools/ls-apis/api-manifest.toml +++ b/dev-tools/ls-apis/api-manifest.toml @@ -266,18 +266,6 @@ and exists as a client library within omicron. This is because the Dendrite \ repo is not currently open source. """ -[[apis]] -client_package_name = "ereport-client" -label = "ereport" -server_package_name = "ereport-api" -versioned_how = "server" -notes = """ -Implemented by sled-agents and by MGS, and consumed by Nexus to collect \ -ereports. - -The sled-agent and MGS APIs are server-versioned, so this can be as well. -""" - [[apis]] client_package_name = "lldpd-client" label = "LLDP daemon" diff --git a/dev-tools/openapi-manager/Cargo.toml b/dev-tools/openapi-manager/Cargo.toml index 288e68e4fd3..fc9048412fc 100644 --- a/dev-tools/openapi-manager/Cargo.toml +++ b/dev-tools/openapi-manager/Cargo.toml @@ -18,7 +18,6 @@ cockroach-admin-api.workspace = true debug-ignore.workspace = true dns-server-api.workspace = true dropshot.workspace = true -ereport-api.workspace = true hex.workspace = true fs-err.workspace = true gateway-api.workspace = true diff --git a/dev-tools/openapi-manager/src/omicron.rs b/dev-tools/openapi-manager/src/omicron.rs index a415e68a002..cc562cd4871 100644 --- a/dev-tools/openapi-manager/src/omicron.rs +++ b/dev-tools/openapi-manager/src/omicron.rs @@ -85,18 +85,6 @@ pub fn all_apis() -> Vec { ident: "dns-server", extra_validation: None, }, - ManagedApiConfig { - title: "Ereport Reporter API", - versions: Versions::new_versioned( - ereport_api::supported_versions() - ), - description: "API for ereport producers", - boundary: ApiBoundary::Internal, - api_description: - ereport_api::ereport_api_mod::stub_api_description, - ident: "ereport", - extra_validation: None, - }, ManagedApiConfig { title: "Installinator API", versions: Versions::new_lockstep(semver::Version::new(0,0,1)), diff --git a/ereport/api/Cargo.toml b/ereport/api/Cargo.toml deleted file mode 100644 index cf154dc5e25..00000000000 --- a/ereport/api/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "ereport-api" -version = "0.1.0" -edition = "2024" - -[dependencies] -ereport-types.workspace = true -dropshot.workspace = true -openapi-manager-types.workspace = true -schemars.workspace = true -semver.workspace = true -serde.workspace = true -serde_json.workspace = true -thiserror.workspace = true -uuid.workspace = true -omicron-workspace-hack.workspace = true - -[lints] -workspace = true diff --git a/ereport/api/src/lib.rs b/ereport/api/src/lib.rs deleted file mode 100644 index 145ca37f450..00000000000 --- a/ereport/api/src/lib.rs +++ /dev/null @@ -1,116 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. - -//! HTTP API for ereport producers. - -use dropshot::HttpError; -use dropshot::HttpResponseOk; -use dropshot::Path; -use dropshot::Query; -use dropshot::RequestContext; -use dropshot::ResultsPage; -pub use ereport_types::Ena; -pub use ereport_types::Ereport; -pub use ereport_types::EreporterGenerationUuid; -pub use ereport_types::Reporter; -use openapi_manager_types::{ - SupportedVersion, SupportedVersions, api_versions, -}; -use schemars::JsonSchema; -use serde::Deserialize; -use serde::Serialize; -use std::num::NonZeroU32; -use uuid::Uuid; - -api_versions!([ - // WHEN CHANGING THE API (part 1 of 2): - // - // +- Pick a new semver and define it in the list below. The list MUST - // | remain sorted, which generally means that your version should go at - // | the very top. - // | - // | Duplicate this line, uncomment the *second* copy, update that copy for - // | your new API version, and leave the first copy commented out as an - // | example for the next person. - // v - // (next_int, IDENT), - (1, INITIAL), -]); - -// WHEN CHANGING THE API (part 2 of 2): -// -// The call to `api_versions!` above defines constants of type -// `semver::Version` that you can use in your Dropshot API definition to specify -// the version when a particular endpoint was added or removed. For example, if -// you used: -// -// (2, ADD_FOOBAR) -// -// Then you could use `VERSION_ADD_FOOBAR` as the version in which endpoints -// were added or removed. - -/// API for ereport producers. -#[dropshot::api_description] -pub trait EreportApi { - type Context; - - /// Collect a tranche of ereports from this reporter. - #[endpoint { - method = POST, - path = "/ereports/{reporter_id}", - }] - async fn ereports_collect( - rqctx: RequestContext, - path: Path, - query: Query, - ) -> Result, HttpError>; -} - -#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] -pub struct ReporterPath { - /// The UUID of the reporter from which to collect ereports. - pub reporter_id: Uuid, -} - -#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] -pub struct EreportQuery { - /// The generation (restart nonce) of the reporter at which all other query - /// parameters are valid. - /// - /// If this value does not match the reporter's current generation, the - /// reporter's response will include the current generation, and will start - /// at the earliest known ENA, rather than the provided `last_seen` ENA.` - pub generation: EreporterGenerationUuid, - - /// If present, the reporter should not include ENAs earlier than this one - /// in its response, provided that the query's requested generation matches - /// the current generation. - pub start_at: Option, - - /// The ENA of the last ereport committed to persistent storage from the - /// requested reporter generation. - /// - /// If the generation parameter matches the reporter's current generation, - /// it is permitted to discard any ereports with ENAs up to and including - /// this value. If the generation has changed from the provided generation, - /// the reporter will not discard data. - pub committed: Option, - - /// Maximum number of ereports to return in this tranche. - pub limit: NonZeroU32, -} - -/// A tranche of ereports received from a reporter. -#[derive(Debug, Serialize, Deserialize, JsonSchema)] -pub struct Ereports { - /// The reporter's current generation ID. - /// - /// If this is not equal to the current known generation, then the reporter - /// has restarted. - pub generation: EreporterGenerationUuid, - /// The ereports in this tranche, and the ENA of the next page of ereports - /// (if one exists).) - #[serde(flatten)] - pub reports: ResultsPage, -} diff --git a/ereport/types/Cargo.toml b/ereport/types/Cargo.toml index cd1bb0d812f..ec808747203 100644 --- a/ereport/types/Cargo.toml +++ b/ereport/types/Cargo.toml @@ -4,12 +4,13 @@ version = "0.1.0" edition = "2024" [dependencies] -omicron-uuid-kinds.workspace = true +dropshot.workspace = true schemars.workspace = true serde.workspace = true serde_json.workspace = true uuid.workspace = true omicron-workspace-hack.workspace = true +omicron-uuid-kinds.workspace = true [lints] workspace = true diff --git a/ereport/types/src/lib.rs b/ereport/types/src/lib.rs index 2835f48248f..2d911413ecc 100644 --- a/ereport/types/src/lib.rs +++ b/ereport/types/src/lib.rs @@ -9,6 +9,7 @@ pub use omicron_uuid_kinds::EreporterGenerationUuid; use schemars::JsonSchema; use serde::Deserialize; use serde::Serialize; +use std::num::NonZeroU32; use uuid::Uuid; /// An ereport message. @@ -101,6 +102,49 @@ pub struct Event { pub data: serde_json::Value, } +/// Query parameters to request a tranche of ereports from a reporter. +#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] +pub struct EreportQuery { + /// The generation (restart nonce) of the reporter at which all other query + /// parameters are valid. + /// + /// If this value does not match the reporter's current generation, the + /// reporter's response will include the current generation, and will start + /// at the earliest known ENA, rather than the provided `last_seen` ENA.` + pub generation: EreporterGenerationUuid, + + /// If present, the reporter should not include ENAs earlier than this one + /// in its response, provided that the query's requested generation matches + /// the current generation. + pub start_at: Option, + + /// The ENA of the last ereport committed to persistent storage from the + /// requested reporter generation. + /// + /// If the generation parameter matches the reporter's current generation, + /// it is permitted to discard any ereports with ENAs up to and including + /// this value. If the generation has changed from the provided generation, + /// the reporter will not discard data. + pub committed: Option, + + /// Maximum number of ereports to return in this tranche. + pub limit: NonZeroU32, +} + +/// A tranche of ereports received from a reporter. +#[derive(Debug, Serialize, Deserialize, JsonSchema)] +pub struct Ereports { + /// The reporter's current generation ID. + /// + /// If this is not equal to the current known generation, then the reporter + /// has restarted. + pub generation: EreporterGenerationUuid, + /// The ereports in this tranche, and the ENA of the next page of ereports + /// (if one exists).) + #[serde(flatten)] + pub reports: dropshot::ResultsPage, +} + #[cfg(test)] mod tests { use super::*; diff --git a/gateway-api/Cargo.toml b/gateway-api/Cargo.toml index 840bb90b689..45aa8d4fa83 100644 --- a/gateway-api/Cargo.toml +++ b/gateway-api/Cargo.toml @@ -9,6 +9,7 @@ workspace = true [dependencies] dropshot.workspace = true +ereport-types.workspace = true gateway-types.workspace = true omicron-common.workspace = true omicron-uuid-kinds.workspace = true diff --git a/gateway-api/src/lib.rs b/gateway-api/src/lib.rs index e0c9993b50f..93246444bb5 100644 --- a/gateway-api/src/lib.rs +++ b/gateway-api/src/lib.rs @@ -475,6 +475,21 @@ pub trait GatewayApi { async fn sp_all_ids( rqctx: RequestContext, ) -> Result>, HttpError>; + + /// Request ereports from the target service processor. + /// + /// Query parameters provide the ENAs of the initial ereport in the returned + /// tranche, the SP's restart ID that the control plane believes is current, + /// and the (optional) last committed ENA. + #[endpoint { + method = POST, + path = "/sp/{type}/{slot}/ereports" + }] + async fn sp_ereports_ingest( + rqctx: RequestContext, + path: Path, + query: Query, + ) -> Result, HttpError>; } #[derive(Deserialize, JsonSchema)] diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index bbe88ca07cc..e754daf1855 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -14,7 +14,6 @@ camino.workspace = true chrono.workspace = true clap.workspace = true dropshot.workspace = true -ereport-api.workspace = true futures.workspace = true gateway-api.workspace = true gateway-messages.workspace = true diff --git a/gateway/src/http_entrypoints.rs b/gateway/src/http_entrypoints.rs index 3bcb17a57c7..00403cc067f 100644 --- a/gateway/src/http_entrypoints.rs +++ b/gateway/src/http_entrypoints.rs @@ -932,6 +932,20 @@ impl GatewayApi for GatewayImpl { }; apictx.latencies.instrument_dropshot_handler(&rqctx, handler).await } + + async fn sp_ereports_ingest( + rqctx: RequestContext, + path: Path, + query: Query, + ) -> Result, HttpError> { + let apictx = rqctx.context(); + let handler = async { + HttpError::for_internal_error( + "endpoint not yet implemented".to_string(), + ) + }; + apictx.latencies.instrument_dropshot_handler(&rqctx, handler).await + } } // wrap `SpComponent::try_from(&str)` into a usable form for dropshot endpoints diff --git a/nexus/Cargo.toml b/nexus/Cargo.toml index 157e326ecfa..3658e4a72cc 100644 --- a/nexus/Cargo.toml +++ b/nexus/Cargo.toml @@ -31,7 +31,6 @@ crucible-pantry-client.workspace = true crucible-common.workspace = true dns-service-client.workspace = true dpd-client.workspace = true -ereport-client.workspace = true mg-admin-client.workspace = true dropshot.workspace = true fatfs.workspace = true diff --git a/openapi/ereport/ereport-1.0.0-e41934.json b/openapi/ereport/ereport-1.0.0-e41934.json deleted file mode 100644 index be4cce56350..00000000000 --- a/openapi/ereport/ereport-1.0.0-e41934.json +++ /dev/null @@ -1,272 +0,0 @@ -{ - "openapi": "3.0.3", - "info": { - "title": "Ereport Reporter API", - "description": "API for ereport producers", - "contact": { - "url": "https://oxide.computer", - "email": "api@oxide.computer" - }, - "version": "1.0.0" - }, - "paths": { - "/ereports/{reporter_id}": { - "post": { - "summary": "Collect a tranche of ereports from this reporter.", - "operationId": "ereports_collect", - "parameters": [ - { - "in": "path", - "name": "reporter_id", - "description": "The UUID of the reporter from which to collect ereports.", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "in": "query", - "name": "committed", - "description": "The ENA of the last ereport committed to persistent storage from the requested reporter generation.\n\nIf the generation parameter matches the reporter's current generation, it is permitted to discard any ereports with ENAs up to and including this value. If the generation has changed from the provided generation, the reporter will not discard data.", - "schema": { - "$ref": "#/components/schemas/Ena" - } - }, - { - "in": "query", - "name": "generation", - "description": "The generation (restart nonce) of the reporter at which all other query parameters are valid.\n\nIf this value does not match the reporter's current generation, the reporter's response will include the current generation, and will start at the earliest known ENA, rather than the provided `last_seen` ENA.`", - "required": true, - "schema": { - "$ref": "#/components/schemas/TypedUuidForEreporterGenerationKind" - } - }, - { - "in": "query", - "name": "limit", - "description": "Maximum number of ereports to return in this tranche.", - "required": true, - "schema": { - "type": "integer", - "format": "uint32", - "minimum": 1 - } - }, - { - "in": "query", - "name": "start_at", - "description": "If present, the reporter should not include ENAs earlier than this one in its response, provided that the query's requested generation matches the current generation.", - "schema": { - "$ref": "#/components/schemas/Ena" - } - } - ], - "responses": { - "200": { - "description": "successful operation", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Ereports" - } - } - } - }, - "4XX": { - "$ref": "#/components/responses/Error" - }, - "5XX": { - "$ref": "#/components/responses/Error" - } - } - } - } - }, - "components": { - "schemas": { - "Ena": { - "description": "An Error Numeric Association (ENA)", - "type": "integer", - "format": "uint64", - "minimum": 0 - }, - "Ereport": { - "description": "An ereport message.", - "type": "object", - "properties": { - "ena": { - "description": "The ENA of the ereport.", - "allOf": [ - { - "$ref": "#/components/schemas/Ena" - } - ] - }, - "report": { - "description": "The body of the ereport.", - "allOf": [ - { - "$ref": "#/components/schemas/ReportKind" - } - ] - } - }, - "required": [ - "ena", - "report" - ] - }, - "Ereports": { - "description": "A tranche of ereports received from a reporter.", - "type": "object", - "properties": { - "generation": { - "description": "The reporter's current generation ID.\n\nIf this is not equal to the current known generation, then the reporter has restarted.", - "allOf": [ - { - "$ref": "#/components/schemas/TypedUuidForEreporterGenerationKind" - } - ] - }, - "items": { - "description": "list of items on this page of results", - "type": "array", - "items": { - "$ref": "#/components/schemas/Ereport" - } - }, - "next_page": { - "nullable": true, - "description": "token used to fetch the next page of results (if any)", - "type": "string" - } - }, - "required": [ - "generation", - "items" - ] - }, - "Error": { - "description": "Error information from a response.", - "type": "object", - "properties": { - "error_code": { - "type": "string" - }, - "message": { - "type": "string" - }, - "request_id": { - "type": "string" - } - }, - "required": [ - "message", - "request_id" - ] - }, - "Event": { - "type": "object", - "properties": { - "class": { - "type": "string" - }, - "data": {} - }, - "required": [ - "class", - "data" - ] - }, - "LossReport": { - "description": "The number of ereports that were discarded, if it is known.\n\nIf ereports are dropped because a buffer has reached its capacity, the reporter is strongly encouraged to attempt to count the number of ereports lost. In other cases, such as a reporter crashing and restarting, the reporter may not be capable of determining the number of ereports that were lost, or even *if* data loss actually occurred.", - "oneOf": [ - { - "description": "An unknown number of ereports MAY have been lost.", - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "unknown" - ] - } - }, - "required": [ - "type" - ] - }, - { - "description": "The provided number of ereports are known to have been lost.", - "type": "object", - "properties": { - "lost": { - "type": "integer", - "format": "uint32", - "minimum": 0 - }, - "type": { - "type": "string", - "enum": [ - "exact" - ] - } - }, - "required": [ - "lost", - "type" - ] - } - ] - }, - "ReportKind": { - "description": "The body of an ereport: either an event is reported, or a loss report.", - "oneOf": [ - { - "description": "An ereport.", - "type": "object", - "properties": { - "event": { - "$ref": "#/components/schemas/Event" - } - }, - "required": [ - "event" - ], - "additionalProperties": false - }, - { - "description": "Ereports were lost, or may have been lost.", - "type": "object", - "properties": { - "loss": { - "$ref": "#/components/schemas/LossReport" - } - }, - "required": [ - "loss" - ], - "additionalProperties": false - } - ] - }, - "TypedUuidForEreporterGenerationKind": { - "type": "string", - "format": "uuid" - } - }, - "responses": { - "Error": { - "description": "Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - } - } - } -} diff --git a/openapi/ereport/ereport-latest.json b/openapi/ereport/ereport-latest.json deleted file mode 120000 index bb893cfafb5..00000000000 --- a/openapi/ereport/ereport-latest.json +++ /dev/null @@ -1 +0,0 @@ -ereport-1.0.0-e41934.json \ No newline at end of file diff --git a/openapi/gateway.json b/openapi/gateway.json index b1a7adc96e2..582e4ba33c9 100644 --- a/openapi/gateway.json +++ b/openapi/gateway.json @@ -1110,6 +1110,87 @@ } } }, + "/sp/{type}/{slot}/ereports": { + "post": { + "summary": "Request ereports from the target service processor.", + "description": "Query parameters provide the ENAs of the initial ereport in the returned tranche, the SP's restart ID that the control plane believes is current, and the (optional) last committed ENA.", + "operationId": "sp_ereports_ingest", + "parameters": [ + { + "in": "path", + "name": "slot", + "required": true, + "schema": { + "type": "integer", + "format": "uint32", + "minimum": 0 + } + }, + { + "in": "path", + "name": "type", + "required": true, + "schema": { + "$ref": "#/components/schemas/SpType" + } + }, + { + "in": "query", + "name": "committed", + "description": "The ENA of the last ereport committed to persistent storage from the requested reporter generation.\n\nIf the generation parameter matches the reporter's current generation, it is permitted to discard any ereports with ENAs up to and including this value. If the generation has changed from the provided generation, the reporter will not discard data.", + "schema": { + "$ref": "#/components/schemas/Ena" + } + }, + { + "in": "query", + "name": "generation", + "description": "The generation (restart nonce) of the reporter at which all other query parameters are valid.\n\nIf this value does not match the reporter's current generation, the reporter's response will include the current generation, and will start at the earliest known ENA, rather than the provided `last_seen` ENA.`", + "required": true, + "schema": { + "$ref": "#/components/schemas/TypedUuidForEreporterGenerationKind" + } + }, + { + "in": "query", + "name": "limit", + "description": "Maximum number of ereports to return in this tranche.", + "required": true, + "schema": { + "type": "integer", + "format": "uint32", + "minimum": 1 + } + }, + { + "in": "query", + "name": "start_at", + "description": "If present, the reporter should not include ENAs earlier than this one in its response, provided that the query's requested generation matches the current generation.", + "schema": { + "$ref": "#/components/schemas/Ena" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Ereports" + } + } + } + }, + "4XX": { + "$ref": "#/components/responses/Error" + }, + "5XX": { + "$ref": "#/components/responses/Error" + } + } + } + }, "/sp/{type}/{slot}/host-phase2-progress": { "get": { "summary": "Get the most recent host phase2 request we've seen from the target SP.", @@ -1533,6 +1614,68 @@ "secs" ] }, + "Ena": { + "description": "An Error Numeric Association (ENA)", + "type": "integer", + "format": "uint64", + "minimum": 0 + }, + "Ereport": { + "description": "An ereport message.", + "type": "object", + "properties": { + "ena": { + "description": "The ENA of the ereport.", + "allOf": [ + { + "$ref": "#/components/schemas/Ena" + } + ] + }, + "report": { + "description": "The body of the ereport.", + "allOf": [ + { + "$ref": "#/components/schemas/ReportKind" + } + ] + } + }, + "required": [ + "ena", + "report" + ] + }, + "Ereports": { + "description": "A tranche of ereports received from a reporter.", + "type": "object", + "properties": { + "generation": { + "description": "The reporter's current generation ID.\n\nIf this is not equal to the current known generation, then the reporter has restarted.", + "allOf": [ + { + "$ref": "#/components/schemas/TypedUuidForEreporterGenerationKind" + } + ] + }, + "items": { + "description": "list of items on this page of results", + "type": "array", + "items": { + "$ref": "#/components/schemas/Ereport" + } + }, + "next_page": { + "nullable": true, + "description": "token used to fetch the next page of results (if any)", + "type": "string" + } + }, + "required": [ + "generation", + "items" + ] + }, "Error": { "description": "Error information from a response.", "type": "object", @@ -1552,6 +1695,19 @@ "request_id" ] }, + "Event": { + "type": "object", + "properties": { + "class": { + "type": "string" + }, + "data": {} + }, + "required": [ + "class", + "data" + ] + }, "GetCfpaParams": { "type": "object", "properties": { @@ -1752,6 +1908,47 @@ } ] }, + "LossReport": { + "description": "The number of ereports that were discarded, if it is known.\n\nIf ereports are dropped because a buffer has reached its capacity, the reporter is strongly encouraged to attempt to count the number of ereports lost. In other cases, such as a reporter crashing and restarting, the reporter may not be capable of determining the number of ereports that were lost, or even *if* data loss actually occurred.", + "oneOf": [ + { + "description": "An unknown number of ereports MAY have been lost.", + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "unknown" + ] + } + }, + "required": [ + "type" + ] + }, + { + "description": "The provided number of ereports are known to have been lost.", + "type": "object", + "properties": { + "lost": { + "type": "integer", + "format": "uint32", + "minimum": 0 + }, + "type": { + "type": "string", + "enum": [ + "exact" + ] + } + }, + "required": [ + "lost", + "type" + ] + } + ] + }, "MeasurementErrorCode": { "oneOf": [ { @@ -2321,6 +2518,37 @@ "A2" ] }, + "ReportKind": { + "description": "The body of an ereport: either an event is reported, or a loss report.", + "oneOf": [ + { + "description": "An ereport.", + "type": "object", + "properties": { + "event": { + "$ref": "#/components/schemas/Event" + } + }, + "required": [ + "event" + ], + "additionalProperties": false + }, + { + "description": "Ereports were lost, or may have been lost.", + "type": "object", + "properties": { + "loss": { + "$ref": "#/components/schemas/LossReport" + } + }, + "required": [ + "loss" + ], + "additionalProperties": false + } + ] + }, "RotCfpa": { "type": "object", "properties": { @@ -3418,6 +3646,10 @@ } ] }, + "TypedUuidForEreporterGenerationKind": { + "type": "string", + "format": "uuid" + }, "UpdateAbortBody": { "type": "object", "properties": { diff --git a/sled-agent/Cargo.toml b/sled-agent/Cargo.toml index c03919292d7..39e5a46b641 100644 --- a/sled-agent/Cargo.toml +++ b/sled-agent/Cargo.toml @@ -31,7 +31,6 @@ dns-service-client.workspace = true dpd-client.workspace = true display-error-chain.workspace = true dropshot.workspace = true -ereport-api.workspace = true flate2.workspace = true flume.workspace = true futures.workspace = true From cb673ec31a42818c9bc90b84e57279fbc532dfe0 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Tue, 1 Apr 2025 10:36:50 -0700 Subject: [PATCH 02/32] we're calling them "restart IDs" now --- Cargo.lock | 1 - ereport/types/Cargo.toml | 1 - ereport/types/src/lib.rs | 39 ++++++++++++++----------------------- openapi/gateway.json | 42 ++++++++++++++++++++-------------------- uuid-kinds/src/lib.rs | 2 +- 5 files changed, 37 insertions(+), 48 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 300f85ff92c..3431feefd0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3042,7 +3042,6 @@ dependencies = [ "schemars", "serde", "serde_json", - "uuid", ] [[package]] diff --git a/ereport/types/Cargo.toml b/ereport/types/Cargo.toml index ec808747203..9f6137ab010 100644 --- a/ereport/types/Cargo.toml +++ b/ereport/types/Cargo.toml @@ -8,7 +8,6 @@ dropshot.workspace = true schemars.workspace = true serde.workspace = true serde_json.workspace = true -uuid.workspace = true omicron-workspace-hack.workspace = true omicron-uuid-kinds.workspace = true diff --git a/ereport/types/src/lib.rs b/ereport/types/src/lib.rs index 2d911413ecc..1510466da3a 100644 --- a/ereport/types/src/lib.rs +++ b/ereport/types/src/lib.rs @@ -5,12 +5,11 @@ //! Core types for representing ereports. use core::fmt; -pub use omicron_uuid_kinds::EreporterGenerationUuid; +pub use omicron_uuid_kinds::EreporterRestartUuid; use schemars::JsonSchema; use serde::Deserialize; use serde::Serialize; use std::num::NonZeroU32; -use uuid::Uuid; /// An ereport message. #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)] @@ -59,14 +58,6 @@ impl fmt::LowerHex for Ena { fmt::LowerHex::fmt(&self.0, f) } } -/// Uniquely identifies the entity that generated an ereport. -#[derive( - Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema, -)] -pub struct Reporter { - pub reporter_id: Uuid, - pub gen_id: EreporterGenerationUuid, -} /// The body of an ereport: either an event is reported, or a loss report. #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)] @@ -105,26 +96,26 @@ pub struct Event { /// Query parameters to request a tranche of ereports from a reporter. #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] pub struct EreportQuery { - /// The generation (restart nonce) of the reporter at which all other query - /// parameters are valid. + /// The restart ID of the reporter at which all other query parameters are + /// valid. /// - /// If this value does not match the reporter's current generation, the + /// If this value does not match the reporter's restart ID, the /// reporter's response will include the current generation, and will start - /// at the earliest known ENA, rather than the provided `last_seen` ENA.` - pub generation: EreporterGenerationUuid, + /// at the earliest known ENA, rather than the provided `start_at` ENA. + pub restart_id: EreporterRestartUuid, /// If present, the reporter should not include ENAs earlier than this one - /// in its response, provided that the query's requested generation matches - /// the current generation. + /// in its response, provided that the query's requested restart ID matches + /// the current restart ID. pub start_at: Option, /// The ENA of the last ereport committed to persistent storage from the - /// requested reporter generation. + /// requested reporter restart generation. /// - /// If the generation parameter matches the reporter's current generation, + /// If the restart ID parameter matches the reporter's current restart ID, /// it is permitted to discard any ereports with ENAs up to and including - /// this value. If the generation has changed from the provided generation, - /// the reporter will not discard data. + /// this value. If the restart ID has changed from the provided one, the + /// reporter will not discard data. pub committed: Option, /// Maximum number of ereports to return in this tranche. @@ -134,11 +125,11 @@ pub struct EreportQuery { /// A tranche of ereports received from a reporter. #[derive(Debug, Serialize, Deserialize, JsonSchema)] pub struct Ereports { - /// The reporter's current generation ID. + /// The reporter's current restart ID. /// - /// If this is not equal to the current known generation, then the reporter + /// If this is not equal to the current known restart ID, then the reporter /// has restarted. - pub generation: EreporterGenerationUuid, + pub restart_id: EreporterRestartUuid, /// The ereports in this tranche, and the ENA of the next page of ereports /// (if one exists).) #[serde(flatten)] diff --git a/openapi/gateway.json b/openapi/gateway.json index 582e4ba33c9..8125a24116e 100644 --- a/openapi/gateway.json +++ b/openapi/gateway.json @@ -1137,35 +1137,35 @@ { "in": "query", "name": "committed", - "description": "The ENA of the last ereport committed to persistent storage from the requested reporter generation.\n\nIf the generation parameter matches the reporter's current generation, it is permitted to discard any ereports with ENAs up to and including this value. If the generation has changed from the provided generation, the reporter will not discard data.", + "description": "The ENA of the last ereport committed to persistent storage from the requested reporter restart generation.\n\nIf the restart ID parameter matches the reporter's current restart ID, it is permitted to discard any ereports with ENAs up to and including this value. If the restart ID has changed from the provided one, the reporter will not discard data.", "schema": { "$ref": "#/components/schemas/Ena" } }, { "in": "query", - "name": "generation", - "description": "The generation (restart nonce) of the reporter at which all other query parameters are valid.\n\nIf this value does not match the reporter's current generation, the reporter's response will include the current generation, and will start at the earliest known ENA, rather than the provided `last_seen` ENA.`", + "name": "limit", + "description": "Maximum number of ereports to return in this tranche.", "required": true, "schema": { - "$ref": "#/components/schemas/TypedUuidForEreporterGenerationKind" + "type": "integer", + "format": "uint32", + "minimum": 1 } }, { "in": "query", - "name": "limit", - "description": "Maximum number of ereports to return in this tranche.", + "name": "restart_id", + "description": "The restart ID of the reporter at which all other query parameters are valid.\n\nIf this value does not match the reporter's restart ID, the reporter's response will include the current generation, and will start at the earliest known ENA, rather than the provided `start_at` ENA.", "required": true, "schema": { - "type": "integer", - "format": "uint32", - "minimum": 1 + "$ref": "#/components/schemas/TypedUuidForEreporterRestartKind" } }, { "in": "query", "name": "start_at", - "description": "If present, the reporter should not include ENAs earlier than this one in its response, provided that the query's requested generation matches the current generation.", + "description": "If present, the reporter should not include ENAs earlier than this one in its response, provided that the query's requested restart ID matches the current restart ID.", "schema": { "$ref": "#/components/schemas/Ena" } @@ -1650,14 +1650,6 @@ "description": "A tranche of ereports received from a reporter.", "type": "object", "properties": { - "generation": { - "description": "The reporter's current generation ID.\n\nIf this is not equal to the current known generation, then the reporter has restarted.", - "allOf": [ - { - "$ref": "#/components/schemas/TypedUuidForEreporterGenerationKind" - } - ] - }, "items": { "description": "list of items on this page of results", "type": "array", @@ -1669,11 +1661,19 @@ "nullable": true, "description": "token used to fetch the next page of results (if any)", "type": "string" + }, + "restart_id": { + "description": "The reporter's current restart ID.\n\nIf this is not equal to the current known restart ID, then the reporter has restarted.", + "allOf": [ + { + "$ref": "#/components/schemas/TypedUuidForEreporterRestartKind" + } + ] } }, "required": [ - "generation", - "items" + "items", + "restart_id" ] }, "Error": { @@ -3646,7 +3646,7 @@ } ] }, - "TypedUuidForEreporterGenerationKind": { + "TypedUuidForEreporterRestartKind": { "type": "string", "format": "uuid" }, diff --git a/uuid-kinds/src/lib.rs b/uuid-kinds/src/lib.rs index cd5821293a5..bc83eb373b7 100644 --- a/uuid-kinds/src/lib.rs +++ b/uuid-kinds/src/lib.rs @@ -59,7 +59,7 @@ impl_typed_uuid_kind! { DemoSaga => "demo_saga", Downstairs => "downstairs", DownstairsRegion => "downstairs_region", - EreporterGeneration => "ereporter_generation", + EreporterRestart => "ereporter_restart", ExternalIp => "external_ip", Instance => "instance", LoopbackAddress => "loopback_address", From 8d66c091e5449d0022fb098195bb803d4980ba19 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Tue, 1 Apr 2025 11:34:57 -0700 Subject: [PATCH 03/32] whoopsie... --- Cargo.lock | 1 + gateway/Cargo.toml | 1 + gateway/src/http_entrypoints.rs | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3431feefd0b..c826d2a0c28 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6941,6 +6941,7 @@ dependencies = [ "chrono", "clap", "dropshot 0.16.0", + "ereport-types", "expectorate", "futures", "gateway-api", diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index e754daf1855..dcc2613ed07 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -14,6 +14,7 @@ camino.workspace = true chrono.workspace = true clap.workspace = true dropshot.workspace = true +ereport-types.workspace = true futures.workspace = true gateway-api.workspace = true gateway-messages.workspace = true diff --git a/gateway/src/http_entrypoints.rs b/gateway/src/http_entrypoints.rs index 00403cc067f..14418e80238 100644 --- a/gateway/src/http_entrypoints.rs +++ b/gateway/src/http_entrypoints.rs @@ -940,9 +940,9 @@ impl GatewayApi for GatewayImpl { ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - HttpError::for_internal_error( + Err(HttpError::for_internal_error( "endpoint not yet implemented".to_string(), - ) + )) }; apictx.latencies.instrument_dropshot_handler(&rqctx, handler).await } From df3a49316f089e05d0733b7fb15e5d62c0bde84b Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Tue, 1 Apr 2025 14:26:38 -0700 Subject: [PATCH 04/32] unused variables --- gateway/src/http_entrypoints.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gateway/src/http_entrypoints.rs b/gateway/src/http_entrypoints.rs index 14418e80238..c0021df211d 100644 --- a/gateway/src/http_entrypoints.rs +++ b/gateway/src/http_entrypoints.rs @@ -935,8 +935,8 @@ impl GatewayApi for GatewayImpl { async fn sp_ereports_ingest( rqctx: RequestContext, - path: Path, - query: Query, + _path: Path, + _query: Query, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { From 731966af644caf31a36c1b97690d854d0b0a39a4 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Wed, 2 Apr 2025 12:54:59 -0700 Subject: [PATCH 05/32] regenerate golden file --- dev-tools/ls-apis/tests/api_dependencies.out | 3 --- 1 file changed, 3 deletions(-) diff --git a/dev-tools/ls-apis/tests/api_dependencies.out b/dev-tools/ls-apis/tests/api_dependencies.out index 210418066d1..ed35331ce3e 100644 --- a/dev-tools/ls-apis/tests/api_dependencies.out +++ b/dev-tools/ls-apis/tests/api_dependencies.out @@ -42,9 +42,6 @@ Dendrite DPD (client: dpd-client) Downstairs Controller (debugging only) (client: dsc-client) -ereport (client: ereport-client) - consumed by: omicron-nexus (omicron/nexus) via 1 path - Management Gateway Service (client: gateway-client) consumed by: dpd (dendrite/dpd) via 1 path consumed by: omicron-nexus (omicron/nexus) via 3 paths From e32448109b239e1cf66d7b0a0f6066fa1d426d3b Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Wed, 2 Apr 2025 12:57:25 -0700 Subject: [PATCH 06/32] less structured ereport type this should make it easier for MGS to blindly turn CBOR into JSON. we can enforce more structure when deserialing. --- ereport/types/src/lib.rs | 106 ++++++++++++--------------------------- openapi/gateway.json | 99 ++---------------------------------- 2 files changed, 36 insertions(+), 169 deletions(-) diff --git a/ereport/types/src/lib.rs b/ereport/types/src/lib.rs index 1510466da3a..30d80477cb6 100644 --- a/ereport/types/src/lib.rs +++ b/ereport/types/src/lib.rs @@ -16,8 +16,8 @@ use std::num::NonZeroU32; pub struct Ereport { /// The ENA of the ereport. pub ena: Ena, - /// The body of the ereport. - pub report: ReportKind, + #[serde(flatten)] + pub data: serde_json::Map, } /// An Error Numeric Association (ENA) @@ -59,40 +59,6 @@ impl fmt::LowerHex for Ena { } } -/// The body of an ereport: either an event is reported, or a loss report. -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum ReportKind { - /// An ereport. - Event(Event), - /// Ereports were lost, or may have been lost. - Loss(LossReport), -} - -/// The number of ereports that were discarded, if it is known. -/// -/// If ereports are dropped because a buffer has reached its capacity, -/// the reporter is strongly encouraged to attempt to count the number -/// of ereports lost. In other cases, such as a reporter crashing and -/// restarting, the reporter may not be capable of determining the -/// number of ereports that were lost, or even *if* data loss actually -/// occurred. -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "snake_case")] -#[serde(tag = "type", content = "lost")] -pub enum LossReport { - /// An unknown number of ereports MAY have been lost. - Unknown, - /// The provided number of ereports are known to have been lost. - Exact(u32), -} - -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)] -pub struct Event { - pub class: String, - pub data: serde_json::Value, -} - /// Query parameters to request a tranche of ereports from a reporter. #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] pub struct EreportQuery { @@ -141,47 +107,41 @@ mod tests { use super::*; #[test] - fn test_roundtrip() { - let ereport = Ereport { - ena: Ena(0x3cae76440c100001), - report: ReportKind::Event(Event { - // Example ereport taken from https://rfd.shared.oxide.computer/rfd/0520#_ereports_in_the_fma - class: "ereport.cpu.generic-x86.cache".to_string(), - data: serde_json::json!({ + fn test_arb_json_deserializes() { + let ereport = serde_json::json!({ + "ena": Ena(0x3cae76440c100001), + "version": 0x0, + "class": "list.suspect", + "uuid": "0348743e-0600-4c77-b7ea-6eda191536e4", + "code": "FMD-8000-0W", + "diag-time": "1705014884 472900", + "de": { + "version": 0x0, + "scheme": "fmd", + "authority": { + "version": 0x0, + "product-id": "oxide", + "server-id": "BRM42220016", + }, + "mod-name": "fmd-self-diagnosis", + "mod-version": "1.0", + }, + "fault-list": [ + { "version": 0x0, - "class": "list.suspect", - "uuid": "0348743e-0600-4c77-b7ea-6eda191536e4", - "code": "FMD-8000-0W", - "diag-time": "1705014884 472900", - "de": { - "version": 0x0, - "scheme": "fmd", - "authority": { - "version": 0x0, - "product-id": "oxide", - "server-id": "BRM42220016", - }, - "mod-name": "fmd-self-diagnosis", - "mod-version": "1.0", - }, - "fault-list": [ - { - "version": 0x0, - "class": "defect.sunos.fmd.nosub", - "certainty": 0x64, - "nosub_class": "ereport.cpu.generic-x86.cache", - } - ], - "fault-status": 0x1, - "severity": "minor", - }), - }), - }; + "class": "defect.sunos.fmd.nosub", + "certainty": 0x64, + "nosub_class": "ereport.cpu.generic-x86.cache", + } + ], + "fault-status": 0x1, + "severity": "minor", + }); let ereport_string = serde_json::to_string_pretty(&ereport) .expect("ereport should serialize"); eprintln!("JSON: {ereport_string}"); - let deserialized = dbg!(serde_json::from_str(&ereport_string)) + let deserialized = dbg!(serde_json::from_str::(&ereport_string)) .expect("ereport should deserialize"); - assert_eq!(ereport, deserialized) + eprintln!("EREPORT: {deserialized:#?}"); } } diff --git a/openapi/gateway.json b/openapi/gateway.json index 8125a24116e..4bdba6bf717 100644 --- a/openapi/gateway.json +++ b/openapi/gateway.json @@ -1631,20 +1631,12 @@ "$ref": "#/components/schemas/Ena" } ] - }, - "report": { - "description": "The body of the ereport.", - "allOf": [ - { - "$ref": "#/components/schemas/ReportKind" - } - ] } }, "required": [ - "ena", - "report" - ] + "ena" + ], + "additionalProperties": true }, "Ereports": { "description": "A tranche of ereports received from a reporter.", @@ -1695,19 +1687,6 @@ "request_id" ] }, - "Event": { - "type": "object", - "properties": { - "class": { - "type": "string" - }, - "data": {} - }, - "required": [ - "class", - "data" - ] - }, "GetCfpaParams": { "type": "object", "properties": { @@ -1908,47 +1887,6 @@ } ] }, - "LossReport": { - "description": "The number of ereports that were discarded, if it is known.\n\nIf ereports are dropped because a buffer has reached its capacity, the reporter is strongly encouraged to attempt to count the number of ereports lost. In other cases, such as a reporter crashing and restarting, the reporter may not be capable of determining the number of ereports that were lost, or even *if* data loss actually occurred.", - "oneOf": [ - { - "description": "An unknown number of ereports MAY have been lost.", - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "unknown" - ] - } - }, - "required": [ - "type" - ] - }, - { - "description": "The provided number of ereports are known to have been lost.", - "type": "object", - "properties": { - "lost": { - "type": "integer", - "format": "uint32", - "minimum": 0 - }, - "type": { - "type": "string", - "enum": [ - "exact" - ] - } - }, - "required": [ - "lost", - "type" - ] - } - ] - }, "MeasurementErrorCode": { "oneOf": [ { @@ -2518,37 +2456,6 @@ "A2" ] }, - "ReportKind": { - "description": "The body of an ereport: either an event is reported, or a loss report.", - "oneOf": [ - { - "description": "An ereport.", - "type": "object", - "properties": { - "event": { - "$ref": "#/components/schemas/Event" - } - }, - "required": [ - "event" - ], - "additionalProperties": false - }, - { - "description": "Ereports were lost, or may have been lost.", - "type": "object", - "properties": { - "loss": { - "$ref": "#/components/schemas/LossReport" - } - }, - "required": [ - "loss" - ], - "additionalProperties": false - } - ] - }, "RotCfpa": { "type": "object", "properties": { From 4cf9246e3885a9539438f1ad55c01434889c405c Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Thu, 3 Apr 2025 12:31:06 -0700 Subject: [PATCH 07/32] update mgs dep --- Cargo.lock | 179 ++++++++++++++++++++++++++++++++--------------------- Cargo.toml | 4 +- 2 files changed, 112 insertions(+), 71 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c826d2a0c28..08f6f9dbe7c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -713,7 +713,7 @@ version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "cexpr", "clang-sys", "itertools 0.12.1", @@ -736,7 +736,7 @@ version = "0.71.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "cexpr", "clang-sys", "itertools 0.12.1", @@ -805,9 +805,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.6.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" dependencies = [ "serde", ] @@ -1314,7 +1314,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" dependencies = [ "ciborium-io", - "half", + "half 2.4.1", ] [[package]] @@ -1607,7 +1607,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" dependencies = [ "lazy_static", - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] @@ -1891,7 +1891,7 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "crossterm_winapi", "futures-core", "mio", @@ -2411,7 +2411,7 @@ version = "2.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "470eb10efc8646313634c99bb1593f402a6434cbd86e266770c6e39219adb86a" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "byteorder", "chrono", "diesel_derives", @@ -3457,7 +3457,7 @@ dependencies = [ "clap", "futures", "gateway-client", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", "omicron-common", "omicron-workspace-hack", "reqwest", @@ -3478,7 +3478,7 @@ version = "0.1.0" dependencies = [ "base64 0.22.1", "chrono", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", "omicron-workspace-hack", "progenitor 0.9.1", "rand 0.8.5", @@ -3490,12 +3490,29 @@ dependencies = [ "uuid", ] +[[package]] +name = "gateway-messages" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115#871a785a01d53e434331e995057bdafda7ffd115" +dependencies = [ + "bitflags 2.9.0", + "hubpack", + "serde", + "serde-big-array", + "serde_repr", + "smoltcp 0.9.1", + "static_assertions", + "strum_macros 0.25.3", + "uuid", + "zerocopy 0.6.6", +] + [[package]] name = "gateway-messages" version = "0.1.0" source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=9bbac475dcaac88286c07a20b6bd3e94fc81d7f0#9bbac475dcaac88286c07a20b6bd3e94fc81d7f0" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "hubpack", "serde", "serde-big-array", @@ -3510,22 +3527,25 @@ dependencies = [ [[package]] name = "gateway-sp-comms" version = "0.1.1" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=9bbac475dcaac88286c07a20b6bd3e94fc81d7f0#9bbac475dcaac88286c07a20b6bd3e94fc81d7f0" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115#871a785a01d53e434331e995057bdafda7ffd115" dependencies = [ "async-trait", "backoff", "futures", "fxhash", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", "hex", "hubpack", "hubtools", "lru-cache", + "lzss", "nix 0.27.1", "once_cell", "paste", "serde", "serde-big-array", + "serde_cbor", + "serde_json", "slog", "slog-error-chain", "socket2", @@ -3545,7 +3565,7 @@ version = "0.1.0" dependencies = [ "camino", "dropshot 0.16.0", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", "gateway-types", "omicron-gateway", "omicron-test-utils", @@ -3560,7 +3580,7 @@ dependencies = [ name = "gateway-types" version = "0.1.0" dependencies = [ - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", "hex", "ipcc", "omicron-common", @@ -3638,7 +3658,7 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "libc", "libgit2-sys", "log", @@ -3750,6 +3770,12 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" + [[package]] name = "half" version = "2.4.1" @@ -4183,7 +4209,7 @@ dependencies = [ [[package]] name = "hubtools" version = "0.4.6" -source = "git+https://github.com/oxidecomputer/hubtools.git?branch=main#8a66b292eb179b9d7e7d00f2d4484b1e76b66949" +source = "git+https://github.com/oxidecomputer/hubtools.git?branch=main#688fb6d97f69a652a7578b8ad069e681bf2e152d" dependencies = [ "hex", "lpc55_areas", @@ -4628,7 +4654,7 @@ name = "ingot" version = "0.1.0" source = "git+https://github.com/oxidecomputer/ingot.git?rev=bff93247fe75ff889121e39d494cc3805fc01906#bff93247fe75ff889121e39d494cc3805fc01906" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "ingot-macros", "ingot-types", "macaddr", @@ -5194,7 +5220,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] @@ -5249,7 +5275,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "libc", "redox_syscall 0.5.7", ] @@ -5448,6 +5474,15 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "lzss" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e2b9a6124e5200c13bb5c5d1124bf93b451bff69b651912810039e36ca97eb" +dependencies = [ + "void", +] + [[package]] name = "macaddr" version = "1.0.1" @@ -5554,7 +5589,7 @@ dependencies = [ "anyhow", "clap", "futures", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", "gateway-test-utils", "libc", "omicron-gateway", @@ -6020,7 +6055,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", "gateway-test-utils", "nexus-sled-agent-shared", "nexus-types", @@ -6084,7 +6119,7 @@ version = "0.1.0" dependencies = [ "futures", "gateway-client", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", "gateway-test-utils", "hubtools", "omicron-workspace-hack", @@ -6357,7 +6392,7 @@ dependencies = [ "dns-service-client", "dropshot 0.16.0", "futures", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", "gateway-test-utils", "headers", "hickory-resolver", @@ -6472,7 +6507,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "cfg-if", "libc", "memoffset", @@ -6484,7 +6519,7 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "cfg-if", "cfg_aliases 0.1.1", "libc", @@ -6496,7 +6531,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "cfg-if", "cfg_aliases 0.2.1", "libc", @@ -6945,7 +6980,7 @@ dependencies = [ "expectorate", "futures", "gateway-api", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", "gateway-sp-comms", "gateway-test-utils", "gateway-types", @@ -7066,7 +7101,7 @@ dependencies = [ "fatfs", "futures", "gateway-client", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", "gateway-test-utils", "headers", "hex", @@ -7202,7 +7237,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", "gateway-test-utils", "http", "humantime", @@ -7566,7 +7601,7 @@ dependencies = [ "base64 0.22.1", "base64ct", "bitflags 1.3.2", - "bitflags 2.6.0", + "bitflags 2.9.0", "bstr", "buf-list", "byteorder", @@ -7601,7 +7636,7 @@ dependencies = [ "futures-sink", "futures-task", "futures-util", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=9bbac475dcaac88286c07a20b6bd3e94fc81d7f0)", "generic-array", "getrandom 0.2.15", "getrandom 0.3.1", @@ -7642,7 +7677,7 @@ dependencies = [ "percent-encoding", "petgraph 0.6.5", "phf", - "phf_shared 0.11.2", + "phf_shared", "pkcs8", "postgres-types", "predicates", @@ -7730,9 +7765,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.3" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "oorandom" @@ -7829,7 +7864,7 @@ version = "0.10.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "cfg-if", "foreign-types 0.3.2", "libc", @@ -7872,7 +7907,7 @@ name = "opte" version = "0.1.0" source = "git+https://github.com/oxidecomputer/opte?rev=cd9aa6467c5e62c6d97f6aafa2150d6930e3a0fa#cd9aa6467c5e62c6d97f6aafa2150d6930e3a0fa" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "cfg-if", "dyn-clone", "illumos-sys-hdrs", @@ -8717,7 +8752,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ - "phf_shared 0.11.2", + "phf_shared", ] [[package]] @@ -8727,7 +8762,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" dependencies = [ "phf_generator", - "phf_shared 0.11.2", + "phf_shared", ] [[package]] @@ -8736,19 +8771,10 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" dependencies = [ - "phf_shared 0.11.2", + "phf_shared", "rand 0.8.5", ] -[[package]] -name = "phf_shared" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" -dependencies = [ - "siphasher", -] - [[package]] name = "phf_shared" version = "0.11.2" @@ -9413,7 +9439,7 @@ checksum = "14cae93065090804185d3b75f0bf93b8eeda30c7a9b4a33d3bdb3988d6229e50" dependencies = [ "bit-set 0.8.0", "bit-vec 0.8.0", - "bitflags 2.6.0", + "bitflags 2.9.0", "lazy_static", "num-traits", "rand 0.8.5", @@ -9676,7 +9702,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "cassowary", "compact_str", "crossterm", @@ -9787,7 +9813,7 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", ] [[package]] @@ -10021,7 +10047,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ "base64 0.21.7", - "bitflags 2.6.0", + "bitflags 2.9.0", "serde", "serde_derive", ] @@ -10108,7 +10134,7 @@ dependencies = [ "aes", "aes-gcm", "async-trait", - "bitflags 2.6.0", + "bitflags 2.9.0", "byteorder", "cbc", "chacha20", @@ -10283,7 +10309,7 @@ version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "errno", "libc", "linux-raw-sys 0.4.14", @@ -10433,7 +10459,7 @@ version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7803e8936da37efd9b6d4478277f4b2b9bb5cdb37a113e8d63222e58da647e63" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "cfg-if", "clipboard-win", "fd-lock", @@ -10632,7 +10658,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "core-foundation", "core-foundation-sys", "libc", @@ -10693,6 +10719,16 @@ dependencies = [ "smallvec 0.6.14", ] +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half 1.8.3", + "serde", +] + [[package]] name = "serde_derive" version = "1.0.219" @@ -11402,7 +11438,7 @@ dependencies = [ "clap", "dropshot 0.16.0", "futures", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", "gateway-types", "hex", "nix 0.29.0", @@ -11583,14 +11619,13 @@ dependencies = [ [[package]] name = "string_cache" -version = "0.8.7" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" dependencies = [ "new_debug_unreachable", - "once_cell", "parking_lot 0.12.3", - "phf_shared 0.10.0", + "phf_shared", "precomputed-hash", "serde", ] @@ -11783,7 +11818,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "core-foundation", "system-configuration-sys", ] @@ -12576,7 +12611,7 @@ name = "transceiver-messages" version = "0.1.1" source = "git+https://github.com/oxidecomputer/transceiver-control#4aac6125a8e6cefbb71d9f8a3d1fe6704207d476" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", "clap", "hubpack", "schemars", @@ -13167,9 +13202,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.15.1" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0f540e3240398cce6128b64ba83fdbdd86129c16a3aa1a3a252efd66eb3d587" +checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" dependencies = [ "getrandom 0.3.1", "serde", @@ -13219,6 +13254,12 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + [[package]] name = "vsss-rs" version = "3.3.4" @@ -13571,7 +13612,7 @@ dependencies = [ "fs-err", "futures", "gateway-client", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", "gateway-test-utils", "hex", "hickory-resolver", @@ -13700,7 +13741,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] @@ -13955,7 +13996,7 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 350e0fb6263..b8b432c9b12 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -409,8 +409,8 @@ gateway-client = { path = "clients/gateway-client" } # is "fine", because SP/MGS communication maintains forwards and backwards # compatibility, but will mean that faux-mgs might be missing new # functionality.) -gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "9bbac475dcaac88286c07a20b6bd3e94fc81d7f0", default-features = false, features = ["std"] } -gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "9bbac475dcaac88286c07a20b6bd3e94fc81d7f0" } +gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "871a785a01d53e434331e995057bdafda7ffd115", default-features = false, features = ["std"] } +gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "871a785a01d53e434331e995057bdafda7ffd115" } gateway-test-utils = { path = "gateway-test-utils" } gateway-types = { path = "gateway-types" } gethostname = "0.5.0" From 49973ae13a00f785fd2a10be6935bce084528f54 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Thu, 3 Apr 2025 12:31:16 -0700 Subject: [PATCH 08/32] track unrelated mgs changes (factor me out pls) --- gateway-types/src/component_details.rs | 2 ++ gateway/src/metrics.rs | 18 +++++++++++++++++- sp-sim/src/gimlet.rs | 24 ++++++++++++++++++++++++ sp-sim/src/sidecar.rs | 23 +++++++++++++++++++++++ 4 files changed, 66 insertions(+), 1 deletion(-) diff --git a/gateway-types/src/component_details.rs b/gateway-types/src/component_details.rs index 2b41d4b6f7c..2c0dad8c95d 100644 --- a/gateway-types/src/component_details.rs +++ b/gateway-types/src/component_details.rs @@ -374,6 +374,7 @@ pub enum MeasurementKind { InputCurrent, InputVoltage, Speed, + CpuTctl, } impl From for MeasurementKind { @@ -387,6 +388,7 @@ impl From for MeasurementKind { MeasurementKind::InputCurrent => Self::InputCurrent, MeasurementKind::InputVoltage => Self::InputVoltage, MeasurementKind::Speed => Self::Speed, + MeasurementKind::CpuTctl => Self::CpuTctl, } } } diff --git a/gateway/src/metrics.rs b/gateway/src/metrics.rs index 7e873e326e8..df5d1c765e6 100644 --- a/gateway/src/metrics.rs +++ b/gateway/src/metrics.rs @@ -791,11 +791,13 @@ impl SpPoller { // We do this first so that we only have to clone the // sensor's name if there's an error, rather than always // cloning it in *case* there's an error. + const TCTL_NAME: &str = "amd_cpu_tctl"; if let Err(error) = m.value { let kind = match m.kind { MeasurementKind::Temperature if is_tctl => { - "amd_cpu_tctl" + TCTL_NAME } + MeasurementKind::CpuTctl => TCTL_NAME, MeasurementKind::Temperature => "temperature", MeasurementKind::Current => "current", MeasurementKind::Voltage => "voltage", @@ -878,6 +880,17 @@ impl SpPoller { &metric::Temperature { sensor, datum: 0.0 }, ) } + + (Ok(datum), MeasurementKind::CpuTctl) => Sample::new( + target, + &metric::AmdCpuTctl { sensor, datum }, + ), + (Err(_), MeasurementKind::CpuTctl) => { + Sample::new_missing( + target, + &metric::AmdCpuTctl { sensor, datum: 0.0 }, + ) + } (Ok(datum), MeasurementKind::Current) => Sample::new( target, &metric::Current { sensor, datum }, @@ -1204,5 +1217,8 @@ fn comms_error_str(error: CommunicationError) -> &'static str { CommunicationError::BadTrailingDataSize { .. } => { "bad_trailing_data_size" } + CommunicationError::BadDecompressionSize { .. } => { + "bad_decompressed_size" + } } } diff --git a/sp-sim/src/gimlet.rs b/sp-sim/src/gimlet.rs index ce1bd77268e..68e1742c1e5 100644 --- a/sp-sim/src/gimlet.rs +++ b/sp-sim/src/gimlet.rs @@ -34,6 +34,8 @@ use gateway_messages::SpError; use gateway_messages::SpPort; use gateway_messages::SpRequest; use gateway_messages::SpStateV2; +use gateway_messages::DumpSegment; +use gateway_messages::DumpTask; use gateway_messages::ignition::{self, LinkEvents}; use gateway_messages::sp_impl::Sender; use gateway_messages::sp_impl::SpHandler; @@ -1502,6 +1504,28 @@ impl SpHandler for Handler { } } } + + fn get_task_dump_count(&mut self) -> Result { + unimplemented!() + } + + fn task_dump_read_start( + &mut self, + _index: u32, + _key: [u8; 16], + ) -> Result { + unimplemented!() + } + + fn task_dump_read_continue( + &mut self, + _key: [u8; 16], + _seq: u32, + _buf: &mut [u8], + ) -> Result, SpError> { + unimplemented!() + } + } impl SimSpHandler for Handler { diff --git a/sp-sim/src/sidecar.rs b/sp-sim/src/sidecar.rs index c5b0c317350..e2e4b63b619 100644 --- a/sp-sim/src/sidecar.rs +++ b/sp-sim/src/sidecar.rs @@ -27,6 +27,8 @@ use gateway_messages::ComponentAction; use gateway_messages::ComponentActionResponse; use gateway_messages::ComponentDetails; use gateway_messages::DiscoverResponse; +use gateway_messages::DumpSegment; +use gateway_messages::DumpTask; use gateway_messages::IgnitionCommand; use gateway_messages::IgnitionState; use gateway_messages::MgsError; @@ -1202,6 +1204,27 @@ impl SpHandler for Handler { } } } + + fn get_task_dump_count(&mut self) -> Result { + unimplemented!() + } + + fn task_dump_read_start( + &mut self, + _index: u32, + _key: [u8; 16], + ) -> Result { + unimplemented!() + } + + fn task_dump_read_continue( + &mut self, + _key: [u8; 16], + _seq: u32, + _buf: &mut [u8], + ) -> Result, SpError> { + unimplemented!() + } } impl SimSpHandler for Handler { From 20863c6d7c660799981e5d39fd3edaae0e3584ec Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Thu, 3 Apr 2025 14:01:25 -0700 Subject: [PATCH 09/32] plumbing --- Cargo.lock | 34 +++++++------- Cargo.toml | 4 +- gateway/src/management_switch.rs | 47 +++++++++++++++++-- gateway/src/management_switch/location_map.rs | 3 ++ 4 files changed, 66 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 08f6f9dbe7c..4491381ae7e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3457,7 +3457,7 @@ dependencies = [ "clap", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", "omicron-common", "omicron-workspace-hack", "reqwest", @@ -3478,7 +3478,7 @@ version = "0.1.0" dependencies = [ "base64 0.22.1", "chrono", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", "omicron-workspace-hack", "progenitor 0.9.1", "rand 0.8.5", @@ -3493,7 +3493,7 @@ dependencies = [ [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115#871a785a01d53e434331e995057bdafda7ffd115" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=9bbac475dcaac88286c07a20b6bd3e94fc81d7f0#9bbac475dcaac88286c07a20b6bd3e94fc81d7f0" dependencies = [ "bitflags 2.9.0", "hubpack", @@ -3510,7 +3510,7 @@ dependencies = [ [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=9bbac475dcaac88286c07a20b6bd3e94fc81d7f0#9bbac475dcaac88286c07a20b6bd3e94fc81d7f0" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4#d4de62c0444652c3571e22f21e6e1f281fb8cfd4" dependencies = [ "bitflags 2.9.0", "hubpack", @@ -3527,13 +3527,13 @@ dependencies = [ [[package]] name = "gateway-sp-comms" version = "0.1.1" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115#871a785a01d53e434331e995057bdafda7ffd115" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4#d4de62c0444652c3571e22f21e6e1f281fb8cfd4" dependencies = [ "async-trait", "backoff", "futures", "fxhash", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", "hex", "hubpack", "hubtools", @@ -3565,7 +3565,7 @@ version = "0.1.0" dependencies = [ "camino", "dropshot 0.16.0", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", "gateway-types", "omicron-gateway", "omicron-test-utils", @@ -3580,7 +3580,7 @@ dependencies = [ name = "gateway-types" version = "0.1.0" dependencies = [ - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", "hex", "ipcc", "omicron-common", @@ -5589,7 +5589,7 @@ dependencies = [ "anyhow", "clap", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", "gateway-test-utils", "libc", "omicron-gateway", @@ -6055,7 +6055,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", "gateway-test-utils", "nexus-sled-agent-shared", "nexus-types", @@ -6119,7 +6119,7 @@ version = "0.1.0" dependencies = [ "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", "gateway-test-utils", "hubtools", "omicron-workspace-hack", @@ -6392,7 +6392,7 @@ dependencies = [ "dns-service-client", "dropshot 0.16.0", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", "gateway-test-utils", "headers", "hickory-resolver", @@ -6980,7 +6980,7 @@ dependencies = [ "expectorate", "futures", "gateway-api", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", "gateway-sp-comms", "gateway-test-utils", "gateway-types", @@ -7101,7 +7101,7 @@ dependencies = [ "fatfs", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", "gateway-test-utils", "headers", "hex", @@ -7237,7 +7237,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", "gateway-test-utils", "http", "humantime", @@ -11438,7 +11438,7 @@ dependencies = [ "clap", "dropshot 0.16.0", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", "gateway-types", "hex", "nix 0.29.0", @@ -13612,7 +13612,7 @@ dependencies = [ "fs-err", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=871a785a01d53e434331e995057bdafda7ffd115)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", "gateway-test-utils", "hex", "hickory-resolver", diff --git a/Cargo.toml b/Cargo.toml index b8b432c9b12..fe049c2f28f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -409,8 +409,8 @@ gateway-client = { path = "clients/gateway-client" } # is "fine", because SP/MGS communication maintains forwards and backwards # compatibility, but will mean that faux-mgs might be missing new # functionality.) -gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "871a785a01d53e434331e995057bdafda7ffd115", default-features = false, features = ["std"] } -gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "871a785a01d53e434331e995057bdafda7ffd115" } +gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "d4de62c0444652c3571e22f21e6e1f281fb8cfd4", default-features = false, features = ["std"] } +gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "d4de62c0444652c3571e22f21e6e1f281fb8cfd4" } gateway-test-utils = { path = "gateway-test-utils" } gateway-types = { path = "gateway-types" } gethostname = "0.5.0" diff --git a/gateway/src/management_switch.rs b/gateway/src/management_switch.rs index c8cd9f8c8ae..7f71aeabf27 100644 --- a/gateway/src/management_switch.rs +++ b/gateway/src/management_switch.rs @@ -29,6 +29,9 @@ use gateway_sp_comms::SharedSocket; use gateway_sp_comms::SingleSp; use gateway_sp_comms::SpRetryConfig; use gateway_sp_comms::default_discovery_addr; +use gateway_sp_comms::default_ereport_addr; +use gateway_sp_comms::ereport; +use gateway_sp_comms::shared_socket; use serde::Deserialize; use serde::Serialize; use slog::Logger; @@ -48,6 +51,8 @@ use tokio::task::JoinHandle; pub struct SwitchConfig { #[serde(default = "default_udp_listen_port")] pub udp_listen_port: u16, + #[serde(default = "default_ereport_listen_port")] + pub ereport_udp_listen_port: u16, pub local_ignition_controller_interface: String, pub rpc_retry_config: RetryConfig, pub location: LocationConfig, @@ -77,6 +82,10 @@ fn default_udp_listen_port() -> u16 { gateway_sp_comms::MGS_PORT } +fn default_ereport_listen_port() -> u16 { + gateway_sp_comms::ereport::MGS_PORT +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize, Serialize)] pub struct SpIdentifier { pub typ: SpType, @@ -161,7 +170,7 @@ pub struct ManagementSwitch { // `new()`. We need to hold onto it to prevent it being dropped, though: // When it's dropped, it cancels the background tokio task that loops on // that socket receiving incoming packets. - _shared_socket: Option, + _shared_socket: Option>, location_map: Arc>>, discovery_task: JoinHandle<()>, log: Logger, @@ -186,6 +195,7 @@ impl ManagementSwitch { // Convert our config into actual SP handles and sockets, keyed by // `SwitchPort` (newtype around an index into `config.port`). let mut shared_socket = None; + let mut ereport_socket = None; let mut port_to_handle = Vec::with_capacity(config.port.len()); let mut port_to_desc = Vec::with_capacity(config.port.len()); let mut port_to_ignition_target = Vec::with_capacity(config.port.len()); @@ -202,7 +212,7 @@ impl ManagementSwitch { shared_socket = Some( SharedSocket::bind( config.udp_listen_port, - Arc::clone(&host_phase2_provider), + shared_socket::ControlPlaneAgentHandler::new(&host_phase2_provider, &log), log.clone(), ) .await?, @@ -214,10 +224,29 @@ impl ManagementSwitch { Some(v) => v, }; + let ereport_socket = match &mut ereport_socket { + None => { + let log = log.new(slog::o!("socket" => "ereport")); + ereport_socket = Some( + SharedSocket::bind( + config.ereport_udp_listen_port, + ereport::EreportHandler::new(log.clone()), + log, + ) + .await?, + ); + + ereport_socket.as_ref().unwrap() + } + + Some(v) => v, + }; SingleSp::new( &socket, + ereport_socket, gateway_sp_comms::SwitchPortConfig { discovery_addr: default_discovery_addr(), + ereport_addr: default_ereport_addr(), interface: interface.clone(), }, retry_config, @@ -225,7 +254,7 @@ impl ManagementSwitch { .await } - SwitchPortConfig::Simulated { addr, .. } => { + SwitchPortConfig::Simulated { addr, ereport_addr, .. } => { // Bind a new socket for each simulated switch port. let bind_addr: SocketAddrV6 = SocketAddrV6::new(Ipv6Addr::UNSPECIFIED, 0, 0, 0); @@ -236,9 +265,21 @@ impl ManagementSwitch { err, }) })?; + let ereport_bind_addr: SocketAddrV6 = + SocketAddrV6::new(Ipv6Addr::UNSPECIFIED, 0, 0, 0); + let ereport_socket = UdpSocket::bind(ereport_bind_addr) + .await + .map_err(|err| { + StartupError::BindError(BindError { + addr: ereport_bind_addr, + err, + }) + })?; SingleSp::new_direct_socket_for_testing( socket, *addr, + ereport_socket, + *ereport_addr, retry_config, log.clone(), ) diff --git a/gateway/src/management_switch/location_map.rs b/gateway/src/management_switch/location_map.rs index f4433c1b49a..c6a524b48ae 100644 --- a/gateway/src/management_switch/location_map.rs +++ b/gateway/src/management_switch/location_map.rs @@ -35,6 +35,7 @@ pub enum SwitchPortConfig { Simulated { fake_interface: String, addr: SocketAddrV6, + ereport_addr: SocketAddrV6, }, } @@ -470,6 +471,7 @@ mod tests { config: SwitchPortConfig::Simulated { fake_interface: "fake".to_string(), addr: "[::1]:0".parse().unwrap(), + ereport_addr: "[::1]:0".parse().unwrap(), }, ignition_target: 0, location: HashMap::from([ @@ -546,6 +548,7 @@ mod tests { config: SwitchPortConfig::Simulated { fake_interface: "fake".to_string(), addr: "[::1]:0".parse().unwrap(), + ereport_addr: "[::1]:0".parse().unwrap(), }, ignition_target: 0, location: HashMap::from([ From f941a08867ab08b780f8e37e54eb6c1bf152756b Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Thu, 3 Apr 2025 15:56:29 -0700 Subject: [PATCH 10/32] sp-sim plumbing --- Cargo.lock | 2 + Cargo.toml | 1 + nexus/tests/integration_tests/metrics.rs | 1 + sp-sim/Cargo.toml | 2 + sp-sim/src/config.rs | 25 +++ sp-sim/src/ereport.rs | 206 +++++++++++++++++++++++ sp-sim/src/gimlet.rs | 68 +++++++- sp-sim/src/lib.rs | 1 + 8 files changed, 302 insertions(+), 4 deletions(-) create mode 100644 sp-sim/src/ereport.rs diff --git a/Cargo.lock b/Cargo.lock index 4491381ae7e..8ffb07215b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11445,11 +11445,13 @@ dependencies = [ "omicron-common", "omicron-workspace-hack", "serde", + "serde_cbor", "slog", "slog-dtrace", "thiserror 1.0.69", "tokio", "toml 0.8.20", + "uuid", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index fe049c2f28f..053a4c35b29 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -607,6 +607,7 @@ scopeguard = "1.2.0" secrecy = "0.8.0" semver = { version = "1.0.25", features = ["std", "serde"] } serde = { version = "1.0", default-features = false, features = [ "derive", "rc" ] } +serde_cbor = "0.11.2" serde_human_bytes = { git = "https://github.com/oxidecomputer/serde_human_bytes", branch = "main" } serde_json = "1.0.139" serde_tokenstream = "0.2" diff --git a/nexus/tests/integration_tests/metrics.rs b/nexus/tests/integration_tests/metrics.rs index 8d664f06f08..1636a5a5471 100644 --- a/nexus/tests/integration_tests/metrics.rs +++ b/nexus/tests/integration_tests/metrics.rs @@ -676,6 +676,7 @@ async fn test_mgs_metrics( for sensor in &component.sensors { use gateway_messages::measurement::MeasurementKind as Kind; match sensor.def.kind { + Kind::CpuTctl => cpu_tctl += 1, Kind::Temperature => { // Currently, Tctl measurements are reported as a // "temperature" measurement, but are tracked by a diff --git a/sp-sim/Cargo.toml b/sp-sim/Cargo.toml index 66819bf9c52..f606f4111f2 100644 --- a/sp-sim/Cargo.toml +++ b/sp-sim/Cargo.toml @@ -18,6 +18,7 @@ gateway-types.workspace = true hex = { workspace = true, features = [ "serde" ] } omicron-common.workspace = true serde.workspace = true +serde_cbor.workspace = true slog.workspace = true slog-dtrace.workspace = true thiserror.workspace = true @@ -25,6 +26,7 @@ tokio = { workspace = true, features = [ "full" ] } toml.workspace = true omicron-workspace-hack.workspace = true nix.workspace = true +uuid.workspace = true [[bin]] name = "sp-sim" diff --git a/sp-sim/src/config.rs b/sp-sim/src/config.rs index 28d0f3760ad..e8c54d0f9de 100644 --- a/sp-sim/src/config.rs +++ b/sp-sim/src/config.rs @@ -11,6 +11,7 @@ use gateway_messages::DeviceCapabilities; use gateway_messages::DevicePresence; use serde::Deserialize; use serde::Serialize; +use std::collections::VecDeque; use std::net::Ipv6Addr; use std::net::SocketAddrV6; use std::path::Path; @@ -76,6 +77,9 @@ pub struct SpCommonConfig { /// Network config for the two (fake) KSZ8463 ports. #[serde(skip_serializing_if = "Option::is_none", default)] pub network_config: Option<[NetworkConfig; 2]>, + /// Network config for the (fake) ereport UDP ports. + #[serde(skip_serializing_if = "Option::is_none", default)] + pub ereport_network_config: Option<[NetworkConfig; 2]>, /// Fake serial number pub serial_number: String, /// 32-byte seed to create a manufacturing root certificate. @@ -94,6 +98,9 @@ pub struct SpCommonConfig { /// Simulate a RoT stage0 with no caboose #[serde(default)] pub no_stage0_caboose: bool, + /// Fake ereport restart generations. + #[serde(skip_serializing_if = "VecDeque::is_empty", default)] + pub ereport_restarts: VecDeque, } /// Configuration of a simulated SP component @@ -214,3 +221,21 @@ impl GimletConfig { Ok(config) } } + +/// Represents a single simulated restart generation of the simulated SP's +/// ereporter. +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct EreportRestart { + pub id: uuid::Uuid, + pub metadata: toml::map::Map, + pub ereports: Vec, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Ereport { + pub task_name: String, + pub task_gen: u32, + pub uptime: u64, + #[serde(flatten)] + pub data: toml::map::Map, +} diff --git a/sp-sim/src/ereport.rs b/sp-sim/src/ereport.rs new file mode 100644 index 00000000000..b5a9d853070 --- /dev/null +++ b/sp-sim/src/ereport.rs @@ -0,0 +1,206 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +use crate::config::Ereport; +use crate::config::EreportRestart; +use gateway_messages::EreportHeader; +use gateway_messages::EreportHeaderV0; +use gateway_messages::EreportRequest; +use gateway_messages::EreportRequestFlags; +use gateway_messages::ereport::Ena; +use gateway_messages::ereport::RestartId; +use std::collections::VecDeque; +use std::io::Cursor; + +pub(crate) struct EreportState { + restarts: VecDeque, + current_restart: Option, + log: slog::Logger, +} + +impl EreportState { + pub(crate) fn new( + mut restarts: VecDeque, + log: slog::Logger, + ) -> Self { + let current_restart = restarts.pop_front().map(RestartState::from); + Self { restarts, current_restart, log } + } + + pub(crate) fn pretend_to_restart(&mut self) { + self.current_restart = + self.restarts.pop_front().map(RestartState::from); + } + + pub(crate) fn handle_request<'buf>( + &mut self, + request: EreportRequest, + buf: &'buf mut [u8], + ) -> &'buf [u8] { + let EreportRequest::V0(req) = request; + slog::info!(self.log, "ereport request: {req:?}"); + + let current_restart = match self.current_restart.as_mut() { + None => { + let amt = gateway_messages::serialize( + buf, + &EreportHeader::V0(EreportHeaderV0::new_empty( + req.restart_id, + )), + ) + .expect("serialization shouldn't fail"); + return &buf[..amt]; + } + Some(c) => c, + }; + + if req.restart_id != current_restart.restart_id { + slog::info!( + self.log, + "requested restart ID is not current, pretending to have \ + restarted..."; + "req_restart_id" => ?req.restart_id, + "current_restart_id" => ?current_restart.restart_id, + ); + let amt = gateway_messages::serialize( + buf, + &EreportHeader::V0(EreportHeaderV0::new_restarted( + current_restart.restart_id, + )), + ) + .expect("serialization shouldn't fail"); + let amt = { + let mut cursor = Cursor::new(&mut buf[amt..]); + serde_cbor::to_writer(&mut cursor, ¤t_restart.meta) + .expect("serializing metadata should fit in a packet..."); + amt + cursor.position() as usize + }; + return &buf[..amt]; + } + + if req.flags.contains(EreportRequestFlags::COMMIT) { + let committed = req.committed_ena; + let mut discarded = 0; + while current_restart + .ereports + .front() + .map(|(ena, _)| ena.0 <= committed.0) + .unwrap_or(false) + { + current_restart.ereports.pop_front(); + discarded += 1; + } + + slog::info!( + self.log, + "discarded {discarded} ereports up to {committed:?}" + ); + } + + let mut respondant_ereports = current_restart + .ereports + .iter() + .filter(|(ena, _)| ena.0 >= req.start_ena.0); + let end = if let Some((ena, ereport)) = respondant_ereports.next() { + let mut pos = gateway_messages::serialize( + buf, + &EreportHeader::V0(EreportHeaderV0::new_data( + current_restart.restart_id, + )), + ) + .expect("serialization shouldn't fail"); + pos += gateway_messages::serialize(&mut buf[pos..], ena) + .expect("serialing ena shouldn't fail"); + let bytes = serde_cbor::to_vec(ereport).unwrap(); + buf[pos..pos + bytes.len()].copy_from_slice(&bytes[..]); + pos += bytes.len(); + slog::debug!( + self.log, + "wrote initial ereport: {ereport:#?}"; + "ena" => ?ena, + "pos" => pos, + "bytes" => bytes.len(), + ); + + // try to fill the rest of the packet + for (_, ereport) in respondant_ereports { + let bytes = serde_cbor::to_vec(ereport).unwrap(); + // packet full! + if buf[pos..].len() < bytes.len() { + break; + } + + buf[pos..pos + bytes.len()].copy_from_slice(&bytes[..]); + pos += bytes.len(); + slog::debug!( + self.log, + "wrote subsequent ereport: {ereport:#?}"; + "pos" => pos, + "bytes" => bytes.len(), + ); + } + pos + } else { + gateway_messages::serialize( + buf, + &EreportHeader::V0(EreportHeaderV0::new_empty(req.restart_id)), + ) + .expect("serialization shouldn't fail") + }; + + &buf[..end] + } +} + +type EreportList = Vec; + +impl Ereport { + fn to_list(self) -> EreportList { + let Ereport { task_name, task_gen, uptime, data } = self; + vec![ + task_name.into(), + task_gen.into(), + (uptime as i64).into(), + data.into(), + ] + } +} + +struct RestartState { + ereports: VecDeque<(Ena, EreportList)>, + meta: toml::map::Map, + restart_id: RestartId, +} + +impl From for RestartState { + fn from(restart: EreportRestart) -> Self { + let EreportRestart { id, metadata, ereports } = restart; + let ereports = ereports + .into_iter() + .enumerate() + .map(|(ena, ereport)| (Ena(ena as u64), ereport.to_list())) + .collect(); + Self { ereports, meta: metadata, restart_id: RestartId(id.as_u128()) } + } +} + +// fn toml2cbor(toml: &toml::Value) -> serde_cbor::Value { +// match *toml { +// toml::Value::String(ref s) => serde_cbor::Value::Text(s.clone()), +// toml::Value::Integer(i) => serde_cbor::Value::Integer(i as i128), +// toml::Value::Float(f) => serde_cbor::Value::Float(f), +// toml::Value::Boolean(b) => serde_cbor::Value::Bool(b), +// toml::Value::Datetime(d) => unimplemented!("don't use toml datetimes"), +// toml::Value::Array(ref a) => { +// serde_cbor::Value::Array(a.iter().map(toml2cbor).collect()) +// } +// toml::Value::Table(ref t) => serde_cbor::Value::Map(toml2cbor_table::(toml)) +// } +// } + +// fn toml2cbor_table>(toml: &toml::Table) -> BTreeMap { +// toml.iter().map(|(k, v) { +// (k.clone().into(), toml2cbor(v)) +// }).collect() +// } diff --git a/sp-sim/src/gimlet.rs b/sp-sim/src/gimlet.rs index 68e1742c1e5..18834c730bb 100644 --- a/sp-sim/src/gimlet.rs +++ b/sp-sim/src/gimlet.rs @@ -7,6 +7,7 @@ use crate::SIM_ROT_BOARD; use crate::SimulatedSp; use crate::config::GimletConfig; use crate::config::SpComponentConfig; +use crate::ereport::EreportState; use crate::helpers::rot_slot_id_from_u16; use crate::helpers::rot_slot_id_to_u16; use crate::sensors::Sensors; @@ -22,6 +23,8 @@ use futures::future; use gateway_messages::CfpaPage; use gateway_messages::ComponentAction; use gateway_messages::ComponentActionResponse; +use gateway_messages::DumpSegment; +use gateway_messages::DumpTask; use gateway_messages::Header; use gateway_messages::MgsRequest; use gateway_messages::MgsResponse; @@ -34,8 +37,6 @@ use gateway_messages::SpError; use gateway_messages::SpPort; use gateway_messages::SpRequest; use gateway_messages::SpStateV2; -use gateway_messages::DumpSegment; -use gateway_messages::DumpTask; use gateway_messages::ignition::{self, LinkEvents}; use gateway_messages::sp_impl::Sender; use gateway_messages::sp_impl::SpHandler; @@ -222,6 +223,20 @@ impl Gimlet { let servers = [servers.0, servers.1]; + let ereport_servers = match &gimlet.common.ereport_network_config { + Some(cfg) => { + assert_eq!(cfg.len(), 2); // gimlet SP always has 2 ports + + let servers = future::try_join( + UdpServer::new(&cfg[0], &log), + UdpServer::new(&cfg[1], &log), + ) + .await?; + Some([servers.0, servers.1]) + } + None => None, + }; + for component_config in &gimlet.common.components { let id = component_config.id.as_str(); let component = SpComponent::try_from(id) @@ -277,6 +292,11 @@ impl Gimlet { let local_addrs = [servers[0].local_addr(), servers[1].local_addr()]; let (inner, handler, responses_sent_count) = UdpTask::new( servers, + ereport_servers, + EreportState::new( + gimlet.common.ereport_restarts.clone(), + log.new(slog::o!("sim-component" => "ereport-state")), + ), gimlet.common.components.clone(), attached_mgs, gimlet.common.serial_number.clone(), @@ -488,6 +508,8 @@ struct Ack; struct UdpTask { udp0: UdpServer, udp1: UdpServer, + ereport_servers: Option<[UdpServer; 2]>, + ereport_state: EreportState, handler: Arc>, commands: mpsc::UnboundedReceiver, responses_sent_count: watch::Sender, @@ -498,6 +520,8 @@ impl UdpTask { #[allow(clippy::too_many_arguments)] fn new( servers: [UdpServer; 2], + ereport_servers: Option<[UdpServer; 2]>, + ereport_state: EreportState, components: Vec, attached_mgs: AttachedMgsSerialConsole, serial_number: String, @@ -514,7 +538,7 @@ impl UdpTask { components, attached_mgs, incoming_serial_console, - log, + log.clone(), old_rot_state, no_stage0_caboose, ))); @@ -524,6 +548,8 @@ impl UdpTask { Self { udp0, udp1, + ereport_servers, + ereport_state, handler: Arc::clone(&handler), commands, responses_sent_count, @@ -539,6 +565,25 @@ impl UdpTask { let mut responsiveness = Responsiveness::Responsive; let mut throttle_count = usize::MAX; let mut throttler: Option> = None; + + async fn ereport_recv( + sock: Option<&mut UdpServer>, + ) -> anyhow::Result<( + gateway_messages::EreportRequest, + SocketAddrV6, + &mut UdpServer, + )> { + match sock { + Some(sock) => { + let (msg, addr) = sock.recv_from().await?; + let (req, _) = gateway_messages::deserialize::< + gateway_messages::EreportRequest, + >(msg)?; + Ok((req, addr, sock)) + } + None => futures::future::pending().await, + } + } loop { let incr_throttle_count: Pin< Box> + Send>, @@ -547,6 +592,10 @@ impl UdpTask { } else { Box::pin(future::pending()) }; + let (ereport0, ereport1) = match self.ereport_servers.as_mut() { + Some([e0, e1]) => (Some(e0), Some(e1)), + None => (None, None), + }; select! { Some(n) = incr_throttle_count => { throttle_count = throttle_count.saturating_add(n); @@ -591,6 +640,18 @@ impl UdpTask { } } + recv = ereport_recv(ereport0) => { + let (req, addr, sock) = recv?; + let rsp = self.ereport_state.handle_request(req, &mut out_buf); + sock.send_to(rsp, addr).await?; + } + + recv = ereport_recv(ereport1) => { + let (req, addr, sock) = recv?; + let rsp = self.ereport_state.handle_request(req, &mut out_buf); + sock.send_to(rsp, addr).await?; + } + command = self.commands.recv() => { // if sending half is gone, we're about to be killed anyway let command = match command { @@ -1525,7 +1586,6 @@ impl SpHandler for Handler { ) -> Result, SpError> { unimplemented!() } - } impl SimSpHandler for Handler { diff --git a/sp-sim/src/lib.rs b/sp-sim/src/lib.rs index 1f1721747a1..2464d02ffe8 100644 --- a/sp-sim/src/lib.rs +++ b/sp-sim/src/lib.rs @@ -3,6 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. pub mod config; +mod ereport; mod gimlet; mod helpers; mod sensors; From d1cd98b6c4469e840c285826409e4cc68c5a80ca Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Thu, 3 Apr 2025 16:14:03 -0700 Subject: [PATCH 11/32] wire up api (poorly) --- Cargo.lock | 1 + gateway/Cargo.toml | 1 + gateway/src/http_entrypoints.rs | 51 +++++++++++++++++++++++++++++---- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8ffb07215b7..d905e374d18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6991,6 +6991,7 @@ dependencies = [ "ipcc", "omicron-common", "omicron-test-utils", + "omicron-uuid-kinds", "omicron-workspace-hack", "oximeter", "oximeter-instruments", diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index dcc2613ed07..188bcce71a4 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -40,6 +40,7 @@ tokio-tungstenite.workspace = true toml.workspace = true uuid.workspace = true omicron-workspace-hack.workspace = true +omicron-uuid-kinds.workspace = true oximeter.workspace = true oximeter-producer.workspace = true oximeter-instruments = { workspace = true, features = ["http-instruments"] } diff --git a/gateway/src/http_entrypoints.rs b/gateway/src/http_entrypoints.rs index c0021df211d..69df34ec39d 100644 --- a/gateway/src/http_entrypoints.rs +++ b/gateway/src/http_entrypoints.rs @@ -935,14 +935,55 @@ impl GatewayApi for GatewayImpl { async fn sp_ereports_ingest( rqctx: RequestContext, - _path: Path, - _query: Query, + path: Path, + query: Query, ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { - Err(HttpError::for_internal_error( - "endpoint not yet implemented".to_string(), - )) + use gateway_sp_comms::ereport; + use omicron_uuid_kinds::GenericUuid; + + let ereport_types::EreportQuery { + restart_id, + start_at, + committed, + // TODO(eliza) + limit, + } = query.into_inner(); + let sp = apictx.mgmt_switch.sp(path.into_inner().sp.into())?; + let req_restart_id = + ereport::RestartId(restart_id.as_untyped_uuid().as_u128()); + let start_ena = start_at + .map(|ereport_types::Ena(e)| ereport::Ena(e)) + .unwrap_or(ereport::Ena(0)); + + let committed_ena = + committed.map(|ereport_types::Ena(e)| ereport::Ena(e)); + let ereport::EreportTranche { restart_id, ereports } = sp + .ereports(req_restart_id, start_ena, committed_ena) + .await + .map_err(|_| { + HttpError::for_internal_error( + "TODO(eliza) HAVE A GOOD ERROR FOR THIS".to_string(), + ) + })?; + let restart_id = + ereport_types::EreporterRestartUuid::from_u128(restart_id.0); + let ereports = ereports + .into_iter() + .map(|ereport::Ereport { ena: ereport::Ena(ena), data }| { + ereport_types::Ereport { + ena: ereport_types::Ena(ena), + data, + } + }) + .collect(); + let reports = dropshot::ResultsPage::new( + ereports, + &dropshot::EmptyScanParams {}, + |ereport_types::Ereport { ena, .. }, _| *ena, + )?; + Ok(HttpResponseOk(ereport_types::Ereports { restart_id, reports })) }; apictx.latencies.instrument_dropshot_handler(&rqctx, handler).await } From a45ff03e2de0453e45a1498b475d20d2dbc1dc05 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Fri, 4 Apr 2025 11:49:25 -0700 Subject: [PATCH 12/32] demo hour --- Cargo.lock | 32 ++++++++-------- Cargo.toml | 4 +- gateway/examples/config.toml | 3 ++ sp-sim/examples/config.toml | 74 ++++++++++++++++++++++++++++++++++-- sp-sim/src/ereport.rs | 16 +++++--- 5 files changed, 103 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d905e374d18..98f186b9f0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3457,7 +3457,7 @@ dependencies = [ "clap", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", "omicron-common", "omicron-workspace-hack", "reqwest", @@ -3478,7 +3478,7 @@ version = "0.1.0" dependencies = [ "base64 0.22.1", "chrono", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", "omicron-workspace-hack", "progenitor 0.9.1", "rand 0.8.5", @@ -3510,7 +3510,7 @@ dependencies = [ [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4#d4de62c0444652c3571e22f21e6e1f281fb8cfd4" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08#b13af9370fbb0db7474dfe7d79e7d1e6aca17f08" dependencies = [ "bitflags 2.9.0", "hubpack", @@ -3527,13 +3527,13 @@ dependencies = [ [[package]] name = "gateway-sp-comms" version = "0.1.1" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4#d4de62c0444652c3571e22f21e6e1f281fb8cfd4" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08#b13af9370fbb0db7474dfe7d79e7d1e6aca17f08" dependencies = [ "async-trait", "backoff", "futures", "fxhash", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", "hex", "hubpack", "hubtools", @@ -3565,7 +3565,7 @@ version = "0.1.0" dependencies = [ "camino", "dropshot 0.16.0", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", "gateway-types", "omicron-gateway", "omicron-test-utils", @@ -3580,7 +3580,7 @@ dependencies = [ name = "gateway-types" version = "0.1.0" dependencies = [ - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", "hex", "ipcc", "omicron-common", @@ -5589,7 +5589,7 @@ dependencies = [ "anyhow", "clap", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", "gateway-test-utils", "libc", "omicron-gateway", @@ -6055,7 +6055,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", "gateway-test-utils", "nexus-sled-agent-shared", "nexus-types", @@ -6119,7 +6119,7 @@ version = "0.1.0" dependencies = [ "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", "gateway-test-utils", "hubtools", "omicron-workspace-hack", @@ -6392,7 +6392,7 @@ dependencies = [ "dns-service-client", "dropshot 0.16.0", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", "gateway-test-utils", "headers", "hickory-resolver", @@ -6980,7 +6980,7 @@ dependencies = [ "expectorate", "futures", "gateway-api", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", "gateway-sp-comms", "gateway-test-utils", "gateway-types", @@ -7102,7 +7102,7 @@ dependencies = [ "fatfs", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", "gateway-test-utils", "headers", "hex", @@ -7238,7 +7238,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", "gateway-test-utils", "http", "humantime", @@ -11439,7 +11439,7 @@ dependencies = [ "clap", "dropshot 0.16.0", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", "gateway-types", "hex", "nix 0.29.0", @@ -13615,7 +13615,7 @@ dependencies = [ "fs-err", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=d4de62c0444652c3571e22f21e6e1f281fb8cfd4)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", "gateway-test-utils", "hex", "hickory-resolver", diff --git a/Cargo.toml b/Cargo.toml index 053a4c35b29..fa8e0607c90 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -409,8 +409,8 @@ gateway-client = { path = "clients/gateway-client" } # is "fine", because SP/MGS communication maintains forwards and backwards # compatibility, but will mean that faux-mgs might be missing new # functionality.) -gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "d4de62c0444652c3571e22f21e6e1f281fb8cfd4", default-features = false, features = ["std"] } -gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "d4de62c0444652c3571e22f21e6e1f281fb8cfd4" } +gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "b13af9370fbb0db7474dfe7d79e7d1e6aca17f08", default-features = false, features = ["std"] } +gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "b13af9370fbb0db7474dfe7d79e7d1e6aca17f08" } gateway-test-utils = { path = "gateway-test-utils" } gateway-types = { path = "gateway-types" } gethostname = "0.5.0" diff --git a/gateway/examples/config.toml b/gateway/examples/config.toml index cc0223dc473..a5727ae86dc 100644 --- a/gateway/examples/config.toml +++ b/gateway/examples/config.toml @@ -57,6 +57,7 @@ sp_port_2 = ["switch1"] kind = "simulated" fake-interface = "fake-switch0" addr = "[::1]:33300" +ereport-addr = "[::1]:44400" ignition-target = 1 location = { switch0 = ["switch", 0], switch1 = ["switch", 1] } @@ -64,6 +65,7 @@ location = { switch0 = ["switch", 0], switch1 = ["switch", 1] } kind = "simulated" fake-interface = "fake-sled0" addr = "[::1]:33310" +ereport-addr = "[::1]:44410" ignition-target = 2 location = { switch0 = ["sled", 0], switch1 = ["sled", 0] } @@ -71,6 +73,7 @@ location = { switch0 = ["sled", 0], switch1 = ["sled", 0] } kind = "simulated" fake-interface = "fake-sled1" addr = "[::1]:33320" +ereport-addr = "[::1]:44420" ignition-target = 3 location = { switch0 = ["sled", 1], switch1 = ["sled", 1] } diff --git a/sp-sim/examples/config.toml b/sp-sim/examples/config.toml index 8c88ac6afe1..f28766d46aa 100644 --- a/sp-sim/examples/config.toml +++ b/sp-sim/examples/config.toml @@ -15,6 +15,14 @@ bind_addr = "[::1]:33300" [simulated_sps.sidecar.network_config.simulated] bind_addr = "[::1]:33301" +[[simulated_sps.sidecar.ereport_network_config]] +[simulated_sps.sidecar.ereport_network_config.simulated] +bind_addr = "[::1]:44400" + +[[simulated_sps.sidecar.ereport_network_config]] +[simulated_sps.sidecar.ereport_network_config.simulated] +bind_addr = "[::1]:44401" + [[simulated_sps.gimlet]] serial_number = "SimGimlet0" manufacturing_root_cert_seed = "01de01de01de01de01de01de01de01de01de01de01de01de01de01de01de01de" @@ -28,6 +36,14 @@ bind_addr = "[::1]:33310" [simulated_sps.gimlet.network_config.simulated] bind_addr = "[::1]:33311" +[[simulated_sps.gimlet.ereport_network_config]] +[simulated_sps.gimlet.ereport_network_config.simulated] +bind_addr = "[::1]:44410" + +[[simulated_sps.gimlet.ereport_network_config]] +[simulated_sps.gimlet.ereport_network_config.simulated] +bind_addr = "[::1]:44411" + [[simulated_sps.gimlet.components]] id = "sp3-host-cpu" device = "sp3-host-cpu" @@ -56,6 +72,53 @@ sensors = [ { name = "CPU", kind = "Temperature", last_data.value = 64.5, last_data.timestamp = 1234 }, ] +[[simulated_sps.gimlet.ereport_restarts]] +id = "af1ebf85-36ba-4c31-bbec-b9825d6d9d8b" + +[simulated_sps.gimlet.ereport_restarts.metadata] +chassis_model = "SimGimletSp" +chassis_serial = "SimGimlet0" +chassis_revision = 4 +hubris_archive_id = "fefefe" + +[[simulated_sps.gimlet.ereport_restarts.ereports]] +task_name = "task_apollo_server" +task_gen = 13 +uptime = 1233 +class = "gov.nasa.apollo.o2_tanks.stir.begin" +message = "stirring the tanks" + +[[simulated_sps.gimlet.ereport_restarts.ereports]] +task_name = "drv_ae35_server" +task_gen = 1 +uptime = 1234 +class = "io.discovery.ae35.fault" +message = "i've just picked up a fault in the AE-35 unit" +de = { scheme = "fmd", authority = { product-id = "HAL-9000-series computer", server-id = "HAL 9000"}, mod-name = "ae35-diagnosis" } +hours_to_failure = 72 + +[[simulated_sps.gimlet.ereport_restarts.ereports]] +task_name = "task_apollo_server" +task_gen = 13 +uptime = 1237 +class = "gov.nasa.apollo.fault" +message = "houston, we have a problem" +crew = ["Lovell", "Swigert", "Hayes"] + +[[simulated_sps.gimlet.ereport_restarts.ereports]] +task_name = "drv_thingy_server" +task_gen = 2 +uptime = 1240 +class = "flagrant_error" +computer = false + +[[simulated_sps.gimlet.ereport_restarts.ereports]] +task_name = "task_latex_server" +task_gen = 1 +uptime = 1245 +class = "overfull_hbox" +badness = 10000 + [[simulated_sps.gimlet]] serial_number = "SimGimlet1" manufacturing_root_cert_seed = "01de01de01de01de01de01de01de01de01de01de01de01de01de01de01de01de" @@ -69,6 +132,14 @@ bind_addr = "[::1]:33320" [simulated_sps.gimlet.network_config.simulated] bind_addr = "[::1]:33321" +[[simulated_sps.gimlet.ereport_network_config]] +[simulated_sps.gimlet.ereport_network_config.simulated] +bind_addr = "[::1]:44420" + +[[simulated_sps.gimlet.ereport_network_config]] +[simulated_sps.gimlet.ereport_network_config.simulated] +bind_addr = "[::1]:44421" + [[simulated_sps.gimlet.components]] id = "sp3-host-cpu" device = "sp3-host-cpu" @@ -97,15 +168,12 @@ sensors = [ { name = "CPU", kind = "Temperature", last_data.value = 63.1, last_data.timestamp = 1234 }, ] - - [log] # Show log messages of this level and more severe level = "debug" # Example output to a terminal (with colors) mode = "stderr-terminal" - # Example output to a file, appending if it already exists. #mode = "file" #path = "logs/server.log" diff --git a/sp-sim/src/ereport.rs b/sp-sim/src/ereport.rs index b5a9d853070..9ca4c525130 100644 --- a/sp-sim/src/ereport.rs +++ b/sp-sim/src/ereport.rs @@ -80,6 +80,7 @@ impl EreportState { } if req.flags.contains(EreportRequestFlags::COMMIT) { + slog::debug!(self.log, "commit flag is there"); let committed = req.committed_ena; let mut discarded = 0; while current_restart @@ -112,6 +113,8 @@ impl EreportState { .expect("serialization shouldn't fail"); pos += gateway_messages::serialize(&mut buf[pos..], ena) .expect("serialing ena shouldn't fail"); + buf[pos] = 0x9f; // start list + pos += 1; let bytes = serde_cbor::to_vec(ereport).unwrap(); buf[pos..pos + bytes.len()].copy_from_slice(&bytes[..]); pos += bytes.len(); @@ -119,15 +122,15 @@ impl EreportState { self.log, "wrote initial ereport: {ereport:#?}"; "ena" => ?ena, - "pos" => pos, - "bytes" => bytes.len(), + "packet_bytes" => pos, + "ereport_bytes" => bytes.len(), ); // try to fill the rest of the packet for (_, ereport) in respondant_ereports { let bytes = serde_cbor::to_vec(ereport).unwrap(); // packet full! - if buf[pos..].len() < bytes.len() { + if buf[pos..].len() < (bytes.len() + 1) { break; } @@ -136,10 +139,13 @@ impl EreportState { slog::debug!( self.log, "wrote subsequent ereport: {ereport:#?}"; - "pos" => pos, - "bytes" => bytes.len(), + "packet_bytes" => pos, + "ereport_bytes" => bytes.len(), ); } + + buf[pos] = 0xff; // break list; + pos += 1; pos } else { gateway_messages::serialize( From ff56b841f10c151b4bb695c97d48911eac501935 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Fri, 4 Apr 2025 12:11:15 -0700 Subject: [PATCH 13/32] update for gatway fix --- Cargo.lock | 34 +++++++++++++++++----------------- Cargo.toml | 4 ++-- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 98f186b9f0a..511f55170fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3457,7 +3457,7 @@ dependencies = [ "clap", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", "omicron-common", "omicron-workspace-hack", "reqwest", @@ -3478,7 +3478,7 @@ version = "0.1.0" dependencies = [ "base64 0.22.1", "chrono", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", "omicron-workspace-hack", "progenitor 0.9.1", "rand 0.8.5", @@ -3493,7 +3493,7 @@ dependencies = [ [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=9bbac475dcaac88286c07a20b6bd3e94fc81d7f0#9bbac475dcaac88286c07a20b6bd3e94fc81d7f0" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29#6b7c1bf0f2b86067502324c8c06e410fc173ea29" dependencies = [ "bitflags 2.9.0", "hubpack", @@ -3510,7 +3510,7 @@ dependencies = [ [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08#b13af9370fbb0db7474dfe7d79e7d1e6aca17f08" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=9bbac475dcaac88286c07a20b6bd3e94fc81d7f0#9bbac475dcaac88286c07a20b6bd3e94fc81d7f0" dependencies = [ "bitflags 2.9.0", "hubpack", @@ -3527,13 +3527,13 @@ dependencies = [ [[package]] name = "gateway-sp-comms" version = "0.1.1" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08#b13af9370fbb0db7474dfe7d79e7d1e6aca17f08" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29#6b7c1bf0f2b86067502324c8c06e410fc173ea29" dependencies = [ "async-trait", "backoff", "futures", "fxhash", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", "hex", "hubpack", "hubtools", @@ -3565,7 +3565,7 @@ version = "0.1.0" dependencies = [ "camino", "dropshot 0.16.0", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", "gateway-types", "omicron-gateway", "omicron-test-utils", @@ -3580,7 +3580,7 @@ dependencies = [ name = "gateway-types" version = "0.1.0" dependencies = [ - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", "hex", "ipcc", "omicron-common", @@ -5589,7 +5589,7 @@ dependencies = [ "anyhow", "clap", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", "gateway-test-utils", "libc", "omicron-gateway", @@ -6055,7 +6055,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", "gateway-test-utils", "nexus-sled-agent-shared", "nexus-types", @@ -6119,7 +6119,7 @@ version = "0.1.0" dependencies = [ "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", "gateway-test-utils", "hubtools", "omicron-workspace-hack", @@ -6392,7 +6392,7 @@ dependencies = [ "dns-service-client", "dropshot 0.16.0", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", "gateway-test-utils", "headers", "hickory-resolver", @@ -6980,7 +6980,7 @@ dependencies = [ "expectorate", "futures", "gateway-api", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", "gateway-sp-comms", "gateway-test-utils", "gateway-types", @@ -7102,7 +7102,7 @@ dependencies = [ "fatfs", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", "gateway-test-utils", "headers", "hex", @@ -7238,7 +7238,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", "gateway-test-utils", "http", "humantime", @@ -11439,7 +11439,7 @@ dependencies = [ "clap", "dropshot 0.16.0", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", "gateway-types", "hex", "nix 0.29.0", @@ -13615,7 +13615,7 @@ dependencies = [ "fs-err", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=b13af9370fbb0db7474dfe7d79e7d1e6aca17f08)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", "gateway-test-utils", "hex", "hickory-resolver", diff --git a/Cargo.toml b/Cargo.toml index fa8e0607c90..f85645681ff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -409,8 +409,8 @@ gateway-client = { path = "clients/gateway-client" } # is "fine", because SP/MGS communication maintains forwards and backwards # compatibility, but will mean that faux-mgs might be missing new # functionality.) -gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "b13af9370fbb0db7474dfe7d79e7d1e6aca17f08", default-features = false, features = ["std"] } -gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "b13af9370fbb0db7474dfe7d79e7d1e6aca17f08" } +gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "6b7c1bf0f2b86067502324c8c06e410fc173ea29", default-features = false, features = ["std"] } +gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "6b7c1bf0f2b86067502324c8c06e410fc173ea29" } gateway-test-utils = { path = "gateway-test-utils" } gateway-types = { path = "gateway-types" } gethostname = "0.5.0" From e69fc918913b0d1646e3d7f1c9ad67bbee41c303 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Fri, 4 Apr 2025 12:13:11 -0700 Subject: [PATCH 14/32] put fake interface in logs --- gateway/src/management_switch.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/gateway/src/management_switch.rs b/gateway/src/management_switch.rs index 7f71aeabf27..8f483750282 100644 --- a/gateway/src/management_switch.rs +++ b/gateway/src/management_switch.rs @@ -254,7 +254,11 @@ impl ManagementSwitch { .await } - SwitchPortConfig::Simulated { addr, ereport_addr, .. } => { + SwitchPortConfig::Simulated { + addr, + ereport_addr, + fake_interface, + } => { // Bind a new socket for each simulated switch port. let bind_addr: SocketAddrV6 = SocketAddrV6::new(Ipv6Addr::UNSPECIFIED, 0, 0, 0); @@ -281,7 +285,9 @@ impl ManagementSwitch { ereport_socket, *ereport_addr, retry_config, - log.clone(), + log.new( + slog::o!("interface" => fake_interface.clone()), + ), ) } }; From f250dedf3b7c2e052aefe2e85d656d72f356332a Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Fri, 4 Apr 2025 13:09:28 -0700 Subject: [PATCH 15/32] actually good errors --- Cargo.lock | 34 +++++------ Cargo.toml | 4 +- gateway/src/error.rs | 105 ++++++++++++++++++++++---------- gateway/src/http_entrypoints.rs | 14 +++-- 4 files changed, 100 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 511f55170fa..39bf2f4678c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3457,7 +3457,7 @@ dependencies = [ "clap", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", "omicron-common", "omicron-workspace-hack", "reqwest", @@ -3478,7 +3478,7 @@ version = "0.1.0" dependencies = [ "base64 0.22.1", "chrono", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", "omicron-workspace-hack", "progenitor 0.9.1", "rand 0.8.5", @@ -3493,7 +3493,7 @@ dependencies = [ [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29#6b7c1bf0f2b86067502324c8c06e410fc173ea29" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=9bbac475dcaac88286c07a20b6bd3e94fc81d7f0#9bbac475dcaac88286c07a20b6bd3e94fc81d7f0" dependencies = [ "bitflags 2.9.0", "hubpack", @@ -3510,7 +3510,7 @@ dependencies = [ [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=9bbac475dcaac88286c07a20b6bd3e94fc81d7f0#9bbac475dcaac88286c07a20b6bd3e94fc81d7f0" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9#df8f30e4dda3345890dd77021681366438947bf9" dependencies = [ "bitflags 2.9.0", "hubpack", @@ -3527,13 +3527,13 @@ dependencies = [ [[package]] name = "gateway-sp-comms" version = "0.1.1" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29#6b7c1bf0f2b86067502324c8c06e410fc173ea29" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9#df8f30e4dda3345890dd77021681366438947bf9" dependencies = [ "async-trait", "backoff", "futures", "fxhash", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", "hex", "hubpack", "hubtools", @@ -3565,7 +3565,7 @@ version = "0.1.0" dependencies = [ "camino", "dropshot 0.16.0", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", "gateway-types", "omicron-gateway", "omicron-test-utils", @@ -3580,7 +3580,7 @@ dependencies = [ name = "gateway-types" version = "0.1.0" dependencies = [ - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", "hex", "ipcc", "omicron-common", @@ -5589,7 +5589,7 @@ dependencies = [ "anyhow", "clap", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", "gateway-test-utils", "libc", "omicron-gateway", @@ -6055,7 +6055,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", "gateway-test-utils", "nexus-sled-agent-shared", "nexus-types", @@ -6119,7 +6119,7 @@ version = "0.1.0" dependencies = [ "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", "gateway-test-utils", "hubtools", "omicron-workspace-hack", @@ -6392,7 +6392,7 @@ dependencies = [ "dns-service-client", "dropshot 0.16.0", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", "gateway-test-utils", "headers", "hickory-resolver", @@ -6980,7 +6980,7 @@ dependencies = [ "expectorate", "futures", "gateway-api", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", "gateway-sp-comms", "gateway-test-utils", "gateway-types", @@ -7102,7 +7102,7 @@ dependencies = [ "fatfs", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", "gateway-test-utils", "headers", "hex", @@ -7238,7 +7238,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", "gateway-test-utils", "http", "humantime", @@ -11439,7 +11439,7 @@ dependencies = [ "clap", "dropshot 0.16.0", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", "gateway-types", "hex", "nix 0.29.0", @@ -13615,7 +13615,7 @@ dependencies = [ "fs-err", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=6b7c1bf0f2b86067502324c8c06e410fc173ea29)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", "gateway-test-utils", "hex", "hickory-resolver", diff --git a/Cargo.toml b/Cargo.toml index f85645681ff..7965a54e130 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -409,8 +409,8 @@ gateway-client = { path = "clients/gateway-client" } # is "fine", because SP/MGS communication maintains forwards and backwards # compatibility, but will mean that faux-mgs might be missing new # functionality.) -gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "6b7c1bf0f2b86067502324c8c06e410fc173ea29", default-features = false, features = ["std"] } -gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "6b7c1bf0f2b86067502324c8c06e410fc173ea29" } +gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "df8f30e4dda3345890dd77021681366438947bf9", default-features = false, features = ["std"] } +gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "df8f30e4dda3345890dd77021681366438947bf9" } gateway-test-utils = { path = "gateway-test-utils" } gateway-types = { path = "gateway-types" } gethostname = "0.5.0" diff --git a/gateway/src/error.rs b/gateway/src/error.rs index d70c873fb8d..a78f3599129 100644 --- a/gateway/src/error.rs +++ b/gateway/src/error.rs @@ -12,6 +12,7 @@ pub use gateway_sp_comms::error::CommunicationError; use gateway_sp_comms::error::UpdateError; use slog_error_chain::InlineErrorChain; use slog_error_chain::SlogInlineError; +use std::error::Error; use std::time::Duration; use thiserror::Error; @@ -48,6 +49,22 @@ pub enum SpCommsError { }, } +#[derive(Debug, Error, SlogInlineError)] +pub enum EreportError { + #[error("error communicating with SP {sp:?}")] + SpCommunicationFailed { + sp: SpIdentifier, + #[source] + err: CommunicationError, + }, + #[error("error reading ereports from SP {sp:?}")] + Ereport { + sp: SpIdentifier, + #[source] + err: gateway_sp_comms::error::EreportError, + }, +} + /// Errors returned by attempts to look up a SP in the management switch's /// discovery map. #[derive(Debug, Error, SlogInlineError)] @@ -74,32 +91,9 @@ impl From for HttpError { Some("SerialConsoleAttached".to_string()), InlineErrorChain::new(&error).to_string(), ), - SpCommsError::SpCommunicationFailed { - err: - CommunicationError::SpError(SpError::RequestUnsupportedForSp), - .. - } => HttpError::for_bad_request( - Some("RequestUnsupportedForSp".to_string()), - InlineErrorChain::new(&error).to_string(), - ), - SpCommsError::SpCommunicationFailed { - err: - CommunicationError::SpError( - SpError::RequestUnsupportedForComponent, - ), - .. - } => HttpError::for_bad_request( - Some("RequestUnsupportedForComponent".to_string()), - InlineErrorChain::new(&error).to_string(), - ), - SpCommsError::SpCommunicationFailed { - err: - CommunicationError::SpError(SpError::InvalidSlotForComponent), - .. - } => HttpError::for_bad_request( - Some("InvalidSlotForComponent".to_string()), - InlineErrorChain::new(&error).to_string(), - ), + ref e @ SpCommsError::SpCommunicationFailed { ref err, .. } => { + comms_error_to_http(&e, err) + } SpCommsError::UpdateFailed { err: UpdateError::ImageTooLarge, .. @@ -139,13 +133,6 @@ impl From for HttpError { "Timeout ", InlineErrorChain::new(&error).to_string(), ), - SpCommsError::SpCommunicationFailed { .. } => { - http_err_with_message( - dropshot::ErrorStatusCode::SERVICE_UNAVAILABLE, - "SpCommunicationFailed", - InlineErrorChain::new(&error).to_string(), - ) - } SpCommsError::UpdateFailed { .. } => http_err_with_message( dropshot::ErrorStatusCode::SERVICE_UNAVAILABLE, "UpdateFailed", @@ -155,6 +142,58 @@ impl From for HttpError { } } +impl From for HttpError { + fn from(error: EreportError) -> HttpError { + match error { + ref e @ EreportError::SpCommunicationFailed { ref err, .. } => { + comms_error_to_http(&e, err) + } + ref e @ EreportError::Ereport { .. } => http_err_with_message( + dropshot::ErrorStatusCode::INTERNAL_SERVER_ERROR, + "EreportError", + InlineErrorChain::new(&e).to_string(), + ), + } + } +} + +fn comms_error_to_http( + error: &dyn Error, + kind: &CommunicationError, +) -> HttpError { + match kind { + CommunicationError::SpError(SpError::SerialConsoleAlreadyAttached) => { + HttpError::for_bad_request( + Some("SerialConsoleAttached".to_string()), + InlineErrorChain::new(&error).to_string(), + ) + } + CommunicationError::SpError(SpError::RequestUnsupportedForSp) => { + HttpError::for_bad_request( + Some("RequestUnsupportedForSp".to_string()), + InlineErrorChain::new(&error).to_string(), + ) + } + CommunicationError::SpError( + SpError::RequestUnsupportedForComponent, + ) => HttpError::for_bad_request( + Some("RequestUnsupportedForComponent".to_string()), + InlineErrorChain::new(&error).to_string(), + ), + CommunicationError::SpError(SpError::InvalidSlotForComponent) => { + HttpError::for_bad_request( + Some("InvalidSlotForComponent".to_string()), + InlineErrorChain::new(&error).to_string(), + ) + } + _ => http_err_with_message( + dropshot::ErrorStatusCode::SERVICE_UNAVAILABLE, + "SpCommunicationFailed", + InlineErrorChain::new(&error).to_string(), + ), + } +} + impl From for HttpError { fn from(error: SpLookupError) -> Self { match error { diff --git a/gateway/src/http_entrypoints.rs b/gateway/src/http_entrypoints.rs index 69df34ec39d..97d8e8e2bfc 100644 --- a/gateway/src/http_entrypoints.rs +++ b/gateway/src/http_entrypoints.rs @@ -940,6 +940,7 @@ impl GatewayApi for GatewayImpl { ) -> Result, HttpError> { let apictx = rqctx.context(); let handler = async { + use crate::EreportError; use gateway_sp_comms::ereport; use omicron_uuid_kinds::GenericUuid; @@ -950,7 +951,9 @@ impl GatewayApi for GatewayImpl { // TODO(eliza) limit, } = query.into_inner(); - let sp = apictx.mgmt_switch.sp(path.into_inner().sp.into())?; + + let sp_id = path.into_inner().sp.into(); + let sp = apictx.mgmt_switch.sp(sp_id)?; let req_restart_id = ereport::RestartId(restart_id.as_untyped_uuid().as_u128()); let start_ena = start_at @@ -962,10 +965,11 @@ impl GatewayApi for GatewayImpl { let ereport::EreportTranche { restart_id, ereports } = sp .ereports(req_restart_id, start_ena, committed_ena) .await - .map_err(|_| { - HttpError::for_internal_error( - "TODO(eliza) HAVE A GOOD ERROR FOR THIS".to_string(), - ) + .map_err(|error| match error { + gateway_sp_comms::error::EreportError::Communication( + err, + ) => EreportError::SpCommunicationFailed { sp: sp_id, err }, + err => EreportError::Ereport { sp: sp_id, err }, })?; let restart_id = ereport_types::EreporterRestartUuid::from_u128(restart_id.0); From 7d53fdb7cbc2c5b58548fb77a045ad099372f4be Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Sat, 5 Apr 2025 11:16:34 -0700 Subject: [PATCH 16/32] pick up gateway messages tweaks --- Cargo.lock | 40 ++++++++++++++++++++-------------------- Cargo.toml | 4 ++-- sp-sim/src/ereport.rs | 36 +++++++++++++++++++++--------------- sp-sim/src/gimlet.rs | 13 +++++-------- 4 files changed, 48 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 39bf2f4678c..f76799d1de0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1607,7 +1607,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" dependencies = [ "lazy_static", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -3457,7 +3457,7 @@ dependencies = [ "clap", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", "omicron-common", "omicron-workspace-hack", "reqwest", @@ -3478,7 +3478,7 @@ version = "0.1.0" dependencies = [ "base64 0.22.1", "chrono", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", "omicron-workspace-hack", "progenitor 0.9.1", "rand 0.8.5", @@ -3493,7 +3493,7 @@ dependencies = [ [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=9bbac475dcaac88286c07a20b6bd3e94fc81d7f0#9bbac475dcaac88286c07a20b6bd3e94fc81d7f0" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e#663df644d8e731ca293502fb88c1872e38f2929e" dependencies = [ "bitflags 2.9.0", "hubpack", @@ -3510,7 +3510,7 @@ dependencies = [ [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9#df8f30e4dda3345890dd77021681366438947bf9" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=9bbac475dcaac88286c07a20b6bd3e94fc81d7f0#9bbac475dcaac88286c07a20b6bd3e94fc81d7f0" dependencies = [ "bitflags 2.9.0", "hubpack", @@ -3527,13 +3527,13 @@ dependencies = [ [[package]] name = "gateway-sp-comms" version = "0.1.1" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9#df8f30e4dda3345890dd77021681366438947bf9" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e#663df644d8e731ca293502fb88c1872e38f2929e" dependencies = [ "async-trait", "backoff", "futures", "fxhash", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", "hex", "hubpack", "hubtools", @@ -3565,7 +3565,7 @@ version = "0.1.0" dependencies = [ "camino", "dropshot 0.16.0", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", "gateway-types", "omicron-gateway", "omicron-test-utils", @@ -3580,7 +3580,7 @@ dependencies = [ name = "gateway-types" version = "0.1.0" dependencies = [ - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", "hex", "ipcc", "omicron-common", @@ -5220,7 +5220,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -5589,7 +5589,7 @@ dependencies = [ "anyhow", "clap", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", "gateway-test-utils", "libc", "omicron-gateway", @@ -6055,7 +6055,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", "gateway-test-utils", "nexus-sled-agent-shared", "nexus-types", @@ -6119,7 +6119,7 @@ version = "0.1.0" dependencies = [ "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", "gateway-test-utils", "hubtools", "omicron-workspace-hack", @@ -6392,7 +6392,7 @@ dependencies = [ "dns-service-client", "dropshot 0.16.0", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", "gateway-test-utils", "headers", "hickory-resolver", @@ -6980,7 +6980,7 @@ dependencies = [ "expectorate", "futures", "gateway-api", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", "gateway-sp-comms", "gateway-test-utils", "gateway-types", @@ -7102,7 +7102,7 @@ dependencies = [ "fatfs", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", "gateway-test-utils", "headers", "hex", @@ -7238,7 +7238,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", "gateway-test-utils", "http", "humantime", @@ -11439,7 +11439,7 @@ dependencies = [ "clap", "dropshot 0.16.0", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", "gateway-types", "hex", "nix 0.29.0", @@ -13615,7 +13615,7 @@ dependencies = [ "fs-err", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=df8f30e4dda3345890dd77021681366438947bf9)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", "gateway-test-utils", "hex", "hickory-resolver", @@ -13744,7 +13744,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 7965a54e130..5eec498b68a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -409,8 +409,8 @@ gateway-client = { path = "clients/gateway-client" } # is "fine", because SP/MGS communication maintains forwards and backwards # compatibility, but will mean that faux-mgs might be missing new # functionality.) -gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "df8f30e4dda3345890dd77021681366438947bf9", default-features = false, features = ["std"] } -gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "df8f30e4dda3345890dd77021681366438947bf9" } +gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "663df644d8e731ca293502fb88c1872e38f2929e", default-features = false, features = ["std"] } +gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "663df644d8e731ca293502fb88c1872e38f2929e" } gateway-test-utils = { path = "gateway-test-utils" } gateway-types = { path = "gateway-types" } gethostname = "0.5.0" diff --git a/sp-sim/src/ereport.rs b/sp-sim/src/ereport.rs index 9ca4c525130..4b2fc78df8c 100644 --- a/sp-sim/src/ereport.rs +++ b/sp-sim/src/ereport.rs @@ -4,11 +4,11 @@ use crate::config::Ereport; use crate::config::EreportRestart; -use gateway_messages::EreportHeader; -use gateway_messages::EreportHeaderV0; -use gateway_messages::EreportRequest; -use gateway_messages::EreportRequestFlags; +use gateway_messages::ereport; use gateway_messages::ereport::Ena; +use gateway_messages::ereport::EreportRequest; +use gateway_messages::ereport::EreportResponseHeader; +use gateway_messages::ereport::ResponseHeaderV0; use gateway_messages::ereport::RestartId; use std::collections::VecDeque; use std::io::Cursor; @@ -45,7 +45,7 @@ impl EreportState { None => { let amt = gateway_messages::serialize( buf, - &EreportHeader::V0(EreportHeaderV0::new_empty( + &EreportResponseHeader::V0(ResponseHeaderV0::new_empty( req.restart_id, )), ) @@ -65,7 +65,7 @@ impl EreportState { ); let amt = gateway_messages::serialize( buf, - &EreportHeader::V0(EreportHeaderV0::new_restarted( + &EreportResponseHeader::V0(ResponseHeaderV0::new_restarted( current_restart.restart_id, )), ) @@ -79,14 +79,16 @@ impl EreportState { return &buf[..amt]; } - if req.flags.contains(EreportRequestFlags::COMMIT) { - slog::debug!(self.log, "commit flag is there"); - let committed = req.committed_ena; + if let Some(committed_ena) = req.committed_ena() { + slog::debug!( + self.log, + "MGS committed ereports up to {committed_ena:?}" + ); let mut discarded = 0; while current_restart .ereports .front() - .map(|(ena, _)| ena.0 <= committed.0) + .map(|(ena, _)| ena <= &committed_ena) .unwrap_or(false) { current_restart.ereports.pop_front(); @@ -95,7 +97,7 @@ impl EreportState { slog::info!( self.log, - "discarded {discarded} ereports up to {committed:?}" + "discarded {discarded} ereports up to {committed_ena:?}" ); } @@ -106,9 +108,11 @@ impl EreportState { let end = if let Some((ena, ereport)) = respondant_ereports.next() { let mut pos = gateway_messages::serialize( buf, - &EreportHeader::V0(EreportHeaderV0::new_data( - current_restart.restart_id, - )), + &EreportResponseHeader::V0( + ereport::ResponseHeaderV0::new_data( + current_restart.restart_id, + ), + ), ) .expect("serialization shouldn't fail"); pos += gateway_messages::serialize(&mut buf[pos..], ena) @@ -150,7 +154,9 @@ impl EreportState { } else { gateway_messages::serialize( buf, - &EreportHeader::V0(EreportHeaderV0::new_empty(req.restart_id)), + &EreportResponseHeader::V0(ResponseHeaderV0::new_empty( + req.restart_id, + )), ) .expect("serialization shouldn't fail") }; diff --git a/sp-sim/src/gimlet.rs b/sp-sim/src/gimlet.rs index 18834c730bb..87de918d371 100644 --- a/sp-sim/src/gimlet.rs +++ b/sp-sim/src/gimlet.rs @@ -37,6 +37,7 @@ use gateway_messages::SpError; use gateway_messages::SpPort; use gateway_messages::SpRequest; use gateway_messages::SpStateV2; +use gateway_messages::ereport::EreportRequest; use gateway_messages::ignition::{self, LinkEvents}; use gateway_messages::sp_impl::Sender; use gateway_messages::sp_impl::SpHandler; @@ -568,17 +569,13 @@ impl UdpTask { async fn ereport_recv( sock: Option<&mut UdpServer>, - ) -> anyhow::Result<( - gateway_messages::EreportRequest, - SocketAddrV6, - &mut UdpServer, - )> { + ) -> anyhow::Result<(EreportRequest, SocketAddrV6, &mut UdpServer)> + { match sock { Some(sock) => { let (msg, addr) = sock.recv_from().await?; - let (req, _) = gateway_messages::deserialize::< - gateway_messages::EreportRequest, - >(msg)?; + let (req, _) = + gateway_messages::deserialize::(msg)?; Ok((req, addr, sock)) } None => futures::future::pending().await, From d1738a7ee3f5eb95be7fed25e1cd4111f4541c3a Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Sat, 5 Apr 2025 12:13:57 -0700 Subject: [PATCH 17/32] simulator improvements --- sp-sim/examples/config.toml | 20 ++---- sp-sim/src/config.rs | 30 ++++++-- sp-sim/src/ereport.rs | 133 ++++++++++++++++++++++-------------- sp-sim/src/gimlet.rs | 57 ++++++++++++++-- sp-sim/src/lib.rs | 14 ++++ sp-sim/src/sidecar.rs | 25 +++++++ 6 files changed, 201 insertions(+), 78 deletions(-) diff --git a/sp-sim/examples/config.toml b/sp-sim/examples/config.toml index f28766d46aa..ed3fde7a005 100644 --- a/sp-sim/examples/config.toml +++ b/sp-sim/examples/config.toml @@ -72,23 +72,17 @@ sensors = [ { name = "CPU", kind = "Temperature", last_data.value = 64.5, last_data.timestamp = 1234 }, ] -[[simulated_sps.gimlet.ereport_restarts]] -id = "af1ebf85-36ba-4c31-bbec-b9825d6d9d8b" +[simulated_sps.gimlet.ereport_config] +restart_id = "af1ebf85-36ba-4c31-bbec-b9825d6d9d8b" -[simulated_sps.gimlet.ereport_restarts.metadata] -chassis_model = "SimGimletSp" -chassis_serial = "SimGimlet0" -chassis_revision = 4 -hubris_archive_id = "fefefe" - -[[simulated_sps.gimlet.ereport_restarts.ereports]] +[[simulated_sps.gimlet.ereport_config.ereports]] task_name = "task_apollo_server" task_gen = 13 uptime = 1233 class = "gov.nasa.apollo.o2_tanks.stir.begin" message = "stirring the tanks" -[[simulated_sps.gimlet.ereport_restarts.ereports]] +[[simulated_sps.gimlet.ereport_config.ereports]] task_name = "drv_ae35_server" task_gen = 1 uptime = 1234 @@ -97,7 +91,7 @@ message = "i've just picked up a fault in the AE-35 unit" de = { scheme = "fmd", authority = { product-id = "HAL-9000-series computer", server-id = "HAL 9000"}, mod-name = "ae35-diagnosis" } hours_to_failure = 72 -[[simulated_sps.gimlet.ereport_restarts.ereports]] +[[simulated_sps.gimlet.ereport_config.ereports]] task_name = "task_apollo_server" task_gen = 13 uptime = 1237 @@ -105,14 +99,14 @@ class = "gov.nasa.apollo.fault" message = "houston, we have a problem" crew = ["Lovell", "Swigert", "Hayes"] -[[simulated_sps.gimlet.ereport_restarts.ereports]] +[[simulated_sps.gimlet.ereport_config.ereports]] task_name = "drv_thingy_server" task_gen = 2 uptime = 1240 class = "flagrant_error" computer = false -[[simulated_sps.gimlet.ereport_restarts.ereports]] +[[simulated_sps.gimlet.ereport_config.ereports]] task_name = "task_latex_server" task_gen = 1 uptime = 1245 diff --git a/sp-sim/src/config.rs b/sp-sim/src/config.rs index e8c54d0f9de..b78d0ab58fa 100644 --- a/sp-sim/src/config.rs +++ b/sp-sim/src/config.rs @@ -11,7 +11,6 @@ use gateway_messages::DeviceCapabilities; use gateway_messages::DevicePresence; use serde::Deserialize; use serde::Serialize; -use std::collections::VecDeque; use std::net::Ipv6Addr; use std::net::SocketAddrV6; use std::path::Path; @@ -98,9 +97,9 @@ pub struct SpCommonConfig { /// Simulate a RoT stage0 with no caboose #[serde(default)] pub no_stage0_caboose: bool, - /// Fake ereport restart generations. - #[serde(skip_serializing_if = "VecDeque::is_empty", default)] - pub ereport_restarts: VecDeque, + /// Fake ereport configuration + #[serde(default)] + pub ereport_config: EreportConfig, } /// Configuration of a simulated SP component @@ -222,13 +221,32 @@ impl GimletConfig { } } +#[derive( + Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, Default, +)] +pub struct EreportConfig { + #[serde(flatten, default)] + pub restart: EreportRestart, + + #[serde(skip_serializing_if = "Vec::is_empty", default)] + pub ereports: Vec, +} + /// Represents a single simulated restart generation of the simulated SP's /// ereporter. #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] pub struct EreportRestart { - pub id: uuid::Uuid, + #[serde(default = "uuid::Uuid::new_v4")] + pub restart_id: uuid::Uuid, + + #[serde(skip_serializing_if = "toml::map::Map::is_empty", default)] pub metadata: toml::map::Map, - pub ereports: Vec, +} + +impl Default for EreportRestart { + fn default() -> Self { + Self { restart_id: uuid::Uuid::new_v4(), metadata: Default::default() } + } } #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] diff --git a/sp-sim/src/ereport.rs b/sp-sim/src/ereport.rs index 4b2fc78df8c..f8de8a3acdb 100644 --- a/sp-sim/src/ereport.rs +++ b/sp-sim/src/ereport.rs @@ -3,6 +3,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use crate::config::Ereport; +use crate::config::EreportConfig; use crate::config::EreportRestart; use gateway_messages::ereport; use gateway_messages::ereport::Ena; @@ -12,25 +13,87 @@ use gateway_messages::ereport::ResponseHeaderV0; use gateway_messages::ereport::RestartId; use std::collections::VecDeque; use std::io::Cursor; +use tokio::sync::oneshot; pub(crate) struct EreportState { - restarts: VecDeque, - current_restart: Option, + ereports: VecDeque<(Ena, EreportList)>, + meta: toml::map::Map, + /// Next ENA, used for appending new ENAs at runtime. + next_ena: Ena, + restart_id: RestartId, log: slog::Logger, } +#[derive(Debug)] +pub(crate) enum Command { + Restart(EreportRestart, oneshot::Sender<()>), + Append(Ereport, oneshot::Sender), +} + impl EreportState { pub(crate) fn new( - mut restarts: VecDeque, + EreportConfig { restart, ereports }: EreportConfig, log: slog::Logger, ) -> Self { - let current_restart = restarts.pop_front().map(RestartState::from); - Self { restarts, current_restart, log } + let EreportRestart { metadata, restart_id } = restart; + slog::info!( + log, + "configuring sim ereports"; + "restart_id" => ?restart_id, + "n_ereports" => ereports.len(), + "metadata" => ?metadata, + ); + let ereports: VecDeque<(Ena, EreportList)> = ereports + .into_iter() + .enumerate() + .map(|(i, ereport)| (Ena(i as u64), ereport.to_list())) + .collect(); + let restart_id = RestartId(restart_id.as_u128()); + let next_ena = Ena(ereports.len() as u64); + Self { ereports, next_ena, restart_id, meta: metadata, log } + } + + pub(crate) fn handle_command(&mut self, cmd: Command) { + match cmd { + Command::Append(ereport, tx) => { + let ena = self.append_ereport(ereport); + tx.send(ena).map_err(|_| "receiving half died").unwrap(); + } + Command::Restart(restart, tx) => { + self.pretend_to_restart(restart); + tx.send(()).map_err(|_| "receiving half died").unwrap(); + } + } + } + + pub(crate) fn pretend_to_restart( + &mut self, + EreportRestart { metadata, restart_id }: EreportRestart, + ) { + slog::info!( + self.log, + "simulating restart"; + "curr_restart_id" => ?self.restart_id, + "next_restart_id" => ?restart_id, + "metadata" => ?metadata, + ); + self.restart_id = RestartId(restart_id.as_u128()); + self.meta = metadata; + self.ereports.clear(); + self.next_ena = Ena(0); } - pub(crate) fn pretend_to_restart(&mut self) { - self.current_restart = - self.restarts.pop_front().map(RestartState::from); + pub(crate) fn append_ereport(&mut self, ereport: Ereport) -> Ena { + let ena = self.next_ena; + slog::info!( + self.log, + "appending new ereport"; + "ena" => ?ena, + "ereport" => ?ereport, + ); + self.ereports.push_back((ena, ereport.to_list())); + self.next_ena.0 += 1; + ena } pub(crate) fn handle_request<'buf>( @@ -41,38 +104,24 @@ impl EreportState { let EreportRequest::V0(req) = request; slog::info!(self.log, "ereport request: {req:?}"); - let current_restart = match self.current_restart.as_mut() { - None => { - let amt = gateway_messages::serialize( - buf, - &EreportResponseHeader::V0(ResponseHeaderV0::new_empty( - req.restart_id, - )), - ) - .expect("serialization shouldn't fail"); - return &buf[..amt]; - } - Some(c) => c, - }; - - if req.restart_id != current_restart.restart_id { + if req.restart_id != self.restart_id { slog::info!( self.log, "requested restart ID is not current, pretending to have \ restarted..."; "req_restart_id" => ?req.restart_id, - "current_restart_id" => ?current_restart.restart_id, + "current_restart_id" => ?self.restart_id, ); let amt = gateway_messages::serialize( buf, &EreportResponseHeader::V0(ResponseHeaderV0::new_restarted( - current_restart.restart_id, + self.restart_id, )), ) .expect("serialization shouldn't fail"); let amt = { let mut cursor = Cursor::new(&mut buf[amt..]); - serde_cbor::to_writer(&mut cursor, ¤t_restart.meta) + serde_cbor::to_writer(&mut cursor, &self.meta) .expect("serializing metadata should fit in a packet..."); amt + cursor.position() as usize }; @@ -85,13 +134,13 @@ impl EreportState { "MGS committed ereports up to {committed_ena:?}" ); let mut discarded = 0; - while current_restart + while self .ereports .front() .map(|(ena, _)| ena <= &committed_ena) .unwrap_or(false) { - current_restart.ereports.pop_front(); + self.ereports.pop_front(); discarded += 1; } @@ -101,17 +150,13 @@ impl EreportState { ); } - let mut respondant_ereports = current_restart - .ereports - .iter() - .filter(|(ena, _)| ena.0 >= req.start_ena.0); + let mut respondant_ereports = + self.ereports.iter().filter(|(ena, _)| ena.0 >= req.start_ena.0); let end = if let Some((ena, ereport)) = respondant_ereports.next() { let mut pos = gateway_messages::serialize( buf, &EreportResponseHeader::V0( - ereport::ResponseHeaderV0::new_data( - current_restart.restart_id, - ), + ereport::ResponseHeaderV0::new_data(self.restart_id), ), ) .expect("serialization shouldn't fail"); @@ -179,24 +224,6 @@ impl Ereport { } } -struct RestartState { - ereports: VecDeque<(Ena, EreportList)>, - meta: toml::map::Map, - restart_id: RestartId, -} - -impl From for RestartState { - fn from(restart: EreportRestart) -> Self { - let EreportRestart { id, metadata, ereports } = restart; - let ereports = ereports - .into_iter() - .enumerate() - .map(|(ena, ereport)| (Ena(ena as u64), ereport.to_list())) - .collect(); - Self { ereports, meta: metadata, restart_id: RestartId(id.as_u128()) } - } -} - // fn toml2cbor(toml: &toml::Value) -> serde_cbor::Value { // match *toml { // toml::Value::String(ref s) => serde_cbor::Value::Text(s.clone()), diff --git a/sp-sim/src/gimlet.rs b/sp-sim/src/gimlet.rs index 87de918d371..da40c366a9d 100644 --- a/sp-sim/src/gimlet.rs +++ b/sp-sim/src/gimlet.rs @@ -7,6 +7,7 @@ use crate::SIM_ROT_BOARD; use crate::SimulatedSp; use crate::config::GimletConfig; use crate::config::SpComponentConfig; +use crate::ereport; use crate::ereport::EreportState; use crate::helpers::rot_slot_id_from_u16; use crate::helpers::rot_slot_id_to_u16; @@ -63,7 +64,8 @@ use tokio::sync::watch; use tokio::task::{self, JoinHandle}; pub const SIM_GIMLET_BOARD: &str = "SimGimletSp"; -const SP_GITC0: &[u8] = b"ffffffff"; +const SP_GITC0_STRING: &str = "ffffffff"; +const SP_GITC0: &[u8] = SP_GITC0_STRING.as_bytes(); const SP_GITC1: &[u8] = b"fefefefe"; const SP_BORD: &[u8] = SIM_GIMLET_BOARD.as_bytes(); const SP_NAME: &[u8] = b"SimGimlet"; @@ -184,6 +186,28 @@ impl SimulatedSp for Gimlet { } tx } + + async fn ereport_restart(&self, restart: crate::config::EreportRestart) { + let (tx, rx) = oneshot::channel(); + if self + .commands + .send(Command::Ereport(ereport::Command::Restart(restart, tx))) + .is_ok() + { + rx.await.unwrap(); + } + } + + async fn ereport_append( + &self, + ereport: crate::config::Ereport, + ) -> gateway_messages::ereport::Ena { + let (tx, rx) = oneshot::channel(); + self.commands + .send(Command::Ereport(ereport::Command::Append(ereport, tx))) + .expect("simulated gimlet task has died"); + rx.await.unwrap() + } } impl Gimlet { @@ -291,13 +315,32 @@ impl Gimlet { } } let local_addrs = [servers[0].local_addr(), servers[1].local_addr()]; + let ereport_state = { + let mut cfg = gimlet.common.ereport_config.clone(); + if cfg.restart.metadata.is_empty() { + let map = &mut cfg.restart.metadata; + map.insert( + "chassis_model".to_string(), + SIM_GIMLET_BOARD.into(), + ); + map.insert( + "chassis_serial".to_string(), + gimlet.common.serial_number.clone().into(), + ); + map.insert( + "hubris_archive_id".to_string(), + SP_GITC0_STRING.into(), + ); + } + EreportState::new( + cfg, + log.new(slog::o!("sim-component" => "ereport-state")), + ) + }; let (inner, handler, responses_sent_count) = UdpTask::new( servers, ereport_servers, - EreportState::new( - gimlet.common.ereport_restarts.clone(), - log.new(slog::o!("sim-component" => "ereport-state")), - ), + ereport_state, gimlet.common.components.clone(), attached_mgs, gimlet.common.serial_number.clone(), @@ -502,6 +545,7 @@ impl SerialConsoleTcpTask { enum Command { SetResponsiveness(Responsiveness, oneshot::Sender), SetThrottler(Option>, oneshot::Sender), + Ereport(ereport::Command), } struct Ack; @@ -674,7 +718,8 @@ impl UdpTask { } tx.send(Ack) .map_err(|_| "receiving half died").unwrap(); - } + }, + Command::Ereport(cmd) => self.ereport_state.handle_command(cmd), } } } diff --git a/sp-sim/src/lib.rs b/sp-sim/src/lib.rs index 2464d02ffe8..56754c6496c 100644 --- a/sp-sim/src/lib.rs +++ b/sp-sim/src/lib.rs @@ -99,6 +99,20 @@ pub trait SimulatedSp { async fn install_udp_accept_semaphore( &self, ) -> mpsc::UnboundedSender; + + /// Simulate a restart of the SP for the purposes of ereport collection. + /// + /// This will clear any simulated ereports buffered by the simulated SP, and + /// set the simulated snitch task's restart ID and metadata to the provided + /// [`config::EreportRestart`] value. + async fn ereport_restart(&self, restart: config::EreportRestart); + + /// Add a new simulated ereport to the SP's queue of ereports, returning its + /// ENA. + async fn ereport_append( + &self, + restart: config::Ereport, + ) -> gateway_messages::ereport::Ena; } // Helper function to pad a simulated serial number (stored as a `String`) to diff --git a/sp-sim/src/sidecar.rs b/sp-sim/src/sidecar.rs index e2e4b63b619..800feb942c2 100644 --- a/sp-sim/src/sidecar.rs +++ b/sp-sim/src/sidecar.rs @@ -10,6 +10,7 @@ use crate::config::Config; use crate::config::SidecarConfig; use crate::config::SimulatedSpsConfig; use crate::config::SpComponentConfig; +use crate::ereport; use crate::helpers::rot_slot_id_from_u16; use crate::helpers::rot_slot_id_to_u16; use crate::sensors::Sensors; @@ -156,6 +157,28 @@ impl SimulatedSp for Sidecar { } tx } + + async fn ereport_restart(&self, restart: crate::config::EreportRestart) { + let (tx, rx) = oneshot::channel(); + if self + .commands + .send(Command::Ereport(ereport::Command::Restart(restart, tx))) + .is_ok() + { + rx.await.unwrap(); + } + } + + async fn ereport_append( + &self, + ereport: crate::config::Ereport, + ) -> gateway_messages::ereport::Ena { + let (tx, rx) = oneshot::channel(); + self.commands + .send(Command::Ereport(ereport::Command::Append(ereport, tx))) + .expect("simulated sidecar task has died"); + rx.await.unwrap() + } } impl Sidecar { @@ -228,6 +251,7 @@ enum Command { CurrentIgnitionState(oneshot::Sender>), SetResponsiveness(Responsiveness, oneshot::Sender), SetThrottler(Option>, oneshot::Sender), + Ereport(ereport::Command), } #[derive(Debug)] @@ -358,6 +382,7 @@ impl Inner { tx.send(Ack) .map_err(|_| "receiving half died").unwrap(); } + Command::Ereport(_) => todo!("eliza"), } } } From 7cc88ea50539473693b986cdbbb5de4c9f744bd7 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Sat, 5 Apr 2025 12:29:49 -0700 Subject: [PATCH 18/32] add ereports to sim sidecar --- sp-sim/src/gimlet.rs | 76 ++++++++++-------- sp-sim/src/lib.rs | 4 + sp-sim/src/sidecar.rs | 174 ++++++++++++++++++++++++++++++++---------- 3 files changed, 180 insertions(+), 74 deletions(-) diff --git a/sp-sim/src/gimlet.rs b/sp-sim/src/gimlet.rs index da40c366a9d..c74af2c1612 100644 --- a/sp-sim/src/gimlet.rs +++ b/sp-sim/src/gimlet.rs @@ -101,6 +101,7 @@ pub enum SimSpHandledRequest { pub struct Gimlet { local_addrs: Option<[SocketAddrV6; 2]>, + ereport_addrs: Option<[SocketAddrV6; 2]>, handler: Option>>, serial_console_addrs: HashMap, commands: mpsc::UnboundedSender, @@ -134,6 +135,14 @@ impl SimulatedSp for Gimlet { self.local_addrs.map(|addrs| addrs[i]) } + fn local_ereport_addr(&self, port: SpPort) -> Option { + let i = match port { + SpPort::One => 0, + SpPort::Two => 1, + }; + self.ereport_addrs.map(|addrs| addrs[i]) + } + async fn set_responsiveness(&self, r: Responsiveness) { let (tx, rx) = oneshot::channel(); if let Ok(()) = self.commands.send(Command::SetResponsiveness(r, tx)) { @@ -228,6 +237,7 @@ impl Gimlet { let Some(network_config) = &gimlet.common.network_config else { return Ok(Self { local_addrs: None, + ereport_addrs: None, handler: None, serial_console_addrs, commands, @@ -248,18 +258,41 @@ impl Gimlet { let servers = [servers.0, servers.1]; - let ereport_servers = match &gimlet.common.ereport_network_config { - Some(cfg) => { - assert_eq!(cfg.len(), 2); // gimlet SP always has 2 ports + let ereport_log = log.new(slog::o!("component" => "ereport-sim")); + let (ereport_servers, ereport_addrs) = + match &gimlet.common.ereport_network_config { + Some(cfg) => { + assert_eq!(cfg.len(), 2); // gimlet SP always has 2 ports - let servers = future::try_join( - UdpServer::new(&cfg[0], &log), - UdpServer::new(&cfg[1], &log), - ) - .await?; - Some([servers.0, servers.1]) + let servers = future::try_join( + UdpServer::new(&cfg[0], &ereport_log), + UdpServer::new(&cfg[1], &ereport_log), + ) + .await?; + let addrs = + [servers.0.local_addr(), servers.1.local_addr()]; + (Some([servers.0, servers.1]), Some(addrs)) + } + None => (None, None), + }; + let ereport_state = { + let mut cfg = gimlet.common.ereport_config.clone(); + if cfg.restart.metadata.is_empty() { + let map = &mut cfg.restart.metadata; + map.insert( + "chassis_model".to_string(), + SIM_GIMLET_BOARD.into(), + ); + map.insert( + "chassis_serial".to_string(), + gimlet.common.serial_number.clone().into(), + ); + map.insert( + "hubris_archive_id".to_string(), + SP_GITC0_STRING.into(), + ); } - None => None, + EreportState::new(cfg, ereport_log) }; for component_config in &gimlet.common.components { @@ -315,28 +348,6 @@ impl Gimlet { } } let local_addrs = [servers[0].local_addr(), servers[1].local_addr()]; - let ereport_state = { - let mut cfg = gimlet.common.ereport_config.clone(); - if cfg.restart.metadata.is_empty() { - let map = &mut cfg.restart.metadata; - map.insert( - "chassis_model".to_string(), - SIM_GIMLET_BOARD.into(), - ); - map.insert( - "chassis_serial".to_string(), - gimlet.common.serial_number.clone().into(), - ); - map.insert( - "hubris_archive_id".to_string(), - SP_GITC0_STRING.into(), - ); - } - EreportState::new( - cfg, - log.new(slog::o!("sim-component" => "ereport-state")), - ) - }; let (inner, handler, responses_sent_count) = UdpTask::new( servers, ereport_servers, @@ -356,6 +367,7 @@ impl Gimlet { Ok(Self { local_addrs: Some(local_addrs), + ereport_addrs, handler: Some(handler), serial_console_addrs, commands, diff --git a/sp-sim/src/lib.rs b/sp-sim/src/lib.rs index 56754c6496c..098db594f41 100644 --- a/sp-sim/src/lib.rs +++ b/sp-sim/src/lib.rs @@ -45,6 +45,10 @@ pub trait SimulatedSp { /// configured to listen. fn local_addr(&self, port: SpPort) -> Option; + /// Listening UDP ereport address of the given port of this simulated SP, if it was + /// configured to listen for ereport packets. + fn local_ereport_addr(&self, port: SpPort) -> Option; + /// Simulate the SP being unresponsive, in which it ignores all incoming /// messages. async fn set_responsiveness(&self, r: Responsiveness); diff --git a/sp-sim/src/sidecar.rs b/sp-sim/src/sidecar.rs index 800feb942c2..105c125c772 100644 --- a/sp-sim/src/sidecar.rs +++ b/sp-sim/src/sidecar.rs @@ -11,6 +11,7 @@ use crate::config::SidecarConfig; use crate::config::SimulatedSpsConfig; use crate::config::SpComponentConfig; use crate::ereport; +use crate::ereport::EreportState; use crate::helpers::rot_slot_id_from_u16; use crate::helpers::rot_slot_id_to_u16; use crate::sensors::Sensors; @@ -73,6 +74,7 @@ pub const SIM_SIDECAR_BOARD: &str = "SimSidecarSp"; pub struct Sidecar { local_addrs: Option<[SocketAddrV6; 2]>, + ereport_addrs: Option<[SocketAddrV6; 2]>, handler: Option>>, commands: mpsc::UnboundedSender, inner_task: Option>, @@ -104,6 +106,14 @@ impl SimulatedSp for Sidecar { self.local_addrs.map(|addrs| addrs[i]) } + fn local_ereport_addr(&self, port: SpPort) -> Option { + let i = match port { + SpPort::One => 0, + SpPort::Two => 1, + }; + self.ereport_addrs.map(|addrs| addrs[i]) + } + async fn set_responsiveness(&self, r: Responsiveness) { let (tx, rx) = oneshot::channel(); self.commands @@ -191,49 +201,88 @@ impl Sidecar { let (commands, commands_rx) = mpsc::unbounded_channel(); - let (local_addrs, inner_task, handler, responses_sent_count) = - if let Some(network_config) = &sidecar.common.network_config { - // bind to our two local "KSZ" ports - let servers = future::try_join( - UdpServer::new(&network_config[0], &log), - UdpServer::new(&network_config[1], &log), - ) - .await?; - - let servers = [servers.0, servers.1]; - let local_addrs = - [servers[0].local_addr(), servers[1].local_addr()]; - - let (inner, handler, responses_sent_count) = Inner::new( - servers, - sidecar.common.components.clone(), - sidecar.common.serial_number.clone(), - FakeIgnition::new(&config.simulated_sps), - commands_rx, - log, - sidecar.common.old_rot_state, - sidecar.common.no_stage0_caboose, - ); - let inner_task = - task::spawn(async move { inner.run().await.unwrap() }); - - ( - Some(local_addrs), - Some(inner_task), - Some(handler), - Some(responses_sent_count), - ) - } else { - (None, None, None, None) + if let Some(network_config) = &sidecar.common.network_config { + // bind to our two local "KSZ" ports + let servers = future::try_join( + UdpServer::new(&network_config[0], &log), + UdpServer::new(&network_config[1], &log), + ) + .await?; + + let servers = [servers.0, servers.1]; + let local_addrs = + [servers[0].local_addr(), servers[1].local_addr()]; + + let ereport_log = log.new(slog::o!("component" => "ereport-sim")); + let (ereport_servers, ereport_addrs) = + match &sidecar.common.ereport_network_config { + Some(cfg) => { + assert_eq!(cfg.len(), 2); // gimlet SP always has 2 ports + + let servers = future::try_join( + UdpServer::new(&cfg[0], &ereport_log), + UdpServer::new(&cfg[1], &ereport_log), + ) + .await?; + let addrs = + [servers.0.local_addr(), servers.1.local_addr()]; + (Some([servers.0, servers.1]), Some(addrs)) + } + None => (None, None), + }; + let ereport_state = { + let mut cfg = sidecar.common.ereport_config.clone(); + if cfg.restart.metadata.is_empty() { + let map = &mut cfg.restart.metadata; + map.insert( + "chassis_model".to_string(), + SIM_SIDECAR_BOARD.into(), + ); + map.insert( + "chassis_serial".to_string(), + sidecar.common.serial_number.clone().into(), + ); + map.insert( + "hubris_archive_id".to_string(), + "asdfasdfasdf".into(), + ); + } + EreportState::new(cfg, ereport_log) }; - Ok(Self { - local_addrs, - handler, - commands, - inner_task, - responses_sent_count, - }) + let (inner, handler, responses_sent_count) = Inner::new( + servers, + ereport_servers, + ereport_state, + sidecar.common.components.clone(), + sidecar.common.serial_number.clone(), + FakeIgnition::new(&config.simulated_sps), + commands_rx, + log, + sidecar.common.old_rot_state, + sidecar.common.no_stage0_caboose, + ); + let inner_task = + task::spawn(async move { inner.run().await.unwrap() }); + + Ok(Self { + local_addrs: Some(local_addrs), + ereport_addrs, + handler: Some(handler), + commands, + inner_task: Some(inner_task), + responses_sent_count: Some(responses_sent_count), + }) + } else { + Ok(Self { + local_addrs: None, + ereport_addrs: None, + handler: None, + commands, + inner_task: None, + responses_sent_count: None, + }) + } } pub async fn current_ignition_state(&self) -> Vec { @@ -261,6 +310,9 @@ struct Inner { handler: Arc>, udp0: UdpServer, udp1: UdpServer, + ereport0: Option, + ereport1: Option, + ereport_state: EreportState, commands: mpsc::UnboundedReceiver, responses_sent_count: watch::Sender, } @@ -269,6 +321,8 @@ impl Inner { #[allow(clippy::too_many_arguments)] fn new( servers: [UdpServer; 2], + ereport_servers: Option<[UdpServer; 2]>, + ereport_state: EreportState, components: Vec, serial_number: String, ignition: FakeIgnition, @@ -288,9 +342,16 @@ impl Inner { ))); let responses_sent_count = watch::Sender::new(0); let responses_sent_count_rx = responses_sent_count.subscribe(); + let (ereport0, ereport1) = match ereport_servers { + Some([e0, e1]) => (Some(e0), Some(e1)), + None => (None, None), + }; ( Self { handler: Arc::clone(&handler), + ereport0, + ereport1, + ereport_state, udp0, udp1, commands, @@ -302,10 +363,27 @@ impl Inner { } async fn run(mut self) -> Result<()> { + use gateway_messages::ereport::EreportRequest; + let mut out_buf = [0; gateway_messages::MAX_SERIALIZED_SIZE]; let mut responsiveness = Responsiveness::Responsive; let mut throttle_count = usize::MAX; let mut throttler: Option> = None; + + async fn ereport_recv( + sock: Option<&mut UdpServer>, + ) -> anyhow::Result<(EreportRequest, SocketAddrV6, &mut UdpServer)> + { + match sock { + Some(sock) => { + let (msg, addr) = sock.recv_from().await?; + let (req, _) = + gateway_messages::deserialize::(msg)?; + Ok((req, addr, sock)) + } + None => futures::future::pending().await, + } + } loop { let incr_throttle_count: Pin< Box> + Send>, @@ -347,6 +425,18 @@ impl Inner { } } + recv = ereport_recv(self.ereport0.as_mut()) => { + let (req, addr, sock) = recv?; + let rsp = self.ereport_state.handle_request(req, &mut out_buf); + sock.send_to(rsp, addr).await?; + } + + recv = ereport_recv(self.ereport1.as_mut()) => { + let (req, addr, sock) = recv?; + let rsp = self.ereport_state.handle_request(req, &mut out_buf); + sock.send_to(rsp, addr).await?; + } + command = self.commands.recv() => { // if sending half is gone, we're about to be killed anyway let command = match command { @@ -382,7 +472,7 @@ impl Inner { tx.send(Ack) .map_err(|_| "receiving half died").unwrap(); } - Command::Ereport(_) => todo!("eliza"), + Command::Ereport(cmd) => self.ereport_state.handle_command(cmd), } } } From d481e2165fd1e45524709e639b574581fde9ff8d Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Sat, 5 Apr 2025 12:32:57 -0700 Subject: [PATCH 19/32] hakari --- Cargo.lock | 47 +++++++++++++-------------------------- workspace-hack/Cargo.toml | 36 +++++++++++++++--------------- 2 files changed, 33 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f76799d1de0..838c2fc8399 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3457,7 +3457,7 @@ dependencies = [ "clap", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", + "gateway-messages", "omicron-common", "omicron-workspace-hack", "reqwest", @@ -3478,7 +3478,7 @@ version = "0.1.0" dependencies = [ "base64 0.22.1", "chrono", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", + "gateway-messages", "omicron-workspace-hack", "progenitor 0.9.1", "rand 0.8.5", @@ -3507,23 +3507,6 @@ dependencies = [ "zerocopy 0.6.6", ] -[[package]] -name = "gateway-messages" -version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=9bbac475dcaac88286c07a20b6bd3e94fc81d7f0#9bbac475dcaac88286c07a20b6bd3e94fc81d7f0" -dependencies = [ - "bitflags 2.9.0", - "hubpack", - "serde", - "serde-big-array", - "serde_repr", - "smoltcp 0.9.1", - "static_assertions", - "strum_macros 0.25.3", - "uuid", - "zerocopy 0.6.6", -] - [[package]] name = "gateway-sp-comms" version = "0.1.1" @@ -3533,7 +3516,7 @@ dependencies = [ "backoff", "futures", "fxhash", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", + "gateway-messages", "hex", "hubpack", "hubtools", @@ -3565,7 +3548,7 @@ version = "0.1.0" dependencies = [ "camino", "dropshot 0.16.0", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", + "gateway-messages", "gateway-types", "omicron-gateway", "omicron-test-utils", @@ -3580,7 +3563,7 @@ dependencies = [ name = "gateway-types" version = "0.1.0" dependencies = [ - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", + "gateway-messages", "hex", "ipcc", "omicron-common", @@ -5589,7 +5572,7 @@ dependencies = [ "anyhow", "clap", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", + "gateway-messages", "gateway-test-utils", "libc", "omicron-gateway", @@ -6055,7 +6038,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", + "gateway-messages", "gateway-test-utils", "nexus-sled-agent-shared", "nexus-types", @@ -6119,7 +6102,7 @@ version = "0.1.0" dependencies = [ "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", + "gateway-messages", "gateway-test-utils", "hubtools", "omicron-workspace-hack", @@ -6392,7 +6375,7 @@ dependencies = [ "dns-service-client", "dropshot 0.16.0", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", + "gateway-messages", "gateway-test-utils", "headers", "hickory-resolver", @@ -6980,7 +6963,7 @@ dependencies = [ "expectorate", "futures", "gateway-api", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", + "gateway-messages", "gateway-sp-comms", "gateway-test-utils", "gateway-types", @@ -7102,7 +7085,7 @@ dependencies = [ "fatfs", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", + "gateway-messages", "gateway-test-utils", "headers", "hex", @@ -7238,7 +7221,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", + "gateway-messages", "gateway-test-utils", "http", "humantime", @@ -7637,7 +7620,7 @@ dependencies = [ "futures-sink", "futures-task", "futures-util", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=9bbac475dcaac88286c07a20b6bd3e94fc81d7f0)", + "gateway-messages", "generic-array", "getrandom 0.2.15", "getrandom 0.3.1", @@ -11439,7 +11422,7 @@ dependencies = [ "clap", "dropshot 0.16.0", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", + "gateway-messages", "gateway-types", "hex", "nix 0.29.0", @@ -13615,7 +13598,7 @@ dependencies = [ "fs-err", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", + "gateway-messages", "gateway-test-utils", "hex", "hickory-resolver", diff --git a/workspace-hack/Cargo.toml b/workspace-hack/Cargo.toml index 33b49a59412..a549ee9e176 100644 --- a/workspace-hack/Cargo.toml +++ b/workspace-hack/Cargo.toml @@ -26,7 +26,7 @@ base16ct = { version = "0.2.0", default-features = false, features = ["alloc"] } base64 = { version = "0.22.1" } base64ct = { version = "1.6.0", default-features = false, features = ["std"] } bitflags-dff4ba8e3ae991db = { package = "bitflags", version = "1.3.2" } -bitflags-f595c2ba2a3f28df = { package = "bitflags", version = "2.6.0", default-features = false, features = ["serde"] } +bitflags-f595c2ba2a3f28df = { package = "bitflags", version = "2.9.0", default-features = false, features = ["serde"] } bstr = { version = "1.10.0" } buf-list = { version = "1.0.3", default-features = false, features = ["tokio1"] } byteorder = { version = "1.5.0" } @@ -57,7 +57,7 @@ futures-io = { version = "0.3.31" } futures-sink = { version = "0.3.31" } futures-task = { version = "0.3.31", default-features = false, features = ["std"] } futures-util = { version = "0.3.31", features = ["channel", "io", "sink"] } -gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "9bbac475dcaac88286c07a20b6bd3e94fc81d7f0", features = ["std"] } +gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "663df644d8e731ca293502fb88c1872e38f2929e", features = ["std"] } generic-array = { version = "0.14.7", default-features = false, features = ["more_lengths", "zeroize"] } getrandom-6f8ce4dd05d13bba = { package = "getrandom", version = "0.2.15", default-features = false, features = ["js", "rdrand", "std"] } group = { version = "0.13.0", default-features = false, features = ["alloc"] } @@ -85,7 +85,7 @@ num-bigint-dig = { version = "0.8.4", default-features = false, features = ["i12 num-integer = { version = "0.1.46", features = ["i128"] } num-iter = { version = "0.1.45", default-features = false, features = ["i128"] } num-traits = { version = "0.2.19", features = ["i128", "libm"] } -once_cell = { version = "1.20.3" } +once_cell = { version = "1.21.3" } openapiv3 = { version = "2.0.0", default-features = false, features = ["skip_serializing_defaults"] } peg-runtime = { version = "0.8.5", default-features = false, features = ["std"] } pem-rfc7468 = { version = "0.7.0", default-features = false, features = ["std"] } @@ -117,7 +117,7 @@ similar = { version = "2.7.0", features = ["bytes", "inline", "unicode"] } slog = { version = "2.7.0", features = ["dynamic-keys", "max_level_trace", "release_max_level_debug", "release_max_level_trace"] } smallvec = { version = "1.14.0", default-features = false, features = ["const_new"] } spin = { version = "0.9.8" } -string_cache = { version = "0.8.7" } +string_cache = { version = "0.8.9" } subtle = { version = "2.6.1" } syn-f595c2ba2a3f28df = { package = "syn", version = "2.0.98", features = ["extra-traits", "fold", "full", "visit", "visit-mut"] } time = { version = "0.3.36", features = ["formatting", "local-offset", "macros", "parsing"] } @@ -131,7 +131,7 @@ toml_edit-3c51e837cfc5589a = { package = "toml_edit", version = "0.22.24", featu tracing = { version = "0.1.40", features = ["log"] } usdt = { version = "0.5.0" } usdt-impl = { version = "0.5.0", default-features = false, features = ["asm", "des"] } -uuid = { version = "1.15.1", features = ["serde", "v4"] } +uuid = { version = "1.16.0", features = ["serde", "v4"] } x509-cert = { version = "0.2.5" } zerocopy-c38e5c1d305a1b54 = { package = "zerocopy", version = "0.8.10", default-features = false, features = ["derive", "simd"] } zerocopy-ca01ad9e24f5d932 = { package = "zerocopy", version = "0.7.35", features = ["derive", "simd"] } @@ -148,7 +148,7 @@ base16ct = { version = "0.2.0", default-features = false, features = ["alloc"] } base64 = { version = "0.22.1" } base64ct = { version = "1.6.0", default-features = false, features = ["std"] } bitflags-dff4ba8e3ae991db = { package = "bitflags", version = "1.3.2" } -bitflags-f595c2ba2a3f28df = { package = "bitflags", version = "2.6.0", default-features = false, features = ["serde"] } +bitflags-f595c2ba2a3f28df = { package = "bitflags", version = "2.9.0", default-features = false, features = ["serde"] } bstr = { version = "1.10.0" } buf-list = { version = "1.0.3", default-features = false, features = ["tokio1"] } byteorder = { version = "1.5.0" } @@ -180,7 +180,7 @@ futures-io = { version = "0.3.31" } futures-sink = { version = "0.3.31" } futures-task = { version = "0.3.31", default-features = false, features = ["std"] } futures-util = { version = "0.3.31", features = ["channel", "io", "sink"] } -gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "9bbac475dcaac88286c07a20b6bd3e94fc81d7f0", features = ["std"] } +gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "663df644d8e731ca293502fb88c1872e38f2929e", features = ["std"] } generic-array = { version = "0.14.7", default-features = false, features = ["more_lengths", "zeroize"] } getrandom-6f8ce4dd05d13bba = { package = "getrandom", version = "0.2.15", default-features = false, features = ["js", "rdrand", "std"] } group = { version = "0.13.0", default-features = false, features = ["alloc"] } @@ -208,7 +208,7 @@ num-bigint-dig = { version = "0.8.4", default-features = false, features = ["i12 num-integer = { version = "0.1.46", features = ["i128"] } num-iter = { version = "0.1.45", default-features = false, features = ["i128"] } num-traits = { version = "0.2.19", features = ["i128", "libm"] } -once_cell = { version = "1.20.3" } +once_cell = { version = "1.21.3" } openapiv3 = { version = "2.0.0", default-features = false, features = ["skip_serializing_defaults"] } peg-runtime = { version = "0.8.5", default-features = false, features = ["std"] } pem-rfc7468 = { version = "0.7.0", default-features = false, features = ["std"] } @@ -240,7 +240,7 @@ similar = { version = "2.7.0", features = ["bytes", "inline", "unicode"] } slog = { version = "2.7.0", features = ["dynamic-keys", "max_level_trace", "release_max_level_debug", "release_max_level_trace"] } smallvec = { version = "1.14.0", default-features = false, features = ["const_new"] } spin = { version = "0.9.8" } -string_cache = { version = "0.8.7" } +string_cache = { version = "0.8.9" } subtle = { version = "2.6.1" } syn-dff4ba8e3ae991db = { package = "syn", version = "1.0.109", features = ["extra-traits", "fold", "full", "visit"] } syn-f595c2ba2a3f28df = { package = "syn", version = "2.0.98", features = ["extra-traits", "fold", "full", "visit", "visit-mut"] } @@ -257,7 +257,7 @@ tracing = { version = "0.1.40", features = ["log"] } unicode-xid = { version = "0.2.6" } usdt = { version = "0.5.0" } usdt-impl = { version = "0.5.0", default-features = false, features = ["asm", "des"] } -uuid = { version = "1.15.1", features = ["serde", "v4"] } +uuid = { version = "1.16.0", features = ["serde", "v4"] } x509-cert = { version = "0.2.5" } zerocopy-c38e5c1d305a1b54 = { package = "zerocopy", version = "0.8.10", default-features = false, features = ["derive", "simd"] } zerocopy-ca01ad9e24f5d932 = { package = "zerocopy", version = "0.7.35", features = ["derive", "simd"] } @@ -266,7 +266,7 @@ zip-3b31131e45eafb45 = { package = "zip", version = "0.6.6", default-features = zip-f595c2ba2a3f28df = { package = "zip", version = "2.1.3", default-features = false, features = ["bzip2", "deflate"] } [target.x86_64-unknown-linux-gnu.dependencies] -bitflags-f595c2ba2a3f28df = { package = "bitflags", version = "2.6.0", default-features = false, features = ["std"] } +bitflags-f595c2ba2a3f28df = { package = "bitflags", version = "2.9.0", default-features = false, features = ["std"] } cookie = { version = "0.18.1", default-features = false, features = ["percent-encode"] } dof = { version = "0.3.0", default-features = false, features = ["des"] } getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3.1", default-features = false, features = ["std"] } @@ -278,7 +278,7 @@ rustix = { version = "0.38.37", features = ["event", "fs", "net", "pipe", "proce tokio-rustls = { version = "0.26.0", default-features = false, features = ["logging", "ring", "tls12"] } [target.x86_64-unknown-linux-gnu.build-dependencies] -bitflags-f595c2ba2a3f28df = { package = "bitflags", version = "2.6.0", default-features = false, features = ["std"] } +bitflags-f595c2ba2a3f28df = { package = "bitflags", version = "2.9.0", default-features = false, features = ["std"] } cookie = { version = "0.18.1", default-features = false, features = ["percent-encode"] } dof = { version = "0.3.0", default-features = false, features = ["des"] } getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3.1", default-features = false, features = ["std"] } @@ -290,7 +290,7 @@ rustix = { version = "0.38.37", features = ["event", "fs", "net", "pipe", "proce tokio-rustls = { version = "0.26.0", default-features = false, features = ["logging", "ring", "tls12"] } [target.x86_64-apple-darwin.dependencies] -bitflags-f595c2ba2a3f28df = { package = "bitflags", version = "2.6.0", default-features = false, features = ["std"] } +bitflags-f595c2ba2a3f28df = { package = "bitflags", version = "2.9.0", default-features = false, features = ["std"] } cookie = { version = "0.18.1", default-features = false, features = ["percent-encode"] } getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3.1", default-features = false, features = ["std"] } hyper-rustls = { version = "0.27.3", default-features = false, features = ["http1", "http2", "ring", "tls12", "webpki-tokio"] } @@ -300,7 +300,7 @@ rustix = { version = "0.38.37", features = ["event", "fs", "net", "pipe", "proce tokio-rustls = { version = "0.26.0", default-features = false, features = ["logging", "ring", "tls12"] } [target.x86_64-apple-darwin.build-dependencies] -bitflags-f595c2ba2a3f28df = { package = "bitflags", version = "2.6.0", default-features = false, features = ["std"] } +bitflags-f595c2ba2a3f28df = { package = "bitflags", version = "2.9.0", default-features = false, features = ["std"] } cookie = { version = "0.18.1", default-features = false, features = ["percent-encode"] } getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3.1", default-features = false, features = ["std"] } hyper-rustls = { version = "0.27.3", default-features = false, features = ["http1", "http2", "ring", "tls12", "webpki-tokio"] } @@ -310,7 +310,7 @@ rustix = { version = "0.38.37", features = ["event", "fs", "net", "pipe", "proce tokio-rustls = { version = "0.26.0", default-features = false, features = ["logging", "ring", "tls12"] } [target.aarch64-apple-darwin.dependencies] -bitflags-f595c2ba2a3f28df = { package = "bitflags", version = "2.6.0", default-features = false, features = ["std"] } +bitflags-f595c2ba2a3f28df = { package = "bitflags", version = "2.9.0", default-features = false, features = ["std"] } cookie = { version = "0.18.1", default-features = false, features = ["percent-encode"] } getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3.1", default-features = false, features = ["std"] } hyper-rustls = { version = "0.27.3", default-features = false, features = ["http1", "http2", "ring", "tls12", "webpki-tokio"] } @@ -320,7 +320,7 @@ rustix = { version = "0.38.37", features = ["event", "fs", "net", "pipe", "proce tokio-rustls = { version = "0.26.0", default-features = false, features = ["logging", "ring", "tls12"] } [target.aarch64-apple-darwin.build-dependencies] -bitflags-f595c2ba2a3f28df = { package = "bitflags", version = "2.6.0", default-features = false, features = ["std"] } +bitflags-f595c2ba2a3f28df = { package = "bitflags", version = "2.9.0", default-features = false, features = ["std"] } cookie = { version = "0.18.1", default-features = false, features = ["percent-encode"] } getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3.1", default-features = false, features = ["std"] } hyper-rustls = { version = "0.27.3", default-features = false, features = ["http1", "http2", "ring", "tls12", "webpki-tokio"] } @@ -330,7 +330,7 @@ rustix = { version = "0.38.37", features = ["event", "fs", "net", "pipe", "proce tokio-rustls = { version = "0.26.0", default-features = false, features = ["logging", "ring", "tls12"] } [target.x86_64-unknown-illumos.dependencies] -bitflags-f595c2ba2a3f28df = { package = "bitflags", version = "2.6.0", default-features = false, features = ["std"] } +bitflags-f595c2ba2a3f28df = { package = "bitflags", version = "2.9.0", default-features = false, features = ["std"] } cookie = { version = "0.18.1", default-features = false, features = ["percent-encode"] } dof = { version = "0.3.0", default-features = false, features = ["des"] } getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3.1", default-features = false, features = ["std"] } @@ -343,7 +343,7 @@ tokio-rustls = { version = "0.26.0", default-features = false, features = ["logg toml_edit-cdcf2f9584511fe6 = { package = "toml_edit", version = "0.19.15", features = ["serde"] } [target.x86_64-unknown-illumos.build-dependencies] -bitflags-f595c2ba2a3f28df = { package = "bitflags", version = "2.6.0", default-features = false, features = ["std"] } +bitflags-f595c2ba2a3f28df = { package = "bitflags", version = "2.9.0", default-features = false, features = ["std"] } clang-sys = { version = "1.8.1", default-features = false, features = ["clang_11_0", "runtime"] } cookie = { version = "0.18.1", default-features = false, features = ["percent-encode"] } dof = { version = "0.3.0", default-features = false, features = ["des"] } From 619ccf46a9eb23bf0d62e096b34902cdb5d8301e Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Sat, 5 Apr 2025 13:18:38 -0700 Subject: [PATCH 20/32] give them both something to say --- sp-sim/examples/config.toml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sp-sim/examples/config.toml b/sp-sim/examples/config.toml index ed3fde7a005..35f6ad46529 100644 --- a/sp-sim/examples/config.toml +++ b/sp-sim/examples/config.toml @@ -162,6 +162,21 @@ sensors = [ { name = "CPU", kind = "Temperature", last_data.value = 63.1, last_data.timestamp = 1234 }, ] + +[simulated_sps.gimlet.ereport_config] +restart_id = "55e30cc7-a109-492f-aca9-735ed725df3c" + +[[simulated_sps.gimlet.ereport_config.ereports]] +task_name = "task_thermal_server" +task_gen = 1 +uptime = 1233 +class = "computer.oxide.gimlet.chassis_integrity.fault" +nosub_class = "chassis_integrity.cat_hair_detected" +message = "cat hair detected inside gimlet" +de = { scheme = "fmd", mod-name = "hubris-thermal-diagnosis", mod-version = "1.0", authority = { "product-id" = "oxide", server-id = "SimGimlet1" }} +certainty = 0x64 +cat_hair_amount = 10000 + [log] # Show log messages of this level and more severe level = "debug" From 914dcd415979cf76f038ffc35dec023e9637ddb7 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Mon, 7 Apr 2025 09:38:08 -0700 Subject: [PATCH 21/32] update MGS --- Cargo.lock | 49 +++++++++++++++++++++----------- Cargo.toml | 4 +-- gateway/src/management_switch.rs | 11 ++++--- 3 files changed, 40 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 838c2fc8399..8a8e0401431 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3457,7 +3457,7 @@ dependencies = [ "clap", "futures", "gateway-client", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", "omicron-common", "omicron-workspace-hack", "reqwest", @@ -3478,7 +3478,7 @@ version = "0.1.0" dependencies = [ "base64 0.22.1", "chrono", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", "omicron-workspace-hack", "progenitor 0.9.1", "rand 0.8.5", @@ -3507,16 +3507,33 @@ dependencies = [ "zerocopy 0.6.6", ] +[[package]] +name = "gateway-messages" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f#79a344e3f7e7fdface0c63ca5afa802aa8c4d66f" +dependencies = [ + "bitflags 2.9.0", + "hubpack", + "serde", + "serde-big-array", + "serde_repr", + "smoltcp 0.9.1", + "static_assertions", + "strum_macros 0.25.3", + "uuid", + "zerocopy 0.6.6", +] + [[package]] name = "gateway-sp-comms" version = "0.1.1" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e#663df644d8e731ca293502fb88c1872e38f2929e" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f#79a344e3f7e7fdface0c63ca5afa802aa8c4d66f" dependencies = [ "async-trait", "backoff", "futures", "fxhash", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", "hex", "hubpack", "hubtools", @@ -3548,7 +3565,7 @@ version = "0.1.0" dependencies = [ "camino", "dropshot 0.16.0", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", "gateway-types", "omicron-gateway", "omicron-test-utils", @@ -3563,7 +3580,7 @@ dependencies = [ name = "gateway-types" version = "0.1.0" dependencies = [ - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", "hex", "ipcc", "omicron-common", @@ -5572,7 +5589,7 @@ dependencies = [ "anyhow", "clap", "futures", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", "gateway-test-utils", "libc", "omicron-gateway", @@ -6038,7 +6055,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", "gateway-test-utils", "nexus-sled-agent-shared", "nexus-types", @@ -6102,7 +6119,7 @@ version = "0.1.0" dependencies = [ "futures", "gateway-client", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", "gateway-test-utils", "hubtools", "omicron-workspace-hack", @@ -6375,7 +6392,7 @@ dependencies = [ "dns-service-client", "dropshot 0.16.0", "futures", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", "gateway-test-utils", "headers", "hickory-resolver", @@ -6963,7 +6980,7 @@ dependencies = [ "expectorate", "futures", "gateway-api", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", "gateway-sp-comms", "gateway-test-utils", "gateway-types", @@ -7085,7 +7102,7 @@ dependencies = [ "fatfs", "futures", "gateway-client", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", "gateway-test-utils", "headers", "hex", @@ -7221,7 +7238,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", "gateway-test-utils", "http", "humantime", @@ -7620,7 +7637,7 @@ dependencies = [ "futures-sink", "futures-task", "futures-util", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", "generic-array", "getrandom 0.2.15", "getrandom 0.3.1", @@ -11422,7 +11439,7 @@ dependencies = [ "clap", "dropshot 0.16.0", "futures", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", "gateway-types", "hex", "nix 0.29.0", @@ -13598,7 +13615,7 @@ dependencies = [ "fs-err", "futures", "gateway-client", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", "gateway-test-utils", "hex", "hickory-resolver", diff --git a/Cargo.toml b/Cargo.toml index 5eec498b68a..cf591e57657 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -409,8 +409,8 @@ gateway-client = { path = "clients/gateway-client" } # is "fine", because SP/MGS communication maintains forwards and backwards # compatibility, but will mean that faux-mgs might be missing new # functionality.) -gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "663df644d8e731ca293502fb88c1872e38f2929e", default-features = false, features = ["std"] } -gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "663df644d8e731ca293502fb88c1872e38f2929e" } +gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "79a344e3f7e7fdface0c63ca5afa802aa8c4d66f", default-features = false, features = ["std"] } +gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "79a344e3f7e7fdface0c63ca5afa802aa8c4d66f" } gateway-test-utils = { path = "gateway-test-utils" } gateway-types = { path = "gateway-types" } gethostname = "0.5.0" diff --git a/gateway/src/management_switch.rs b/gateway/src/management_switch.rs index 8f483750282..15ce15adbb6 100644 --- a/gateway/src/management_switch.rs +++ b/gateway/src/management_switch.rs @@ -212,10 +212,10 @@ impl ManagementSwitch { shared_socket = Some( SharedSocket::bind( config.udp_listen_port, - shared_socket::ControlPlaneAgentHandler::new(&host_phase2_provider, &log), - log.clone(), + shared_socket::ControlPlaneAgentHandler::new(&host_phase2_provider), + log.new(slog::o!("socket" => "control-plane-agent")), ) - .await?, + .await? ); shared_socket.as_ref().unwrap() @@ -226,12 +226,11 @@ impl ManagementSwitch { let ereport_socket = match &mut ereport_socket { None => { - let log = log.new(slog::o!("socket" => "ereport")); ereport_socket = Some( SharedSocket::bind( config.ereport_udp_listen_port, - ereport::EreportHandler::new(log.clone()), - log, + ereport::EreportHandler::default(), + log.new(slog::o!("socket" => "ereport")), ) .await?, ); From 539b0ce29a65660cebec9320e66652d268ea3595 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Tue, 8 Apr 2025 09:41:53 -0700 Subject: [PATCH 22/32] honor limit --- Cargo.lock | 35 +++++++++++++++++---------------- Cargo.toml | 4 ++-- ereport/types/src/lib.rs | 5 +++-- gateway/src/http_entrypoints.rs | 13 +++++++++--- 4 files changed, 33 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8a8e0401431..f7df23e14d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3457,7 +3457,7 @@ dependencies = [ "clap", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", "omicron-common", "omicron-workspace-hack", "reqwest", @@ -3478,7 +3478,7 @@ version = "0.1.0" dependencies = [ "base64 0.22.1", "chrono", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", "omicron-workspace-hack", "progenitor 0.9.1", "rand 0.8.5", @@ -3493,7 +3493,7 @@ dependencies = [ [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e#663df644d8e731ca293502fb88c1872e38f2929e" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae#58d073a96b6e91c26f8a40778b10fcc5ec4045ae" dependencies = [ "bitflags 2.9.0", "hubpack", @@ -3510,7 +3510,7 @@ dependencies = [ [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f#79a344e3f7e7fdface0c63ca5afa802aa8c4d66f" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e#663df644d8e731ca293502fb88c1872e38f2929e" dependencies = [ "bitflags 2.9.0", "hubpack", @@ -3527,13 +3527,14 @@ dependencies = [ [[package]] name = "gateway-sp-comms" version = "0.1.1" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f#79a344e3f7e7fdface0c63ca5afa802aa8c4d66f" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae#58d073a96b6e91c26f8a40778b10fcc5ec4045ae" dependencies = [ "async-trait", "backoff", + "base64 0.22.1", "futures", "fxhash", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", "hex", "hubpack", "hubtools", @@ -3565,7 +3566,7 @@ version = "0.1.0" dependencies = [ "camino", "dropshot 0.16.0", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", "gateway-types", "omicron-gateway", "omicron-test-utils", @@ -3580,7 +3581,7 @@ dependencies = [ name = "gateway-types" version = "0.1.0" dependencies = [ - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", "hex", "ipcc", "omicron-common", @@ -5589,7 +5590,7 @@ dependencies = [ "anyhow", "clap", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", "gateway-test-utils", "libc", "omicron-gateway", @@ -6055,7 +6056,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", "gateway-test-utils", "nexus-sled-agent-shared", "nexus-types", @@ -6119,7 +6120,7 @@ version = "0.1.0" dependencies = [ "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", "gateway-test-utils", "hubtools", "omicron-workspace-hack", @@ -6392,7 +6393,7 @@ dependencies = [ "dns-service-client", "dropshot 0.16.0", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", "gateway-test-utils", "headers", "hickory-resolver", @@ -6980,7 +6981,7 @@ dependencies = [ "expectorate", "futures", "gateway-api", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", "gateway-sp-comms", "gateway-test-utils", "gateway-types", @@ -7102,7 +7103,7 @@ dependencies = [ "fatfs", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", "gateway-test-utils", "headers", "hex", @@ -7238,7 +7239,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", "gateway-test-utils", "http", "humantime", @@ -11439,7 +11440,7 @@ dependencies = [ "clap", "dropshot 0.16.0", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", "gateway-types", "hex", "nix 0.29.0", @@ -13615,7 +13616,7 @@ dependencies = [ "fs-err", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=79a344e3f7e7fdface0c63ca5afa802aa8c4d66f)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", "gateway-test-utils", "hex", "hickory-resolver", diff --git a/Cargo.toml b/Cargo.toml index cf591e57657..ba4349b161d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -409,8 +409,8 @@ gateway-client = { path = "clients/gateway-client" } # is "fine", because SP/MGS communication maintains forwards and backwards # compatibility, but will mean that faux-mgs might be missing new # functionality.) -gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "79a344e3f7e7fdface0c63ca5afa802aa8c4d66f", default-features = false, features = ["std"] } -gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "79a344e3f7e7fdface0c63ca5afa802aa8c4d66f" } +gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "58d073a96b6e91c26f8a40778b10fcc5ec4045ae", default-features = false, features = ["std"] } +gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "58d073a96b6e91c26f8a40778b10fcc5ec4045ae" } gateway-test-utils = { path = "gateway-test-utils" } gateway-types = { path = "gateway-types" } gethostname = "0.5.0" diff --git a/ereport/types/src/lib.rs b/ereport/types/src/lib.rs index 30d80477cb6..ee5d1f93e7f 100644 --- a/ereport/types/src/lib.rs +++ b/ereport/types/src/lib.rs @@ -140,8 +140,9 @@ mod tests { let ereport_string = serde_json::to_string_pretty(&ereport) .expect("ereport should serialize"); eprintln!("JSON: {ereport_string}"); - let deserialized = dbg!(serde_json::from_str::(&ereport_string)) - .expect("ereport should deserialize"); + let deserialized = + dbg!(serde_json::from_str::(&ereport_string)) + .expect("ereport should deserialize"); eprintln!("EREPORT: {deserialized:#?}"); } } diff --git a/gateway/src/http_entrypoints.rs b/gateway/src/http_entrypoints.rs index 97d8e8e2bfc..086bd1bf025 100644 --- a/gateway/src/http_entrypoints.rs +++ b/gateway/src/http_entrypoints.rs @@ -48,6 +48,8 @@ use gateway_types::update::HostPhase2RecoveryImageId; use gateway_types::update::InstallinatorImageId; use gateway_types::update::SpUpdateStatus; use omicron_common::update::ArtifactHash; +use omicron_uuid_kinds::GenericUuid; +use std::num::NonZeroU8; use std::str; use std::sync::Arc; @@ -942,28 +944,33 @@ impl GatewayApi for GatewayImpl { let handler = async { use crate::EreportError; use gateway_sp_comms::ereport; - use omicron_uuid_kinds::GenericUuid; let ereport_types::EreportQuery { restart_id, start_at, committed, - // TODO(eliza) limit, } = query.into_inner(); let sp_id = path.into_inner().sp.into(); let sp = apictx.mgmt_switch.sp(sp_id)?; + let req_restart_id = ereport::RestartId(restart_id.as_untyped_uuid().as_u128()); let start_ena = start_at .map(|ereport_types::Ena(e)| ereport::Ena(e)) .unwrap_or(ereport::Ena(0)); + // If the limit is greater than 255, just clamp to that for now. + // TODO(eliza): eventually, we may want to request multiple tranches + // from the SP until we either receive an empty one or satisfy the + // limit requested by Nexus. + let limit = NonZeroU8::try_from(limit).unwrap_or(NonZeroU8::MAX); let committed_ena = committed.map(|ereport_types::Ena(e)| ereport::Ena(e)); + let ereport::EreportTranche { restart_id, ereports } = sp - .ereports(req_restart_id, start_ena, committed_ena) + .ereports(req_restart_id, start_ena, limit, committed_ena) .await .map_err(|error| match error { gateway_sp_comms::error::EreportError::Communication( From 46c3612aec58850591e5fb2fd3eb271c938c0941 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Wed, 9 Apr 2025 14:14:51 -0700 Subject: [PATCH 23/32] update SP simulator --- Cargo.lock | 34 +++++------ Cargo.toml | 4 +- sp-sim/src/ereport.rs | 134 +++++++++++++++++++++++++----------------- 3 files changed, 99 insertions(+), 73 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f7df23e14d2..5c2f89f5988 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3457,7 +3457,7 @@ dependencies = [ "clap", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", "omicron-common", "omicron-workspace-hack", "reqwest", @@ -3478,7 +3478,7 @@ version = "0.1.0" dependencies = [ "base64 0.22.1", "chrono", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", "omicron-workspace-hack", "progenitor 0.9.1", "rand 0.8.5", @@ -3493,7 +3493,7 @@ dependencies = [ [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae#58d073a96b6e91c26f8a40778b10fcc5ec4045ae" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e#663df644d8e731ca293502fb88c1872e38f2929e" dependencies = [ "bitflags 2.9.0", "hubpack", @@ -3510,7 +3510,7 @@ dependencies = [ [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e#663df644d8e731ca293502fb88c1872e38f2929e" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e#83d252cc1f9dc3d01326bc99f29fb330f544e32e" dependencies = [ "bitflags 2.9.0", "hubpack", @@ -3527,14 +3527,14 @@ dependencies = [ [[package]] name = "gateway-sp-comms" version = "0.1.1" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae#58d073a96b6e91c26f8a40778b10fcc5ec4045ae" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e#83d252cc1f9dc3d01326bc99f29fb330f544e32e" dependencies = [ "async-trait", "backoff", "base64 0.22.1", "futures", "fxhash", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", "hex", "hubpack", "hubtools", @@ -3566,7 +3566,7 @@ version = "0.1.0" dependencies = [ "camino", "dropshot 0.16.0", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", "gateway-types", "omicron-gateway", "omicron-test-utils", @@ -3581,7 +3581,7 @@ dependencies = [ name = "gateway-types" version = "0.1.0" dependencies = [ - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", "hex", "ipcc", "omicron-common", @@ -5590,7 +5590,7 @@ dependencies = [ "anyhow", "clap", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", "gateway-test-utils", "libc", "omicron-gateway", @@ -6056,7 +6056,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", "gateway-test-utils", "nexus-sled-agent-shared", "nexus-types", @@ -6120,7 +6120,7 @@ version = "0.1.0" dependencies = [ "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", "gateway-test-utils", "hubtools", "omicron-workspace-hack", @@ -6393,7 +6393,7 @@ dependencies = [ "dns-service-client", "dropshot 0.16.0", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", "gateway-test-utils", "headers", "hickory-resolver", @@ -6981,7 +6981,7 @@ dependencies = [ "expectorate", "futures", "gateway-api", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", "gateway-sp-comms", "gateway-test-utils", "gateway-types", @@ -7103,7 +7103,7 @@ dependencies = [ "fatfs", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", "gateway-test-utils", "headers", "hex", @@ -7239,7 +7239,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", "gateway-test-utils", "http", "humantime", @@ -11440,7 +11440,7 @@ dependencies = [ "clap", "dropshot 0.16.0", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", "gateway-types", "hex", "nix 0.29.0", @@ -13616,7 +13616,7 @@ dependencies = [ "fs-err", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=58d073a96b6e91c26f8a40778b10fcc5ec4045ae)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", "gateway-test-utils", "hex", "hickory-resolver", diff --git a/Cargo.toml b/Cargo.toml index ba4349b161d..13ddc3594a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -409,8 +409,8 @@ gateway-client = { path = "clients/gateway-client" } # is "fine", because SP/MGS communication maintains forwards and backwards # compatibility, but will mean that faux-mgs might be missing new # functionality.) -gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "58d073a96b6e91c26f8a40778b10fcc5ec4045ae", default-features = false, features = ["std"] } -gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "58d073a96b6e91c26f8a40778b10fcc5ec4045ae" } +gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "83d252cc1f9dc3d01326bc99f29fb330f544e32e", default-features = false, features = ["std"] } +gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "83d252cc1f9dc3d01326bc99f29fb330f544e32e" } gateway-test-utils = { path = "gateway-test-utils" } gateway-types = { path = "gateway-types" } gethostname = "0.5.0" diff --git a/sp-sim/src/ereport.rs b/sp-sim/src/ereport.rs index f8de8a3acdb..18419d33e27 100644 --- a/sp-sim/src/ereport.rs +++ b/sp-sim/src/ereport.rs @@ -101,10 +101,22 @@ impl EreportState { request: EreportRequest, buf: &'buf mut [u8], ) -> &'buf [u8] { + use serde::ser::Serializer; + let EreportRequest::V0(req) = request; slog::info!(self.log, "ereport request: {req:?}"); - if req.restart_id != self.restart_id { + let mut pos = gateway_messages::serialize( + buf, + &EreportResponseHeader::V0(ResponseHeaderV0 { + restart_id: self.restart_id, + }), + ) + .expect("header must serialize"); + + // If we "restarted", encode the current metadata map, and start at ENA + // 0. + let (meta_map, start_ena) = if req.restart_id != self.restart_id { slog::info!( self.log, "requested restart ID is not current, pretending to have \ @@ -112,58 +124,81 @@ impl EreportState { "req_restart_id" => ?req.restart_id, "current_restart_id" => ?self.restart_id, ); - let amt = gateway_messages::serialize( - buf, - &EreportResponseHeader::V0(ResponseHeaderV0::new_restarted( - self.restart_id, - )), - ) - .expect("serialization shouldn't fail"); - let amt = { - let mut cursor = Cursor::new(&mut buf[amt..]); - serde_cbor::to_writer(&mut cursor, &self.meta) - .expect("serializing metadata should fit in a packet..."); - amt + cursor.position() as usize - }; - return &buf[..amt]; - } + (&self.meta, Ena(0)) + } else { + // If we didn't "restart", we should honor the committed ENA (if the + // request includes one), and we should start at the requested ENA. + if let Some(committed_ena) = req.committed_ena() { + slog::debug!( + self.log, + "MGS committed ereports up to {committed_ena:?}" + ); + let mut discarded = 0; + while self + .ereports + .front() + .map(|(ena, _)| ena <= &committed_ena) + .unwrap_or(false) + { + self.ereports.pop_front(); + discarded += 1; + } - if let Some(committed_ena) = req.committed_ena() { - slog::debug!( - self.log, - "MGS committed ereports up to {committed_ena:?}" - ); - let mut discarded = 0; - while self - .ereports - .front() - .map(|(ena, _)| ena <= &committed_ena) - .unwrap_or(false) - { - self.ereports.pop_front(); - discarded += 1; + slog::info!( + self.log, + "discarded {discarded} ereports up to {committed_ena:?}" + ); } - slog::info!( - self.log, - "discarded {discarded} ereports up to {committed_ena:?}" + (&Default::default(), req.start_ena) + }; + pos += { + use serde::ser::SerializeMap; + + let mut cursor = Cursor::new(&mut buf[pos..]); + // Rather than just using `serde_cbor::to_writer`, we'll manually + // construct a `Serializer`, so that we can call the `serialize_map` + // method *without* a length to force it to use the "indefinite-length" + // encoding. + let mut serializer = serde_cbor::Serializer::new( + serde_cbor::ser::IoWrite::new(&mut cursor), ); + let mut map = + serializer.serialize_map(None).expect("map should start"); + for (key, value) in meta_map { + map.serialize_entry(key, value) + .expect("element should serialize"); + } + map.end().expect("map should end"); + cursor.position() as usize + }; + + // Is there enough remaining space for ereports? We need at least 10 + // bytes (8 for the ENA, and at least two bytes to encode an empty CBOR + // list) + if buf[pos..].len() < 10 { + return &buf[..pos]; } - let mut respondant_ereports = - self.ereports.iter().filter(|(ena, _)| ena.0 >= req.start_ena.0); - let end = if let Some((ena, ereport)) = respondant_ereports.next() { - let mut pos = gateway_messages::serialize( - buf, - &EreportResponseHeader::V0( - ereport::ResponseHeaderV0::new_data(self.restart_id), - ), - ) - .expect("serialization shouldn't fail"); + let mut respondant_ereports = self + .ereports + .iter() + .filter(|(ena, _)| ena.0 >= start_ena.0) + .take(req.limit as usize); + if let Some((ena, ereport)) = respondant_ereports.next() { pos += gateway_messages::serialize(&mut buf[pos..], ena) .expect("serialing ena shouldn't fail"); buf[pos] = 0x9f; // start list pos += 1; + + // Okay, this is a little bit goofy: we're going to encode each + // message to a separate Vec before writing it to the packet buffer. + // This is because we need to know if the *whole* ereport fits in + // the packet before deciding whether or not to include it. + // + // We could certainly be a bit more efficient here by reusing a + // dedicated encoding buffer for this, but honestly? This is the SP + // simulator, so I don't care enough. let bytes = serde_cbor::to_vec(ereport).unwrap(); buf[pos..pos + bytes.len()].copy_from_slice(&bytes[..]); pos += bytes.len(); @@ -195,18 +230,9 @@ impl EreportState { buf[pos] = 0xff; // break list; pos += 1; - pos - } else { - gateway_messages::serialize( - buf, - &EreportResponseHeader::V0(ResponseHeaderV0::new_empty( - req.restart_id, - )), - ) - .expect("serialization shouldn't fail") - }; + } - &buf[..end] + &buf[..pos] } } From a7905e0bf020016a2e696733f7589b599cd590b5 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Wed, 9 Apr 2025 14:23:02 -0700 Subject: [PATCH 24/32] rm unused import whoops i got alert-fatigued --- sp-sim/src/ereport.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/sp-sim/src/ereport.rs b/sp-sim/src/ereport.rs index 18419d33e27..9968da70aa1 100644 --- a/sp-sim/src/ereport.rs +++ b/sp-sim/src/ereport.rs @@ -5,7 +5,6 @@ use crate::config::Ereport; use crate::config::EreportConfig; use crate::config::EreportRestart; -use gateway_messages::ereport; use gateway_messages::ereport::Ena; use gateway_messages::ereport::EreportRequest; use gateway_messages::ereport::EreportResponseHeader; From 02b65b27de733108430759d5954332eade2cbd78 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Thu, 10 Apr 2025 09:58:05 -0700 Subject: [PATCH 25/32] pass through ereport addrs in gateway-test-utils --- gateway-test-utils/configs/config.test.toml | 4 +++ .../configs/sp_sim_config.test.toml | 32 +++++++++++++++++++ gateway-test-utils/src/setup.rs | 14 +++++--- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/gateway-test-utils/configs/config.test.toml b/gateway-test-utils/configs/config.test.toml index 1e8f06e9159..b278cf406c7 100644 --- a/gateway-test-utils/configs/config.test.toml +++ b/gateway-test-utils/configs/config.test.toml @@ -67,6 +67,7 @@ sp_port_2 = ["switch1"] kind = "simulated" fake-interface = "fake-switch0" addr = "[::1]:0" +ereport-addr = "[::1]:0" ignition-target = 0 location = { switch0 = ["switch", 0], switch1 = ["switch", 1] } @@ -74,6 +75,7 @@ location = { switch0 = ["switch", 0], switch1 = ["switch", 1] } kind = "simulated" fake-interface = "fake-switch1" addr = "[::1]:0" +ereport-addr = "[::1]:0" ignition-target = 1 location = { switch0 = ["switch", 1], switch1 = ["switch", 0] } @@ -81,6 +83,7 @@ location = { switch0 = ["switch", 1], switch1 = ["switch", 0] } kind = "simulated" fake-interface = "fake-sled0" addr = "[::1]:0" +ereport-addr = "[::1]:0" ignition-target = 2 location = { switch0 = ["sled", 0], switch1 = ["sled", 0] } @@ -88,6 +91,7 @@ location = { switch0 = ["sled", 0], switch1 = ["sled", 0] } kind = "simulated" fake-interface = "fake-sled1" addr = "[::1]:0" +ereport-addr = "[::1]:0" ignition-target = 3 location = { switch0 = ["sled", 1], switch1 = ["sled", 1] } diff --git a/gateway-test-utils/configs/sp_sim_config.test.toml b/gateway-test-utils/configs/sp_sim_config.test.toml index 3f86214760b..e7c44524b22 100644 --- a/gateway-test-utils/configs/sp_sim_config.test.toml +++ b/gateway-test-utils/configs/sp_sim_config.test.toml @@ -20,6 +20,14 @@ bind_addr = "[::1]:0" [simulated_sps.sidecar.network_config.simulated] bind_addr = "[::1]:0" +[[simulated_sps.sidecar.ereport_network_config]] +[simulated_sps.sidecar.ereport_network_config.simulated] +bind_addr = "[::1]:0" + +[[simulated_sps.sidecar.ereport_network_config]] +[simulated_sps.sidecar.ereport_network_config.simulated] +bind_addr = "[::1]:0" + [[simulated_sps.sidecar.components]] id = "dev-0" device = "fake-tmp-sensor" @@ -53,6 +61,14 @@ bind_addr = "[::1]:0" [simulated_sps.sidecar.network_config.simulated] bind_addr = "[::1]:0" +[[simulated_sps.sidecar.ereport_network_config]] +[simulated_sps.sidecar.ereport_network_config.simulated] +bind_addr = "[::1]:0" + +[[simulated_sps.sidecar.ereport_network_config]] +[simulated_sps.sidecar.ereport_network_config.simulated] +bind_addr = "[::1]:0" + [[simulated_sps.gimlet]] serial_number = "SimGimlet00" manufacturing_root_cert_seed = "01de01de01de01de01de01de01de01de01de01de01de01de01de01de01de01de" @@ -66,6 +82,14 @@ bind_addr = "[::1]:0" [simulated_sps.gimlet.network_config.simulated] bind_addr = "[::1]:0" +[[simulated_sps.gimlet.ereport_network_config]] +[simulated_sps.gimlet.ereport_network_config.simulated] +bind_addr = "[::1]:0" + +[[simulated_sps.gimlet.ereport_network_config]] +[simulated_sps.gimlet.ereport_network_config.simulated] +bind_addr = "[::1]:0" + [[simulated_sps.gimlet.components]] id = "sp3-host-cpu" device = "sp3-host-cpu" @@ -181,6 +205,14 @@ bind_addr = "[::1]:0" [simulated_sps.gimlet.network_config.simulated] bind_addr = "[::1]:0" +[[simulated_sps.gimlet.ereport_network_config]] +[simulated_sps.gimlet.ereport_network_config.simulated] +bind_addr = "[::1]:0" + +[[simulated_sps.gimlet.ereport_network_config]] +[simulated_sps.gimlet.ereport_network_config.simulated] +bind_addr = "[::1]:0" + [[simulated_sps.gimlet.components]] id = "sp3-host-cpu" device = "sp3-host-cpu" diff --git a/gateway-test-utils/src/setup.rs b/gateway-test-utils/src/setup.rs index 5254880357e..6f9f663e1bb 100644 --- a/gateway-test-utils/src/setup.rs +++ b/gateway-test-utils/src/setup.rs @@ -131,16 +131,22 @@ pub async fn test_setup_with_config( // assume that matches whether we end up as `switch0` or `switch1` let target_sp = port_description.location.get(&expected_location).unwrap(); - let sp_addr = match target_sp.typ { + let (sp_addr, sp_ereport_addr) = match target_sp.typ { SpType::Switch => { - simrack.sidecars[target_sp.slot].local_addr(sp_port) + let switch = &simrack.sidecars[target_sp.slot]; + (switch.local_addr(sp_port), switch.local_ereport_addr(sp_port)) + } + SpType::Sled => { + let sled = &simrack.gimlets[target_sp.slot]; + (sled.local_addr(sp_port), sled.local_ereport_addr(sp_port)) } - SpType::Sled => simrack.gimlets[target_sp.slot].local_addr(sp_port), SpType::Power => todo!(), }; match &mut port_description.config { - SwitchPortConfig::Simulated { addr, .. } => { + SwitchPortConfig::Simulated { addr, ereport_addr, .. } => { *addr = sp_addr.unwrap(); + *ereport_addr = + sp_ereport_addr.expect("no ereport addr configured"); } SwitchPortConfig::SwitchZoneInterface { .. } => { panic!("test config using `switch-zone-interface` config") From 64fd8f3f70ea73fe4f54b3ef6d71b887fded0df3 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Thu, 10 Apr 2025 13:47:20 -0700 Subject: [PATCH 26/32] update to pick up request IDs from MGS this updates the MGS dep again to grab oxidecomputer/management-gateway-service@8a49211667642f2a5f9efdbe7ea19080f056c53c --- Cargo.lock | 32 ++++++++++++++++---------------- Cargo.toml | 4 ++-- sp-sim/src/ereport.rs | 1 + 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5c2f89f5988..6619a026d54 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3457,7 +3457,7 @@ dependencies = [ "clap", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", "omicron-common", "omicron-workspace-hack", "reqwest", @@ -3478,7 +3478,7 @@ version = "0.1.0" dependencies = [ "base64 0.22.1", "chrono", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", "omicron-workspace-hack", "progenitor 0.9.1", "rand 0.8.5", @@ -3510,7 +3510,7 @@ dependencies = [ [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e#83d252cc1f9dc3d01326bc99f29fb330f544e32e" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff#c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff" dependencies = [ "bitflags 2.9.0", "hubpack", @@ -3527,14 +3527,14 @@ dependencies = [ [[package]] name = "gateway-sp-comms" version = "0.1.1" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e#83d252cc1f9dc3d01326bc99f29fb330f544e32e" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff#c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff" dependencies = [ "async-trait", "backoff", "base64 0.22.1", "futures", "fxhash", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", "hex", "hubpack", "hubtools", @@ -3566,7 +3566,7 @@ version = "0.1.0" dependencies = [ "camino", "dropshot 0.16.0", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", "gateway-types", "omicron-gateway", "omicron-test-utils", @@ -3581,7 +3581,7 @@ dependencies = [ name = "gateway-types" version = "0.1.0" dependencies = [ - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", "hex", "ipcc", "omicron-common", @@ -5590,7 +5590,7 @@ dependencies = [ "anyhow", "clap", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", "gateway-test-utils", "libc", "omicron-gateway", @@ -6056,7 +6056,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", "gateway-test-utils", "nexus-sled-agent-shared", "nexus-types", @@ -6120,7 +6120,7 @@ version = "0.1.0" dependencies = [ "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", "gateway-test-utils", "hubtools", "omicron-workspace-hack", @@ -6393,7 +6393,7 @@ dependencies = [ "dns-service-client", "dropshot 0.16.0", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", "gateway-test-utils", "headers", "hickory-resolver", @@ -6981,7 +6981,7 @@ dependencies = [ "expectorate", "futures", "gateway-api", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", "gateway-sp-comms", "gateway-test-utils", "gateway-types", @@ -7103,7 +7103,7 @@ dependencies = [ "fatfs", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", "gateway-test-utils", "headers", "hex", @@ -7239,7 +7239,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", "gateway-test-utils", "http", "humantime", @@ -11440,7 +11440,7 @@ dependencies = [ "clap", "dropshot 0.16.0", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", "gateway-types", "hex", "nix 0.29.0", @@ -13616,7 +13616,7 @@ dependencies = [ "fs-err", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=83d252cc1f9dc3d01326bc99f29fb330f544e32e)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", "gateway-test-utils", "hex", "hickory-resolver", diff --git a/Cargo.toml b/Cargo.toml index 13ddc3594a8..c23a9b85634 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -409,8 +409,8 @@ gateway-client = { path = "clients/gateway-client" } # is "fine", because SP/MGS communication maintains forwards and backwards # compatibility, but will mean that faux-mgs might be missing new # functionality.) -gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "83d252cc1f9dc3d01326bc99f29fb330f544e32e", default-features = false, features = ["std"] } -gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "83d252cc1f9dc3d01326bc99f29fb330f544e32e" } +gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff", default-features = false, features = ["std"] } +gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff" } gateway-test-utils = { path = "gateway-test-utils" } gateway-types = { path = "gateway-types" } gethostname = "0.5.0" diff --git a/sp-sim/src/ereport.rs b/sp-sim/src/ereport.rs index 9968da70aa1..b9809c4dad1 100644 --- a/sp-sim/src/ereport.rs +++ b/sp-sim/src/ereport.rs @@ -108,6 +108,7 @@ impl EreportState { let mut pos = gateway_messages::serialize( buf, &EreportResponseHeader::V0(ResponseHeaderV0 { + request_id: req.request_id, restart_id: self.restart_id, }), ) From 24b009ba1eff16467dab851ad22762a924ad1fde Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Thu, 10 Apr 2025 15:07:19 -0700 Subject: [PATCH 27/32] simple ereport ingestion integration test --- .../configs/sp_sim_config.test.toml | 53 +++++++++++++++++++ gateway/Cargo.toml | 1 + gateway/tests/integration_tests/mod.rs | 1 + 3 files changed, 55 insertions(+) diff --git a/gateway-test-utils/configs/sp_sim_config.test.toml b/gateway-test-utils/configs/sp_sim_config.test.toml index e7c44524b22..bdfbf60fdcd 100644 --- a/gateway-test-utils/configs/sp_sim_config.test.toml +++ b/gateway-test-utils/configs/sp_sim_config.test.toml @@ -191,6 +191,46 @@ sensors = [ { name = "Northwest", kind = "Speed", last_data.value = 2275.0, last_data.timestamp = 1234 }, ] +[simulated_sps.gimlet.ereport_config] +restart_id = "af1ebf85-36ba-4c31-bbec-b9825d6d9d8b" + +[[simulated_sps.gimlet.ereport_config.ereports]] +task_name = "task_apollo_server" +task_gen = 13 +uptime = 1233 +class = "gov.nasa.apollo.o2_tanks.stir.begin" +message = "stirring the tanks" + +[[simulated_sps.gimlet.ereport_config.ereports]] +task_name = "drv_ae35_server" +task_gen = 1 +uptime = 1234 +class = "io.discovery.ae35.fault" +message = "i've just picked up a fault in the AE-35 unit" +de = { scheme = "fmd", authority = { product-id = "HAL-9000-series computer", server-id = "HAL 9000"}, mod-name = "ae35-diagnosis" } +hours_to_failure = 72 + +[[simulated_sps.gimlet.ereport_config.ereports]] +task_name = "task_apollo_server" +task_gen = 13 +uptime = 1237 +class = "gov.nasa.apollo.fault" +message = "houston, we have a problem" +crew = ["Lovell", "Swigert", "Hayes"] + +[[simulated_sps.gimlet.ereport_config.ereports]] +task_name = "drv_thingy_server" +task_gen = 2 +uptime = 1240 +class = "flagrant_error" +computer = false + +[[simulated_sps.gimlet.ereport_config.ereports]] +task_name = "task_latex_server" +task_gen = 1 +uptime = 1245 +class = "overfull_hbox" +badness = 10000 [[simulated_sps.gimlet]] serial_number = "SimGimlet01" @@ -315,6 +355,19 @@ sensors = [ { name = "Northwest", kind = "Speed", last_data.value = 2212.0, last_data.timestamp = 1234 }, ] +[simulated_sps.gimlet.ereport_config] +restart_id = "55e30cc7-a109-492f-aca9-735ed725df3c" + +[[simulated_sps.gimlet.ereport_config.ereports]] +task_name = "task_thermal_server" +task_gen = 1 +uptime = 1233 +class = "computer.oxide.gimlet.chassis_integrity.fault" +nosub_class = "chassis_integrity.cat_hair_detected" +message = "cat hair detected inside gimlet" +de = { scheme = "fmd", mod-name = "hubris-thermal-diagnosis", mod-version = "1.0", authority = { "product-id" = "oxide", server-id = "SimGimlet1" }} +certainty = 0x64 +cat_hair_amount = 10000 # # NOTE: for the test suite, the [log] section is ignored; sp-sim logs are rolled diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index 188bcce71a4..480bfac1902 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -28,6 +28,7 @@ ipcc.workspace = true omicron-common.workspace = true schemars.workspace = true serde.workspace = true +serde_json.workspace = true signal-hook.workspace = true signal-hook-tokio.workspace = true slog.workspace = true diff --git a/gateway/tests/integration_tests/mod.rs b/gateway/tests/integration_tests/mod.rs index a52df7ca90c..bb5b64e4098 100644 --- a/gateway/tests/integration_tests/mod.rs +++ b/gateway/tests/integration_tests/mod.rs @@ -6,5 +6,6 @@ mod component_list; mod config; +mod ereports; mod location_discovery; mod serial_console; From fea34387900a7acc482f628a18452664cbf308e8 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Thu, 10 Apr 2025 15:18:37 -0700 Subject: [PATCH 28/32] so it turns out i'm stupid. fix that. --- Cargo.lock | 34 +++++++++++++++++----------------- Cargo.toml | 4 ++-- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6619a026d54..701b84aa55d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3457,7 +3457,7 @@ dependencies = [ "clap", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", "omicron-common", "omicron-workspace-hack", "reqwest", @@ -3478,7 +3478,7 @@ version = "0.1.0" dependencies = [ "base64 0.22.1", "chrono", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", "omicron-workspace-hack", "progenitor 0.9.1", "rand 0.8.5", @@ -3493,7 +3493,7 @@ dependencies = [ [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e#663df644d8e731ca293502fb88c1872e38f2929e" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc#41f0017661816dd7375f64529f5756b13278f5bc" dependencies = [ "bitflags 2.9.0", "hubpack", @@ -3510,7 +3510,7 @@ dependencies = [ [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff#c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e#663df644d8e731ca293502fb88c1872e38f2929e" dependencies = [ "bitflags 2.9.0", "hubpack", @@ -3527,14 +3527,14 @@ dependencies = [ [[package]] name = "gateway-sp-comms" version = "0.1.1" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff#c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc#41f0017661816dd7375f64529f5756b13278f5bc" dependencies = [ "async-trait", "backoff", "base64 0.22.1", "futures", "fxhash", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", "hex", "hubpack", "hubtools", @@ -3566,7 +3566,7 @@ version = "0.1.0" dependencies = [ "camino", "dropshot 0.16.0", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", "gateway-types", "omicron-gateway", "omicron-test-utils", @@ -3581,7 +3581,7 @@ dependencies = [ name = "gateway-types" version = "0.1.0" dependencies = [ - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", "hex", "ipcc", "omicron-common", @@ -5590,7 +5590,7 @@ dependencies = [ "anyhow", "clap", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", "gateway-test-utils", "libc", "omicron-gateway", @@ -6056,7 +6056,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", "gateway-test-utils", "nexus-sled-agent-shared", "nexus-types", @@ -6120,7 +6120,7 @@ version = "0.1.0" dependencies = [ "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", "gateway-test-utils", "hubtools", "omicron-workspace-hack", @@ -6393,7 +6393,7 @@ dependencies = [ "dns-service-client", "dropshot 0.16.0", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", "gateway-test-utils", "headers", "hickory-resolver", @@ -6981,7 +6981,7 @@ dependencies = [ "expectorate", "futures", "gateway-api", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", "gateway-sp-comms", "gateway-test-utils", "gateway-types", @@ -7103,7 +7103,7 @@ dependencies = [ "fatfs", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", "gateway-test-utils", "headers", "hex", @@ -7239,7 +7239,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", "gateway-test-utils", "http", "humantime", @@ -11440,7 +11440,7 @@ dependencies = [ "clap", "dropshot 0.16.0", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", "gateway-types", "hex", "nix 0.29.0", @@ -13616,7 +13616,7 @@ dependencies = [ "fs-err", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff)", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", "gateway-test-utils", "hex", "hickory-resolver", diff --git a/Cargo.toml b/Cargo.toml index c23a9b85634..dff86e65e3d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -409,8 +409,8 @@ gateway-client = { path = "clients/gateway-client" } # is "fine", because SP/MGS communication maintains forwards and backwards # compatibility, but will mean that faux-mgs might be missing new # functionality.) -gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff", default-features = false, features = ["std"] } -gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "c26dad3a9d4a44e75e1d07d5f4aa21875fcfaeff" } +gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "41f0017661816dd7375f64529f5756b13278f5bc", default-features = false, features = ["std"] } +gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "41f0017661816dd7375f64529f5756b13278f5bc" } gateway-test-utils = { path = "gateway-test-utils" } gateway-types = { path = "gateway-types" } gethostname = "0.5.0" From 69a6c0a5dba7f96970115b07148faaf04f9a848b Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Fri, 11 Apr 2025 12:07:37 -0700 Subject: [PATCH 29/32] add some simple ereport integration tests --- .../configs/sp_sim_config.test.toml | 2 +- gateway/tests/integration_tests/ereports.rs | 374 ++++++++++++++++++ 2 files changed, 375 insertions(+), 1 deletion(-) create mode 100644 gateway/tests/integration_tests/ereports.rs diff --git a/gateway-test-utils/configs/sp_sim_config.test.toml b/gateway-test-utils/configs/sp_sim_config.test.toml index bdfbf60fdcd..069b7602fba 100644 --- a/gateway-test-utils/configs/sp_sim_config.test.toml +++ b/gateway-test-utils/configs/sp_sim_config.test.toml @@ -216,7 +216,7 @@ task_gen = 13 uptime = 1237 class = "gov.nasa.apollo.fault" message = "houston, we have a problem" -crew = ["Lovell", "Swigert", "Hayes"] +crew = ["Lovell", "Swigert", "Haise"] [[simulated_sps.gimlet.ereport_config.ereports]] task_name = "drv_thingy_server" diff --git a/gateway/tests/integration_tests/ereports.rs b/gateway/tests/integration_tests/ereports.rs new file mode 100644 index 00000000000..a6fa2c9e8b1 --- /dev/null +++ b/gateway/tests/integration_tests/ereports.rs @@ -0,0 +1,374 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// Copyright 2025 Oxide Computer Company + +use dropshot::test_util; +use gateway_messages::SpPort; +use gateway_test_utils::current_simulator_state; +use gateway_test_utils::setup; +use gateway_types::component::SpType; +use omicron_uuid_kinds::GenericUuid; +use std::sync::LazyLock; +use uuid::Uuid; + +struct EreportRequest { + sled: usize, + restart_id: Uuid, + start_ena: u64, + committed_ena: Option, + limit: usize, +} + +impl EreportRequest { + async fn response( + self, + client: &test_util::ClientTestContext, + ) -> ereport_types::Ereports { + let Self { sled, restart_id, start_ena, committed_ena, limit } = self; + use std::fmt::Write; + + let base = client.url("/sp/sled"); + let mut url = format!( + "{base}/{sled}/ereports?restart_id={restart_id}&start_at={start_ena}&limit={limit}" + ); + if let Some(committed) = committed_ena { + write!(&mut url, "&committed={committed}").unwrap(); + } + // N.B. that we must use `ClientTestContext::make_request` rather than one + // of the higher level helpers like `objects_post`, as our combination of + // method and status code is a bit weird. + let mut response = client + .make_request::<()>( + http::Method::POST, + &url, + None, + http::StatusCode::OK, + ) + .await + .unwrap(); + test_util::read_json::(&mut response).await + } +} + +type JsonObject = serde_json::map::Map; +macro_rules! def_ereport { + ($NAME:ident: $($json:tt)+) => { + pub(super) static $NAME: LazyLock = + LazyLock::new(|| match serde_json::json!($($json)+) { + serde_json::Value::Object(obj) => obj, + it => panic!( + "expected {} to be a JSON object, but found: {it:?}", + stringify!($NAME) + ), + }); + }; +} + +mod sled0 { + use super::*; + pub(super) static RESTART_0: LazyLock = LazyLock::new(|| { + "af1ebf85-36ba-4c31-bbec-b9825d6d9d8b".parse().expect("is a valid UUID") + }); + + def_ereport! { + EREPORT_0: { + "chassis_model": "SimGimletSp", + "chassis_serial": "SimGimlet00", + "hubris_archive_id": "ffffffff", + "hubris_task_name": "task_apollo_server", + "hubris_task_gen": 13, + "hubris_uptime_ms": 1233, + "class": "gov.nasa.apollo.o2_tanks.stir.begin", + "message": "stirring the tanks", + } + } + def_ereport! { + EREPORT_1: { + "chassis_model": "SimGimletSp", + "chassis_serial": "SimGimlet00", + "hubris_archive_id": "ffffffff", + "hubris_task_name": "drv_ae35_server", + "hubris_task_gen": 1, + "hubris_uptime_ms": 1234, + "class": "io.discovery.ae35.fault", + "message": "i've just picked up a fault in the AE-35 unit", + "de": { + "scheme": "fmd", + "mod-name": "ae35-diagnosis", + "authority": { + "product-id": "HAL-9000-series computer", + "server-id": "HAL 9000", + }, + }, + "hours_to_failure": 72, + } + } + def_ereport! { + EREPORT_2: { + "chassis_model": "SimGimletSp", + "chassis_serial": "SimGimlet00", + "hubris_archive_id": "ffffffff", + "hubris_task_name": "task_apollo_server", + "hubris_task_gen": 13, + "hubris_uptime_ms": 1237, + "class": "gov.nasa.apollo.fault", + "message": "houston, we have a problem", + "crew": [ + "Lovell", + "Swigert", + "Haise", + ], + } + } + + def_ereport! { + EREPORT_3: { + "chassis_model": "SimGimletSp", + "chassis_serial": "SimGimlet00", + "hubris_archive_id": "ffffffff", + "hubris_task_name": "drv_thingy_server", + "hubris_task_gen": 2, + "hubris_uptime_ms": 1240, + "class": "flagrant_error", + "computer": false, + } + } + + def_ereport! { + EREPORT_4: { + "chassis_model": "SimGimletSp", + "chassis_serial": "SimGimlet00", + "hubris_archive_id": "ffffffff", + "hubris_task_name": "task_latex_server", + "hubris_task_gen": 1, + "hubris_uptime_ms": 1245, + "class": "overfull_hbox", + "badness": 10000, + } + } +} + +mod sled1 { + use super::*; + pub(super) static RESTART_0: LazyLock = LazyLock::new(|| { + "55e30cc7-a109-492f-aca9-735ed725df3c".parse().expect("is a valid UUID") + }); + + def_ereport! { + EREPORT_0: { + "chassis_model": "SimGimletSp", + "chassis_serial": "SimGimlet01", + "hubris_archive_id": "ffffffff", + "hubris_task_name": "task_thermal_server", + "hubris_task_gen": 1, + "hubris_uptime_ms": 1233, + "class": "computer.oxide.gimlet.chassis_integrity.fault", + "nosub_class": "chassis_integrity.cat_hair_detected", + "message": "cat hair detected inside gimlet", + "de": { + "scheme": "fmd", + "mod-name": "hubris-thermal-diagnosis", + "mod-version": "1.0", + "authority": { + "product-id": "oxide", + "server-id": "SimGimlet1", + } + }, + "certainty": 0x64, + "cat_hair_amount": 10000, + } + } +} + +/// Double check that we have at least 1 sidecar and 2 gimlets and that all +/// SPs are enabled. +async fn check_sim_state( + simrack: &sp_sim::SimRack, +) -> Vec { + let sim_state = current_simulator_state(simrack).await; + assert!( + sim_state + .iter() + .filter(|sp| sp.ignition.id.typ == SpType::Sled) + .count() + >= 2 + ); + assert!(sim_state.iter().any(|sp| sp.ignition.id.typ == SpType::Switch)); + assert!(sim_state.iter().all(|sp| sp.state.is_ok())); + sim_state +} + +#[tokio::test] +async fn ereports_basic() { + let testctx = setup::test_setup("ereports_basic", SpPort::One).await; + let client = &testctx.client; + let simrack = &testctx.simrack; + check_sim_state(simrack).await; + + let ereport_types::Ereports { restart_id, reports } = dbg!( + EreportRequest { + sled: 1, + restart_id: Uuid::new_v4(), + start_ena: 0, + committed_ena: None, + limit: 100 + } + .response(client) + .await + ); + + assert_eq!(restart_id.as_untyped_uuid(), &*sled1::RESTART_0); + let reports = reports.items; + assert_eq!(reports.len(), 1, "expected 1 ereport, found: {:#?}", reports); + let report = &reports[0]; + assert_eq!(report.ena, ereport_types::Ena(0)); + assert_eq!(report.data, *sled1::EREPORT_0); + + testctx.teardown().await; +} + +#[tokio::test] +async fn ereports_limit() { + let testctx = setup::test_setup("ereports_limit", SpPort::One).await; + let client = &testctx.client; + let simrack = &testctx.simrack; + check_sim_state(simrack).await; + + let ereport_types::Ereports { restart_id, reports } = dbg!( + EreportRequest { + sled: 0, + restart_id: Uuid::new_v4(), + start_ena: 0, + committed_ena: None, + limit: 2 + } + .response(client) + .await + ); + + assert_eq!(restart_id.as_untyped_uuid(), &*sled0::RESTART_0); + let reports = reports.items; + assert_eq!(reports.len(), 2, "expected 2 ereports, found: {:#?}", reports); + let report = &reports[0]; + assert_eq!(report.ena, ereport_types::Ena(0)); + assert_eq!(report.data, *sled0::EREPORT_0); + + let report = &reports[1]; + assert_eq!(report.ena, ereport_types::Ena(1)); + assert_eq!(report.data, *sled0::EREPORT_1); + + let ereport_types::Ereports { restart_id, reports } = dbg!( + EreportRequest { + sled: 0, + restart_id: restart_id.into_untyped_uuid(), + start_ena: 2, + committed_ena: None, + limit: 2 + } + .response(client) + .await + ); + + assert_eq!(restart_id.as_untyped_uuid(), &*sled0::RESTART_0); + let reports = reports.items; + assert_eq!(reports.len(), 2, "expected 2 ereports, found: {:#?}", reports); + let report = &reports[0]; + assert_eq!(report.ena, ereport_types::Ena(2)); + assert_eq!(report.data, *sled0::EREPORT_2); + + let report = &reports[1]; + assert_eq!(report.ena, ereport_types::Ena(3)); + assert_eq!(report.data, *sled0::EREPORT_3); + + testctx.teardown().await; +} + +#[tokio::test] +async fn ereports_commit() { + let testctx = setup::test_setup("ereports_limit", SpPort::One).await; + let client = &testctx.client; + let simrack = &testctx.simrack; + check_sim_state(simrack).await; + + let ereport_types::Ereports { restart_id, reports } = dbg!( + EreportRequest { + sled: 0, + restart_id: Uuid::new_v4(), + start_ena: 2, + committed_ena: Some(1), + limit: 2 + } + .response(client) + .await + ); + + // No ereports should be discarded by a request with a non-matching restart + // ID. + assert_eq!(restart_id.as_untyped_uuid(), &*sled0::RESTART_0); + let reports = reports.items; + assert_eq!(reports.len(), 2, "expected 2 ereports, found: {:#?}", reports); + let report = &reports[0]; + assert_eq!(report.ena, ereport_types::Ena(0)); + assert_eq!(report.data, *sled0::EREPORT_0); + + let report = &reports[1]; + assert_eq!(report.ena, ereport_types::Ena(1)); + assert_eq!(report.data, *sled0::EREPORT_1); + + // Now, send a request with a committed ENA *and* a matching restart ID. + let ereport_types::Ereports { restart_id, reports } = dbg!( + EreportRequest { + sled: 0, + restart_id: restart_id.into_untyped_uuid(), + start_ena: 0, + committed_ena: Some(1), + limit: 2 + } + .response(client) + .await + ); + + assert_eq!(restart_id.as_untyped_uuid(), &*sled0::RESTART_0); + let reports = reports.items; + assert_eq!(reports.len(), 2, "expected 2 ereports, found: {:#?}", reports); + let report = &reports[0]; + assert_eq!(report.ena, ereport_types::Ena(2)); + assert_eq!(report.data, *sled0::EREPORT_2); + + let report = &reports[1]; + assert_eq!(report.ena, ereport_types::Ena(3)); + assert_eq!(report.data, *sled0::EREPORT_3); + + // Even if the start ENA of a subsequent request is 0, we shouldn't see any + // ereports with ENAs lower than the committed ENA. + let ereport_types::Ereports { restart_id, reports } = dbg!( + EreportRequest { + sled: 0, + restart_id: restart_id.into_untyped_uuid(), + start_ena: 0, + committed_ena: None, + limit: 100 + } + .response(client) + .await + ); + + assert_eq!(restart_id.as_untyped_uuid(), &*sled0::RESTART_0); + let reports = reports.items; + assert_eq!(reports.len(), 3, "expected 3 ereports, found: {:#?}", reports); + let report = &reports[0]; + assert_eq!(report.ena, ereport_types::Ena(2)); + assert_eq!(report.data, *sled0::EREPORT_2); + + let report = &reports[1]; + assert_eq!(report.ena, ereport_types::Ena(3)); + assert_eq!(report.data, *sled0::EREPORT_3); + + let report = &reports[2]; + assert_eq!(report.ena, ereport_types::Ena(4)); + assert_eq!(report.data, *sled0::EREPORT_4); + + testctx.teardown().await; +} From 4dd8878d8b65bf64e1593a643391e2eed09e7e95 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Fri, 11 Apr 2025 14:07:30 -0700 Subject: [PATCH 30/32] pick up latest gateway-sp-comms update to pick up oxidecomputer/management-gateway-service@a6b180dbb4262a94d73165a0d072b33376d174f8 --- Cargo.lock | 51 +++++++++++---------------------- Cargo.toml | 4 +-- gateway/src/http_entrypoints.rs | 7 +++-- workspace-hack/Cargo.toml | 4 +-- 4 files changed, 25 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 701b84aa55d..e1ab6e732ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3457,7 +3457,7 @@ dependencies = [ "clap", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", + "gateway-messages", "omicron-common", "omicron-workspace-hack", "reqwest", @@ -3478,7 +3478,7 @@ version = "0.1.0" dependencies = [ "base64 0.22.1", "chrono", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", + "gateway-messages", "omicron-workspace-hack", "progenitor 0.9.1", "rand 0.8.5", @@ -3493,24 +3493,7 @@ dependencies = [ [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc#41f0017661816dd7375f64529f5756b13278f5bc" -dependencies = [ - "bitflags 2.9.0", - "hubpack", - "serde", - "serde-big-array", - "serde_repr", - "smoltcp 0.9.1", - "static_assertions", - "strum_macros 0.25.3", - "uuid", - "zerocopy 0.6.6", -] - -[[package]] -name = "gateway-messages" -version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e#663df644d8e731ca293502fb88c1872e38f2929e" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=a6b180dbb4262a94d73165a0d072b33376d174f8#a6b180dbb4262a94d73165a0d072b33376d174f8" dependencies = [ "bitflags 2.9.0", "hubpack", @@ -3527,14 +3510,14 @@ dependencies = [ [[package]] name = "gateway-sp-comms" version = "0.1.1" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc#41f0017661816dd7375f64529f5756b13278f5bc" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=a6b180dbb4262a94d73165a0d072b33376d174f8#a6b180dbb4262a94d73165a0d072b33376d174f8" dependencies = [ "async-trait", "backoff", "base64 0.22.1", "futures", "fxhash", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", + "gateway-messages", "hex", "hubpack", "hubtools", @@ -3566,7 +3549,7 @@ version = "0.1.0" dependencies = [ "camino", "dropshot 0.16.0", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", + "gateway-messages", "gateway-types", "omicron-gateway", "omicron-test-utils", @@ -3581,7 +3564,7 @@ dependencies = [ name = "gateway-types" version = "0.1.0" dependencies = [ - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", + "gateway-messages", "hex", "ipcc", "omicron-common", @@ -5590,7 +5573,7 @@ dependencies = [ "anyhow", "clap", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", + "gateway-messages", "gateway-test-utils", "libc", "omicron-gateway", @@ -6056,7 +6039,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", + "gateway-messages", "gateway-test-utils", "nexus-sled-agent-shared", "nexus-types", @@ -6120,7 +6103,7 @@ version = "0.1.0" dependencies = [ "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", + "gateway-messages", "gateway-test-utils", "hubtools", "omicron-workspace-hack", @@ -6393,7 +6376,7 @@ dependencies = [ "dns-service-client", "dropshot 0.16.0", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", + "gateway-messages", "gateway-test-utils", "headers", "hickory-resolver", @@ -6981,7 +6964,7 @@ dependencies = [ "expectorate", "futures", "gateway-api", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", + "gateway-messages", "gateway-sp-comms", "gateway-test-utils", "gateway-types", @@ -7103,7 +7086,7 @@ dependencies = [ "fatfs", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", + "gateway-messages", "gateway-test-utils", "headers", "hex", @@ -7239,7 +7222,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", + "gateway-messages", "gateway-test-utils", "http", "humantime", @@ -7638,7 +7621,7 @@ dependencies = [ "futures-sink", "futures-task", "futures-util", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=663df644d8e731ca293502fb88c1872e38f2929e)", + "gateway-messages", "generic-array", "getrandom 0.2.15", "getrandom 0.3.1", @@ -11440,7 +11423,7 @@ dependencies = [ "clap", "dropshot 0.16.0", "futures", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", + "gateway-messages", "gateway-types", "hex", "nix 0.29.0", @@ -13616,7 +13599,7 @@ dependencies = [ "fs-err", "futures", "gateway-client", - "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=41f0017661816dd7375f64529f5756b13278f5bc)", + "gateway-messages", "gateway-test-utils", "hex", "hickory-resolver", diff --git a/Cargo.toml b/Cargo.toml index dff86e65e3d..dd28c8dc943 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -409,8 +409,8 @@ gateway-client = { path = "clients/gateway-client" } # is "fine", because SP/MGS communication maintains forwards and backwards # compatibility, but will mean that faux-mgs might be missing new # functionality.) -gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "41f0017661816dd7375f64529f5756b13278f5bc", default-features = false, features = ["std"] } -gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "41f0017661816dd7375f64529f5756b13278f5bc" } +gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "a6b180dbb4262a94d73165a0d072b33376d174f8", default-features = false, features = ["std"] } +gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "a6b180dbb4262a94d73165a0d072b33376d174f8" } gateway-test-utils = { path = "gateway-test-utils" } gateway-types = { path = "gateway-types" } gethostname = "0.5.0" diff --git a/gateway/src/http_entrypoints.rs b/gateway/src/http_entrypoints.rs index 086bd1bf025..5ecfd2061b9 100644 --- a/gateway/src/http_entrypoints.rs +++ b/gateway/src/http_entrypoints.rs @@ -955,8 +955,7 @@ impl GatewayApi for GatewayImpl { let sp_id = path.into_inner().sp.into(); let sp = apictx.mgmt_switch.sp(sp_id)?; - let req_restart_id = - ereport::RestartId(restart_id.as_untyped_uuid().as_u128()); + let req_restart_id = restart_id.into_untyped_uuid(); let start_ena = start_at .map(|ereport_types::Ena(e)| ereport::Ena(e)) .unwrap_or(ereport::Ena(0)); @@ -979,7 +978,9 @@ impl GatewayApi for GatewayImpl { err => EreportError::Ereport { sp: sp_id, err }, })?; let restart_id = - ereport_types::EreporterRestartUuid::from_u128(restart_id.0); + ereport_types::EreporterRestartUuid::from_untyped_uuid( + restart_id, + ); let ereports = ereports .into_iter() .map(|ereport::Ereport { ena: ereport::Ena(ena), data }| { diff --git a/workspace-hack/Cargo.toml b/workspace-hack/Cargo.toml index a549ee9e176..6651c7b434d 100644 --- a/workspace-hack/Cargo.toml +++ b/workspace-hack/Cargo.toml @@ -57,7 +57,7 @@ futures-io = { version = "0.3.31" } futures-sink = { version = "0.3.31" } futures-task = { version = "0.3.31", default-features = false, features = ["std"] } futures-util = { version = "0.3.31", features = ["channel", "io", "sink"] } -gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "663df644d8e731ca293502fb88c1872e38f2929e", features = ["std"] } +gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "a6b180dbb4262a94d73165a0d072b33376d174f8", features = ["std"] } generic-array = { version = "0.14.7", default-features = false, features = ["more_lengths", "zeroize"] } getrandom-6f8ce4dd05d13bba = { package = "getrandom", version = "0.2.15", default-features = false, features = ["js", "rdrand", "std"] } group = { version = "0.13.0", default-features = false, features = ["alloc"] } @@ -180,7 +180,7 @@ futures-io = { version = "0.3.31" } futures-sink = { version = "0.3.31" } futures-task = { version = "0.3.31", default-features = false, features = ["std"] } futures-util = { version = "0.3.31", features = ["channel", "io", "sink"] } -gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "663df644d8e731ca293502fb88c1872e38f2929e", features = ["std"] } +gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "a6b180dbb4262a94d73165a0d072b33376d174f8", features = ["std"] } generic-array = { version = "0.14.7", default-features = false, features = ["more_lengths", "zeroize"] } getrandom-6f8ce4dd05d13bba = { package = "getrandom", version = "0.2.15", default-features = false, features = ["js", "rdrand", "std"] } group = { version = "0.13.0", default-features = false, features = ["alloc"] } From 7ea4ef307d58959037818960c6fd375b882790fd Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Sat, 12 Apr 2025 10:58:06 -0700 Subject: [PATCH 31/32] fix sim mgs/sp SMF configs missing ereport addrs --- smf/mgs-sim/config.toml | 3 +++ smf/sp-sim/config.toml | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/smf/mgs-sim/config.toml b/smf/mgs-sim/config.toml index b23614f662f..e7c876eec5b 100644 --- a/smf/mgs-sim/config.toml +++ b/smf/mgs-sim/config.toml @@ -57,6 +57,7 @@ sp_port_2 = ["switch1"] kind = "simulated" fake-interface = "fake-switch0" addr = "[::1]:33300" +ereport-addr = "[::1]:44400" ignition-target = 1 location = { switch0 = ["switch", 0], switch1 = ["switch", 1] } @@ -64,6 +65,7 @@ location = { switch0 = ["switch", 0], switch1 = ["switch", 1] } kind = "simulated" fake-interface = "fake-sled0" addr = "[::1]:33310" +ereport-addr = "[::1]:44410" ignition-target = 2 location = { switch0 = ["sled", 0], switch1 = ["sled", 0] } @@ -71,6 +73,7 @@ location = { switch0 = ["sled", 0], switch1 = ["sled", 0] } kind = "simulated" fake-interface = "fake-sled1" addr = "[::1]:33320" +ereport-addr = "[::1]:44420" ignition-target = 3 location = { switch0 = ["sled", 1], switch1 = ["sled", 1] } diff --git a/smf/sp-sim/config.toml b/smf/sp-sim/config.toml index bde9d84e0ed..3d05cfaca28 100644 --- a/smf/sp-sim/config.toml +++ b/smf/sp-sim/config.toml @@ -15,6 +15,14 @@ bind_addr = "[::1]:33300" [simulated_sps.sidecar.network_config.simulated] bind_addr = "[::1]:33301" +[[simulated_sps.sidecar.ereport_network_config]] +[simulated_sps.sidecar.ereport_network_config.simulated] +bind_addr = "[::1]:44400" + +[[simulated_sps.sidecar.ereport_network_config]] +[simulated_sps.sidecar.ereport_network_config.simulated] +bind_addr = "[::1]:44401" + [[simulated_sps.gimlet]] serial_number = "SimGimlet0" manufacturing_root_cert_seed = "01de01de01de01de01de01de01de01de01de01de01de01de01de01de01de01de" @@ -28,6 +36,14 @@ bind_addr = "[::1]:33310" [simulated_sps.gimlet.network_config.simulated] bind_addr = "[::1]:33311" +[[simulated_sps.gimlet.ereport_network_config]] +[simulated_sps.gimlet.ereport_network_config.simulated] +bind_addr = "[::1]:44410" + +[[simulated_sps.gimlet.ereport_network_config]] +[simulated_sps.gimlet.ereport_network_config.simulated] +bind_addr = "[::1]:44411" + [[simulated_sps.gimlet.components]] id = "sp3-host-cpu" device = "sp3-host-cpu" @@ -49,6 +65,14 @@ bind_addr = "[::1]:33320" [simulated_sps.gimlet.network_config.simulated] bind_addr = "[::1]:33321" +[[simulated_sps.gimlet.ereport_network_config]] +[simulated_sps.gimlet.ereport_network_config.simulated] +bind_addr = "[::1]:44420" + +[[simulated_sps.gimlet.ereport_network_config]] +[simulated_sps.gimlet.ereport_network_config.simulated] +bind_addr = "[::1]:44421" + [[simulated_sps.gimlet.components]] id = "sp3-host-cpu" device = "sp3-host-cpu" From 9af73b62dc20c6c70fe37408860b85e220baf866 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Tue, 15 Apr 2025 12:45:42 -0700 Subject: [PATCH 32/32] update & track gateway-messages changes --- Cargo.lock | 59 ++++++++++---- Cargo.toml | 4 +- gateway/tests/integration_tests/ereports.rs | 6 ++ sp-sim/src/ereport.rs | 89 ++++++++++----------- 4 files changed, 92 insertions(+), 66 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a7c1a2942a0..b2ac3bc7fde 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3480,7 +3480,7 @@ dependencies = [ "clap", "futures", "gateway-client", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=18215eeae855bd0a820ce00608a83d6ea9959596)", "omicron-common", "omicron-workspace-hack", "reqwest", @@ -3502,7 +3502,7 @@ version = "0.1.0" dependencies = [ "base64 0.22.1", "chrono", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=18215eeae855bd0a820ce00608a83d6ea9959596)", "omicron-workspace-hack", "progenitor 0.9.1", "rand 0.8.5", @@ -3514,6 +3514,23 @@ dependencies = [ "uuid", ] +[[package]] +name = "gateway-messages" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=18215eeae855bd0a820ce00608a83d6ea9959596#18215eeae855bd0a820ce00608a83d6ea9959596" +dependencies = [ + "bitflags 2.9.0", + "hubpack", + "serde", + "serde-big-array", + "serde_repr", + "smoltcp 0.9.1", + "static_assertions", + "strum_macros 0.25.3", + "uuid", + "zerocopy 0.6.6", +] + [[package]] name = "gateway-messages" version = "0.1.0" @@ -3534,14 +3551,14 @@ dependencies = [ [[package]] name = "gateway-sp-comms" version = "0.1.1" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=a6b180dbb4262a94d73165a0d072b33376d174f8#a6b180dbb4262a94d73165a0d072b33376d174f8" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=18215eeae855bd0a820ce00608a83d6ea9959596#18215eeae855bd0a820ce00608a83d6ea9959596" dependencies = [ "async-trait", "backoff", "base64 0.22.1", "futures", "fxhash", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=18215eeae855bd0a820ce00608a83d6ea9959596)", "hex", "hubpack", "hubtools", @@ -3552,6 +3569,7 @@ dependencies = [ "paste", "serde", "serde-big-array", + "serde_bytes", "serde_cbor", "serde_json", "slog", @@ -3573,7 +3591,7 @@ version = "0.1.0" dependencies = [ "camino", "dropshot 0.16.0", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=18215eeae855bd0a820ce00608a83d6ea9959596)", "gateway-types", "omicron-gateway", "omicron-test-utils", @@ -3588,7 +3606,7 @@ dependencies = [ name = "gateway-types" version = "0.1.0" dependencies = [ - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=18215eeae855bd0a820ce00608a83d6ea9959596)", "hex", "ipcc", "omicron-common", @@ -5652,7 +5670,7 @@ dependencies = [ "anyhow", "clap", "futures", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=18215eeae855bd0a820ce00608a83d6ea9959596)", "gateway-test-utils", "libc", "omicron-gateway", @@ -6092,7 +6110,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=18215eeae855bd0a820ce00608a83d6ea9959596)", "gateway-test-utils", "nexus-sled-agent-shared", "nexus-types", @@ -6156,7 +6174,7 @@ version = "0.1.0" dependencies = [ "futures", "gateway-client", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=18215eeae855bd0a820ce00608a83d6ea9959596)", "gateway-test-utils", "hubtools", "omicron-workspace-hack", @@ -6430,7 +6448,7 @@ dependencies = [ "dns-service-client", "dropshot 0.16.0", "futures", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=18215eeae855bd0a820ce00608a83d6ea9959596)", "gateway-test-utils", "headers", "hickory-resolver", @@ -7029,7 +7047,7 @@ dependencies = [ "expectorate", "futures", "gateway-api", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=18215eeae855bd0a820ce00608a83d6ea9959596)", "gateway-sp-comms", "gateway-test-utils", "gateway-types", @@ -7152,7 +7170,7 @@ dependencies = [ "fatfs", "futures", "gateway-client", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=18215eeae855bd0a820ce00608a83d6ea9959596)", "gateway-test-utils", "headers", "hex", @@ -7288,7 +7306,7 @@ dependencies = [ "expectorate", "futures", "gateway-client", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=18215eeae855bd0a820ce00608a83d6ea9959596)", "gateway-test-utils", "http", "humantime", @@ -7709,7 +7727,7 @@ dependencies = [ "futures-sink", "futures-task", "futures-util", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=a6b180dbb4262a94d73165a0d072b33376d174f8)", "generic-array", "getrandom 0.2.15", "getrandom 0.3.1", @@ -10873,6 +10891,15 @@ dependencies = [ "smallvec 0.6.14", ] +[[package]] +name = "serde_bytes" +version = "0.11.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96" +dependencies = [ + "serde", +] + [[package]] name = "serde_cbor" version = "0.11.2" @@ -11606,7 +11633,7 @@ dependencies = [ "clap", "dropshot 0.16.0", "futures", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=18215eeae855bd0a820ce00608a83d6ea9959596)", "gateway-types", "hex", "nix 0.29.0", @@ -13822,7 +13849,7 @@ dependencies = [ "fs-err", "futures", "gateway-client", - "gateway-messages", + "gateway-messages 0.1.0 (git+https://github.com/oxidecomputer/management-gateway-service?rev=18215eeae855bd0a820ce00608a83d6ea9959596)", "gateway-test-utils", "hex", "hickory-resolver", diff --git a/Cargo.toml b/Cargo.toml index 8992858e1fc..5433d39a2d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -409,8 +409,8 @@ gateway-client = { path = "clients/gateway-client" } # is "fine", because SP/MGS communication maintains forwards and backwards # compatibility, but will mean that faux-mgs might be missing new # functionality.) -gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "a6b180dbb4262a94d73165a0d072b33376d174f8", default-features = false, features = ["std"] } -gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "a6b180dbb4262a94d73165a0d072b33376d174f8" } +gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "18215eeae855bd0a820ce00608a83d6ea9959596", default-features = false, features = ["std"] } +gateway-sp-comms = { git = "https://github.com/oxidecomputer/management-gateway-service", rev = "18215eeae855bd0a820ce00608a83d6ea9959596" } gateway-test-utils = { path = "gateway-test-utils" } gateway-types = { path = "gateway-types" } gethostname = "0.5.0" diff --git a/gateway/tests/integration_tests/ereports.rs b/gateway/tests/integration_tests/ereports.rs index a6fa2c9e8b1..e87d401f076 100644 --- a/gateway/tests/integration_tests/ereports.rs +++ b/gateway/tests/integration_tests/ereports.rs @@ -80,6 +80,7 @@ mod sled0 { "hubris_task_name": "task_apollo_server", "hubris_task_gen": 13, "hubris_uptime_ms": 1233, + "ereport_message_version": 0, "class": "gov.nasa.apollo.o2_tanks.stir.begin", "message": "stirring the tanks", } @@ -92,6 +93,7 @@ mod sled0 { "hubris_task_name": "drv_ae35_server", "hubris_task_gen": 1, "hubris_uptime_ms": 1234, + "ereport_message_version": 0, "class": "io.discovery.ae35.fault", "message": "i've just picked up a fault in the AE-35 unit", "de": { @@ -113,6 +115,7 @@ mod sled0 { "hubris_task_name": "task_apollo_server", "hubris_task_gen": 13, "hubris_uptime_ms": 1237, + "ereport_message_version": 0, "class": "gov.nasa.apollo.fault", "message": "houston, we have a problem", "crew": [ @@ -131,6 +134,7 @@ mod sled0 { "hubris_task_name": "drv_thingy_server", "hubris_task_gen": 2, "hubris_uptime_ms": 1240, + "ereport_message_version": 0, "class": "flagrant_error", "computer": false, } @@ -144,6 +148,7 @@ mod sled0 { "hubris_task_name": "task_latex_server", "hubris_task_gen": 1, "hubris_uptime_ms": 1245, + "ereport_message_version": 0, "class": "overfull_hbox", "badness": 10000, } @@ -164,6 +169,7 @@ mod sled1 { "hubris_task_name": "task_thermal_server", "hubris_task_gen": 1, "hubris_uptime_ms": 1233, + "ereport_message_version": 0, "class": "computer.oxide.gimlet.chassis_integrity.fault", "nosub_class": "chassis_integrity.cat_hair_detected", "message": "cat hair detected inside gimlet", diff --git a/sp-sim/src/ereport.rs b/sp-sim/src/ereport.rs index b9809c4dad1..bf2909886a2 100644 --- a/sp-sim/src/ereport.rs +++ b/sp-sim/src/ereport.rs @@ -15,7 +15,7 @@ use std::io::Cursor; use tokio::sync::oneshot; pub(crate) struct EreportState { - ereports: VecDeque<(Ena, EreportList)>, + ereports: VecDeque, meta: toml::map::Map, /// Next ENA, used for appending new ENAs at runtime. next_ena: Ena, @@ -29,6 +29,12 @@ pub(crate) enum Command { Append(Ereport, oneshot::Sender), } +struct EreportListEntry { + ena: Ena, + ereport: Ereport, + bytes: Vec, +} + impl EreportState { pub(crate) fn new( EreportConfig { restart, ereports }: EreportConfig, @@ -42,10 +48,10 @@ impl EreportState { "n_ereports" => ereports.len(), "metadata" => ?metadata, ); - let ereports: VecDeque<(Ena, EreportList)> = ereports + let ereports: VecDeque<_> = ereports .into_iter() .enumerate() - .map(|(i, ereport)| (Ena(i as u64), ereport.to_list())) + .map(|(i, ereport)| ereport.to_entry(Ena(i as u64))) .collect(); let restart_id = RestartId(restart_id.as_u128()); let next_ena = Ena(ereports.len() as u64); @@ -90,7 +96,7 @@ impl EreportState { "ena" => ?ena, "ereport" => ?ereport, ); - self.ereports.push_back((ena, ereport.to_list())); + self.ereports.push_back(ereport.to_entry(ena)); self.next_ena.0 += 1; ena } @@ -137,7 +143,7 @@ impl EreportState { while self .ereports .front() - .map(|(ena, _)| ena <= &committed_ena) + .map(|ereport| ereport.ena <= committed_ena) .unwrap_or(false) { self.ereports.pop_front(); @@ -183,23 +189,16 @@ impl EreportState { let mut respondant_ereports = self .ereports .iter() - .filter(|(ena, _)| ena.0 >= start_ena.0) + .filter(|ereport| ereport.ena >= start_ena) .take(req.limit as usize); - if let Some((ena, ereport)) = respondant_ereports.next() { + if let Some(EreportListEntry { ena, ereport, bytes }) = + respondant_ereports.next() + { pos += gateway_messages::serialize(&mut buf[pos..], ena) .expect("serialing ena shouldn't fail"); buf[pos] = 0x9f; // start list pos += 1; - // Okay, this is a little bit goofy: we're going to encode each - // message to a separate Vec before writing it to the packet buffer. - // This is because we need to know if the *whole* ereport fits in - // the packet before deciding whether or not to include it. - // - // We could certainly be a bit more efficient here by reusing a - // dedicated encoding buffer for this, but honestly? This is the SP - // simulator, so I don't care enough. - let bytes = serde_cbor::to_vec(ereport).unwrap(); buf[pos..pos + bytes.len()].copy_from_slice(&bytes[..]); pos += bytes.len(); slog::debug!( @@ -211,8 +210,8 @@ impl EreportState { ); // try to fill the rest of the packet - for (_, ereport) in respondant_ereports { - let bytes = serde_cbor::to_vec(ereport).unwrap(); + for EreportListEntry { ena, ereport, bytes } in respondant_ereports + { // packet full! if buf[pos..].len() < (bytes.len() + 1) { break; @@ -223,6 +222,7 @@ impl EreportState { slog::debug!( self.log, "wrote subsequent ereport: {ereport:#?}"; + "ena" => ?ena, "packet_bytes" => pos, "ereport_bytes" => bytes.len(), ); @@ -236,36 +236,29 @@ impl EreportState { } } -type EreportList = Vec; - impl Ereport { - fn to_list(self) -> EreportList { - let Ereport { task_name, task_gen, uptime, data } = self; - vec![ - task_name.into(), - task_gen.into(), - (uptime as i64).into(), - data.into(), - ] + fn to_entry(self, ena: Ena) -> EreportListEntry { + let &Ereport { uptime, task_gen, ref task_name, ref data } = &self; + let body_bytes = match serde_cbor::to_vec(data) { + Ok(bytes) => bytes, + Err(e) => { + panic!("Failed to serialize ereport body: {e}\ndata: {data:#?}",) + } + }; + let bytes = match serde_cbor::to_vec(&( + task_name, + task_gen, + uptime, + // force byte array serialization --- serde will by default turn a + // `Vec` into a sequence of integers, which is ghastly (and not + // what MGS expects...) + serde_cbor::Value::Bytes(body_bytes), + )) { + Ok(bytes) => bytes, + Err(e) => panic!( + "Failed to serialize ereport tuple: {e}\nereport: {self:#?}", + ), + }; + EreportListEntry { ena, ereport: self, bytes } } } - -// fn toml2cbor(toml: &toml::Value) -> serde_cbor::Value { -// match *toml { -// toml::Value::String(ref s) => serde_cbor::Value::Text(s.clone()), -// toml::Value::Integer(i) => serde_cbor::Value::Integer(i as i128), -// toml::Value::Float(f) => serde_cbor::Value::Float(f), -// toml::Value::Boolean(b) => serde_cbor::Value::Bool(b), -// toml::Value::Datetime(d) => unimplemented!("don't use toml datetimes"), -// toml::Value::Array(ref a) => { -// serde_cbor::Value::Array(a.iter().map(toml2cbor).collect()) -// } -// toml::Value::Table(ref t) => serde_cbor::Value::Map(toml2cbor_table::(toml)) -// } -// } - -// fn toml2cbor_table>(toml: &toml::Table) -> BTreeMap { -// toml.iter().map(|(k, v) { -// (k.clone().into(), toml2cbor(v)) -// }).collect() -// }