-
Notifications
You must be signed in to change notification settings - Fork 47
[reconfigurator-cli] RoT bootloader support #8620
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[reconfigurator-cli] RoT bootloader support #8620
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks -- a few questions.
pub fn sled_stage0_version( | ||
&self, | ||
sled_id: SledUuid, | ||
) -> anyhow::Result<Option<&str>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does Option
mean here -- i.e. under what circumstances is it possible to return None
? And can this return an &ArtifactVersion
to match what sled_update_rot_bootloader_versions
accepts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Being honest, I was just copying what @davepacheco had done for the SP
omicron/nexus/reconfigurator/planning/src/system.rs
Lines 518 to 526 in 2b32fc6
pub fn sled_sp_active_version( | |
&self, | |
sled_id: SledUuid, | |
) -> anyhow::Result<Option<&str>> { | |
let sled = self.sleds.get(&sled_id).with_context(|| { | |
format!("attempted to access sled {} not found in system", sled_id) | |
})?; | |
Ok(sled.sp_active_caboose().map(|c| c.version.as_ref())) | |
} |
That said, I think I have an idea as to why he did it this way. These methods are only used for the cmd_sled_show
function. If I were to return ArtifactVersion
, then I would have to parse the result back to a string within the cmd_sled_show
function, otherwise the output would look like this:
RoT bootloader stage 0 version: Some(ArtifactVersion("0.0.1"))
instead of:
omicron/dev-tools/reconfigurator-cli/tests/output/cmds-example-stdout
Lines 43 to 44 in 2b32fc6
SP active version: Some("0.0.1") | |
SP inactive version: None |
As to why he used an option, I'm not entirely sure. I'd like to keep it like this for now, just so it matches what the SP does. When @davepacheco comes back, I'll ask him why it was an option in the first place, and happy to change it if it'd be better to not have the Option. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Summarizing for myself (tell me if this sounds wrong): this structure is a model of the state of a simulated system (though it may have been seeded from state from a real system). The only things it does with SP versions is (1) initialize them based on whatever the caller provides, (2) allow the caller to change them via a simulated SP firmware update, and (3) report the current version.
sled_sp_active_version()
returns None
if the underlying sp_active_caboose
field is None
. I believe the only way this can happen is if this simulated system was seeded from a reconfigurator state file using an inventory collection that's missing information about this SP. I think the only way you can get here today is if you load a state file with reconfigurator-cli
and tell it to use an inventory collection that's missing this SP, though there's no reason another code path couldn't hit it. (This code path winds up going through sled_full()
.)
I don't remember if there's a particularly important reason to support this aside from the fact that inventory collections can always be missing stuff due to transient failures and it could be annoying if reconfigurator-cli
couldn't do anything with such a collection. It may have been just that it seemed pretty easy to support, given how little we do with this field.
@@ -596,6 +633,43 @@ impl SystemDescription { | |||
part_number: sp_state.model.clone(), | |||
serial_number: sp_state.serial_number.clone(), | |||
}; | |||
if let Some(stage0) = &s.stage0_caboose() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the &
required here and in stage0_next_caboose
below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aha! it is not 😄
pub stage0: Option<Arc<nexus_types::inventory::Caboose>>, | ||
pub stage0_next: Option<Arc<nexus_types::inventory::Caboose>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same q here I guess -- can we prefill these values to something reasonable? In production we always have these filled out, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above, I'd like to ask @davepacheco why it was done this way with the SPs to begin with
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for taking the time to review!
pub fn sled_stage0_version( | ||
&self, | ||
sled_id: SledUuid, | ||
) -> anyhow::Result<Option<&str>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Being honest, I was just copying what @davepacheco had done for the SP
omicron/nexus/reconfigurator/planning/src/system.rs
Lines 518 to 526 in 2b32fc6
pub fn sled_sp_active_version( | |
&self, | |
sled_id: SledUuid, | |
) -> anyhow::Result<Option<&str>> { | |
let sled = self.sleds.get(&sled_id).with_context(|| { | |
format!("attempted to access sled {} not found in system", sled_id) | |
})?; | |
Ok(sled.sp_active_caboose().map(|c| c.version.as_ref())) | |
} |
That said, I think I have an idea as to why he did it this way. These methods are only used for the cmd_sled_show
function. If I were to return ArtifactVersion
, then I would have to parse the result back to a string within the cmd_sled_show
function, otherwise the output would look like this:
RoT bootloader stage 0 version: Some(ArtifactVersion("0.0.1"))
instead of:
omicron/dev-tools/reconfigurator-cli/tests/output/cmds-example-stdout
Lines 43 to 44 in 2b32fc6
SP active version: Some("0.0.1") | |
SP inactive version: None |
As to why he used an option, I'm not entirely sure. I'd like to keep it like this for now, just so it matches what the SP does. When @davepacheco comes back, I'll ask him why it was an option in the first place, and happy to change it if it'd be better to not have the Option. WDYT?
@@ -596,6 +633,43 @@ impl SystemDescription { | |||
part_number: sp_state.model.clone(), | |||
serial_number: sp_state.serial_number.clone(), | |||
}; | |||
if let Some(stage0) = &s.stage0_caboose() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aha! it is not 😄
pub stage0: Option<Arc<nexus_types::inventory::Caboose>>, | ||
pub stage0_next: Option<Arc<nexus_types::inventory::Caboose>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above, I'd like to ask @davepacheco why it was done this way with the SPs to begin with
Equivalent of #8273 for RoT bootloader