Skip to content

Commit 3b3931b

Browse files
authored
[reconfigurator] Pre-checks and post_update actions for RoT bootloader update (#8325)
This commit implements several checks that must happen before updating an RoT bootloader, and post-update actions. Related: #7988
1 parent 3e94daa commit 3b3931b

File tree

12 files changed

+929
-112
lines changed

12 files changed

+929
-112
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

clients/gateway-client/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@ serde.workspace = true
2222
serde_json.workspace = true
2323
schemars.workspace = true
2424
slog.workspace = true
25+
thiserror.workspace = true
2526
uuid.workspace = true
2627
omicron-workspace-hack.workspace = true

clients/gateway-client/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ progenitor::generate_api!(
6363
HostPhase2RecoveryImageId = { derives = [PartialEq, Eq, PartialOrd, Ord] },
6464
ImageVersion = { derives = [PartialEq, Eq, PartialOrd, Ord] },
6565
RotImageDetails = { derives = [PartialEq, Eq, PartialOrd, Ord] },
66-
RotImageError = { derives = [ PartialEq, Eq, PartialOrd, Ord] },
66+
RotImageError = { derives = [ thiserror::Error, PartialEq, Eq, PartialOrd, Ord] },
6767
RotState = { derives = [PartialEq, Eq, PartialOrd, Ord] },
6868
SpComponentCaboose = { derives = [PartialEq, Eq] },
6969
SpIdentifier = { derives = [Copy, PartialEq, Hash, Eq] },

nexus/mgs-updates/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ chrono.workspace = true
1111
futures.workspace = true
1212
gateway-client.workspace = true
1313
gateway-types.workspace = true
14+
gateway-messages.workspace = true
1415
iddqd.workspace = true
1516
id-map.workspace = true
1617
internal-dns-resolver.workspace = true

nexus/mgs-updates/src/common_sp_update.rs

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ pub trait SpComponentUpdateHelper {
267267
log: &'a slog::Logger,
268268
mgs_clients: &'a mut MgsClients,
269269
update: &'a PendingMgsUpdate,
270-
) -> BoxFuture<'a, Result<(), GatewayClientError>>;
270+
) -> BoxFuture<'a, Result<(), PostUpdateError>>;
271271
}
272272

273273
/// Describes the live state of the component before the update begins
@@ -319,12 +319,66 @@ pub enum PrecheckError {
319319
WrongInactiveVersion { expected: ExpectedVersion, found: FoundVersion },
320320
}
321321

322-
#[derive(Debug)]
322+
#[derive(Debug, thiserror::Error)]
323+
pub enum PostUpdateError {
324+
#[error("communicating with MGS")]
325+
GatewayClientError(#[from] GatewayClientError),
326+
327+
#[error("transient error: {message:?}")]
328+
TransientError { message: String },
329+
330+
#[error("fatal error: {error:?}")]
331+
FatalError { error: String },
332+
}
333+
334+
impl PostUpdateError {
335+
pub fn is_fatal(&self) -> bool {
336+
match self {
337+
PostUpdateError::GatewayClientError(error) => {
338+
!matches!(error, gateway_client::Error::CommunicationError(_))
339+
}
340+
PostUpdateError::TransientError { .. } => false,
341+
PostUpdateError::FatalError { .. } => true,
342+
}
343+
}
344+
}
345+
346+
#[derive(Debug, Clone)]
323347
pub enum FoundVersion {
324348
MissingVersion,
325349
Version(String),
326350
}
327351

352+
impl FoundVersion {
353+
pub fn matches(
354+
&self,
355+
expected: &ExpectedVersion,
356+
) -> Result<(), PrecheckError> {
357+
match (expected, &self) {
358+
// expected garbage, found garbage
359+
(ExpectedVersion::NoValidVersion, FoundVersion::MissingVersion) => {
360+
()
361+
}
362+
// expected a specific version and found it
363+
(
364+
ExpectedVersion::Version(artifact_version),
365+
FoundVersion::Version(found_version),
366+
) if artifact_version.to_string() == *found_version => (),
367+
// anything else is a mismatch
368+
(ExpectedVersion::NoValidVersion, FoundVersion::Version(_))
369+
| (ExpectedVersion::Version(_), FoundVersion::MissingVersion)
370+
| (ExpectedVersion::Version(_), FoundVersion::Version(_)) => {
371+
return Err(PrecheckError::WrongInactiveVersion {
372+
expected: expected.clone(),
373+
found: self.clone(),
374+
});
375+
}
376+
};
377+
378+
Ok(())
379+
}
380+
}
381+
328382
pub(crate) fn error_means_caboose_is_invalid(
329383
error: &GatewayClientError,
330384
) -> bool {

0 commit comments

Comments
 (0)