From ae954e057584cf3b06f37edd2c21c795ae6db491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Sch=C3=B6chlin?= Date: Sun, 24 Nov 2024 17:24:43 +0100 Subject: [PATCH 1/8] reduce binary size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marc Schöchlin --- Cargo.lock | 59 +++++++++++------------------------------------------- Cargo.toml | 9 ++++++--- 2 files changed, 18 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8f78874..562c821 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -136,7 +136,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -174,16 +174,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" -[[package]] -name = "colored" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" -dependencies = [ - "lazy_static", - "windows-sys 0.48.0", -] - [[package]] name = "crossterm" version = "0.25.0" @@ -316,10 +306,8 @@ dependencies = [ "clap", "clap_complete", "cli-table", - "colored", "ctrlc", "env_logger", - "hostname", "inline_colorization", "inquire", "libc", @@ -328,17 +316,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "hostname" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" -dependencies = [ - "libc", - "match_cfg", - "winapi", -] - [[package]] name = "humantime" version = "2.1.0" @@ -376,15 +353,9 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "lazy_static" -version = "1.5.0" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2" [[package]] name = "libc" @@ -414,12 +385,6 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" -[[package]] -name = "match_cfg" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" - [[package]] name = "memchr" version = "2.7.4" @@ -490,9 +455,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.89" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -546,9 +511,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustix" -version = "0.38.40" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ "bitflags 2.6.0", "errno", @@ -586,7 +551,7 @@ checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.89", ] [[package]] @@ -656,9 +621,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.87" +version = "2.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" dependencies = [ "proc-macro2", "quote", @@ -699,9 +664,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-segmentation" diff --git a/Cargo.toml b/Cargo.toml index 6e5c3fa..e2f5d64 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,17 +1,20 @@ +[profile.release] +strip = true +opt-level = "z" +codegen-units = 1 +lto = true + [package] name = "hostctl" version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] -hostname = "0.3.1" libc = "0.2.153" env_logger = "0.11.3" clap = { version = "4.5.4", features = ["derive"] } clap_complete = "4.2" -colored = "2.1.0" inline_colorization = "0.1.6" serde_json = "1.0.115" regex = "1.10.4" From 39fa6e9b95a82746e42f1969bd6ac178c0533cdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Sch=C3=B6chlin?= Date: Sun, 24 Nov 2024 18:58:58 +0100 Subject: [PATCH 2/8] Trying MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marc Schöchlin --- README.md | 10 +++++----- misc/hostctl_bash_completion.sh | 2 +- src/groups_config.rs | 7 +++++++ src/parameters.rs | 10 +++++++--- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 2c3ef7f..24f825d 100644 --- a/README.md +++ b/README.md @@ -56,14 +56,14 @@ Invoke hostctl to execute commands or scripts on the specified hosts. cd ${INSTALL_DIR?The installation base directory}/hostctl git clone https://github.com/scoopex/hostctl.git hostctl cd hostctl - cargo build --release - ln -snf ${INSTALL_DIR?The installation base directory}/hostctl/target/release/hostctl ~/bin/hostctl + cargo build + ln -snf ${INSTALL_DIR?The installation base directory}/hostctl/target/debug/hostctl ~/bin/hostctl ``` 3. Build completions ``` - target/release/hostctl generate-completions bash > misc/hostctl_bash_completion.sh - target/release/hostctl generate-completions zsh > misc/hostctl_zsh_completion.sh - target/release/hostctl generate-completions fish > misc/hostctl_fish_completion.sh + hostctl generate-completions bash > misc/hostctl_bash_completion.sh + hostctl generate-completions zsh > misc/hostctl_zsh_completion.sh + hostctl generate-completions fish > misc/hostctl_fish_completion.sh echo "source $INSTALLDIR/hostctl/misc/hostctl_bash_completion.sh" >> .bashrc exec bash ``` diff --git a/misc/hostctl_bash_completion.sh b/misc/hostctl_bash_completion.sh index 5552770..b925ce6 100644 --- a/misc/hostctl_bash_completion.sh +++ b/misc/hostctl_bash_completion.sh @@ -19,7 +19,7 @@ _hostctl() { case "${cmd}" in hostctl) - opts="-c -e -r -n -s -a -j -d -f -q -b -i -o -l -t -w -p -m -h -V --command --execute-local --recipe --nodes --show --array --json --debug --forcecolor --quiet --batchmode --inscreen --optssh --login --term --wait --prompt --makeselection --log-level --help --version [ITEMS]..." + opts="-c -e -r -n -s -a -j -d -f -q -b -i -o -l -t -w -p -m -h -V --command --execute-local --recipe --nodes --show --for-complete --array --json --debug --forcecolor --quiet --batchmode --inscreen --optssh --login --sudo --term --wait --prompt --makeselection --log-level --help --version [ITEM]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 diff --git a/src/groups_config.rs b/src/groups_config.rs index 58ed8fa..98d3d3e 100644 --- a/src/groups_config.rs +++ b/src/groups_config.rs @@ -22,6 +22,13 @@ pub fn unified_node_list(items: Vec) -> Vec { sorted_vec } +pub fn dump_groups_for_completion(){ + let groups_map = get_groups_and_nodes(vec!["all".to_string()]); + for (group_name, _) in groups_map.iter() { + println!("{}", group_name); + } +} + pub fn dump_groups(items: Vec, json: bool) { let groups_map = get_groups_and_nodes(items); if json { diff --git a/src/parameters.rs b/src/parameters.rs index cd445e7..1de2bc3 100644 --- a/src/parameters.rs +++ b/src/parameters.rs @@ -59,7 +59,7 @@ pub struct CommandLineArgs { /// Recipes can be stored in $HOME/.hostctl/recipe/ or /recipe/ and can /// be called by their basename. /// Alternatively, recipes can be called be their fully qualified path. - #[arg(short, long, default_value = "")] + #[arg(short, long, default_value = "", value_hint = clap::ValueHint::AnyPath)] pub(crate) recipe: String, /// Specify hosts instead of groups. @@ -70,6 +70,10 @@ pub struct CommandLineArgs { #[arg(short, long)] pub(crate) show: bool, + /// output for shell completion + #[arg(long)] + pub(crate) for_completion: bool, + /// Output an array list od nodes #[arg(short, long)] pub(crate) array: bool, @@ -135,6 +139,6 @@ pub struct CommandLineArgs { pub(crate) log_level: String, /// Groups or nodes for the iteration - #[arg()] + #[arg(value_name = "ITEM")] pub(crate) items: Vec, -} +} \ No newline at end of file From c30df108bb892bbab4ad0a1c6492e6399c3e7962 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Sch=C3=B6chlin?= Date: Sat, 30 Nov 2024 12:39:57 +0100 Subject: [PATCH 3/8] refactor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marc Schöchlin --- src/main.rs | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/main.rs b/src/main.rs index 9c9e77e..9350ecc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,12 +15,26 @@ use crate::utils::{dump_recipes, output_str, OutputType}; use std::env; use std::io; -fn generate_completions(shell: G) { - let mut cmd = CommandLineArgs::command(); - let bin_name = env!("CARGO_PKG_NAME"); - generate(shell, &mut cmd, bin_name, &mut io::stdout()); + +fn shell_completions(){ + if let Some(shell) = env::args().nth(1) { + if shell == "generate-completions" { + if let Some(shell_name) = env::args().nth(2) { + let shell_enum = shell_name.parse::(); + if let Ok(shell_enum) = shell_enum { + let mut cmd = CommandLineArgs::command(); + let bin_name = env!("CARGO_PKG_NAME"); + generate(shell_enum, &mut cmd, bin_name, &mut io::stdout()); + exit(0); + } + } + eprintln!("Usage: {} generate-completions ", env!("CARGO_PKG_NAME")); + exit(1); + } + } } + fn main() { unsafe { libc::umask(0o077) }; @@ -31,19 +45,7 @@ fn main() { let mut cli = CommandLineArgs::parse(); - if let Some(shell) = env::args().nth(1) { - if shell == "generate-completions" { - if let Some(shell_name) = env::args().nth(2) { - let shell_enum = shell_name.parse::(); - if let Ok(shell_enum) = shell_enum { - generate_completions(shell_enum); - return; - } - } - eprintln!("Usage: {} generate-completions ", env!("CARGO_PKG_NAME")); - return; - } - } + shell_completions(); env_logger::Builder::from_env( Env::default().default_filter_or(cli.log_level.clone()) From 6856bbd551eb3ce164386eff1e6c9080479286a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Sch=C3=B6chlin?= Date: Sat, 30 Nov 2024 13:59:04 +0100 Subject: [PATCH 4/8] refactor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marc Schöchlin --- src/main.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 9350ecc..d7c22b7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,7 +15,6 @@ use crate::utils::{dump_recipes, output_str, OutputType}; use std::env; use std::io; - fn shell_completions(){ if let Some(shell) = env::args().nth(1) { if shell == "generate-completions" { From 4ae12f115d6f8251b901e2eecee9fd4439c6c8df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Sch=C3=B6chlin?= Date: Wed, 4 Dec 2024 12:57:53 +0100 Subject: [PATCH 5/8] teardown screen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marc Schöchlin --- src/execute.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/execute.rs b/src/execute.rs index b3a2c3e..55628d3 100644 --- a/src/execute.rs +++ b/src/execute.rs @@ -32,7 +32,7 @@ fn establish_screen_session(args: &CommandLineArgs){ .args(["-t", "init", "-S", &*args.inscreen, "-d", "-m", "sleep", "120"]) .output() .expect("failed to start base screen"); - output(format!("Wait for screen session for {} seconds", num), OutputType::Error); + output(format!("Wait for screen session for {} seconds", num), OutputType::Info); thread::sleep(Duration::from_secs(1)); }, 1 => { @@ -89,8 +89,6 @@ fn establish_base_command(args: &CommandLineArgs, base_executable: &str, node: & if COUNTER.fetch_add(1, Ordering::Relaxed) == 0 { establish_screen_session(args); } - output(format!("NOTE: command were execute in a screen session, attach by executing 'screen -x {}'", args.inscreen), OutputType::Info); - output_str("(see 'man screen' or 'STRG + a :help' for getting information about handling screen sessions)", OutputType::Info); cmd = Command::new("screen"); cmd.args(["-x", &*args.inscreen, "-m", "-X", "screen", "-t", node]); @@ -185,7 +183,6 @@ fn execute_remote(node: String, templated_lines: Vec, args: &CommandLine } output(format!("Execute remote : {:?}", cmd), OutputType::Detail); - //output(format!("Execute remote : {:?}", cmd.to_string()), OutputType::Detail); if args.term { cmd.stdin(Stdio::inherit()) .stdout(Stdio::inherit()) @@ -346,6 +343,18 @@ pub fn execute_nodes(nodes: Vec, only_nodes: bool, execute_local: bool, } } + if args.inscreen != "" { + output_str("NOTE: Teardown 'init' screen now", OutputType::Detail); + Command::new("screen") + .args(["-x", &*args.inscreen,"-p","init", "-X","kill"]) + .output() + .expect("Failed to teadown 'init' screen"); + + output(format!("NOTE: command were executed in a screen session, attach to the screen session by executing 'screen -x {}'", args.inscreen), OutputType::Info); + output_str("(see 'man screen' or 'STRG + a :help' for getting information about handling screen sessions)", OutputType::Info); + + } + failed_nodes.sort(); failed_nodes.dedup(); From 128d79e1110c0308b90fd0160ef818b1d337aab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Sch=C3=B6chlin?= Date: Fri, 4 Apr 2025 18:13:08 +0200 Subject: [PATCH 6/8] fix returncode --- hostctl.conf | 9 ++++----- src/execute.rs | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/hostctl.conf b/hostctl.conf index 5557504..5a08b83 100644 --- a/hostctl.conf +++ b/hostctl.conf @@ -1,7 +1,6 @@ # : : , , ... -foobar-l01-(ap|db)\d+ : web1 : foobar-l01-ap01, foobar-l01-ap02, foobar-l01-ap03, foobar-l01-ap04, foobar-l01-ap05, foobar-l01-ap06 -foobar-l01-(ap|db)\d+ : db1 : foobar-l01-db01, foobar-l01-db02, foobar-l01-db03 - -jump-barfoo : web2 : barfoo-l01-ap01, barfoo-l01-ap02, barfoo-l01-ap03, barfoo-l01-ap04, barfoo-l01-ap05, barfoo-l01-ap06 -jump-barfoo : db2 : barfoo-l01-db01, barfoo-l01-db02, barfoo-l01-db03 +#foobar-l01-(ap|db)\d+ : web1 : foobar-l01-ap01, foobar-l01-ap02, foobar-l01-ap03, foobar-l01-ap04, foobar-l01-ap05, foobar-l01-ap06 +#foobar-l01-(ap|db)\d+ : db1 : foobar-l01-db01, foobar-l01-db02, foobar-l01-db03 +#jump-barfoo : web2 : barfoo-l01-ap01, barfoo-l01-ap02, barfoo-l01-ap03, barfoo-l01-ap04, barfoo-l01-ap05, barfoo-l01-ap06 +#jump-barfoo : db2 : barfoo-l01-db01, barfoo-l01-db02, barfoo-l01-db03 diff --git a/src/execute.rs b/src/execute.rs index 55628d3..8a3df34 100644 --- a/src/execute.rs +++ b/src/execute.rs @@ -213,10 +213,10 @@ fn execute_remote(node: String, templated_lines: Vec, args: &CommandLine let status = child.wait().expect("Failed to wait for script"); if !status.success() { output(format!("FAILED, EXITCODE WAS : {}\n", status.code().unwrap()), OutputType::Error); - false; + return false; } output("\nSUCCESS\n".to_string(), OutputType::Info); - true + return true; } #[derive(Debug, PartialEq)] From 26f3d899aa3af6cd019170c6096e7f84c1f54e07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Sch=C3=B6chlin?= Date: Fri, 4 Apr 2025 21:16:06 +0200 Subject: [PATCH 7/8] fix --- src/execute.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/execute.rs b/src/execute.rs index 8a3df34..4f916e3 100644 --- a/src/execute.rs +++ b/src/execute.rs @@ -297,6 +297,7 @@ pub fn execute_nodes(nodes: Vec, only_nodes: bool, execute_local: bool, let number_of_nodes = nodes.len(); let mut number_of_current = 0; let mut failed_nodes: Vec = Vec::new(); + let mut successful_nodes: Vec = Vec::new(); if nodes.len() == 0 { output_str("EXIT: No nodes were specified", OutputType::Fatal); @@ -318,6 +319,7 @@ pub fn execute_nodes(nodes: Vec, only_nodes: bool, execute_local: bool, match res { NodeResult::Failed => { failed_nodes.push(node.clone());}, NodeResult::Quit => {failed_nodes.push(node.clone()); break 'node_loop}, + NodeResult::Ok => {successful_nodes.push(node.clone());}, _ => {} } if args.wait > 0 { @@ -361,6 +363,10 @@ pub fn execute_nodes(nodes: Vec, only_nodes: bool, execute_local: bool, if failed_nodes.len() > 0 { let failed_nodes_str = failed_nodes.join(", "); output(format!("\n\nCOMPLETED - ONE OR MORE NODES FAILED!\n\nFAILED NODES: {failed_nodes_str}"), OutputType::Error); + if successful_nodes.len() > 0{ + let successful_nodes_str = failed_nodes.join(", "); + output(format!("SUCCESSFUL NODES: {successful_nodes_str}"), OutputType::Error); + } } else { output_str("\n\nCOMPLETED - ALL NODES WERE SUCCESSFUL", OutputType::Info); } From 9e9623d62dce667a980a7bd2a75081992510dcee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Sch=C3=B6chlin?= Date: Fri, 4 Apr 2025 21:19:55 +0200 Subject: [PATCH 8/8] update --- misc/hostctl_bash_completion.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/hostctl_bash_completion.sh b/misc/hostctl_bash_completion.sh index b925ce6..b22820c 100644 --- a/misc/hostctl_bash_completion.sh +++ b/misc/hostctl_bash_completion.sh @@ -19,7 +19,7 @@ _hostctl() { case "${cmd}" in hostctl) - opts="-c -e -r -n -s -a -j -d -f -q -b -i -o -l -t -w -p -m -h -V --command --execute-local --recipe --nodes --show --for-complete --array --json --debug --forcecolor --quiet --batchmode --inscreen --optssh --login --sudo --term --wait --prompt --makeselection --log-level --help --version [ITEM]..." + opts="-c -e -r -n -s -a -j -d -f -q -b -i -o -l -t -w -p -m -h -V --command --execute-local --recipe --nodes --show --for-completion --array --json --debug --forcecolor --quiet --batchmode --inscreen --optssh --login --sudo --term --wait --prompt --makeselection --log-level --help --version [ITEM]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0