2025-10-14 12:47:33 -07:00
|
|
|
use crate::actions;
|
|
|
|
|
use crate::context::SproutContext;
|
2025-11-03 02:04:21 -05:00
|
|
|
use alloc::format;
|
|
|
|
|
use alloc::rc::Rc;
|
2025-10-19 20:23:55 -07:00
|
|
|
use anyhow::{Context, Result};
|
2025-11-02 23:28:31 -05:00
|
|
|
use edera_sprout_config::phases::PhaseConfiguration;
|
2025-10-14 12:47:33 -07:00
|
|
|
|
2025-10-19 20:23:55 -07:00
|
|
|
/// Executes the specified [phase] of the boot process.
|
|
|
|
|
/// The value [phase] should be a reference of a specific phase in the [PhasesConfiguration].
|
|
|
|
|
/// Any error from the actions is propagated into the [Result] and will interrupt further
|
|
|
|
|
/// execution of phase actions.
|
|
|
|
|
pub fn phase(context: Rc<SproutContext>, phase: &[PhaseConfiguration]) -> Result<()> {
|
2025-10-14 12:47:33 -07:00
|
|
|
for item in phase {
|
|
|
|
|
let mut context = context.fork();
|
2025-10-19 21:44:05 -07:00
|
|
|
// Insert the values into the context.
|
2025-10-14 12:47:33 -07:00
|
|
|
context.insert(&item.values);
|
|
|
|
|
let context = context.freeze();
|
|
|
|
|
|
2025-10-19 21:44:05 -07:00
|
|
|
// Execute all the actions in this phase configuration.
|
2025-10-14 12:47:33 -07:00
|
|
|
for action in item.actions.iter() {
|
|
|
|
|
actions::execute(context.clone(), action)
|
|
|
|
|
.context(format!("unable to execute action '{}'", action))?;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2025-12-20 21:45:35 -08:00
|
|
|
|
|
|
|
|
/// Manual hook called by code in the bootloader that hands off to another image.
|
|
|
|
|
/// This is used to perform actions like clearing the screen.
|
|
|
|
|
pub fn before_handoff(context: &SproutContext) -> Result<()> {
|
|
|
|
|
// If we have not been asked to retain the boot console, then we should clear the screen.
|
|
|
|
|
if !context.root().options().retain_boot_console {
|
|
|
|
|
uefi::system::with_stdout(|stdout| stdout.reset(true)).context("unable to clear screen")?;
|
|
|
|
|
}
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|