From 2291c608c86f940ec9236906289d53b9bfd69223 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C5=A1a=20Tomi=C4=87?= Date: Tue, 28 Jan 2025 18:53:55 +0100 Subject: [PATCH] refactor(cli): integrate fs-err library for file operations (#1255) --- Cargo.Bazel.lock | 22 ++++++++++++++++++- Cargo.lock | 5 +++++ rs/cli/src/artifact_downloader.rs | 2 +- rs/cli/src/auth.rs | 4 ++-- rs/cli/src/commands/der_to_principal.rs | 2 +- .../src/commands/update_authorized_subnets.rs | 2 +- rs/cli/src/commands/upgrade.rs | 12 +++++----- rs/cli/src/cordoned_feature_fetcher.rs | 4 ++-- rs/cli/src/discourse_client.rs | 2 +- rs/cli/src/qualification/run_xnet_test.rs | 2 +- rs/cli/src/qualification/util.rs | 14 ++++++------ rs/cli/src/store.rs | 4 ++-- .../unit_tests/cordoned_feature_fetcher.rs | 6 ++--- rs/cli/src/unit_tests/ctx_init.rs | 2 +- rs/cli/src/unit_tests/health_client.rs | 6 ++--- rs/cli/src/unit_tests/node_labels.rs | 6 ++--- rs/ic-management-backend/src/git_ic_repo.rs | 4 ++-- rs/ic-management-backend/src/health.rs | 4 ++-- rs/ic-management-backend/src/node_labels.rs | 4 ++-- rs/ic-management-backend/src/registry.rs | 6 ++--- .../Cargo.toml | 1 + .../src/downloader_loop.rs | 8 +++---- .../multiservice-discovery/Cargo.toml | 1 + .../multiservice-discovery/src/definition.rs | 15 ++++++------- .../multiservice-discovery/src/main.rs | 2 +- .../service-discovery/Cargo.toml | 1 + .../service-discovery/src/file_sd.rs | 2 +- .../service-discovery/src/lib.rs | 2 +- rs/ic-observability/sns-downloader/Cargo.toml | 1 + .../sns-downloader/src/downloader_loop.rs | 8 +++---- rs/slack-notifications/Cargo.toml | 1 + rs/slack-notifications/src/main.rs | 4 ++-- 32 files changed, 94 insertions(+), 65 deletions(-) diff --git a/Cargo.Bazel.lock b/Cargo.Bazel.lock index ba999d7c8..2999aa324 100644 --- a/Cargo.Bazel.lock +++ b/Cargo.Bazel.lock @@ -1,5 +1,5 @@ { - "checksum": "601d274f5413afdb0d91d2bc6012fa2ee15de9b5f6b3cff8d89c08768cdd4184", + "checksum": "cc45b1bfc5914f24e89a7c8c6021bf9e0959d61987b2904e57c93991572fa7c8", "crates": { "actix-codec 0.5.2": { "name": "actix-codec", @@ -34715,6 +34715,10 @@ "id": "crossbeam-channel 0.5.14", "target": "crossbeam_channel" }, + { + "id": "fs-err 3.0.0", + "target": "fs_err" + }, { "id": "futures 0.3.31", "target": "futures" @@ -34837,6 +34841,10 @@ "id": "crossbeam-channel 0.5.14", "target": "crossbeam_channel" }, + { + "id": "fs-err 3.0.0", + "target": "fs_err" + }, { "id": "futures-util 0.3.31", "target": "futures_util" @@ -47497,6 +47505,10 @@ "id": "crossbeam-channel 0.5.14", "target": "crossbeam_channel" }, + { + "id": "fs-err 3.0.0", + "target": "fs_err" + }, { "id": "futures 0.3.31", "target": "futures" @@ -48224,6 +48236,10 @@ "id": "env_logger 0.11.6", "target": "env_logger" }, + { + "id": "fs-err 3.0.0", + "target": "fs_err" + }, { "id": "futures 0.3.31", "target": "futures" @@ -48992,6 +49008,10 @@ "id": "crossbeam-channel 0.5.14", "target": "crossbeam_channel" }, + { + "id": "fs-err 3.0.0", + "target": "fs_err" + }, { "id": "futures-util 0.3.31", "target": "futures_util" diff --git a/Cargo.lock b/Cargo.lock index 76411e15e..7bfcc42a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5943,6 +5943,7 @@ dependencies = [ "crossbeam", "crossbeam-channel", "flate2", + "fs-err", "futures", "futures-util", "humantime", @@ -5972,6 +5973,7 @@ dependencies = [ "clap", "crossbeam", "crossbeam-channel", + "fs-err", "futures-util", "humantime", "multiservice-discovery-shared", @@ -7761,6 +7763,7 @@ dependencies = [ "anyhow", "crossbeam", "crossbeam-channel", + "fs-err", "futures", "ic-interfaces-registry", "ic-metrics", @@ -7889,6 +7892,7 @@ dependencies = [ "clap", "dotenv", "env_logger 0.11.6", + "fs-err", "futures", "ic-agent", "ic-management-types", @@ -8009,6 +8013,7 @@ dependencies = [ "clap", "crossbeam", "crossbeam-channel", + "fs-err", "futures-util", "humantime", "ic-canisters", diff --git a/rs/cli/src/artifact_downloader.rs b/rs/cli/src/artifact_downloader.rs index 0329c23e5..061be0369 100644 --- a/rs/cli/src/artifact_downloader.rs +++ b/rs/cli/src/artifact_downloader.rs @@ -38,7 +38,7 @@ pub trait ArtifactDownloader: Sync + Send { let download_dir = format!("{}/tmp/ic/{}", dirs::home_dir().expect("home_dir is not set").as_path().display(), subdir); let download_dir = Path::new(&download_dir); - std::fs::create_dir_all(download_dir).unwrap_or_else(|_| panic!("create_dir_all failed for {}", download_dir.display())); + fs_err::create_dir_all(download_dir).unwrap_or_else(|_| panic!("create_dir_all failed for {}", download_dir.display())); let download_image = format!("{}/update-img.tar.gz", download_dir.to_str().unwrap()); let download_image = Path::new(&download_image); diff --git a/rs/cli/src/auth.rs b/rs/cli/src/auth.rs index c3a69130c..3088788d2 100644 --- a/rs/cli/src/auth.rs +++ b/rs/cli/src/auth.rs @@ -207,13 +207,13 @@ impl Neuron { let parent = path.parent().ok_or(anyhow::anyhow!("Expected parent to exist"))?; if !parent.exists() { - std::fs::create_dir_all(parent)? + fs_err::create_dir_all(parent)? } let key_pair = rosetta_core::models::Ed25519KeyPair::generate(42); if !path.exists() { - std::fs::write(&path, key_pair.to_pem())?; + fs_err::write(&path, key_pair.to_pem())?; } Ok(path) } diff --git a/rs/cli/src/commands/der_to_principal.rs b/rs/cli/src/commands/der_to_principal.rs index 4663f907c..41890688b 100644 --- a/rs/cli/src/commands/der_to_principal.rs +++ b/rs/cli/src/commands/der_to_principal.rs @@ -16,7 +16,7 @@ impl ExecutableCommand for DerToPrincipal { } async fn execute(&self, _ctx: crate::ctx::DreContext) -> anyhow::Result<()> { - let principal = ic_base_types::PrincipalId::new_self_authenticating(&std::fs::read(&self.path)?); + let principal = ic_base_types::PrincipalId::new_self_authenticating(&fs_err::read(&self.path)?); println!("{}", principal); Ok(()) } diff --git a/rs/cli/src/commands/update_authorized_subnets.rs b/rs/cli/src/commands/update_authorized_subnets.rs index 4d02b89c9..31d95c3fa 100644 --- a/rs/cli/src/commands/update_authorized_subnets.rs +++ b/rs/cli/src/commands/update_authorized_subnets.rs @@ -183,7 +183,7 @@ impl ExecutableCommand for UpdateAuthorizedSubnets { impl UpdateAuthorizedSubnets { fn parse_csv(&self) -> anyhow::Result> { let contents = match &self.path { - Some(p) => std::fs::read_to_string(p)?, + Some(p) => fs_err::read_to_string(p)?, None => { info!("Using embedded version of authorized subnets csv that is added during build time"); DEFAULT_AUTHORIZED_SUBNETS_CSV.to_string() diff --git a/rs/cli/src/commands/upgrade.rs b/rs/cli/src/commands/upgrade.rs index c2499f09b..5d511b5c8 100644 --- a/rs/cli/src/commands/upgrade.rs +++ b/rs/cli/src/commands/upgrade.rs @@ -31,7 +31,7 @@ impl Upgrade { let update_check_path = dirs::cache_dir().expect("Failed to find a cache dir").join("dre_update_check"); if !proceed_with_upgrade { // Check for a new release once per day - if let Ok(metadata) = std::fs::metadata(&update_check_path) { + if let Ok(metadata) = fs_err::metadata(&update_check_path) { let last_check = metadata.modified().unwrap(); let now = std::time::SystemTime::now(); if now.duration_since(last_check).unwrap().as_secs() < 60 * 60 * 24 { @@ -57,7 +57,7 @@ impl Upgrade { .map_err(|e| anyhow::anyhow!("Configuring backend failed: {:?}", e))?; // Touch update check file - std::fs::write(&update_check_path, "").map_err(|e| anyhow::anyhow!("Couldn't touch update check file: {:?}", e))?; + fs_err::write(&update_check_path, "").map_err(|e| anyhow::anyhow!("Couldn't touch update check file: {:?}", e))?; let releases = maybe_configured_backend .fetch() @@ -105,8 +105,8 @@ impl Upgrade { let new_dre_path = tmp_dir.path().join(&asset.name); let asset_path = tmp_dir.path().join("asset"); - let asset_file = std::fs::File::create(&asset_path).map_err(|e| anyhow::anyhow!("Couldn't create file: {:?}", e))?; - let new_dre_file = std::fs::File::create(&new_dre_path).map_err(|e| anyhow::anyhow!("Couldn't create file: {:?}", e))?; + let asset_file = fs_err::File::create(&asset_path).map_err(|e| anyhow::anyhow!("Couldn't create file: {:?}", e))?; + let new_dre_file = fs_err::File::create(&new_dre_path).map_err(|e| anyhow::anyhow!("Couldn't create file: {:?}", e))?; self_update::Download::from_url(&asset.download_url) .show_progress(true) @@ -116,7 +116,7 @@ impl Upgrade { info!("Asset downloaded successfully"); let value: Value = - serde_json::from_str(&std::fs::read_to_string(&asset_path).unwrap()).map_err(|e| anyhow::anyhow!("Couldn't open asset: {:?}", e))?; + serde_json::from_str(&fs_err::read_to_string(&asset_path).unwrap()).map_err(|e| anyhow::anyhow!("Couldn't open asset: {:?}", e))?; let download_url = match value.get("browser_download_url") { Some(Value::String(d)) => d, @@ -134,7 +134,7 @@ impl Upgrade { // Since its possible to upgrade to an older version // remove the metafile so that the check will be run // with the new version again - std::fs::remove_file(&update_check_path)?; + fs_err::remove_file(&update_check_path)?; Ok(UpdateStatus::Updated(release.version.clone())) } diff --git a/rs/cli/src/cordoned_feature_fetcher.rs b/rs/cli/src/cordoned_feature_fetcher.rs index e439164c0..8f64b5e6f 100644 --- a/rs/cli/src/cordoned_feature_fetcher.rs +++ b/rs/cli/src/cordoned_feature_fetcher.rs @@ -50,7 +50,7 @@ impl CordonedFeatureFetcherImpl { .bytes() .await?; - if let Err(e) = std::fs::write(&self.local_copy, &bytes) { + if let Err(e) = fs_err::write(&self.local_copy, &bytes) { warn!( "Failed to update cordoned features cache on path `{}` due to: {:?}", self.local_copy.display(), @@ -63,7 +63,7 @@ impl CordonedFeatureFetcherImpl { } fn fetch_from_file(&self) -> anyhow::Result> { - let contents = std::fs::read(&self.local_copy)?; + let contents = fs_err::read(&self.local_copy)?; self.parse(&contents) } diff --git a/rs/cli/src/discourse_client.rs b/rs/cli/src/discourse_client.rs index e2989179f..97d279556 100644 --- a/rs/cli/src/discourse_client.rs +++ b/rs/cli/src/discourse_client.rs @@ -257,7 +257,7 @@ fn get_subnet_topics_map() -> BTreeMap { } fn get_subnet_topics_from_path(path: &Path) -> anyhow::Result> { - let file = std::fs::File::open(path)?; + let file = fs_err::File::open(path)?; serde_json::from_reader(file).map_err(anyhow::Error::from) } diff --git a/rs/cli/src/qualification/run_xnet_test.rs b/rs/cli/src/qualification/run_xnet_test.rs index bc857e383..64d040901 100644 --- a/rs/cli/src/qualification/run_xnet_test.rs +++ b/rs/cli/src/qualification/run_xnet_test.rs @@ -42,7 +42,7 @@ impl Step for RunXnetTest { if !key.exists() { anyhow::bail!("Principal key for xnet testing not found at {}", key.display()); } - let file = std::fs::File::open(&key)?; + let file = fs_err::File::open(&key)?; file.set_permissions(PermissionsExt::from_mode(0o400))?; let e2e_bin = ctx.download_executable(E2E_TEST_DRIVER, &self.version).await?; diff --git a/rs/cli/src/qualification/util.rs b/rs/cli/src/qualification/util.rs index 27c24460c..50d2d5694 100644 --- a/rs/cli/src/qualification/util.rs +++ b/rs/cli/src/qualification/util.rs @@ -34,7 +34,7 @@ pub struct StepCtx { impl StepCtx { pub fn new(dre_ctx: DreContext, artifacts: Option, from_version: String, to_version: String) -> anyhow::Result { let artifacts_of_run = artifacts.as_ref().map(|t| { - if let Err(e) = std::fs::create_dir_all(t) { + if let Err(e) = fs_err::create_dir_all(t) { panic!("Couldn't create dir {}: {:?}", t.display(), e) } t.clone() @@ -62,13 +62,13 @@ impl StepCtx { pub async fn download_canister(&self, canister: &str, version: &str) -> anyhow::Result { let cache = dirs::cache_dir().ok_or(anyhow::anyhow!("Can't cache dir"))?.join(IC_EXECUTABLES_DIR); if !cache.exists() { - std::fs::create_dir_all(&cache)?; + fs_err::create_dir_all(&cache)?; } let artifact_path = cache.join(format!("{}/{}.{}", canister, canister, version)); let artifact_dir = artifact_path.parent().unwrap(); if !artifact_dir.exists() { - std::fs::create_dir(artifact_dir)?; + fs_err::create_dir(artifact_dir)?; } let canister_path = PathBuf::from_str(&format!("{}.wasm", artifact_path.display())).map_err(|e| anyhow::anyhow!(e))?; @@ -84,7 +84,7 @@ impl StepCtx { let response = self.client.get(&url).send().await?.error_for_status()?.bytes().await?; let mut d = GzDecoder::new(&response[..]); let mut collector: Vec = vec![]; - let mut file = std::fs::File::create(&canister_path)?; + let mut file = fs_err::File::create(&canister_path)?; d.read_to_end(&mut collector)?; file.write_all(&collector)?; @@ -95,13 +95,13 @@ impl StepCtx { pub async fn download_executable(&self, executable: &str, version: &str) -> anyhow::Result { let cache = dirs::cache_dir().ok_or(anyhow::anyhow!("Can't cache dir"))?.join(IC_EXECUTABLES_DIR); if !cache.exists() { - std::fs::create_dir_all(&cache)?; + fs_err::create_dir_all(&cache)?; } let exe_path = cache.join(format!("{}/{}.{}", executable, executable, version)); let artifact_dir = exe_path.parent().unwrap(); if !artifact_dir.exists() { - std::fs::create_dir(artifact_dir)?; + fs_err::create_dir(artifact_dir)?; } if exe_path.exists() && exe_path.is_file() { @@ -128,7 +128,7 @@ impl StepCtx { let response = self.client.get(&url).send().await?.error_for_status()?.bytes().await?; let mut d = GzDecoder::new(&response[..]); let mut collector: Vec = vec![]; - let mut file = std::fs::File::create(&exe_path)?; + let mut file = fs_err::File::create(&exe_path)?; d.read_to_end(&mut collector)?; file.write_all(&collector)?; diff --git a/rs/cli/src/store.rs b/rs/cli/src/store.rs index b2d96d8cd..a47922be5 100644 --- a/rs/cli/src/store.rs +++ b/rs/cli/src/store.rs @@ -1,5 +1,3 @@ -use std::{io::Read, os::unix::fs::PermissionsExt, path::PathBuf, sync::Arc, time::Duration}; - use flate2::bufread::GzDecoder; use ic_canisters::governance::governance_canister_version; use ic_management_backend::{ @@ -11,6 +9,8 @@ use ic_management_backend::{ use ic_management_types::Network; use ic_registry_local_registry::LocalRegistry; use log::{debug, info, warn}; +use std::os::unix::fs::PermissionsExt; +use std::{io::Read, path::PathBuf, sync::Arc, time::Duration}; use crate::{ auth::Neuron, diff --git a/rs/cli/src/unit_tests/cordoned_feature_fetcher.rs b/rs/cli/src/unit_tests/cordoned_feature_fetcher.rs index 748286b73..2d8a5a28e 100644 --- a/rs/cli/src/unit_tests/cordoned_feature_fetcher.rs +++ b/rs/cli/src/unit_tests/cordoned_feature_fetcher.rs @@ -8,7 +8,7 @@ use serde_yaml::Mapping; use crate::store::Store; fn ensure_empty(file: PathBuf) { - std::fs::write(file, "").unwrap(); + fs_err::write(file, "").unwrap(); } fn write_to_cache(contents: &[CordonedFeature], path: PathBuf) { @@ -16,7 +16,7 @@ fn write_to_cache(contents: &[CordonedFeature], path: PathBuf) { mapping.insert("features".into(), serde_yaml::to_value(contents).unwrap()); let root = serde_yaml::Value::Mapping(mapping); - std::fs::write(path, serde_yaml::to_string(&root).unwrap()).unwrap() + fs_err::write(path, serde_yaml::to_string(&root).unwrap()).unwrap() } #[derive(Debug)] @@ -122,7 +122,7 @@ fn cordoned_feature_fetcher_tests() { } let cordoned_features = maybe_cordoned_features.unwrap(); - let cache_contents = std::fs::read_to_string(store.cordoned_features_file_outer().unwrap()).unwrap(); + let cache_contents = fs_err::read_to_string(store.cordoned_features_file_outer().unwrap()).unwrap(); let cordoned_features_from_cache = cordoned_feature_fetcher.parse_outer(cache_contents.as_bytes()).unwrap(); if !cordoned_features.eq(&cordoned_features_from_cache) { diff --git a/rs/cli/src/unit_tests/ctx_init.rs b/rs/cli/src/unit_tests/ctx_init.rs index 3a868d0de..24ba06473 100644 --- a/rs/cli/src/unit_tests/ctx_init.rs +++ b/rs/cli/src/unit_tests/ctx_init.rs @@ -20,7 +20,7 @@ fn status_file_path() -> PathBuf { fn get_deleted_status_file() -> PathBuf { let status_file = status_file_path(); if status_file.exists() { - std::fs::remove_file(&status_file).unwrap() + fs_err::remove_file(&status_file).unwrap() } status_file } diff --git a/rs/cli/src/unit_tests/health_client.rs b/rs/cli/src/unit_tests/health_client.rs index 24de30185..8156b4357 100644 --- a/rs/cli/src/unit_tests/health_client.rs +++ b/rs/cli/src/unit_tests/health_client.rs @@ -101,8 +101,8 @@ fn health_client_tests() { let cache_path = store.node_health_file_outer(&network).unwrap(); match &scenario.cache { - Some(cache) => std::fs::write(&cache_path, serde_json::to_string_pretty(cache).unwrap()).unwrap(), - None => std::fs::write(&cache_path, "").unwrap(), + Some(cache) => fs_err::write(&cache_path, serde_json::to_string_pretty(cache).unwrap()).unwrap(), + None => fs_err::write(&cache_path, "").unwrap(), } let health_client = store.health_client(&network).unwrap(); @@ -122,7 +122,7 @@ fn health_client_tests() { } let nodes_info = maybe_nodes_info.unwrap(); - let contents = std::fs::read_to_string(&cache_path).unwrap(); + let contents = fs_err::read_to_string(&cache_path).unwrap(); let cached: Vec = serde_json::from_str(&contents).unwrap(); if !PartialEq::eq(&cached, &nodes_info) { diff --git a/rs/cli/src/unit_tests/node_labels.rs b/rs/cli/src/unit_tests/node_labels.rs index 2b9017469..9cfe909f7 100644 --- a/rs/cli/src/unit_tests/node_labels.rs +++ b/rs/cli/src/unit_tests/node_labels.rs @@ -7,7 +7,7 @@ use itertools::Itertools; use crate::store::Store; fn ensure_empty(path: PathBuf) { - std::fs::write(path, "").unwrap() + fs_err::write(path, "").unwrap() } fn write_cache(guests: &[Guest], path: PathBuf) { @@ -24,7 +24,7 @@ fn write_cache(guests: &[Guest], path: PathBuf) { let mut root = serde_yaml::Mapping::new(); root.insert("data".into(), data.into()); - std::fs::write(path, serde_yaml::to_string(&root).unwrap()).unwrap() + fs_err::write(path, serde_yaml::to_string(&root).unwrap()).unwrap() } #[derive(Debug)] @@ -146,7 +146,7 @@ fn test_node_labels() { } let labels = maybe_labels.unwrap(); - let content = std::fs::read_to_string(labels_path.clone()).unwrap(); + let content = fs_err::read_to_string(labels_path.clone()).unwrap(); let labels_from_cache = node_labels::parse_data(content).unwrap(); if !labels.eq(&labels_from_cache) { failed_scenarios.push((labels, scenario)); diff --git a/rs/ic-management-backend/src/git_ic_repo.rs b/rs/ic-management-backend/src/git_ic_repo.rs index 9433ca65a..53d20405d 100644 --- a/rs/ic-management-backend/src/git_ic_repo.rs +++ b/rs/ic-management-backend/src/git_ic_repo.rs @@ -35,7 +35,7 @@ impl IcRepo { info!("IC git repo path: {}, lock file path: {}", &repo_path.display(), &lock_file_path); if !repo_path.exists() { - std::fs::create_dir_all(&repo_path).map_err(|e| IoError::Io { + fs_err::create_dir_all(&repo_path).map_err(|e| IoError::Io { source: e, path: repo_path.to_path_buf(), })?; @@ -60,7 +60,7 @@ impl IcRepo { Ok(output) => output.status.success(), Err(_) => false, } { - std::fs::remove_dir_all(&repo_path).map_err(|e| IoError::Io { + fs_err::remove_dir_all(&repo_path).map_err(|e| IoError::Io { source: e, path: repo_path.to_path_buf(), })?; diff --git a/rs/ic-management-backend/src/health.rs b/rs/ic-management-backend/src/health.rs index 62142f8c4..ac46b920a 100644 --- a/rs/ic-management-backend/src/health.rs +++ b/rs/ic-management-backend/src/health.rs @@ -38,7 +38,7 @@ impl HealthStatusQuerier for HealthClient { (true, None) => Err(anyhow::anyhow!("Cannot run offline with no local cache destination")), // Should load from local cache (true, Some(path)) => { - let contents = std::fs::read_to_string(&path)?; + let contents = fs_err::read_to_string(&path)?; serde_json::from_str(&contents) .map_err(|e| anyhow::anyhow!("Failed to deserialize from local cache on path `{}` due to: {:?}", path.display(), e)) } @@ -53,7 +53,7 @@ impl HealthStatusQuerier for HealthClient { if let Some(path) = local_cache { let contents = serde_json::to_string_pretty(&nodes)?; - std::fs::write(&path, &contents) + fs_err::write(&path, &contents) .map_err(|e| anyhow::anyhow!("Failed to update local cache on path `{}` due to: {:?}", path.display(), e))?; } Ok(nodes) diff --git a/rs/ic-management-backend/src/node_labels.rs b/rs/ic-management-backend/src/node_labels.rs index df05c8cdf..5e2fd6723 100644 --- a/rs/ic-management-backend/src/node_labels.rs +++ b/rs/ic-management-backend/src/node_labels.rs @@ -12,14 +12,14 @@ pub async fn query_guests(network: &String, local_cache: Option, offlin Some(path) => { info!("Loading labels from cache `{}`", path.display()); - let contents = std::fs::read_to_string(path)?; + let contents = fs_err::read_to_string(path)?; parse_data(contents) } } } else { let data = fetch_data(network).await?; if let Some(path) = local_cache { - std::fs::write(path, &data)?; + fs_err::write(path, &data)?; } parse_data(data) } diff --git a/rs/ic-management-backend/src/registry.rs b/rs/ic-management-backend/src/registry.rs index 794c7753c..4b0edf23a 100644 --- a/rs/ic-management-backend/src/registry.rs +++ b/rs/ic-management-backend/src/registry.rs @@ -910,7 +910,7 @@ pub fn local_cache_path() -> PathBuf { } .join("ic-registry-cache"); if !path.exists() { - std::fs::create_dir_all(&path).expect("failed to create local cache directory"); + fs_err::create_dir_all(&path).expect("failed to create local cache directory"); } path } @@ -918,7 +918,7 @@ pub fn local_cache_path() -> PathBuf { pub fn local_registry_path(network: &Network) -> PathBuf { let path = local_cache_path().join(Path::new(network.name.as_str())).join("local_registry"); if !path.exists() { - std::fs::create_dir_all(&path).expect("failed to create local registry directory"); + fs_err::create_dir_all(&path).expect("failed to create local registry directory"); } path } @@ -981,7 +981,7 @@ pub async fn sync_local_store_with_path(target_network: &Network, local_registry target_network.name, local_registry_path.display() ); - std::fs::remove_dir_all(local_registry_path)?; + fs_err::remove_dir_all(local_registry_path)?; panic!( "Registry version local {} > remote {}, this should never happen", local_latest_version, remote_version diff --git a/rs/ic-observability/multiservice-discovery-downloader/Cargo.toml b/rs/ic-observability/multiservice-discovery-downloader/Cargo.toml index aa9335a75..48be23b84 100644 --- a/rs/ic-observability/multiservice-discovery-downloader/Cargo.toml +++ b/rs/ic-observability/multiservice-discovery-downloader/Cargo.toml @@ -10,6 +10,7 @@ license.workspace = true clap = { workspace = true } crossbeam-channel = { workspace = true } crossbeam = { workspace = true } +fs-err = { workspace = true } futures-util = { workspace = true } humantime = { workspace = true } multiservice-discovery-shared = { path = "../multiservice-discovery-shared" } diff --git a/rs/ic-observability/multiservice-discovery-downloader/src/downloader_loop.rs b/rs/ic-observability/multiservice-discovery-downloader/src/downloader_loop.rs index 59c8b3153..f616c552c 100644 --- a/rs/ic-observability/multiservice-discovery-downloader/src/downloader_loop.rs +++ b/rs/ic-observability/multiservice-discovery-downloader/src/downloader_loop.rs @@ -99,9 +99,9 @@ fn generate_config(cli: &CliArgs, targets: Vec, logger: Logger) { crate::Generator::Metric => JobType::all_for_ic_nodes(), }; - if std::fs::metadata(&cli.output_dir).is_err() { - std::fs::create_dir_all(cli.output_dir.parent().unwrap()).unwrap(); - std::fs::File::create(&cli.output_dir).unwrap(); + if fs_err::metadata(&cli.output_dir).is_err() { + fs_err::create_dir_all(cli.output_dir.parent().unwrap()).unwrap(); + fs_err::File::create(&cli.output_dir).unwrap(); } for job in &jobs { @@ -156,7 +156,7 @@ fn generate_config(cli: &CliArgs, targets: Vec, logger: Logger) { let path = cli.output_dir.join(format!("{}.json", job)); - match std::fs::write(&path, config) { + match fs_err::write(&path, config) { Ok(_) => {} Err(e) => debug!(logger, "Failed to write config to file"; "err" => format!("{}", e)), } diff --git a/rs/ic-observability/multiservice-discovery/Cargo.toml b/rs/ic-observability/multiservice-discovery/Cargo.toml index fca372b0d..843234fe8 100644 --- a/rs/ic-observability/multiservice-discovery/Cargo.toml +++ b/rs/ic-observability/multiservice-discovery/Cargo.toml @@ -11,6 +11,7 @@ base64 = { workspace = true } clap = { workspace = true } crossbeam = { workspace = true } crossbeam-channel = { workspace = true } +fs-err = { workspace = true } futures-util = { workspace = true } humantime = { workspace = true } ic-crypto-utils-threshold-sig-der = { workspace = true } diff --git a/rs/ic-observability/multiservice-discovery/src/definition.rs b/rs/ic-observability/multiservice-discovery/src/definition.rs index e171f8922..8ad19bcce 100644 --- a/rs/ic-observability/multiservice-discovery/src/definition.rs +++ b/rs/ic-observability/multiservice-discovery/src/definition.rs @@ -20,7 +20,6 @@ use std::collections::HashSet; use std::error::Error; use std::fmt::Debug; use std::fmt::{Display, Error as FmtError, Formatter}; -use std::fs; use std::io::Write; use std::net::SocketAddr; use std::sync::Arc; @@ -86,8 +85,8 @@ impl PartialEq for Definition { impl From for Definition { fn from(fs_definition: FSDefinition) -> Self { - if std::fs::metadata(&fs_definition.registry_path).is_err() { - std::fs::create_dir_all(fs_definition.registry_path.clone()).unwrap(); + if fs_err::metadata(&fs_definition.registry_path).is_err() { + fs_err::create_dir_all(fs_definition.registry_path.clone()).unwrap(); } let log = make_logger(); Self { @@ -203,12 +202,12 @@ impl Definition { poll_interval: Duration, registry_query_timeout: Duration, ) -> Self { - let global_registry_path = std::fs::canonicalize(global_registry_path).expect("Invalid global registry path"); + let global_registry_path = fs_err::canonicalize(global_registry_path).expect("Invalid global registry path"); // The path needs to be sanitized otherwise any file in the environment can be overwritten, let sanitized_name = name.replace(['.', '/'], "_"); let registry_path = global_registry_path.join(sanitized_name); - if std::fs::metadata(®istry_path).is_err() { - std::fs::create_dir_all(registry_path.clone()).unwrap(); + if fs_err::metadata(®istry_path).is_err() { + fs_err::create_dir_all(registry_path.clone()).unwrap(); } Self { nns_urls, @@ -511,7 +510,7 @@ impl DefinitionsSupervisor { pub(crate) async fn load_or_create_defs(&self, metrics: RunningDefinitionsMetrics) -> Result<(), Box> { if let Some(networks_state_file) = self.networks_state_file.clone() { if networks_state_file.exists() { - let file_content = fs::read_to_string(networks_state_file.clone())?; + let file_content = fs_err::read_to_string(networks_state_file.clone())?; let initial_definitions: Vec = serde_json::from_str(&file_content)?; let names = initial_definitions.iter().map(|def| def.name.clone()).collect::>(); info!(self.log, "Definitions loaded from {:?}:\n{:?}", networks_state_file.as_path(), names); @@ -532,7 +531,7 @@ impl DefinitionsSupervisor { pub(crate) async fn persist_defs(&self, existing: &mut BTreeMap) -> Result<(), Box> { if let Some(networks_state_file) = self.networks_state_file.clone() { retry::retry(retry::delay::Exponential::from_millis(10).take(5), || { - std::fs::OpenOptions::new() + fs_err::OpenOptions::new() .create(true) .truncate(true) .write(true) diff --git a/rs/ic-observability/multiservice-discovery/src/main.rs b/rs/ic-observability/multiservice-discovery/src/main.rs index 8c5807c9e..5b7548cc5 100644 --- a/rs/ic-observability/multiservice-discovery/src/main.rs +++ b/rs/ic-observability/multiservice-discovery/src/main.rs @@ -96,7 +96,7 @@ fn main() { Err(e) => { error!(log, "Failed to load or create definitions, deleting the state file."); if let Some(file) = &cli_args.networks_state_file { - if let Err(e) = std::fs::remove_file(file) { + if let Err(e) = fs_err::remove_file(file) { error!(log, "Failed to delete the state file"; "error" => format!("{:?}", e)); } } diff --git a/rs/ic-observability/service-discovery/Cargo.toml b/rs/ic-observability/service-discovery/Cargo.toml index 7e7d689de..1f596d2cd 100644 --- a/rs/ic-observability/service-discovery/Cargo.toml +++ b/rs/ic-observability/service-discovery/Cargo.toml @@ -10,6 +10,7 @@ license.workspace = true anyhow = { workspace = true } crossbeam = { workspace = true } crossbeam-channel = { workspace = true } +fs-err = { workspace = true } futures = { workspace = true } ic-interfaces-registry = { workspace = true } ic-metrics = { workspace = true } diff --git a/rs/ic-observability/service-discovery/src/file_sd.rs b/rs/ic-observability/service-discovery/src/file_sd.rs index 5112760c3..a9a675a10 100644 --- a/rs/ic-observability/service-discovery/src/file_sd.rs +++ b/rs/ic-observability/service-discovery/src/file_sd.rs @@ -39,7 +39,7 @@ impl FileSd { } let job_path = self.base_directory.join(job.to_string()); if !job_path.is_dir() { - std::fs::create_dir(&job_path)?; + fs_err::create_dir(&job_path)?; } let target_path = job_path.join("ic_service_discovery.json"); diff --git a/rs/ic-observability/service-discovery/src/lib.rs b/rs/ic-observability/service-discovery/src/lib.rs index 103b5f2d7..ae0233a38 100644 --- a/rs/ic-observability/service-discovery/src/lib.rs +++ b/rs/ic-observability/service-discovery/src/lib.rs @@ -155,7 +155,7 @@ impl IcServiceDiscoveryImpl { /// lifetime of a service instance. I.e., removing an IC as a scrape target /// requires rebooting the service. pub fn load_new_ics(&self, log: Logger) -> Result<(), IcServiceDiscoveryError> { - let paths = std::fs::read_dir(&self.ic_scraping_targets_dir)?; + let paths = fs_err::read_dir(&self.ic_scraping_targets_dir)?; let mut registries_lock_guard = self.registries.write().unwrap(); for path in paths { let path = path?; diff --git a/rs/ic-observability/sns-downloader/Cargo.toml b/rs/ic-observability/sns-downloader/Cargo.toml index b18cc056e..3cac1f1b6 100644 --- a/rs/ic-observability/sns-downloader/Cargo.toml +++ b/rs/ic-observability/sns-downloader/Cargo.toml @@ -10,6 +10,7 @@ license.workspace = true clap = { workspace = true } crossbeam = { workspace = true } crossbeam-channel = { workspace = true } +fs-err = { workspace = true } futures-util = { workspace = true } humantime = { workspace = true } multiservice-discovery-shared = { path = "../multiservice-discovery-shared" } diff --git a/rs/ic-observability/sns-downloader/src/downloader_loop.rs b/rs/ic-observability/sns-downloader/src/downloader_loop.rs index d99c8decb..72e6acace 100644 --- a/rs/ic-observability/sns-downloader/src/downloader_loop.rs +++ b/rs/ic-observability/sns-downloader/src/downloader_loop.rs @@ -129,9 +129,9 @@ pub async fn run_downloader_loop(logger: Logger, cli: CliArgs, stop_signal: Rece } fn generate_config(cli: &CliArgs, targets: Vec, logger: Logger) { - if std::fs::metadata(&cli.output_dir).is_err() { - std::fs::create_dir_all(cli.output_dir.parent().unwrap()).unwrap(); - std::fs::File::create(&cli.output_dir).unwrap(); + if fs_err::metadata(&cli.output_dir).is_err() { + fs_err::create_dir_all(cli.output_dir.parent().unwrap()).unwrap(); + fs_err::File::create(&cli.output_dir).unwrap(); } let config = SnsCanisterConfigStructure { @@ -142,7 +142,7 @@ fn generate_config(cli: &CliArgs, targets: Vec, logger: Logger) { } .build(targets); let path = cli.output_dir.join("canisters.json"); - match std::fs::write(path, config) { + match fs_err::write(path, config) { Ok(_) => {} Err(e) => debug!(logger, "Failed to write config to file"; "err" => format!("{}", e)), } diff --git a/rs/slack-notifications/Cargo.toml b/rs/slack-notifications/Cargo.toml index e14c6a687..31f838515 100644 --- a/rs/slack-notifications/Cargo.toml +++ b/rs/slack-notifications/Cargo.toml @@ -14,6 +14,7 @@ anyhow = { workspace = true } candid = { workspace = true } dotenv = { workspace = true } env_logger = { workspace = true } +fs-err = { workspace = true } futures = { workspace = true } ic-agent = { workspace = true } ic-management-types = { workspace = true } diff --git a/rs/slack-notifications/src/main.rs b/rs/slack-notifications/src/main.rs index 1c69bd081..4c95dcf6b 100644 --- a/rs/slack-notifications/src/main.rs +++ b/rs/slack-notifications/src/main.rs @@ -72,7 +72,7 @@ impl ProposalCheckpointStore { pub fn new(name: &str) -> anyhow::Result { let file_path = format!("checkpoint_{name}.json"); if std::path::Path::new(&file_path).exists() { - let checkpoint = serde_json::from_str::(&std::fs::read_to_string(file_path)?)?; + let checkpoint = serde_json::from_str::(&fs_err::read_to_string(file_path)?)?; Ok(Self { file_path: format!("checkpoint_{name}.json"), checkpoint, @@ -92,7 +92,7 @@ impl ProposalCheckpointStore { fn save(&mut self, checkpoint: ProposalCheckpoint) -> anyhow::Result<()> { self.checkpoint = checkpoint; retry::retry(retry::delay::Exponential::from_millis(10).take(5), || { - std::fs::OpenOptions::new() + fs_err::OpenOptions::new() .create(true) .truncate(true) .write(true)