Skip to content
Draft
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
46bd6e1
start
ayaegashi Oct 20, 2025
13c37b3
temp
ayaegashi Oct 21, 2025
711c1b3
draft
ayaegashi Oct 21, 2025
5613037
update hc in status
ayaegashi Oct 21, 2025
412f93b
fix signature
ayaegashi Oct 21, 2025
1f10dfb
add test
ayaegashi Oct 21, 2025
cd912ff
don't use constant
ayaegashi Oct 21, 2025
f351e60
import std any
ayaegashi Oct 21, 2025
b271ef8
Merge remote-tracking branch 'origin/main' into user/ayaegashi/update-hc
ayaegashi Oct 22, 2025
83a3d09
fix ut
ayaegashi Oct 22, 2025
0e54277
use a const
ayaegashi Oct 22, 2025
c41f1ea
add selinux policies
ayaegashi Oct 22, 2025
6e4aefa
add condition to skip
ayaegashi Oct 22, 2025
357190f
Merge remote-tracking branch 'origin/main' into user/ayaegashi/update-hc
ayaegashi Oct 24, 2025
647b4d0
create new method
ayaegashi Oct 24, 2025
f3ef4f5
remove comments
ayaegashi Oct 24, 2025
1beec72
change doc comment
ayaegashi Oct 24, 2025
1e5a9ab
make ctx clone
ayaegashi Oct 24, 2025
6574217
don't clone
ayaegashi Oct 24, 2025
3143e1c
don't pass mutable subsystems
ayaegashi Oct 24, 2025
4b5279c
use try for each
ayaegashi Oct 24, 2025
ff0b194
nits
ayaegashi Oct 27, 2025
bf4edc5
move extensions subsystem between management and hooks
ayaegashi Oct 27, 2025
89cf9e3
Merge remote-tracking branch 'origin/main' into user/ayaegashi/update-hc
ayaegashi Oct 28, 2025
204636b
try override
ayaegashi Oct 29, 2025
d3487ff
run extensions host
ayaegashi Oct 29, 2025
ef4929e
try helper
ayaegashi Oct 29, 2025
f27914e
use logrus
ayaegashi Oct 29, 2025
5bfa1ef
try confexts in root-verity
ayaegashi Oct 29, 2025
1677d76
try logging in with umi
ayaegashi Oct 29, 2025
863ccb5
fix typo
ayaegashi Oct 29, 2025
5dd66f8
try az acr
ayaegashi Oct 30, 2025
16be3c0
use helper everywhere
ayaegashi Oct 30, 2025
2b47be1
fail if file not found
ayaegashi Oct 30, 2025
d8d2c23
fix
ayaegashi Oct 30, 2025
ec4d91a
add working dir
ayaegashi Oct 30, 2025
8684089
disable path valid
ayaegashi Oct 30, 2025
ab748ff
use path valid
ayaegashi Oct 30, 2025
4c025dd
skip oras and delete bash scripts
ayaegashi Oct 30, 2025
40edbe1
edit build script
ayaegashi Oct 30, 2025
356625b
a bunch of restructuring
ayaegashi Oct 30, 2025
db48c7a
typo
ayaegashi Oct 30, 2025
b74a126
remove unnecessary template
ayaegashi Oct 30, 2025
adc8a15
add back install oras and clean up
ayaegashi Oct 30, 2025
f1512ab
clean up
ayaegashi Oct 30, 2025
7848004
Merge remote-tracking branch 'origin/user/ayaegashi/use-storm' into u…
ayaegashi Oct 30, 2025
8126860
pull in changes from other branch
ayaegashi Oct 30, 2025
724d268
debug output
ayaegashi Oct 30, 2025
ca3c6bb
use storm for remove
ayaegashi Oct 30, 2025
be9ff2f
remove false
ayaegashi Oct 30, 2025
51dabce
fix
ayaegashi Oct 30, 2025
ebee9f3
add extensions to pre2e
ayaegashi Oct 30, 2025
5c2a931
remove commented code
ayaegashi Oct 30, 2025
6f9eb09
ai fixes
ayaegashi Oct 30, 2025
90652f2
ran go mod tidy
ayaegashi Oct 30, 2025
ba7928b
add push=false
ayaegashi Oct 30, 2025
20ba985
fix num clones
ayaegashi Oct 30, 2025
fb16b9c
remove =
ayaegashi Oct 30, 2025
38f9d44
please work
ayaegashi Oct 30, 2025
73ee858
fix
ayaegashi Oct 30, 2025
0032327
remove quote
ayaegashi Oct 30, 2025
165299b
return err
ayaegashi Oct 30, 2025
cd8bd7a
add debug
ayaegashi Oct 30, 2025
9b1a162
print out command
ayaegashi Oct 30, 2025
2cb047b
remove stdout
ayaegashi Oct 30, 2025
13f5ad3
Merge remote-tracking branch 'origin/user/ayaegashi/use-storm' into u…
ayaegashi Oct 30, 2025
e3fd452
temporarily stop removing images from acr
ayaegashi Oct 30, 2025
2814a6a
try mounting var etc
ayaegashi Oct 30, 2025
e0940d1
fix mp
ayaegashi Oct 31, 2025
eac8ff8
define new device
ayaegashi Oct 31, 2025
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
6 changes: 5 additions & 1 deletion crates/trident/src/engine/boot/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::path::Path;
use std::{any::Any, path::Path};

use log::debug;
use strum::IntoEnumIterator;
Expand All @@ -25,6 +25,10 @@ impl Subsystem for BootSubsystem {
"boot"
}

fn as_any(&self) -> &dyn Any {
self
}

#[tracing::instrument(name = "boot_configuration", skip_all)]
fn configure(&mut self, ctx: &EngineContext) -> Result<(), TridentError> {
if ctx.is_uki()? {
Expand Down
6 changes: 5 additions & 1 deletion crates/trident/src/engine/clean_install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,10 @@ fn stage_clean_install(
return Err(original_error).message("Failed to execute in chroot");
}

// Update Host Configuration with the paths of extension images.
let updated_hc =
engine::get_extensions_subsystem(subsystems)?.update_host_configuration(&ctx)?;

// At this point, clean install has been staged, so update Host Status
debug!(
"Updating host's servicing state to '{:?}'",
Expand All @@ -265,7 +269,7 @@ fn stage_clean_install(
state.with_host_status(|hs| {
*hs = HostStatus {
servicing_state: ServicingState::CleanInstallStaged,
spec: host_config.clone(),
spec: updated_hc,
spec_old: Default::default(),
ab_active_volume: None,
partition_paths: ctx.partition_paths,
Expand Down
21 changes: 21 additions & 0 deletions crates/trident/src/engine/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::{
any::Any,
fs,
path::{Path, PathBuf},
sync::Mutex,
Expand All @@ -22,6 +23,7 @@ use crate::{
engine::boot::BootSubsystem,
subsystems::{
esp::EspSubsystem,
extensions::ExtensionsSubsystem,
hooks::HooksSubsystem,
initrd::InitrdSubsystem,
management::ManagementSubsystem,
Expand Down Expand Up @@ -59,6 +61,8 @@ pub(crate) use update::{finalize_update, update};
pub(crate) trait Subsystem: Send {
fn name(&self) -> &'static str;

fn as_any(&self) -> &dyn Any;

fn writable_etc_overlay(&self) -> bool {
true
}
Expand Down Expand Up @@ -115,6 +119,7 @@ lazy_static::lazy_static! {
Box::<HooksSubsystem>::default(),
Box::<InitrdSubsystem>::default(),
Box::<SelinuxSubsystem>::default(),
Box::<ExtensionsSubsystem>::default(),
]);
}

Expand Down Expand Up @@ -319,6 +324,22 @@ fn configure(
Ok(())
}

pub fn get_extensions_subsystem(
subsystems: &[Box<dyn Subsystem>],
) -> Result<&ExtensionsSubsystem, TridentError> {
subsystems
.iter()
.find(|s| s.name() == ExtensionsSubsystem::default().name())
.structured(InternalError::Internal(
"Failed to find Extensions subsystem",
))?
.as_any()
.downcast_ref::<ExtensionsSubsystem>()
.structured(InternalError::Internal(
"Failed to downcast to ExtensionsSubsystem",
))
}

pub fn reboot() -> Result<(), TridentError> {
// Sync all writes to the filesystem.
info!("Syncing filesystem");
Expand Down
6 changes: 5 additions & 1 deletion crates/trident/src/engine/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,14 +253,18 @@ fn stage_update(
engine::configure(subsystems, &ctx)?;
};

// Update Host Configuration with the paths of extension images.
let updated_hc =
engine::get_extensions_subsystem(subsystems)?.update_host_configuration(&ctx)?;

// At this point, deployment has been staged, so update servicing state
debug!(
"Updating host's servicing state to '{:?}'",
ServicingState::AbUpdateStaged
);
state.with_host_status(|hs| {
*hs = HostStatus {
spec: ctx.spec,
spec: updated_hc,
spec_old: ctx.spec_old,
servicing_state: ServicingState::AbUpdateStaged,
ab_active_volume: ctx.ab_active_volume,
Expand Down
5 changes: 5 additions & 0 deletions crates/trident/src/subsystems/esp.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::{
any::Any,
fs,
io::Read,
path::{Path, PathBuf},
Expand Down Expand Up @@ -42,6 +43,10 @@ impl Subsystem for EspSubsystem {
"esp"
}

fn as_any(&self) -> &dyn Any {
self
}

#[tracing::instrument(name = "esp_provision", skip_all)]
fn provision(&mut self, ctx: &EngineContext, mount_path: &Path) -> Result<(), TridentError> {
// Perform file-based deployment of ESP images, if needed, after filesystems have been
Expand Down
155 changes: 154 additions & 1 deletion crates/trident/src/subsystems/extensions/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::{
any::Any,
fmt::Display,
fs,
path::{Path, PathBuf},
Expand All @@ -10,7 +11,7 @@ use tempfile::NamedTempFile;

use osutils::{dependencies::Dependency, path};
use trident_api::{
config::Extension,
config::{Extension, HostConfiguration},
constants::internal_params::HTTP_CONNECTION_TIMEOUT_SECONDS,
error::{InternalError, ReportError, TridentError},
primitives::hash::Sha384Hash,
Expand Down Expand Up @@ -90,6 +91,10 @@ impl Subsystem for ExtensionsSubsystem {
"extensions"
}

fn as_any(&self) -> &dyn Any {
self
}

fn provision(&mut self, ctx: &EngineContext, mount_path: &Path) -> Result<(), TridentError> {
// Define staging directory, in which extension images will be downloaded.
let staging_dir = path::join_relative(mount_path, EXTENSION_IMAGE_STAGING_DIRECTORY);
Expand Down Expand Up @@ -253,6 +258,51 @@ impl ExtensionsSubsystem {

Ok(())
}

pub(crate) fn update_host_configuration(
&self,
ctx: &EngineContext,
) -> Result<HostConfiguration, TridentError> {
let mut updated_hc = ctx.spec.clone();

// Update paths of sysexts in the Host Configuration.
for sysext in self
.extensions
.iter()
.filter(|ext| ext.ext_type == ExtensionType::Sysext)
{
// Find corresponding sysext in Host Configuration.
let hc_ext = updated_hc
.os
.sysexts
.iter_mut()
.find(|ext| ext.sha384 == sysext.sha384)
.structured(InternalError::Internal(
"Failed to find previously processed sysext in Host Configuration",
))?;
hc_ext.path = Some(sysext.path.clone());
}

// Update paths of confexts in the Host Configuration.
for confext in self
.extensions
.iter()
.filter(|ext| ext.ext_type == ExtensionType::Confext)
{
// Find corresponding confext in Host Configuration.
let hc_ext = updated_hc
.os
.confexts
.iter_mut()
.find(|ext| ext.sha384 == confext.sha384)
.structured(InternalError::Internal(
"Failed to find previously processed confext in Host Configuration",
))?;
hc_ext.path = Some(confext.path.clone());
}

Ok(updated_hc)
}
}

/// Helper function to identify if the extension exists in the old Host
Expand Down Expand Up @@ -322,6 +372,7 @@ mod tests {
use super::*;

use tempfile::env::temp_dir;
use url::Url;

#[test]
fn test_populate_extensions_empty() {
Expand All @@ -339,6 +390,108 @@ mod tests {
"ExtensionsSubsystem extensions_old should be empty when there are no extensions in the old Host Configuration"
);
}

#[test]
fn test_update_host_configuration_sysexts() {
let mut ctx = EngineContext::default();
ctx.spec.os.sysexts = vec![
Extension {
url: Url::parse("https://example.com/sysext1.raw").unwrap(),
sha384: Sha384Hash::from("a".repeat(96)),
path: None,
},
Extension {
url: Url::parse("https://example.com/sysext2.raw").unwrap(),
sha384: Sha384Hash::from("b".repeat(96)),
path: Some(PathBuf::from("/etc/extensions/sysext2.raw")),
},
];

let subsystem = ExtensionsSubsystem {
extensions: vec![
ExtensionData {
id: "sysext1".to_string(),
name: "sysext1".to_string(),
sha384: Sha384Hash::from("a".repeat(96)),
path: PathBuf::from("/var/lib/extensions/sysext1.raw"),
temp_path: Some(
PathBuf::from(EXTENSION_IMAGE_STAGING_DIRECTORY).join("sysext1.raw"),
),
ext_type: ExtensionType::Sysext,
},
ExtensionData {
id: "sysext2".to_string(),
name: "sysext2".to_string(),
sha384: Sha384Hash::from("b".repeat(96)),
path: PathBuf::from("/etc/extensions/sysext2.raw"),
temp_path: Some(
PathBuf::from(EXTENSION_IMAGE_STAGING_DIRECTORY).join("sysext2.raw"),
),
ext_type: ExtensionType::Sysext,
},
],
extensions_old: vec![],
};
let updated_hc = subsystem.update_host_configuration(&ctx).unwrap();

for i in 0..subsystem.extensions.len() {
assert_eq!(
updated_hc.os.sysexts[i].path,
Some(subsystem.extensions[i].path.clone())
)
}
}

#[test]
fn test_update_host_configuration_confexts() {
let mut ctx = EngineContext::default();
ctx.spec.os.confexts = vec![
Extension {
url: Url::parse("https://example.com/confext1.raw").unwrap(),
sha384: Sha384Hash::from("a".repeat(96)),
path: None,
},
Extension {
url: Url::parse("https://example.com/confext2.raw").unwrap(),
sha384: Sha384Hash::from("b".repeat(96)),
path: Some(PathBuf::from("/usr/lib/confexts/confext2.raw")),
},
];

let subsystem = ExtensionsSubsystem {
extensions: vec![
ExtensionData {
id: "confext1".to_string(),
name: "confext1".to_string(),
sha384: Sha384Hash::from("a".repeat(96)),
path: PathBuf::from("/var/lib/confexts/confext1.raw"),
temp_path: Some(
PathBuf::from(EXTENSION_IMAGE_STAGING_DIRECTORY).join("confext1.raw"),
),
ext_type: ExtensionType::Confext,
},
ExtensionData {
id: "confext2".to_string(),
name: "confext2".to_string(),
sha384: Sha384Hash::from("b".repeat(96)),
path: PathBuf::from("/usr/lib/confexts/confext2.raw"),
temp_path: Some(
PathBuf::from(EXTENSION_IMAGE_STAGING_DIRECTORY).join("confext2.raw"),
),
ext_type: ExtensionType::Confext,
},
],
extensions_old: vec![],
};
let updated_hc = subsystem.update_host_configuration(&ctx).unwrap();

for i in 0..subsystem.extensions.len() {
assert_eq!(
updated_hc.os.confexts[i].path,
Some(subsystem.extensions[i].path.clone())
)
}
}
}

#[cfg(feature = "functional-test")]
Expand Down
5 changes: 5 additions & 0 deletions crates/trident/src/subsystems/hooks.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::{
any::Any,
collections::HashMap,
ffi::OsStr,
os::unix::fs::PermissionsExt,
Expand Down Expand Up @@ -40,6 +41,10 @@ impl Subsystem for HooksSubsystem {
"hooks"
}

fn as_any(&self) -> &dyn Any {
self
}

fn writable_etc_overlay(&self) -> bool {
self.writable_etc_overlay
}
Expand Down
6 changes: 6 additions & 0 deletions crates/trident/src/subsystems/initrd.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::any::Any;

use log::{debug, info};

use osutils::mkinitrd;
Expand All @@ -12,6 +14,10 @@ impl Subsystem for InitrdSubsystem {
"initrd"
}

fn as_any(&self) -> &dyn Any {
self
}

fn writable_etc_overlay(&self) -> bool {
false
}
Expand Down
5 changes: 5 additions & 0 deletions crates/trident/src/subsystems/management.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Subsystem in charge of configuring the Trident agent on the target OS.

use std::{
any::Any,
fs::{self},
path::Path,
};
Expand Down Expand Up @@ -29,6 +30,10 @@ impl Subsystem for ManagementSubsystem {
"management"
}

fn as_any(&self) -> &dyn Any {
self
}

fn validate_host_config(&self, ctx: &EngineContext) -> Result<(), TridentError> {
if ctx.spec.trident.disable {
return Ok(());
Expand Down
6 changes: 5 additions & 1 deletion crates/trident/src/subsystems/network.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{fs, path::Path};
use std::{any::Any, fs, path::Path};

use anyhow::Context;
use log::debug;
Expand All @@ -19,6 +19,10 @@ impl Subsystem for NetworkSubsystem {
"network"
}

fn as_any(&self) -> &dyn Any {
self
}

#[tracing::instrument(name = "network_configuration", skip_all)]
fn configure(&mut self, ctx: &EngineContext) -> Result<(), TridentError> {
match ctx.spec.os.netplan.as_ref() {
Expand Down
Loading
Loading