diff --git a/Cargo.lock b/Cargo.lock index ba811d48..ae421883 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,7 +82,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "220044e6a1bb31ddee4e3db724d29767f352de47445a6cd75e1a173142136c83" dependencies = [ "nom", - "vte", + "vte 0.10.1", ] [[package]] @@ -155,6 +155,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "async-broadcast" version = "0.7.1" @@ -665,7 +671,7 @@ dependencies = [ "crossterm", "strum 0.26.3", "strum_macros 0.26.4", - "unicode-width", + "unicode-width 0.1.13", ] [[package]] @@ -686,7 +692,7 @@ dependencies = [ "encode_unicode", "lazy_static", "libc", - "unicode-width", + "unicode-width 0.1.13", "windows-sys 0.52.0", ] @@ -1641,6 +1647,20 @@ dependencies = [ "serde", ] +[[package]] +name = "indicatif" +version = "0.17.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" +dependencies = [ + "console", + "number_prefix", + "portable-atomic", + "unicode-width 0.2.0", + "vt100", + "web-time", +] + [[package]] name = "inout" version = "0.1.3" @@ -1896,7 +1916,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -2083,6 +2103,12 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + [[package]] name = "numtoa" version = "0.1.0" @@ -2394,6 +2420,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "portable-atomic" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" + [[package]] name = "powerfmt" version = "0.2.0" @@ -3267,6 +3299,7 @@ dependencies = [ "futures", "helm-sys", "indexmap 2.5.0", + "indicatif", "k8s-openapi", "kube", "rand 0.8.5", @@ -3282,6 +3315,7 @@ dependencies = [ "tera", "tokio", "tracing", + "tracing-indicatif", "url", "urlencoding", "utoipa", @@ -3438,6 +3472,7 @@ dependencies = [ "dotenvy", "futures", "indexmap 2.5.0", + "indicatif", "lazy_static", "libc", "rand 0.8.5", @@ -3453,6 +3488,7 @@ dependencies = [ "termion", "tokio", "tracing", + "tracing-indicatif", "tracing-subscriber", "urlencoding", ] @@ -3930,6 +3966,18 @@ dependencies = [ "valuable", ] +[[package]] +name = "tracing-indicatif" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8201ca430e0cd893ef978226fd3516c06d9c494181c8bf4e5b32e30ed4b40aa1" +dependencies = [ + "indicatif", + "tracing", + "tracing-core", + "tracing-subscriber", +] + [[package]] name = "tracing-log" version = "0.2.0" @@ -4117,6 +4165,12 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + [[package]] name = "unicode-xid" version = "0.2.5" @@ -4228,13 +4282,36 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "vt100" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84cd863bf0db7e392ba3bd04994be3473491b31e66340672af5d11943c6274de" +dependencies = [ + "itoa", + "log", + "unicode-width 0.1.13", + "vte 0.11.1", +] + [[package]] name = "vte" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6cbce692ab4ca2f1f3047fcf732430249c0e971bfdd2b234cf2c47ad93af5983" dependencies = [ - "arrayvec", + "arrayvec 0.5.2", + "utf8parse", + "vte_generate_state_changes", +] + +[[package]] +name = "vte" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5022b5fbf9407086c180e9557be968742d839e68346af7792b8592489732197" +dependencies = [ + "arrayvec 0.7.6", "utf8parse", "vte_generate_state_changes", ] @@ -4413,7 +4490,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/Cargo.nix b/Cargo.nix index ef95c5d6..0224a012 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -332,7 +332,7 @@ rec { } { name = "vte"; - packageId = "vte"; + packageId = "vte 0.10.1"; } ]; features = { @@ -492,7 +492,7 @@ rec { }; resolvedDefaultFeatures = [ "derive" "derive_arbitrary" ]; }; - "arrayvec" = rec { + "arrayvec 0.5.2" = rec { crateName = "arrayvec"; version = "0.5.2"; edition = "2018"; @@ -505,6 +505,21 @@ rec { "serde" = [ "dep:serde" ]; }; }; + "arrayvec 0.7.6" = rec { + crateName = "arrayvec"; + version = "0.7.6"; + edition = "2018"; + sha256 = "0l1fz4ccgv6pm609rif37sl5nv5k6lbzi7kkppgzqzh1vwix20kw"; + authors = [ + "bluss" + ]; + features = { + "borsh" = [ "dep:borsh" ]; + "default" = [ "std" ]; + "serde" = [ "dep:serde" ]; + "zeroize" = [ "dep:zeroize" ]; + }; + }; "async-broadcast" = rec { crateName = "async-broadcast"; version = "0.7.1"; @@ -2276,7 +2291,7 @@ rec { } { name = "unicode-width"; - packageId = "unicode-width"; + packageId = "unicode-width 0.1.13"; } ]; features = { @@ -2339,7 +2354,7 @@ rec { } { name = "unicode-width"; - packageId = "unicode-width"; + packageId = "unicode-width 0.1.13"; optional = true; } { @@ -5257,6 +5272,55 @@ rec { }; resolvedDefaultFeatures = [ "default" "serde" "std" ]; }; + "indicatif" = rec { + crateName = "indicatif"; + version = "0.17.11"; + edition = "2021"; + sha256 = "0db2b2r79r9x8x4lysq1ci9xm13c0xg0sqn3z960yh2bk2430fqq"; + dependencies = [ + { + name = "console"; + packageId = "console"; + usesDefaultFeatures = false; + features = [ "ansi-parsing" ]; + } + { + name = "number_prefix"; + packageId = "number_prefix"; + } + { + name = "portable-atomic"; + packageId = "portable-atomic"; + } + { + name = "unicode-width"; + packageId = "unicode-width 0.2.0"; + optional = true; + } + { + name = "vt100"; + packageId = "vt100"; + optional = true; + } + { + name = "web-time"; + packageId = "web-time"; + target = { target, features }: ("wasm32" == target."arch" or null); + } + ]; + features = { + "default" = [ "unicode-width" "console/unicode-width" ]; + "futures" = [ "dep:futures-core" ]; + "improved_unicode" = [ "unicode-segmentation" "unicode-width" "console/unicode-width" ]; + "in_memory" = [ "vt100" ]; + "rayon" = [ "dep:rayon" ]; + "tokio" = [ "dep:tokio" ]; + "unicode-segmentation" = [ "dep:unicode-segmentation" ]; + "unicode-width" = [ "dep:unicode-width" ]; + "vt100" = [ "dep:vt100" ]; + }; + resolvedDefaultFeatures = [ "default" "in_memory" "unicode-width" "vt100" ]; + }; "inout" = rec { crateName = "inout"; version = "0.1.3"; @@ -6214,7 +6278,7 @@ rec { } { name = "windows-targets"; - packageId = "windows-targets 0.48.5"; + packageId = "windows-targets 0.52.6"; target = { target, features }: (target."windows" or false); } ]; @@ -6725,6 +6789,19 @@ rec { }; resolvedDefaultFeatures = [ "proc-macro-crate" "std" ]; }; + "number_prefix" = rec { + crateName = "number_prefix"; + version = "0.4.0"; + edition = "2015"; + sha256 = "1wvh13wvlajqxkb1filsfzbrnq0vrmrw298v2j3sy82z1rm282w3"; + authors = [ + "Benjamin Sago " + ]; + features = { + "default" = [ "std" ]; + }; + resolvedDefaultFeatures = [ "default" "std" ]; + }; "numtoa" = rec { crateName = "numtoa"; version = "0.1.0"; @@ -7704,6 +7781,19 @@ rec { ]; }; + "portable-atomic" = rec { + crateName = "portable-atomic"; + version = "1.11.0"; + edition = "2018"; + sha256 = "0glb2wngflvfmg789qbf6dbnwcf6ai212fs7n0lf1c66rd49n3im"; + libName = "portable_atomic"; + features = { + "critical-section" = [ "dep:critical-section" ]; + "default" = [ "fallback" ]; + "serde" = [ "dep:serde" ]; + }; + resolvedDefaultFeatures = [ "default" "fallback" ]; + }; "powerfmt" = rec { crateName = "powerfmt"; version = "0.2.0"; @@ -10584,6 +10674,10 @@ rec { packageId = "indexmap 2.5.0"; features = [ "serde" ]; } + { + name = "indicatif"; + packageId = "indicatif"; + } { name = "k8s-openapi"; packageId = "k8s-openapi"; @@ -10651,6 +10745,10 @@ rec { name = "tracing"; packageId = "tracing"; } + { + name = "tracing-indicatif"; + packageId = "tracing-indicatif"; + } { name = "url"; packageId = "url"; @@ -11297,6 +11395,10 @@ rec { packageId = "indexmap 2.5.0"; features = [ "serde" ]; } + { + name = "indicatif"; + packageId = "indicatif"; + } { name = "lazy_static"; packageId = "lazy_static"; @@ -11365,6 +11467,10 @@ rec { name = "tracing"; packageId = "tracing"; } + { + name = "tracing-indicatif"; + packageId = "tracing-indicatif"; + } { name = "tracing-subscriber"; packageId = "tracing-subscriber"; @@ -13123,6 +13229,33 @@ rec { }; resolvedDefaultFeatures = [ "default" "once_cell" "std" ]; }; + "tracing-indicatif" = rec { + crateName = "tracing-indicatif"; + version = "0.3.9"; + edition = "2021"; + sha256 = "188anka0xqrjbd7bzj41854rqvf02qszs9l2jzpr7n0c1r1wl0c2"; + libName = "tracing_indicatif"; + dependencies = [ + { + name = "indicatif"; + packageId = "indicatif"; + features = [ "in_memory" ]; + } + { + name = "tracing"; + packageId = "tracing"; + } + { + name = "tracing-core"; + packageId = "tracing-core"; + } + { + name = "tracing-subscriber"; + packageId = "tracing-subscriber"; + } + ]; + + }; "tracing-log" = rec { crateName = "tracing-log"; version = "0.2.0"; @@ -13712,7 +13845,7 @@ rec { features = { }; }; - "unicode-width" = rec { + "unicode-width 0.1.13" = rec { crateName = "unicode-width"; version = "0.1.13"; edition = "2021"; @@ -13730,6 +13863,25 @@ rec { }; resolvedDefaultFeatures = [ "default" ]; }; + "unicode-width 0.2.0" = rec { + crateName = "unicode-width"; + version = "0.2.0"; + edition = "2021"; + sha256 = "1zd0r5vs52ifxn25rs06gxrgz8cmh4xpra922k0xlmrchib1kj0z"; + libName = "unicode_width"; + authors = [ + "kwantam " + "Manish Goregaokar " + ]; + features = { + "compiler_builtins" = [ "dep:compiler_builtins" ]; + "core" = [ "dep:core" ]; + "default" = [ "cjk" ]; + "rustc-dep-of-std" = [ "std" "core" "compiler_builtins" ]; + "std" = [ "dep:std" ]; + }; + resolvedDefaultFeatures = [ "cjk" "default" ]; + }; "unicode-xid" = rec { crateName = "unicode-xid"; version = "0.2.5"; @@ -14080,7 +14232,41 @@ rec { ]; }; - "vte" = rec { + "vt100" = rec { + crateName = "vt100"; + version = "0.15.2"; + edition = "2021"; + sha256 = "1pklc8y984axmxr0cd363srr2d27wd5rj15xlcmkjznvy0xqdkc4"; + authors = [ + "Jesse Luehrs " + ]; + dependencies = [ + { + name = "itoa"; + packageId = "itoa"; + } + { + name = "log"; + packageId = "log"; + } + { + name = "unicode-width"; + packageId = "unicode-width 0.1.13"; + } + { + name = "vte"; + packageId = "vte 0.11.1"; + } + ]; + devDependencies = [ + { + name = "vte"; + packageId = "vte 0.11.1"; + } + ]; + + }; + "vte 0.10.1" = rec { crateName = "vte"; version = "0.10.1"; edition = "2018"; @@ -14092,7 +14278,7 @@ rec { dependencies = [ { name = "arrayvec"; - packageId = "arrayvec"; + packageId = "arrayvec 0.5.2"; optional = true; usesDefaultFeatures = false; } @@ -14113,6 +14299,42 @@ rec { }; resolvedDefaultFeatures = [ "arrayvec" "default" "no_std" ]; }; + "vte 0.11.1" = rec { + crateName = "vte"; + version = "0.11.1"; + edition = "2021"; + sha256 = "15r1ff4j8ndqj9vsyil3wqwxhhl7jsz5g58f31n0h1wlpxgjn0pm"; + authors = [ + "Joe Wilm " + "Christian Duerr " + ]; + dependencies = [ + { + name = "arrayvec"; + packageId = "arrayvec 0.7.6"; + optional = true; + usesDefaultFeatures = false; + } + { + name = "utf8parse"; + packageId = "utf8parse"; + } + { + name = "vte_generate_state_changes"; + packageId = "vte_generate_state_changes"; + } + ]; + features = { + "ansi" = [ "log" ]; + "arrayvec" = [ "dep:arrayvec" ]; + "default" = [ "no_std" ]; + "log" = [ "dep:log" ]; + "nightly" = [ "utf8parse/nightly" ]; + "no_std" = [ "arrayvec" ]; + "serde" = [ "dep:serde" ]; + }; + resolvedDefaultFeatures = [ "arrayvec" "default" "no_std" ]; + }; "vte_generate_state_changes" = rec { crateName = "vte_generate_state_changes"; version = "0.1.2"; @@ -14999,7 +15221,7 @@ rec { dependencies = [ { name = "windows-sys"; - packageId = "windows-sys 0.48.0"; + packageId = "windows-sys 0.59.0"; target = { target, features }: (target."windows" or false); features = [ "Win32_Foundation" "Win32_Storage_FileSystem" "Win32_System_Console" "Win32_System_SystemInformation" ]; } @@ -15409,7 +15631,7 @@ rec { "Win32_Web" = [ "Win32" ]; "Win32_Web_InternetExplorer" = [ "Win32_Web" ]; }; - resolvedDefaultFeatures = [ "Win32" "Win32_Foundation" "Win32_Globalization" "Win32_Storage" "Win32_Storage_FileSystem" "Win32_System" "Win32_System_Com" "Win32_System_Console" "Win32_System_SystemInformation" "Win32_UI" "Win32_UI_Shell" "default" ]; + resolvedDefaultFeatures = [ "Win32" "Win32_Foundation" "Win32_Globalization" "Win32_System" "Win32_System_Com" "Win32_UI" "Win32_UI_Shell" "default" ]; }; "windows-sys 0.52.0" = rec { crateName = "windows-sys"; @@ -15916,7 +16138,7 @@ rec { "Win32_Web" = [ "Win32" ]; "Win32_Web_InternetExplorer" = [ "Win32_Web" ]; }; - resolvedDefaultFeatures = [ "Win32" "Win32_Foundation" "Win32_Networking" "Win32_Networking_WinSock" "Win32_System" "Win32_System_IO" "default" ]; + resolvedDefaultFeatures = [ "Win32" "Win32_Foundation" "Win32_Networking" "Win32_Networking_WinSock" "Win32_Storage" "Win32_Storage_FileSystem" "Win32_System" "Win32_System_Console" "Win32_System_IO" "Win32_System_SystemInformation" "default" ]; }; "windows-targets 0.48.5" = rec { crateName = "windows-targets"; diff --git a/Cargo.toml b/Cargo.toml index 7c48e18d..800e4df1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,7 @@ directories = "5.0" dotenvy = "0.15" futures = "0.3" indexmap = { version = "2.2", features = ["serde"] } +indicatif = "0.17.11" k8s-openapi = { version = "0.24", default-features = false, features = ["v1_32"] } kube = { version = "0.99", default-features = false, features = ["client", "rustls-tls", "ws", "socks5", "http-proxy"] } lazy_static = "1.5" @@ -54,6 +55,7 @@ termion = "4.0" tokio = { version = "1.38", features = ["rt-multi-thread", "macros", "fs", "process", "io-std"] } tower-http = { version = "0.5", features = ["validate-request"] } tracing = "0.1" +tracing-indicatif = "0.3.9" tracing-subscriber = "0.3" url = "2.5" urlencoding = "2.1.3" diff --git a/rust/stackable-cockpit/Cargo.toml b/rust/stackable-cockpit/Cargo.toml index 87380fb8..1decc06f 100644 --- a/rust/stackable-cockpit/Cargo.toml +++ b/rust/stackable-cockpit/Cargo.toml @@ -31,11 +31,13 @@ stackable-operator.workspace = true tera.workspace = true tokio.workspace = true tracing.workspace = true +tracing-indicatif.workspace = true url.workspace = true urlencoding.workspace = true utoipa = { workspace = true, optional = true } which.workspace = true futures.workspace = true +indicatif.workspace = true [dev-dependencies] rstest.workspace = true diff --git a/rust/stackable-cockpit/src/engine/kind/mod.rs b/rust/stackable-cockpit/src/engine/kind/mod.rs index eabe318e..b3f86401 100644 --- a/rust/stackable-cockpit/src/engine/kind/mod.rs +++ b/rust/stackable-cockpit/src/engine/kind/mod.rs @@ -141,9 +141,12 @@ impl Cluster { .await .context(CommandFailedToRunSnafu)?; - ensure!(output.status.success(), CommandErroredOutSnafu { - error: String::from_utf8_lossy(&output.stderr) - }); + ensure!( + output.status.success(), + CommandErroredOutSnafu { + error: String::from_utf8_lossy(&output.stderr) + } + ); let output = String::from_utf8_lossy(&output.stdout); Ok(output.lines().any(|name| name == cluster_name)) diff --git a/rust/stackable-cockpit/src/helm.rs b/rust/stackable-cockpit/src/helm.rs index cd219166..03de0308 100644 --- a/rust/stackable-cockpit/src/helm.rs +++ b/rust/stackable-cockpit/src/helm.rs @@ -183,7 +183,7 @@ pub struct ChartVersion<'a> { /// /// This function expects the fully qualified Helm release name. In case of our /// operators this is: `-operator`. -#[instrument(skip(values_yaml), fields(with_values = values_yaml.is_some()))] +#[instrument(skip(values_yaml), fields(with_values = values_yaml.is_some(), indicatif.pb_show = true))] pub fn install_release_from_repo_or_registry( release_name: &str, ChartVersion { @@ -371,7 +371,7 @@ pub fn get_release(release_name: &str, namespace: &str) -> Result Result<(), Error> { debug!("Add Helm repo"); diff --git a/rust/stackable-cockpit/src/lib.rs b/rust/stackable-cockpit/src/lib.rs index e572b560..7dd66582 100644 --- a/rust/stackable-cockpit/src/lib.rs +++ b/rust/stackable-cockpit/src/lib.rs @@ -1,3 +1,7 @@ +use std::sync::LazyLock; + +use indicatif::ProgressStyle; + pub mod common; pub mod constants; pub mod engine; @@ -6,3 +10,10 @@ pub mod oci; pub mod platform; pub mod utils; pub mod xfer; + +pub(crate) static PROGRESS_BAR_STYLE: LazyLock = LazyLock::new(|| { + ProgressStyle::with_template( + "{span_child_prefix:.bold.dim} Progress {msg}: {wide_bar:.magenta/cyan} {pos}/{len}", + ) + .expect("valid progress template") +}); diff --git a/rust/stackable-cockpit/src/oci.rs b/rust/stackable-cockpit/src/oci.rs index 5e350bd3..337cc876 100644 --- a/rust/stackable-cockpit/src/oci.rs +++ b/rust/stackable-cockpit/src/oci.rs @@ -128,9 +128,12 @@ pub async fn get_oci_index<'a>() -> Result HELM_REPO_NAME_TEST, HELM_REPO_NAME_DEV, ] { - source_index_files.insert(repo_name, ChartSourceMetadata { - entries: HashMap::new(), - }); + source_index_files.insert( + repo_name, + ChartSourceMetadata { + entries: HashMap::new(), + }, + ); } let base_url = format!("https://{HELM_OCI_BASE}/api/v2.0"); diff --git a/rust/stackable-cockpit/src/platform/demo/spec.rs b/rust/stackable-cockpit/src/platform/demo/spec.rs index 75efd265..e32fff43 100644 --- a/rust/stackable-cockpit/src/platform/demo/spec.rs +++ b/rust/stackable-cockpit/src/platform/demo/spec.rs @@ -1,6 +1,8 @@ +use indicatif::ProgressStyle; use serde::{Deserialize, Serialize}; use snafu::{OptionExt, ResultExt, Snafu}; -use tracing::{debug, info, instrument, warn}; +use tracing::{Span, debug, info, instrument, warn}; +use tracing_indicatif::span_ext::IndicatifSpanExt as _; #[cfg(feature = "openapi")] use utoipa::ToSchema; @@ -181,6 +183,7 @@ impl DemoSpec { stack_name = %self.stack, operator_namespace = %install_params.operator_namespace, demo_namespace = %install_params.demo_namespace, + indicatif.pb_show = true ))] async fn prepare_manifests( &self, @@ -189,6 +192,12 @@ impl DemoSpec { transfer_client: &xfer::Client, ) -> Result<(), Error> { info!("Installing demo manifests"); + // Span::current().pb_set_style( + // &ProgressStyle::with_template( + // "{span_child_prefix:.bold.dim} {spinner} {span_name} Installing manifests", + // ) + // .expect("valid progress template"), + // ); let params = install_params .parameters diff --git a/rust/stackable-cockpit/src/platform/manifests.rs b/rust/stackable-cockpit/src/platform/manifests.rs index 7a5df63a..5afb39db 100644 --- a/rust/stackable-cockpit/src/platform/manifests.rs +++ b/rust/stackable-cockpit/src/platform/manifests.rs @@ -1,10 +1,13 @@ -use std::collections::HashMap; +use std::{collections::HashMap, time::Duration}; +use indicatif::ProgressStyle; use snafu::{ResultExt, Snafu}; use stackable_operator::kvp::Labels; -use tracing::{debug, info, instrument}; +use tracing::{Instrument as _, Span, debug, info, info_span, instrument}; +use tracing_indicatif::span_ext::IndicatifSpanExt as _; use crate::{ + PROGRESS_BAR_STYLE, common::manifest::ManifestSpec, helm, utils::{ @@ -62,7 +65,7 @@ pub enum Error { pub trait InstallManifestsExt { // TODO (Techassi): This step shouldn't care about templating the manifests nor fetching them from remote - #[instrument(skip_all, fields(%namespace))] + #[instrument(skip_all, fields(%namespace, indicatif.pb_show = true))] #[allow(async_fn_in_trait)] async fn install_manifests( manifests: &[ManifestSpec], @@ -74,77 +77,115 @@ pub trait InstallManifestsExt { ) -> Result<(), Error> { debug!("Installing manifests"); + Span::current().pb_set_style(&PROGRESS_BAR_STYLE); + Span::current().pb_set_length(manifests.len() as u64); + + tokio::time::sleep(Duration::from_secs(2)).await; + let mut parameters = parameters.clone(); // We add the NAMESPACE parameter, so that stacks/demos can use that to render e.g. the // fqdn service names [which contain the namespace]. parameters.insert("NAMESPACE".to_owned(), namespace.to_owned()); for manifest in manifests { - match manifest { - ManifestSpec::HelmChart(helm_file) => { - debug!(helm_file, "Installing manifest from Helm chart"); - - // Read Helm chart YAML and apply templating - let helm_file = helm_file.into_path_or_url().context(ParsePathOrUrlSnafu { - path_or_url: helm_file.clone(), - })?; - - let helm_chart: helm::Chart = transfer_client - .get(&helm_file, &Template::new(¶meters).then(Yaml::new())) - .await - .context(FileTransferSnafu)?; - - info!(helm_chart.name, helm_chart.version, "Installing Helm chart",); - - // Assumption: that all manifest helm charts refer to repos not registries - helm::add_repo(&helm_chart.repo.name, &helm_chart.repo.url).context( - AddHelmRepositorySnafu { - repo_name: helm_chart.repo.name.clone(), - }, - )?; - - // Serialize chart options to string - let values_yaml = serde_yaml::to_string(&helm_chart.options) - .context(SerializeOptionsSnafu)?; - - // Install the Helm chart using the Helm wrapper - helm::install_release_from_repo_or_registry( - &helm_chart.release_name, - helm::ChartVersion { - chart_source: &helm_chart.repo.name, - chart_name: &helm_chart.name, - chart_version: Some(&helm_chart.version), - }, - Some(&values_yaml), - namespace, - true, - ) - .context(InstallHelmReleaseSnafu { - release_name: helm_chart.release_name, - })?; - } - ManifestSpec::PlainYaml(manifest_file) => { - debug!(manifest_file, "Installing YAML manifest"); - - // Read YAML manifest and apply templating - let path_or_url = - manifest_file - .into_path_or_url() - .context(ParsePathOrUrlSnafu { - path_or_url: manifest_file.clone(), + let span = tracing::warn_span!("install_manifests_iter", indicatif.pb_show = true); + span.pb_set_style( + &ProgressStyle::with_template("{span_child_prefix} boo {span_name}").unwrap(), + ); + + let parameters = parameters.clone(); + let labels = labels.clone(); + async move { + match manifest { + ManifestSpec::HelmChart(helm_file) => { + debug!(helm_file, "Installing manifest from Helm chart"); + + // Read Helm chart YAML and apply templating + let helm_file = + helm_file.into_path_or_url().context(ParsePathOrUrlSnafu { + path_or_url: helm_file.clone(), })?; - let manifests = transfer_client - .get(&path_or_url, &Template::new(¶meters)) - .await - .context(FileTransferSnafu)?; - - client - .deploy_manifests(&manifests, namespace, labels.clone()) - .await - .context(DeployManifestSnafu)? + let helm_chart: helm::Chart = transfer_client + .get(&helm_file, &Template::new(¶meters).then(Yaml::new())) + .await + .context(FileTransferSnafu)?; + + info!(helm_chart.name, helm_chart.version, "Installing Helm chart"); + Span::current().pb_set_message( + format!("Installing {name} Helm chart", name = helm_chart.name) + .as_str(), + ); + // Span::current().pb_set_style( + // &ProgressStyle::with_template( + // "{span_child_prefix:.bold.dim} {spinner} {span_name}", + // ) + // .expect("valid progress template"), + // ); + + // Assumption: that all manifest helm charts refer to repos not registries + helm::add_repo(&helm_chart.repo.name, &helm_chart.repo.url).context( + AddHelmRepositorySnafu { + repo_name: helm_chart.repo.name.clone(), + }, + )?; + + // Serialize chart options to string + let values_yaml = serde_yaml::to_string(&helm_chart.options) + .context(SerializeOptionsSnafu)?; + + // Install the Helm chart using the Helm wrapper + helm::install_release_from_repo_or_registry( + &helm_chart.release_name, + helm::ChartVersion { + chart_source: &helm_chart.repo.name, + chart_name: &helm_chart.name, + chart_version: Some(&helm_chart.version), + }, + Some(&values_yaml), + namespace, + true, + ) + .context(InstallHelmReleaseSnafu { + release_name: helm_chart.release_name, + })?; + } + ManifestSpec::PlainYaml(manifest_file) => { + debug!(manifest_file, "Installing YAML manifest"); + // TODO (@NickLarsenNZ): This span already has a style. + // Span::current().pb_set_style( + // &ProgressStyle::with_template( + // "{span_child_prefix:.bold.dim} {spinner} {span_name} Installing YAML manifest", + // ) + // .expect("valid progress template"), + // ); + + // Read YAML manifest and apply templating + let path_or_url = + manifest_file + .into_path_or_url() + .context(ParsePathOrUrlSnafu { + path_or_url: manifest_file.clone(), + })?; + + let manifests = transfer_client + .get(&path_or_url, &Template::new(¶meters)) + .await + .context(FileTransferSnafu)?; + + client + .deploy_manifests(&manifests, namespace, labels.clone()) + .await + .context(DeployManifestSnafu)?; + } } + + Ok::<(), Error>(()) } + .instrument(span) + .await?; + + Span::current().pb_inc(1); } Ok(()) diff --git a/rust/stackable-cockpit/src/platform/operator/mod.rs b/rust/stackable-cockpit/src/platform/operator/mod.rs index 965afe37..358ca397 100644 --- a/rust/stackable-cockpit/src/platform/operator/mod.rs +++ b/rust/stackable-cockpit/src/platform/operator/mod.rs @@ -1,9 +1,11 @@ use std::{fmt::Display, str::FromStr}; +use indicatif::ProgressStyle; use semver::Version; use serde::Serialize; use snafu::{ResultExt, Snafu, ensure}; -use tracing::{info, instrument}; +use tracing::{Span, info, instrument}; +use tracing_indicatif::{indicatif_println, span_ext::IndicatifSpanExt}; use crate::{ constants::{ @@ -61,10 +63,15 @@ pub struct OperatorSpec { impl Display for OperatorSpec { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}{}", self.name, match &self.version { - Some(v) => format!("={v}"), - None => "".into(), - }) + write!( + f, + "{name}{version_selector}", + name = self.name, + version_selector = match &self.version { + Some(v) => format!("={v}"), + None => "".into(), + } + ) } } @@ -179,6 +186,7 @@ impl OperatorSpec { // display for the inner type if it exists. Otherwise we gte the Debug // impl for the whole Option. version = self.version.as_ref().map(tracing::field::display), + indicatif.pb_show = true, ))] pub fn install( &self, @@ -186,6 +194,12 @@ impl OperatorSpec { chart_source: &ChartSourceType, ) -> Result<(), helm::Error> { info!(operator = %self, "Installing operator"); + Span::current() + .pb_set_message(format!("Installing {name}-operator", name = self.name).as_str()); + // Span::current().pb_set_style( + // &ProgressStyle::with_template("{span_child_prefix:.bold.dim} {spinner} {span_name}") + // .expect("valid progress template"), + // ); let version = self.version.as_ref().map(|v| v.to_string()); let helm_name = self.helm_name(); @@ -221,7 +235,7 @@ impl OperatorSpec { { match helm::uninstall_release(&self.helm_name(), namespace.as_ref(), true) { Ok(status) => { - println!("{status}"); + indicatif_println!("{status}"); Ok(()) } Err(err) => Err(err), diff --git a/rust/stackable-cockpit/src/platform/release/spec.rs b/rust/stackable-cockpit/src/platform/release/spec.rs index 1bb8be6b..f95a15c6 100644 --- a/rust/stackable-cockpit/src/platform/release/spec.rs +++ b/rust/stackable-cockpit/src/platform/release/spec.rs @@ -4,11 +4,12 @@ use serde::{Deserialize, Serialize}; use snafu::{ResultExt, Snafu}; use tokio::task::JoinError; use tracing::{Instrument, Span, info, instrument}; +use tracing_indicatif::span_ext::IndicatifSpanExt as _; #[cfg(feature = "openapi")] use utoipa::ToSchema; use crate::{ - helm, + PROGRESS_BAR_STYLE, helm, platform::{ operator::{self, ChartSourceType, OperatorSpec}, product, @@ -53,6 +54,7 @@ impl ReleaseSpec { %namespace, product.included = tracing::field::Empty, product.excluded = tracing::field::Empty, + indicatif.pb_show = true, ))] pub async fn install( &self, @@ -62,6 +64,8 @@ impl ReleaseSpec { chart_source: &ChartSourceType, ) -> Result<()> { info!("Installing release"); + Span::current().pb_set_message("Progress"); + Span::current().pb_set_style(&PROGRESS_BAR_STYLE); include_products.iter().for_each(|product| { Span::current().record("product.included", product); @@ -70,8 +74,12 @@ impl ReleaseSpec { Span::current().record("product.excluded", product); }); + let operators = self.filter_products(include_products, exclude_products); + + Span::current().pb_set_length(operators.len() as u64); + let namespace = namespace.to_string(); - futures::stream::iter(self.filter_products(include_products, exclude_products)) + futures::stream::iter(operators) .map(|(product_name, product)| { let task_span = tracing::debug_span!("install_operator", product_name = tracing::field::Empty); @@ -103,15 +111,21 @@ impl ReleaseSpec { ) }) .buffer_unordered(10) - .map(|res| res.context(BackgroundTaskSnafu)?) + .map(|res| { + Span::current().pb_inc(1); + res.context(BackgroundTaskSnafu)? + }) .try_collect::<()>() .await } - #[instrument(skip_all)] + #[instrument(skip_all, fields(indicatif.pb_show = true))] pub fn uninstall(&self, namespace: &str) -> Result<()> { info!("Uninstalling release"); + Span::current().pb_set_style(&PROGRESS_BAR_STYLE); + Span::current().pb_set_length(self.products.len() as u64); + for (product_name, product_spec) in &self.products { info!("Uninstalling {product_name}-operator"); @@ -122,6 +136,8 @@ impl ReleaseSpec { // Uninstall operator helm::uninstall_release(&operator.helm_name(), namespace, true) .context(HelmUninstallSnafu)?; + + Span::current().pb_inc(1); } Ok(()) diff --git a/rust/stackable-cockpit/src/platform/stack/spec.rs b/rust/stackable-cockpit/src/platform/stack/spec.rs index 5e638935..d3730c6a 100644 --- a/rust/stackable-cockpit/src/platform/stack/spec.rs +++ b/rust/stackable-cockpit/src/platform/stack/spec.rs @@ -1,6 +1,8 @@ +use indicatif::ProgressStyle; use serde::{Deserialize, Serialize}; use snafu::{OptionExt, ResultExt, Snafu}; -use tracing::{debug, info, instrument, log::warn}; +use tracing::{Span, debug, info, instrument, log::warn}; +use tracing_indicatif::span_ext::IndicatifSpanExt as _; #[cfg(feature = "openapi")] use utoipa::ToSchema; @@ -194,7 +196,7 @@ impl StackSpec { .await } - #[instrument(skip_all, fields(release = %self.release, %operator_namespace))] + #[instrument(skip_all, fields(release = %self.release, %operator_namespace, indicatif.pb_show = true))] pub async fn install_release( &self, release_list: release::ReleaseList, @@ -203,6 +205,12 @@ impl StackSpec { chart_source: &ChartSourceType, ) -> Result<(), Error> { info!(self.release, "Trying to install release"); + Span::current().pb_set_style( + &ProgressStyle::with_template( + "{span_child_prefix:.bold.dim} {spinner} {span_name} Installing operators", + ) + .expect("valid progress template"), + ); // Get the release by name let release = release_list @@ -218,7 +226,7 @@ impl StackSpec { .context(InstallReleaseSnafu) } - #[instrument(skip_all)] + #[instrument(skip_all, fields(indicatif.pb_show = true))] pub async fn prepare_manifests( &self, install_params: StackInstallParameters, @@ -226,6 +234,10 @@ impl StackSpec { transfer_client: &xfer::Client, ) -> Result<(), Error> { info!("Installing stack manifests"); + // Span::current().pb_set_style( + // &ProgressStyle::with_template("{spinner} {span_name} Installing manifests") + // .expect("valid progress template"), + // ); let parameters = install_params .parameters diff --git a/rust/stackable-cockpit/src/platform/stacklet/mod.rs b/rust/stackable-cockpit/src/platform/stacklet/mod.rs index 7c6e6d20..6f7a3e0d 100644 --- a/rust/stackable-cockpit/src/platform/stacklet/mod.rs +++ b/rust/stackable-cockpit/src/platform/stacklet/mod.rs @@ -170,11 +170,14 @@ fn build_products_gvk_list<'a>(product_names: &[&'a str]) -> IndexMap<&'a str, G for product_name in product_names { // Why? Just why? Can we please make this consistent? if *product_name == "spark-history-server" { - map.insert(*product_name, GroupVersionKind { - group: "spark.stackable.tech".into(), - version: "v1alpha1".into(), - kind: "SparkHistoryServer".into(), - }); + map.insert( + *product_name, + GroupVersionKind { + group: "spark.stackable.tech".into(), + version: "v1alpha1".into(), + kind: "SparkHistoryServer".into(), + }, + ); continue; } diff --git a/rust/stackable-cockpit/src/utils/k8s/client.rs b/rust/stackable-cockpit/src/utils/k8s/client.rs index c87b7118..c2c187a8 100644 --- a/rust/stackable-cockpit/src/utils/k8s/client.rs +++ b/rust/stackable-cockpit/src/utils/k8s/client.rs @@ -14,7 +14,7 @@ use serde::Deserialize; use snafu::{OptionExt, ResultExt, Snafu}; use stackable_operator::{commons::listener::Listener, kvp::Labels}; use tokio::sync::RwLock; -use tracing::info; +use tracing::{Instrument, info, info_span, instrument}; #[cfg(doc)] use crate::utils::k8s::ListParamsExt; @@ -98,6 +98,7 @@ impl Client { /// Deploys manifests defined the in raw `manifests` YAML string. This /// method will fail if it is unable to parse the manifests, unable to /// resolve GVKs or unable to patch the dynamic objects. + #[instrument(skip_all, fields(indicatif.pb_show = true))] pub async fn deploy_manifests( &self, manifests: &str, @@ -108,6 +109,8 @@ impl Client { let labels: BTreeMap = labels.into(); for manifest in serde_yaml::Deserializer::from_str(manifests) { + let span = info_span!("install_a_manifest", indicatif.pb_show = true); + let mut object = DynamicObject::deserialize(manifest).context(DeserializeYamlSnafu)?; // Add our own labels to the object @@ -141,6 +144,7 @@ impl Client { &PatchParams::apply("stackablectl"), &Patch::Apply(object), ) + .instrument(span) .await .context(KubeClientPatchSnafu)?; } diff --git a/rust/stackable-cockpit/src/utils/params.rs b/rust/stackable-cockpit/src/utils/params.rs index 623aeac4..65299350 100644 --- a/rust/stackable-cockpit/src/utils/params.rs +++ b/rust/stackable-cockpit/src/utils/params.rs @@ -281,17 +281,23 @@ mod test { let p = iter.next(); assert!(p.is_some()); - assert_eq!(p.unwrap(), &RawParameter { - name: "param1".into(), - value: "value1".into() - }); + assert_eq!( + p.unwrap(), + &RawParameter { + name: "param1".into(), + value: "value1".into() + } + ); let p = iter.next(); assert!(p.is_some()); - assert_eq!(p.unwrap(), &RawParameter { - name: "param2".into(), - value: "value2".into() - }); + assert_eq!( + p.unwrap(), + &RawParameter { + name: "param2".into(), + value: "value2".into() + } + ); let p = iter.next(); assert!(p.is_none()); @@ -309,17 +315,23 @@ mod test { let p = iter.next(); assert!(p.is_some()); - assert_eq!(p.unwrap(), &RawParameter { - name: "param1".into(), - value: "value1".into() - }); + assert_eq!( + p.unwrap(), + &RawParameter { + name: "param1".into(), + value: "value1".into() + } + ); let p = iter.next(); assert!(p.is_some()); - assert_eq!(p.unwrap(), &RawParameter { - name: "param2".into(), - value: "value2".into() - }); + assert_eq!( + p.unwrap(), + &RawParameter { + name: "param2".into(), + value: "value2".into() + } + ); let p = iter.next(); assert!(p.is_none()); @@ -367,10 +379,13 @@ mod test { match input.into_params(valid_parameters) { Ok(validated) => panic!("SHOULD FAIL: {validated:?}"), - Err(err) => assert_eq!(err, IntoParametersError::InvalidParameter { - parameter: "param2".into(), - expected: "param1".into() - }), + Err(err) => assert_eq!( + err, + IntoParametersError::InvalidParameter { + parameter: "param2".into(), + expected: "param1".into() + } + ), } } } diff --git a/rust/stackable-cockpitd/src/handlers/ui.rs b/rust/stackable-cockpitd/src/handlers/ui.rs index 9abdb02b..e250e0bb 100644 --- a/rust/stackable-cockpitd/src/handlers/ui.rs +++ b/rust/stackable-cockpitd/src/handlers/ui.rs @@ -18,11 +18,14 @@ async fn ui() -> Html<&'static str> { } async fn asset(Path(name): Path) -> impl IntoResponse { ( - [(CONTENT_TYPE, match name.rsplit_once('.') { - Some((_, "js")) => HeaderValue::from_static("text/javascript"), - Some((_, "css")) => HeaderValue::from_static("text/css"), - _ => HeaderValue::from_static("application/octet-stream"), - })], + [( + CONTENT_TYPE, + match name.rsplit_once('.') { + Some((_, "js")) => HeaderValue::from_static("text/javascript"), + Some((_, "css")) => HeaderValue::from_static("text/css"), + _ => HeaderValue::from_static("application/octet-stream"), + }, + )], stackable_cockpit_web::ASSETS[&name], ) } diff --git a/rust/stackablectl/Cargo.toml b/rust/stackablectl/Cargo.toml index 6fa40591..6d50927f 100644 --- a/rust/stackablectl/Cargo.toml +++ b/rust/stackablectl/Cargo.toml @@ -32,7 +32,9 @@ tera.workspace = true tokio.workspace = true tracing-subscriber.workspace = true tracing.workspace = true +tracing-indicatif.workspace = true futures.workspace = true +indicatif.workspace = true termion.workspace = true urlencoding.workspace = true libc.workspace = true diff --git a/rust/stackablectl/src/cmds/demo.rs b/rust/stackablectl/src/cmds/demo.rs index 3a4f4c80..b9d8654d 100644 --- a/rust/stackablectl/src/cmds/demo.rs +++ b/rust/stackablectl/src/cmds/demo.rs @@ -3,6 +3,7 @@ use comfy_table::{ ContentArrangement, Row, Table, presets::{NOTHING, UTF8_FULL}, }; +use indicatif::ProgressStyle; use snafu::{OptionExt as _, ResultExt, Snafu, ensure}; use stackable_cockpit::{ common::list, @@ -19,7 +20,8 @@ use stackable_cockpit::{ xfer::{self, cache::Cache}, }; use stackable_operator::kvp::{LabelError, Labels}; -use tracing::{debug, info, instrument}; +use tracing::{Span, debug, info, instrument}; +use tracing_indicatif::span_ext::IndicatifSpanExt as _; use crate::{ args::{CommonClusterArgs, CommonClusterArgsError, CommonNamespaceArgs}, @@ -209,9 +211,15 @@ impl DemoArgs { } /// Print out a list of demos, either as a table (plain), JSON or YAML -#[instrument(skip_all)] +#[instrument(skip_all, fields(indicatif.pb_show = true))] async fn list_cmd(args: &DemoListArgs, cli: &Cli, list: demo::List) -> Result { info!("Listing demos"); + // Span::current().pb_set_style( + // &ProgressStyle::with_template( + // "{span_child_prefix:.bold.dim} {spinner} {span_name} Fetching demo information", + // ) + // .expect("valid progress template"), + // ); match args.output_type { OutputType::Plain | OutputType::Table => { @@ -257,13 +265,19 @@ async fn list_cmd(args: &DemoListArgs, cli: &Cli, list: demo::List) -> Result Result { info!(demo_name = %args.demo_name, "Describing demo"); + // Span::current().pb_set_style( + // &ProgressStyle::with_template( + // "{span_child_prefix:.bold.dim} {spinner} {span_name} Fetching demo information", + // ) + // .expect("valid progress template"), + // ); let demo = list.get(&args.demo_name).ok_or(CmdError::NoSuchDemo { name: args.demo_name.clone(), @@ -316,7 +330,8 @@ async fn describe_cmd( #[instrument(skip_all, fields( demo_name = %args.demo_name, skip_release = args.skip_release, - %release_branch + %release_branch, + indicatif.pb_hide = true, ))] async fn install_cmd( args: &DemoInstallArgs, @@ -326,6 +341,12 @@ async fn install_cmd( release_branch: &str, ) -> Result { info!(demo_name = %args.demo_name, "Installing demo"); + // Span::current().pb_set_style( + // &ProgressStyle::with_template( + // "{span_child_prefix:.bold.dim} {spinner} {span_name} Installing demo", + // ) + // .expect("valid progress template"), + // ); // Init result output and progress output let mut output = cli.result(); diff --git a/rust/stackablectl/src/cmds/operator.rs b/rust/stackablectl/src/cmds/operator.rs index 207b7df4..03b69e23 100644 --- a/rust/stackablectl/src/cmds/operator.rs +++ b/rust/stackablectl/src/cmds/operator.rs @@ -6,6 +6,7 @@ use comfy_table::{ presets::{NOTHING, UTF8_FULL}, }; use indexmap::IndexMap; +use indicatif::ProgressStyle; use semver::Version; use serde::Serialize; use snafu::{ResultExt, Snafu}; @@ -25,7 +26,8 @@ use stackable_cockpit::{ k8s::{self, Client}, }, }; -use tracing::{debug, info, instrument}; +use tracing::{Span, debug, info, instrument}; +use tracing_indicatif::{indicatif_println, span_ext::IndicatifSpanExt}; use crate::{ args::{CommonClusterArgs, CommonClusterArgsError}, @@ -186,9 +188,16 @@ impl OperatorArgs { } } -#[instrument(skip_all)] +#[instrument(skip_all, fields(indicatif.pb_show = true))] async fn list_cmd(args: &OperatorListArgs, cli: &Cli) -> Result { debug!("Listing operators"); + // TODO (@NickLarsenNZ): Remove progress bar from list commands + // Span::current().pb_set_style( + // &ProgressStyle::with_template( + // "{span_child_prefix:.bold.dim} {spinner} {span_name} Fetching operator information", + // ) + // .expect("valid progress template"), + // ); // Build map which maps artifacts to a chart source let source_index_files = @@ -246,6 +255,13 @@ async fn list_cmd(args: &OperatorListArgs, cli: &Cli) -> Result Result { debug!(operator_name = %args.operator_name, "Describing operator"); + // TODO (@NickLarsenNZ): Remove progress bar from describe commands + // Span::current().pb_set_style( + // &ProgressStyle::with_template( + // "{span_child_prefix:.bold.dim} {spinner} {span_name} Fetching operator information", + // ) + // .expect("valid progress template"), + // ); // Build map which maps artifacts to a chart source let source_index_files = @@ -302,9 +318,15 @@ async fn describe_cmd(args: &OperatorDescribeArgs, cli: &Cli) -> Result Result { info!("Installing operator(s)"); + // Span::current().pb_set_style( + // &ProgressStyle::with_template( + // "{span_child_prefix:.bold.dim} {spinner} {span_name} Installing operator(s)", + // ) + // .expect("valid progress template"), + // ); args.local_cluster .install_if_needed() @@ -327,9 +349,8 @@ async fn install_cmd(args: &OperatorInstallArgs, cli: &Cli) -> Result Result Result { info!("Uninstalling operator(s)"); + // Span::current().pb_set_style( + // &ProgressStyle::with_template( + // "{span_child_prefix:.bold.dim} {spinner} {span_name} Uninstalling operator(s)", + // ) + // .expect("valid progress template"), + // ); for operator in &args.operators { operator @@ -385,6 +412,13 @@ fn uninstall_cmd(args: &OperatorUninstallArgs, cli: &Cli) -> Result Result { info!("Listing installed operators"); + // TODO (@NickLarsenNZ): Remove progress bar from installed command + // Span::current().pb_set_style( + // &ProgressStyle::with_template( + // "{span_child_prefix:.bold.dim} {spinner} {span_name} Fetching operator information", + // ) + // .expect("valid progress template"), + // ); type ReleaseList = IndexMap; diff --git a/rust/stackablectl/src/cmds/release.rs b/rust/stackablectl/src/cmds/release.rs index bbaee551..cb21adf6 100644 --- a/rust/stackablectl/src/cmds/release.rs +++ b/rust/stackablectl/src/cmds/release.rs @@ -3,6 +3,7 @@ use comfy_table::{ ContentArrangement, Table, presets::{NOTHING, UTF8_FULL}, }; +use indicatif::ProgressStyle; use snafu::{ResultExt, Snafu}; use stackable_cockpit::{ common::list, @@ -14,7 +15,8 @@ use stackable_cockpit::{ }, xfer::{self, cache::Cache}, }; -use tracing::{debug, info, instrument}; +use tracing::{Span, debug, info, instrument}; +use tracing_indicatif::span_ext::IndicatifSpanExt as _; use crate::{ args::{CommonClusterArgs, CommonClusterArgsError}, @@ -157,6 +159,13 @@ async fn list_cmd( release_list: release::ReleaseList, ) -> Result { info!("Listing releases"); + // TODO (@NickLarsenNZ): Remove progress bar from list command + // Span::current().pb_set_style( + // &ProgressStyle::with_template( + // "{span_child_prefix:.bold.dim} {spinner} {span_name} Fetching release information", + // ) + // .expect("valid progress template"), + // ); match args.output_type { OutputType::Plain | OutputType::Table => { @@ -211,6 +220,13 @@ async fn describe_cmd( release_list: release::ReleaseList, ) -> Result { info!(release = %args.release, "Describing release"); + // TODO (@NickLarsenNZ): Remove progress bar from descibe command + // Span::current().pb_set_style( + // &ProgressStyle::with_template( + // "{span_child_prefix:.bold.dim} {spinner} {span_name} Fetching release information", + // ) + // .expect("valid progress template"), + // ); let release = release_list.get(&args.release); @@ -265,13 +281,20 @@ async fn describe_cmd( } } -#[instrument(skip(cli, release_list))] +#[instrument(skip_all, fields(indicatif.pb_hide = true))] async fn install_cmd( args: &ReleaseInstallArgs, cli: &Cli, release_list: release::ReleaseList, ) -> Result { info!(release = %args.release, "Installing release"); + // Span::current().pb_set_style( + // &ProgressStyle::with_template( + // "{span_child_prefix:.bold.dim} {spinner} {span_name} Installing release", + // ) + // .expect("valid progress template"), + // ); + match release_list.get(&args.release) { Some(release) => { let mut output = cli.result(); @@ -314,12 +337,19 @@ async fn install_cmd( } } -#[instrument(skip(cli, release_list))] +#[instrument(skip_all, fields(indicatif.pb_show = true))] async fn uninstall_cmd( args: &ReleaseUninstallArgs, cli: &Cli, release_list: release::ReleaseList, ) -> Result { + // Span::current().pb_set_style( + // &ProgressStyle::with_template( + // "{span_child_prefix:.bold.dim} {spinner} {span_name} Uninstalling release", + // ) + // .expect("valid progress template"), + // ); + match release_list.get(&args.release) { Some(release) => { release diff --git a/rust/stackablectl/src/cmds/stack.rs b/rust/stackablectl/src/cmds/stack.rs index be78c33a..e7694cf6 100644 --- a/rust/stackablectl/src/cmds/stack.rs +++ b/rust/stackablectl/src/cmds/stack.rs @@ -3,6 +3,7 @@ use comfy_table::{ ContentArrangement, Table, presets::{NOTHING, UTF8_FULL}, }; +use indicatif::ProgressStyle; use snafu::{OptionExt as _, ResultExt, Snafu, ensure}; use stackable_cockpit::{ common::list, @@ -19,7 +20,8 @@ use stackable_cockpit::{ xfer::{self, cache::Cache}, }; use stackable_operator::kvp::{LabelError, Labels}; -use tracing::{debug, info, instrument}; +use tracing::{Span, debug, info, instrument}; +use tracing_indicatif::span_ext::IndicatifSpanExt as _; use crate::{ args::{CommonClusterArgs, CommonClusterArgsError, CommonNamespaceArgs}, @@ -198,6 +200,13 @@ fn list_cmd( stack_list: stack::StackList, ) -> Result { info!("Listing stacks"); + // TODO (@NickLarsenNZ): Remove progress bar from list command + // Span::current().pb_set_style( + // &ProgressStyle::with_template( + // "{span_child_prefix:.bold.dim} {spinner} {span_name} Fetching stack information", + // ) + // .expect("valid progress template"), + // ); match args.output_type { OutputType::Plain | OutputType::Table => { @@ -248,6 +257,13 @@ fn describe_cmd( stack_list: stack::StackList, ) -> Result { info!(stack_name = %args.stack_name, "Describing stack"); + // TODO (@NickLarsenNZ): Remove progress bar from describe command + // Span::current().pb_set_style( + // &ProgressStyle::with_template( + // "{span_child_prefix:.bold.dim} {spinner} {span_name} Fetching stack information", + // ) + // .expect("valid progress template"), + // ); match stack_list.get(&args.stack_name) { Some(stack) => match args.output_type { @@ -303,7 +319,7 @@ fn describe_cmd( } } -#[instrument(skip(cli, stack_list, transfer_client))] +#[instrument(skip_all, fields(indicatif.pb_show = true))] async fn install_cmd( args: &StackInstallArgs, cli: &Cli, @@ -311,6 +327,12 @@ async fn install_cmd( transfer_client: &xfer::Client, ) -> Result { info!(stack_name = %args.stack_name, "Installing stack"); + // Span::current().pb_set_style( + // &ProgressStyle::with_template( + // "{span_child_prefix:.bold.dim} {spinner} {span_name} Installing stack", + // ) + // .expect("valid progress template"), + // ); let files = cli.get_release_files().context(PathOrUrlParseSnafu)?; let release_list = release::ReleaseList::build(&files, transfer_client) diff --git a/rust/stackablectl/src/cmds/stacklet.rs b/rust/stackablectl/src/cmds/stacklet.rs index 2422f65f..8194691b 100644 --- a/rust/stackablectl/src/cmds/stacklet.rs +++ b/rust/stackablectl/src/cmds/stacklet.rs @@ -3,13 +3,15 @@ use comfy_table::{ ContentArrangement, Table, presets::{NOTHING, UTF8_FULL}, }; +use indicatif::ProgressStyle; use snafu::{ResultExt, Snafu}; use stackable_cockpit::{ constants::DEFAULT_NAMESPACE, platform::stacklet::{self, get_credentials_for_product, list_stacklets}, utils::k8s::{self, Client, DisplayCondition}, }; -use tracing::{info, instrument}; +use tracing::{Span, info, instrument}; +use tracing_indicatif::span_ext::IndicatifSpanExt as _; use crate::{ args::CommonNamespaceArgs, @@ -92,6 +94,13 @@ impl StackletArgs { #[instrument(skip_all)] async fn list_cmd(args: &StackletListArgs, cli: &Cli) -> Result { info!("Listing installed stacklets"); + // TODO (@NickLarsenNZ): Remove progress bar from list command + // Span::current().pb_set_style( + // &ProgressStyle::with_template( + // "{span_child_prefix:.bold.dim} {spinner} {span_name} Fetching stacklet information", + // ) + // .expect("valid progress template"), + // ); let client = Client::new().await.context(KubeClientCreateSnafu)?; @@ -205,6 +214,13 @@ async fn list_cmd(args: &StackletListArgs, cli: &Cli) -> Result Result { info!("Displaying stacklet credentials"); + // TODO (@NickLarsenNZ): Remove progress bar from credentials command + // Span::current().pb_set_style( + // &ProgressStyle::with_template( + // "{span_child_prefix:.bold.dim} {spinner} {span_name} Fetching stacklet information", + // ) + // .expect("valid progress template"), + // ); let client = Client::new().await.context(KubeClientCreateSnafu)?; diff --git a/rust/stackablectl/src/main.rs b/rust/stackablectl/src/main.rs index 09bc2269..ddc4d56e 100644 --- a/rust/stackablectl/src/main.rs +++ b/rust/stackablectl/src/main.rs @@ -1,8 +1,18 @@ use clap::Parser; use dotenvy::dotenv; +use indicatif::ProgressStyle; use stackablectl::cli::{Cli, Error}; -use tracing::metadata::LevelFilter; -use tracing_subscriber::fmt; +use tracing::{Level, metadata::LevelFilter}; +use tracing_indicatif::{ + IndicatifLayer, + filter::{IndicatifFilter, hide_indicatif_span_fields}, + indicatif_eprintln, +}; +use tracing_subscriber::{ + fmt::{self, format::DefaultFields}, + layer::{Layer as _, SubscriberExt as _}, + util::SubscriberInitExt as _, +}; #[snafu::report] #[tokio::main] @@ -16,21 +26,44 @@ async fn main() -> Result<(), Error> { .without_time() .with_target(false); - tracing_subscriber::fmt() - .with_max_level(match app.log_level { - Some(level) => LevelFilter::from_level(level), - None => LevelFilter::WARN, - }) - .event_format(format) - .pretty() - .init(); + let indicatif_layer = IndicatifLayer::new() + .with_span_field_formatter(hide_indicatif_span_fields(DefaultFields::new())) + .with_progress_style(ProgressStyle::with_template("{span_child_prefix}{span_name}").unwrap()) + // .with_progress_style(ProgressStyle::with_template("{span_child_prefix:.bold.dim}").expect("valid progress template")) + // .with_max_progress_bars( + // 15, + // Some( + // ProgressStyle::with_template( + // "{span_child_prefix:.bold.dim} ...and {pending_progress_bars} more processes not shown above." + // ) + // .expect("valid progress template") + // ), + // ) + ; + + if let Some(level) = app.log_level { + tracing_subscriber::registry() + .with( + fmt::layer() + .event_format(format) + .pretty() + .with_writer(indicatif_layer.get_stderr_writer()), + ) + .with(LevelFilter::from_level(level)) + .init(); + } else { + tracing_subscriber::registry() + .with(LevelFilter::from_level(Level::INFO)) + .with(indicatif_layer.with_filter(IndicatifFilter::new(false))) + .init(); + } // Load env vars from optional .env file match dotenv() { Ok(_) => (), Err(err) => { if !err.not_found() { - println!("{err}") + indicatif_eprintln!("{err}") } } } diff --git a/rust/xtask/src/openapi.rs b/rust/xtask/src/openapi.rs index 693c3e02..270e64fb 100644 --- a/rust/xtask/src/openapi.rs +++ b/rust/xtask/src/openapi.rs @@ -35,9 +35,12 @@ pub fn generate() -> Result<(), GenOpenapiError> { .write_all(openapi_json.as_bytes()) .context(WriteOpenapiSchemaSnafu)?; let status = codegen.wait().context(ImportOpenapiSchemaRunSnafu)?; - ensure!(status.success(), ImportOpenapiSchemaSnafu { - error_code: status.code() - }); + ensure!( + status.success(), + ImportOpenapiSchemaSnafu { + error_code: status.code() + } + ); Ok(()) }