Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
10 changes: 10 additions & 0 deletions dev-tools/reconfigurator-sp-updater/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,16 @@ fn cmd_config(
expected_transient_boot_preference,
)?;
}
PendingMgsUpdateDetails::RotBootloader {
expected_stage_0_version,
expected_stage_0_next_version,
} => {
writeln!(
&mut s,
" preconditions: stage 0 {:?}, stage 0 next {:?}",
expected_stage_0_version, expected_stage_0_next_version,
)?;
}
}

writeln!(&mut s)?;
Expand Down
9 changes: 9 additions & 0 deletions nexus/mgs-updates/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::driver_update::ApplyUpdateError;
use crate::driver_update::PROGRESS_TIMEOUT;
use crate::driver_update::SpComponentUpdate;
use crate::driver_update::apply_update;
use crate::rot_bootloader_updater::ReconfiguratorRotBootloaderUpdater;
use crate::rot_updater::ReconfiguratorRotUpdater;
use crate::sp_updater::ReconfiguratorSpUpdater;
use futures::FutureExt;
Expand Down Expand Up @@ -322,6 +323,14 @@ impl MgsUpdateDriver {

(sp_update, Box::new(ReconfiguratorRotUpdater {}))
}
nexus_types::deployment::PendingMgsUpdateDetails::RotBootloader {
..
} => {
let sp_update =
SpComponentUpdate::from_request(&log, &request, update_id);

(sp_update, Box::new(ReconfiguratorRotBootloaderUpdater {}))
}
};

let baseboard_id = baseboard_id.clone();
Expand Down
14 changes: 14 additions & 0 deletions nexus/mgs-updates/src/driver_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,20 @@ impl SpComponentUpdate {
update_id,
}
}
PendingMgsUpdateDetails::RotBootloader { .. } => {
SpComponentUpdate {
log: log.clone(),
component: SpComponent::STAGE0,
target_sp_type: request.sp_type,
target_sp_slot: request.slot_id,
// The RoT bootlaoder has two firmware slots, stage0 and
// stage0next. We always request an update to stage0next, which
// is the staging area for the bootloader and in this context
// means "the inactive slot".
firmware_slot: 1,
update_id,
}
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions nexus/mgs-updates/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ mod driver;
mod driver_update;
mod host_phase1_updater;
mod mgs_clients;
mod rot_bootloader_updater;
mod rot_updater;
mod sp_updater;
#[cfg(test)]
Expand Down
40 changes: 40 additions & 0 deletions nexus/mgs-updates/src/rot_bootloader_updater.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// 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/.

//! Module containing types for updating RoT Bootloaders via MGS.

use super::MgsClients;
use crate::SpComponentUpdateHelper;
use crate::common_sp_update::PrecheckError;
use crate::common_sp_update::PrecheckStatus;
use futures::future::BoxFuture;
use nexus_types::deployment::PendingMgsUpdate;

type GatewayClientError = gateway_client::Error<gateway_client::types::Error>;

pub struct ReconfiguratorRotBootloaderUpdater;
impl SpComponentUpdateHelper for ReconfiguratorRotBootloaderUpdater {
/// Checks if the component is already updated or ready for update
fn precheck<'a>(
&'a self,
_log: &'a slog::Logger,
_mgs_clients: &'a mut MgsClients,
_update: &'a PendingMgsUpdate,
) -> BoxFuture<'a, Result<PrecheckStatus, PrecheckError>> {
// TODO-K: To be completed in a follow up PR
todo!()
}

/// Attempts once to perform any post-update actions (e.g., reset the
/// device)
fn post_update<'a>(
&'a self,
_log: &'a slog::Logger,
_mgs_clients: &'a mut MgsClients,
_update: &'a PendingMgsUpdate,
) -> BoxFuture<'a, Result<(), GatewayClientError>> {
// TODO-K: To be completed in a follow up PR
todo!()
}
}
23 changes: 23 additions & 0 deletions nexus/types/src/deployment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1287,6 +1287,14 @@ pub enum PendingMgsUpdateDetails {
/// override persistent preference selection for a single boot
expected_transient_boot_preference: Option<RotSlot>,
},
RotBootloader {
// implicit: component = STAGE0
// implicit: firmware slot id = 1 (always 1 (Stage0Next) for RoT bootloader)
/// expected contents of the stage 0
expected_stage_0_version: ArtifactVersion,
/// expected contents of the stage 0 next
expected_stage_0_next_version: ExpectedVersion,
},
}

impl slog::KV for PendingMgsUpdateDetails {
Expand Down Expand Up @@ -1342,6 +1350,21 @@ impl slog::KV for PendingMgsUpdateDetails {
&format!("{:?}", expected_transient_boot_preference),
)
}
PendingMgsUpdateDetails::RotBootloader {
expected_stage_0_version,
expected_stage_0_next_version,
} => {
serializer
.emit_str(Key::from("component"), "rot_bootloader")?;
serializer.emit_str(
Key::from("expected_stage_0_version"),
&expected_stage_0_version.to_string(),
)?;
serializer.emit_str(
Key::from("expected_stage_0_next_version"),
&format!("{:?}", expected_stage_0_next_version),
)
}
}
}
}
Expand Down
32 changes: 32 additions & 0 deletions openapi/nexus-internal.json
Original file line number Diff line number Diff line change
Expand Up @@ -5491,6 +5491,38 @@
"expected_inactive_version",
"expected_persistent_boot_preference"
]
},
{
"type": "object",
"properties": {
"component": {
"type": "string",
"enum": [
"rot_bootloader"
]
},
"expected_stage_0_next_version": {
"description": "expected contents of the stage 0 next",
"allOf": [
{
"$ref": "#/components/schemas/ExpectedVersion"
}
]
},
"expected_stage_0_version": {
"description": "expected contents of the stage 0",
"allOf": [
{
"$ref": "#/components/schemas/ArtifactVersion"
}
]
}
},
"required": [
"component",
"expected_stage_0_next_version",
"expected_stage_0_version"
]
}
]
},
Expand Down
Loading