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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions clients/bootstrap-agent-lockstep-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ progenitor::generate_api!(
RssStep = bootstrap_agent_lockstep_types::RssStep,
ScrimletReconcilersStatus = bootstrap_agent_lockstep_types::scrimlet_reconcilers::ScrimletReconcilersStatus,
ServiceIpPoolConfig = bootstrap_agent_lockstep_types::ServiceIpPoolConfig,
SledAgentInfo = bootstrap_agent_lockstep_types::SledAgentInfo,
StartSledAgentStatus = bootstrap_agent_lockstep_types::StartSledAgentStatus,
SwitchSlot = sled_agent_types::early_networking::SwitchSlot,
TxEqConfig = sled_agent_types::early_networking::TxEqConfig,
UplinkAddressConfig = sled_agent_types::early_networking::UplinkAddressConfig,
Expand Down
128 changes: 128 additions & 0 deletions openapi/bootstrap-agent-lockstep.json
Original file line number Diff line number Diff line change
Expand Up @@ -1245,6 +1245,18 @@
"last"
]
},
"Ipv6Subnet": {
"description": "Wraps an [`Ipv6Net`] with a compile-time prefix length.",
"type": "object",
"properties": {
"net": {
"$ref": "#/components/schemas/Ipv6Net"
}
},
"required": [
"net"
]
},
"LinkFec": {
"description": "The forward error correction mode of a link.",
"oneOf": [
Expand Down Expand Up @@ -2273,6 +2285,39 @@
"transient_errors"
]
},
{
"type": "object",
"properties": {
"sleds": {
"title": "BiHashMap",
"x-rust-type": {
"crate": "iddqd",
"parameters": [
{
"$ref": "#/components/schemas/SledAgentInfo"
}
],
"path": "iddqd::BiHashMap",
"version": "*"
},
"type": "array",
"items": {
"$ref": "#/components/schemas/SledAgentInfo"
},
"uniqueItems": true
},
"state": {
"type": "string",
"enum": [
"start_sled_agents"
]
}
},
"required": [
"sleds",
"state"
]
},
{
"type": "object",
"properties": {
Expand Down Expand Up @@ -3743,6 +3788,89 @@
"ranges"
]
},
"SledAgentInfo": {
"description": "Status information for a given sled agent",
"type": "object",
"properties": {
"baseboard_id": {
"$ref": "#/components/schemas/BaseboardId"
},
"sled_id": {
"$ref": "#/components/schemas/SledUuid"
},
"sled_subnet": {
"$ref": "#/components/schemas/Ipv6Subnet"
},
"start_state": {
"$ref": "#/components/schemas/SledAgentStartState"
}
},
"required": [
"baseboard_id",
"sled_id",
"sled_subnet",
"start_state"
]
},
"SledAgentStartState": {
"oneOf": [
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"in_progress"
]
}
},
"required": [
"type"
]
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"started"
]
}
},
"required": [
"type"
]
},
{
"type": "object",
"properties": {
"reason": {
"type": "string"
},
"type": {
"type": "string",
"enum": [
"failed"
]
}
},
"required": [
"reason",
"type"
]
}
]
},
"SledUuid": {
"x-rust-type": {
"crate": "omicron-uuid-kinds",
"path": "omicron_uuid_kinds::SledUuid",
"version": "*"
},
"type": "string",
"format": "uuid"
},
"SwitchSlot": {
"description": "Identifies switch physical location",
"oneOf": [
Expand Down
69 changes: 69 additions & 0 deletions sled-agent/bootstrap-agent-lockstep-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use anyhow::Context as _;
use iddqd::IdOrdItem;
use iddqd::IdOrdMap;
use iddqd::id_upcast;
use iddqd::{BiHashItem, BiHashMap, bi_upcast};
use omicron_common::address::AZ_PREFIX_LENGTH;
use omicron_common::address::Ipv6Subnet;
use omicron_common::address::RACK_PREFIX_LENGTH;
Expand All @@ -25,6 +26,7 @@ use omicron_common::api::internal::nexus::Certificate;
use omicron_uuid_kinds::MultirackJoinUuid;
use omicron_uuid_kinds::RackInitUuid;
use omicron_uuid_kinds::RackUuid;
use omicron_uuid_kinds::SledUuid;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use sled_agent_types::early_networking::RackNetworkConfig;
Expand Down Expand Up @@ -456,6 +458,72 @@ pub struct CommitState {
pub transient_errors: BTreeMap<BaseboardId, String>,
}

// Information about the state of a sled agent start request
#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
#[serde(rename_all = "snake_case", tag = "type")]
pub enum SledAgentStartState {
InProgress,
Started,
Failed { reason: String },
}

/// Status information for a given sled agent
#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
pub struct SledAgentInfo {
pub baseboard_id: BaseboardId,
pub sled_id: SledUuid,
pub sled_subnet: Ipv6Subnet<SLED_PREFIX_LENGTH>,
pub start_state: SledAgentStartState,
}

impl BiHashItem for SledAgentInfo {
type K1<'a> = &'a BaseboardId;
type K2<'a> = &'a SledUuid;

fn key1(&self) -> Self::K1<'_> {
&self.baseboard_id
}

fn key2(&self) -> Self::K2<'_> {
&self.sled_id
}

bi_upcast!();
}

#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
pub struct StartSledAgentsStatus {
pub sleds: BiHashMap<SledAgentInfo>,
}

impl StartSledAgentsStatus {
// Create the allocations necessary to start a sled-agent and return a
// preliminary state.
//
// This should only be called once.
pub fn assign_ids_and_subnets(req: MultirackJoinRequest) -> Self {
let rack_subnet = Ipv6Subnet::<RACK_PREFIX_LENGTH>::new(
req.rack_network_config.rack_subnet.addr(),
);
let sleds = req
.trust_quorum_peers
.into_iter()
.enumerate()
.map(|(idx, baseboard_id)| SledAgentInfo {
baseboard_id,
sled_id: SledUuid::new_v4(),
sled_subnet: get_64_subnet(
rack_subnet,
u8::try_from(idx + 1).expect("too many sleds"),
),
start_state: SledAgentStartState::InProgress,
})
.collect();

StartSledAgentsStatus { sleds }
}
}

/// The current state of the `MultirackJoinService` as retrieved from the
/// `output_rx` watch channel.
#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
Expand All @@ -467,6 +535,7 @@ pub enum MultirackJoinServiceState {
TrustQuorumReconfigure(TqReconfigureMsg),
TrustQuorumPreparing(CoordinatorStatus),
TrustQuorumCommitting(CommitState),
StartSledAgents(StartSledAgentsStatus),
Completed,
Failed { message: String },
InvalidMembershipSize { message: String },
Expand Down
6 changes: 6 additions & 0 deletions sled-agent/bootstrap-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,20 @@ workspace = true
[dependencies]
bootstore.workspace = true
camino.workspace = true
omicron-common.workspace = true
omicron-ledger.workspace = true
omicron-uuid-kinds.workspace = true
serde.workspace = true
serde_json = { workspace = true, features = ["raw_value"] }
sled-agent-config-reconciler.workspace = true
sled-agent-measurements.workspace = true
sled-agent-types.workspace = true
slog-error-chain.workspace = true
slog.workspace = true
sprockets-tls.workspace = true
thiserror.workspace = true
tokio.workspace = true
trust-quorum.workspace = true
uuid.workspace = true

omicron-workspace-hack.workspace = true
2 changes: 2 additions & 0 deletions sled-agent/bootstrap-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
//! and the Multirack Join Service. Please do not use it in public facing,
//! non-lockstep, interfaces.

pub mod sprockets;

use bootstore::schemes::v0 as bootstore;
use camino::Utf8PathBuf;
use omicron_ledger::{Ledger, Ledgerable};
Expand Down
Loading
Loading