From 56073748d5793e5029f9cee812bbb6c9e1cf7d87 Mon Sep 17 00:00:00 2001 From: Lut99 Date: Fri, 16 Jan 2026 15:31:11 +0100 Subject: [PATCH 1/4] Updated container OS for `brane-cli` packages to Ubuntu 24.04 This to avoid GLIBC errors with the current Github runners. And it was desperately time to do so. --- brane-cli/src/build_ecu.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/brane-cli/src/build_ecu.rs b/brane-cli/src/build_ecu.rs index caa59f3b..9d370a33 100644 --- a/brane-cli/src/build_ecu.rs +++ b/brane-cli/src/build_ecu.rs @@ -159,13 +159,13 @@ async fn build( /// * `context`: The directory to find the executable in. /// * `override_branelet`: Whether or not to override the branelet executable. If so, assumes the new one is copied to the temporary build folder by the time the DockerFile is run. /// -/// **Returns** +/// **Returns** /// A String that is the new DockerFile on success, or a BuildError otherwise. fn generate_dockerfile(document: &ContainerInfo, context: &Path, override_branelet: bool) -> Result { let mut contents = String::new(); // Get the base image from the document - let base = document.base.clone().unwrap_or_else(|| String::from("ubuntu:20.04")); + let base = document.base.clone().unwrap_or_else(|| String::from("ubuntu:24.04")); // Add default heading writeln_build!(contents, "# Generated by Brane")?; @@ -268,7 +268,7 @@ fn generate_dockerfile(document: &ContainerInfo, context: &Path, override_branel /// * `package_dir`: The directory where we can build the package and store it once done. /// - `convert_crlf`: If true, will not ask to convert CRLF files but instead just do it. /// -/// **Returns** +/// **Returns** /// Nothing if the directory was created successfully, or a BuildError otherwise. fn prepare_directory( document: &ContainerInfo, From 2e4cc696941e4120e3e3a597ff7330f5f39f392b Mon Sep 17 00:00:00 2001 From: Lut99 Date: Wed, 21 Jan 2026 14:40:09 +0100 Subject: [PATCH 2/4] Added missing `.trace()` to error reports --- brane-api/src/packages.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/brane-api/src/packages.rs b/brane-api/src/packages.rs index 6f4d4cf5..acc5daae 100644 --- a/brane-api/src/packages.rs +++ b/brane-api/src/packages.rs @@ -22,6 +22,7 @@ use async_compression::tokio::bufread::GzipDecoder; use brane_cfg::info::Info as _; use brane_cfg::node::{CentralConfig, NodeConfig, NodeKind}; use bytes::Buf; +use error_trace::{ErrorTrace as _, trace}; use log::{debug, error, info, warn}; use rand::Rng; use rand::distr::Alphanumeric; @@ -59,7 +60,7 @@ macro_rules! fail { // Now write the error to stderr and the internal error to the client let err = $err; - error!("{}", err); + error!("{}", err.trace()); return Err(warp::reject::custom(InternalError)); }}; @@ -68,11 +69,11 @@ macro_rules! fail { let path = &$path; if path.is_file() { if let Err(err) = tfs::remove_file(&path).await { - warn!("Failed to remove temporary download result '{}': {}", path.display(), err); + warn!("{}", trace!(("Failed to remove temporary download result '{}'", path.display()), err)); } } else if path.is_dir() { if let Err(err) = tfs::remove_dir_all(&path).await { - warn!("Failed to remove temporary download results '{}': {}", path.display(), err); + warn!("{}", trace!(("Failed to remove temporary download results '{}'", path.display()), err)); } } From 1a1014c0570ad50164cf0be3771de998d88bf47f Mon Sep 17 00:00:00 2001 From: Lut99 Date: Wed, 21 Jan 2026 14:49:20 +0100 Subject: [PATCH 3/4] More `.trace()` fixes --- brane-api/src/data.rs | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/brane-api/src/data.rs b/brane-api/src/data.rs index 60917c94..269892d7 100644 --- a/brane-api/src/data.rs +++ b/brane-api/src/data.rs @@ -19,6 +19,7 @@ use brane_cfg::info::Info as _; use brane_cfg::infra::InfraFile; use brane_cfg::node::NodeConfig; use brane_prx::spec::NewPathRequestTlsOptions; +use error_trace::{ErrorTrace as _, trace}; use log::{debug, error}; use reqwest::StatusCode; use specifications::data::{AssetInfo, DataInfo}; @@ -60,7 +61,7 @@ pub async fn list(context: Context) -> Result { let node_config: NodeConfig = match NodeConfig::from_path(&context.node_config_path) { Ok(config) => config, Err(source) => { - error!("Failed to load NodeConfig file: {}", source); + error!("{}", trace!(("Failed to load NodeConfig file"), source)); return Err(warp::reject::custom(Error::SecretError)); }, }; @@ -73,7 +74,7 @@ pub async fn list(context: Context) -> Result { let infra: InfraFile = match InfraFile::from_path(&node_config.node.central().paths.infra) { Ok(infra) => infra, Err(source) => { - error!("{}", Error::InfrastructureOpenError { path: node_config.node.central().paths.infra.clone(), source }); + error!("{}", Error::InfrastructureOpenError { path: node_config.node.central().paths.infra.clone(), source }.trace()); return Err(warp::reject::custom(Error::SecretError)); }, }; @@ -88,12 +89,12 @@ pub async fn list(context: Context) -> Result { Ok(res) => match res { Ok(res) => res, Err(source) => { - error!("{} (skipping domain)", Error::RequestError { address, source }); + error!("{} (skipping domain)", Error::RequestError { address, source }.trace()); continue; }, }, Err(source) => { - error!("{} (skipping domain)", Error::ProxyError { source }); + error!("{} (skipping domain)", Error::ProxyError { source }.trace()); continue; }, }; @@ -106,7 +107,7 @@ pub async fn list(context: Context) -> Result { let body: String = match res.text().await { Ok(body) => body, Err(source) => { - error!("{} (skipping domain)", Error::ResponseBodyError { address, source }); + error!("{} (skipping domain)", Error::ResponseBodyError { address, source }.trace()); continue; }, }; @@ -114,7 +115,7 @@ pub async fn list(context: Context) -> Result { Ok(body) => body, Err(source) => { debug!("Received body: \"\"\"{}\"\"\"", body); - error!("{} (skipping domain)", Error::ResponseParseError { address, source }); + error!("{} (skipping domain)", Error::ResponseParseError { address, source }.trace()); continue; }, }; @@ -134,7 +135,7 @@ pub async fn list(context: Context) -> Result { let body: String = match serde_json::to_string(&datasets) { Ok(body) => body, Err(source) => { - error!("{}", Error::SerializeError { what: "list of all datasets", source }); + error!("{}", Error::SerializeError { what: "list of all datasets", source }.trace()); fail!(); }, }; @@ -168,7 +169,7 @@ pub async fn get(name: String, context: Context) -> Result config, Err(err) => { - error!("Failed to load NodeConfig file: {}", err); + error!("Failed to load NodeConfig file: {}", err.trace()); return Err(warp::reject::custom(Error::SecretError)); }, }; @@ -181,7 +182,7 @@ pub async fn get(name: String, context: Context) -> Result infra, Err(source) => { - error!("{}", Error::InfrastructureOpenError { path: node_config.node.central().paths.infra.clone(), source }); + error!("{}", Error::InfrastructureOpenError { path: node_config.node.central().paths.infra.clone(), source }.trace()); return Err(warp::reject::custom(Error::SecretError)); }, }; @@ -196,12 +197,12 @@ pub async fn get(name: String, context: Context) -> Result match res { Ok(res) => res, Err(source) => { - error!("{} (skipping domain)", Error::RequestError { address, source }); + error!("{} (skipping domain)", Error::RequestError { address, source }.trace()); continue; }, }, Err(source) => { - error!("{} (skipping domain)", Error::ProxyError { source }); + error!("{} (skipping domain)", Error::ProxyError { source }.trace()); continue; }, }; @@ -214,7 +215,7 @@ pub async fn get(name: String, context: Context) -> Result body, Err(source) => { - error!("{} (skipping domain datasets)", Error::ResponseBodyError { address, source }); + error!("{} (skipping domain datasets)", Error::ResponseBodyError { address, source }.trace()); continue; }, }; @@ -222,7 +223,7 @@ pub async fn get(name: String, context: Context) -> Result body, Err(source) => { debug!("Received body: \"\"\"{}\"\"\"", body); - error!("{} (skipping domain datasets)", Error::ResponseParseError { address, source }); + error!("{} (skipping domain datasets)", Error::ResponseParseError { address, source }.trace()); continue; }, }; @@ -244,7 +245,7 @@ pub async fn get(name: String, context: Context) -> Result body, Err(source) => { - error!("{}", Error::SerializeError { what: "dataset metadata", source }); + error!("{}", Error::SerializeError { what: "dataset metadata", source }.trace()); fail!(); }, }; From c5cfbe3314c7932e63003a41db8f6325670b49c8 Mon Sep 17 00:00:00 2001 From: Lut99 Date: Wed, 21 Jan 2026 15:00:51 +0100 Subject: [PATCH 4/4] More `.trace()` fixes --- brane-api/src/infra.rs | 27 ++++++++++++++------------- brane-api/src/packages.rs | 6 +++--- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/brane-api/src/infra.rs b/brane-api/src/infra.rs index f299ee61..d772a9a4 100644 --- a/brane-api/src/infra.rs +++ b/brane-api/src/infra.rs @@ -18,6 +18,7 @@ use brane_cfg::info::Info as _; use brane_cfg::infra::{InfraFile, InfraLocation}; use brane_cfg::node::NodeConfig; use brane_prx::spec::NewPathRequestTlsOptions; +use error_trace::{ErrorTrace as _, trace}; use log::{debug, error}; use specifications::address::Address; use specifications::package::Capability; @@ -47,7 +48,7 @@ pub async fn registries(context: Context) -> Result { let node_config: NodeConfig = match NodeConfig::from_path(&context.node_config_path) { Ok(config) => config, Err(err) => { - error!("Failed to load NodeConfig file: {}", err); + error!("{}", trace!(("Failed to load NodeConfig file"), err)); return Err(warp::reject::custom(Error::SecretError)); }, }; @@ -60,7 +61,7 @@ pub async fn registries(context: Context) -> Result { let infra: InfraFile = match InfraFile::from_path(&node_config.node.central().paths.infra) { Ok(infra) => infra, Err(source) => { - error!("{}", Error::InfrastructureOpenError { path: node_config.node.central().paths.infra.clone(), source }); + error!("{}", Error::InfrastructureOpenError { path: node_config.node.central().paths.infra.clone(), source }.trace()); return Err(warp::reject::custom(Error::SecretError)); }, }; @@ -75,7 +76,7 @@ pub async fn registries(context: Context) -> Result { let body: String = match serde_json::to_string(&locations) { Ok(body) => body, Err(source) => { - error!("{}", Error::SerializeError { what: "list of all registry endpoints", source }); + error!("{}", Error::SerializeError { what: "list of all registry endpoints", source }.trace()); return Err(warp::reject::custom(Error::SecretError)); }, }; @@ -109,7 +110,7 @@ pub async fn get_registry(loc: String, context: Context) -> Result config, Err(err) => { - error!("Failed to load NodeConfig file: {}", err); + error!("{}", trace!(("Failed to load NodeConfig file"), err)); return Err(warp::reject::custom(Error::SecretError)); }, }; @@ -122,7 +123,7 @@ pub async fn get_registry(loc: String, context: Context) -> Result infra, Err(source) => { - error!("{}", Error::InfrastructureOpenError { path: node_config.node.central().paths.infra.clone(), source }); + error!("{}", Error::InfrastructureOpenError { path: node_config.node.central().paths.infra.clone(), source }.trace()); return Err(warp::reject::custom(Error::SecretError)); }, }; @@ -167,7 +168,7 @@ pub async fn get_capabilities(loc: String, context: Context) -> Result config, Err(err) => { - error!("Failed to load NodeConfig file: {}", err); + error!("{}", trace!(("Failed to load NodeConfig file"), err)); return Err(warp::reject::custom(Error::SecretError)); }, }; @@ -180,7 +181,7 @@ pub async fn get_capabilities(loc: String, context: Context) -> Result infra, Err(source) => { - error!("{}", Error::InfrastructureOpenError { path: node_config.node.central().paths.infra.clone(), source }); + error!("{}", Error::InfrastructureOpenError { path: node_config.node.central().paths.infra.clone(), source }.trace()); return Err(warp::reject::custom(Error::SecretError)); }, }; @@ -199,17 +200,17 @@ pub async fn get_capabilities(loc: String, context: Context) -> Result match res { Ok(res) => res, Err(source) => { - error!("{}", Error::RequestError { address: reg_addr, source }); + error!("{}", Error::RequestError { address: reg_addr, source }.trace()); return Err(warp::reject::custom(Error::SecretError)); }, }, Err(source) => { - error!("{}", Error::ProxyError { source }); + error!("{}", Error::ProxyError { source }.trace()); return Err(warp::reject::custom(Error::SecretError)); }, }; if !res.status().is_success() { - error!("{}", Error::RequestFailure { address: reg_addr, code: res.status(), message: res.text().await.ok() }); + error!("{}", Error::RequestFailure { address: reg_addr, code: res.status(), message: res.text().await.ok() }.trace()); return Err(warp::reject::custom(Error::SecretError)); } @@ -217,14 +218,14 @@ pub async fn get_capabilities(loc: String, context: Context) -> Result caps, Err(source) => { - error!("{}", Error::ResponseBodyError { address: reg_addr, source }); + error!("{}", Error::ResponseBodyError { address: reg_addr, source }.trace()); return Err(warp::reject::custom(Error::SecretError)); }, }; let capabilities: HashSet = match serde_json::from_str(&capabilities) { Ok(caps) => caps, Err(source) => { - error!("{}", Error::ResponseParseError { address: reg_addr, raw: capabilities, source }); + error!("{}", Error::ResponseParseError { address: reg_addr, raw: capabilities, source }.trace()); return Err(warp::reject::custom(Error::SecretError)); }, }; @@ -233,7 +234,7 @@ pub async fn get_capabilities(loc: String, context: Context) -> Result body, Err(source) => { - error!("{}", Error::CapabilitiesSerializeError { source }); + error!("{}", Error::CapabilitiesSerializeError { source }.trace()); return Err(warp::reject::custom(Error::SecretError)); }, }; diff --git a/brane-api/src/packages.rs b/brane-api/src/packages.rs index acc5daae..7cd79b8d 100644 --- a/brane-api/src/packages.rs +++ b/brane-api/src/packages.rs @@ -282,7 +282,7 @@ pub async fn download(name: String, version: String, context: Context) -> Result match latest { Some(version) => version, None => { - error!("{}", Error::NoVersionsFound { name }); + error!("{}", Error::NoVersionsFound { name }.trace()); return Err(warp::reject::not_found()); }, } @@ -302,7 +302,7 @@ pub async fn download(name: String, version: String, context: Context) -> Result Ok(file) => { if let Some(rows) = file.rows { if rows.is_empty() { - error!("{}", Error::UnknownPackage { name, version }); + error!("{}", Error::UnknownPackage { name, version }.trace()); return Err(warp::reject::not_found()); } if rows.len() > 1 { @@ -310,7 +310,7 @@ pub async fn download(name: String, version: String, context: Context) -> Result } rows[0].columns[0].as_ref().unwrap().as_text().unwrap().into() } else { - error!("{}", Error::UnknownPackage { name, version }); + error!("{}", Error::UnknownPackage { name, version }.trace()); return Err(warp::reject::not_found()); } },