Skip to content

Commit 682187c

Browse files
authored
[reconfigurator] Variant for the RoT bootloader on PendingMgsUpdate (#8236)
First PR for the MGS driven update for RoT bootloader Related: #7988
1 parent 299b3ce commit 682187c

File tree

7 files changed

+129
-0
lines changed

7 files changed

+129
-0
lines changed

dev-tools/reconfigurator-sp-updater/src/main.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,16 @@ fn cmd_config(
346346
expected_transient_boot_preference,
347347
)?;
348348
}
349+
PendingMgsUpdateDetails::RotBootloader {
350+
expected_stage0_version,
351+
expected_stage0_next_version,
352+
} => {
353+
writeln!(
354+
&mut s,
355+
" preconditions: stage 0 {:?}, stage 0 next {:?}",
356+
expected_stage0_version, expected_stage0_next_version,
357+
)?;
358+
}
349359
}
350360

351361
writeln!(&mut s)?;

nexus/mgs-updates/src/driver.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::driver_update::ApplyUpdateError;
1010
use crate::driver_update::PROGRESS_TIMEOUT;
1111
use crate::driver_update::SpComponentUpdate;
1212
use crate::driver_update::apply_update;
13+
use crate::rot_bootloader_updater::ReconfiguratorRotBootloaderUpdater;
1314
use crate::rot_updater::ReconfiguratorRotUpdater;
1415
use crate::sp_updater::ReconfiguratorSpUpdater;
1516
use futures::FutureExt;
@@ -322,6 +323,14 @@ impl MgsUpdateDriver {
322323

323324
(sp_update, Box::new(ReconfiguratorRotUpdater {}))
324325
}
326+
nexus_types::deployment::PendingMgsUpdateDetails::RotBootloader {
327+
..
328+
} => {
329+
let sp_update =
330+
SpComponentUpdate::from_request(&log, &request, update_id);
331+
332+
(sp_update, Box::new(ReconfiguratorRotBootloaderUpdater {}))
333+
}
325334
};
326335

327336
let baseboard_id = baseboard_id.clone();

nexus/mgs-updates/src/driver_update.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,20 @@ impl SpComponentUpdate {
9696
update_id,
9797
}
9898
}
99+
PendingMgsUpdateDetails::RotBootloader { .. } => {
100+
SpComponentUpdate {
101+
log: log.clone(),
102+
component: SpComponent::STAGE0,
103+
target_sp_type: request.sp_type,
104+
target_sp_slot: request.slot_id,
105+
// The RoT bootloader has two firmware slots, stage0 and
106+
// stage0next. We always request an update to stage0next, which
107+
// is the staging area for the bootloader and in this context
108+
// means "the inactive slot".
109+
firmware_slot: 1,
110+
update_id,
111+
}
112+
}
99113
}
100114
}
101115
}

nexus/mgs-updates/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ mod driver;
1717
mod driver_update;
1818
mod host_phase1_updater;
1919
mod mgs_clients;
20+
mod rot_bootloader_updater;
2021
mod rot_updater;
2122
mod sp_updater;
2223
#[cfg(test)]
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public
2+
// License, v. 2.0. If a copy of the MPL was not distributed with this
3+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4+
5+
//! Module containing types for updating RoT Bootloaders via MGS.
6+
7+
use super::MgsClients;
8+
use crate::SpComponentUpdateHelper;
9+
use crate::common_sp_update::PrecheckError;
10+
use crate::common_sp_update::PrecheckStatus;
11+
use futures::future::BoxFuture;
12+
use nexus_types::deployment::PendingMgsUpdate;
13+
14+
type GatewayClientError = gateway_client::Error<gateway_client::types::Error>;
15+
16+
pub struct ReconfiguratorRotBootloaderUpdater;
17+
impl SpComponentUpdateHelper for ReconfiguratorRotBootloaderUpdater {
18+
/// Checks if the component is already updated or ready for update
19+
fn precheck<'a>(
20+
&'a self,
21+
_log: &'a slog::Logger,
22+
_mgs_clients: &'a mut MgsClients,
23+
_update: &'a PendingMgsUpdate,
24+
) -> BoxFuture<'a, Result<PrecheckStatus, PrecheckError>> {
25+
// TODO-K: To be completed in a follow up PR
26+
todo!()
27+
}
28+
29+
/// Attempts once to perform any post-update actions (e.g., reset the
30+
/// device)
31+
fn post_update<'a>(
32+
&'a self,
33+
_log: &'a slog::Logger,
34+
_mgs_clients: &'a mut MgsClients,
35+
_update: &'a PendingMgsUpdate,
36+
) -> BoxFuture<'a, Result<(), GatewayClientError>> {
37+
// TODO-K: To be completed in a follow up PR
38+
todo!()
39+
}
40+
}

nexus/types/src/deployment.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,6 +1286,14 @@ pub enum PendingMgsUpdateDetails {
12861286
/// override persistent preference selection for a single boot
12871287
expected_transient_boot_preference: Option<RotSlot>,
12881288
},
1289+
RotBootloader {
1290+
// implicit: component = STAGE0
1291+
// implicit: firmware slot id = 1 (always 1 (Stage0Next) for RoT bootloader)
1292+
/// expected contents of the stage 0
1293+
expected_stage0_version: ArtifactVersion,
1294+
/// expected contents of the stage 0 next
1295+
expected_stage0_next_version: ExpectedVersion,
1296+
},
12891297
}
12901298

12911299
impl slog::KV for PendingMgsUpdateDetails {
@@ -1341,6 +1349,21 @@ impl slog::KV for PendingMgsUpdateDetails {
13411349
&format!("{:?}", expected_transient_boot_preference),
13421350
)
13431351
}
1352+
PendingMgsUpdateDetails::RotBootloader {
1353+
expected_stage0_version,
1354+
expected_stage0_next_version,
1355+
} => {
1356+
serializer
1357+
.emit_str(Key::from("component"), "rot_bootloader")?;
1358+
serializer.emit_str(
1359+
Key::from("expected_stage0_version"),
1360+
&expected_stage0_version.to_string(),
1361+
)?;
1362+
serializer.emit_str(
1363+
Key::from("expected_stage0_next_version"),
1364+
&format!("{:?}", expected_stage0_next_version),
1365+
)
1366+
}
13441367
}
13451368
}
13461369
}

openapi/nexus-internal.json

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5517,6 +5517,38 @@
55175517
"expected_inactive_version",
55185518
"expected_persistent_boot_preference"
55195519
]
5520+
},
5521+
{
5522+
"type": "object",
5523+
"properties": {
5524+
"component": {
5525+
"type": "string",
5526+
"enum": [
5527+
"rot_bootloader"
5528+
]
5529+
},
5530+
"expected_stage0_next_version": {
5531+
"description": "expected contents of the stage 0 next",
5532+
"allOf": [
5533+
{
5534+
"$ref": "#/components/schemas/ExpectedVersion"
5535+
}
5536+
]
5537+
},
5538+
"expected_stage0_version": {
5539+
"description": "expected contents of the stage 0",
5540+
"allOf": [
5541+
{
5542+
"$ref": "#/components/schemas/ArtifactVersion"
5543+
}
5544+
]
5545+
}
5546+
},
5547+
"required": [
5548+
"component",
5549+
"expected_stage0_next_version",
5550+
"expected_stage0_version"
5551+
]
55205552
}
55215553
]
55225554
},

0 commit comments

Comments
 (0)