mirror of
https://github.com/house-of-vanity/rexec.git
synced 2025-07-08 01:04:07 +00:00
Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
080ce8984a | |||
b360e29666 | |||
1d26a9c6be | |||
48e7e2a4e4 | |||
aa0a4e8bd2 | |||
554b68b51e | |||
c206ddaef2 | |||
e620348834 | |||
dc1a67fe01 | |||
1d208149f5 | |||
093157b6ef | |||
04da0fb97c | |||
967d9c0e7d | |||
eb0fd40d9f | |||
d0bbb29078 | |||
5a388853c5 | |||
41bf46c408 | |||
a2b05a7fa6 |
39
.github/workflows/arm_build.yml
vendored
Normal file
39
.github/workflows/arm_build.yml
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
name: ARM Rust static build and publish
|
||||
on: ["push"]
|
||||
# push:
|
||||
# tags:
|
||||
# - '*'
|
||||
#
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
BUILD_TARGET: x86_64-unknown-linux-musl
|
||||
BINARY_NAME: rexec
|
||||
jobs:
|
||||
build:
|
||||
name: Build static binary
|
||||
runs-on: self-hosted
|
||||
container:
|
||||
image: rust:latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
# - uses: dtolnay/rust-toolchain@stable
|
||||
# - name: Build-musl
|
||||
# uses: gmiam/rust-musl-action@master
|
||||
# with:
|
||||
# args: cargo build --target $BUILD_TARGET --release
|
||||
- name: Deps
|
||||
run: |
|
||||
rustup target add x86_64-unknown-linux-musl
|
||||
cargo build --target ${{ env.BUILD_TARGET }} --release
|
||||
|
||||
- name: Get version
|
||||
run: echo "VERSION=$(grep -P '^version = \"\d+\.\d+\.\d+\"' Cargo.toml | awk -F '\"' '{print $2}')" >> $GITHUB_ENV
|
||||
- name: Show version
|
||||
run: echo ${{ env.VERSION }}
|
||||
- uses: actions/upload-artifact@v3.1.2
|
||||
name: Upload artifact
|
||||
with:
|
||||
name: ${{ env.BINARY_NAME }}_${{ env.VERSION }}_${{ env.BUILD_TARGET }}
|
||||
path: target/${{ env.BUILD_TARGET }}/release/${{ env.BINARY_NAME }}
|
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -67,7 +67,7 @@ jobs:
|
||||
|
||||
|
||||
release:
|
||||
name: Release binary
|
||||
name: Making New Release ^_^
|
||||
needs:
|
||||
- build
|
||||
- build_arch
|
||||
|
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1066,7 +1066,7 @@ checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
|
||||
|
||||
[[package]]
|
||||
name = "rexec"
|
||||
version = "1.0.6"
|
||||
version = "1.0.8"
|
||||
dependencies = [
|
||||
"brace-expand",
|
||||
"clap 4.3.4",
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rexec"
|
||||
version = "1.0.7"
|
||||
version = "1.0.8"
|
||||
readme = "https://github.com/house-of-vanity/rexec#readme"
|
||||
edition = "2021"
|
||||
description = "Parallel SSH executor"
|
||||
|
62
README.md
62
README.md
@ -1,14 +1,20 @@
|
||||
# rexec
|
||||
Parallel SSH executor in Rust. It can read servers from `~/.ssh/known_hosts`
|
||||
|
||||
or even expand servers from bash expanshion line `cassandra.{prod,dev}.example.com`
|
||||
**Parallel SSH executor** in Rust with static binary. It can read servers from `~/.ssh/known_hosts`
|
||||
|
||||
or even expand servers from bash expanshion line `cassandra-[1:5].{prod,dev}.example.com`
|
||||
|
||||
[](https://github.com/house-of-vanity/rexec/actions/workflows/release.yml)
|
||||
---
|
||||
|
||||
|
||||
## Usage
|
||||
```shell
|
||||
[ab@test]$ ./rexec -k admin-gce-sc.* --help
|
||||
_|_|_|_| _| _| _|_|_|_| _|_|_|
|
||||
_| _|_| _| _| _| _| _|
|
||||
_|_| _|_|_| _| _|_|_| _|
|
||||
_| _| _| _| _| _|
|
||||
_| _|_|_|_| _| _| _|_|_|_| _|_|_|
|
||||
|
||||
|
||||
Parallel SSH executor in Rust
|
||||
|
||||
Usage: rexec [OPTIONS] --expression <EXPRESSION> --command <COMMAND>
|
||||
@ -24,9 +30,44 @@ Options:
|
||||
-h, --help Print help
|
||||
-V, --version Print version
|
||||
```
|
||||
---
|
||||
|
||||
## Examples
|
||||
```shell
|
||||
[ab@test]$ rexec -e 'cassandra-gce-sc-[1:3].bbs-prod.*' -u ab -c 'df -h /srv/cassandra'
|
||||
[INFO ] Using string expansion to build server list.
|
||||
[INFO ] Matched hosts:
|
||||
[INFO ] cassandra-gce-sc-1.bbs-prod.* [35.221.18.35]
|
||||
[INFO ] cassandra-gce-sc-2.bbs-prod.* [35.212.13.174]
|
||||
[INFO ] cassandra-gce-sc-3.bbs-prod.* [35.211.213.123]
|
||||
Continue on following 3 servers? y
|
||||
[INFO ]
|
||||
|
||||
[INFO ] Run command on 3 servers.
|
||||
[INFO ]
|
||||
|
||||
[INFO ] cassandra-gce-sc-2.bbs-prod.*
|
||||
Code 0
|
||||
STDOUT:
|
||||
Filesystem Size Used Avail Use% Mounted on
|
||||
/dev/mapper/storage-cassandra 1.0T 613G 411G 60% /srv/cassandra
|
||||
|
||||
[INFO ] cassandra-gce-sc-1.bbs-prod.*
|
||||
Code 0
|
||||
STDOUT:
|
||||
Filesystem Size Used Avail Use% Mounted on
|
||||
/dev/mapper/storage-cassandra 1.0T 594G 430G 59% /srv/cassandra
|
||||
|
||||
[INFO ] cassandra-gce-sc-3.bbs-prod.*
|
||||
Code 0
|
||||
STDOUT:
|
||||
Filesystem Size Used Avail Use% Mounted on
|
||||
/dev/mapper/storage-cassandra 1.0T 523G 502G 52% /srv/cassandra
|
||||
```
|
||||
---
|
||||
|
||||
```shell
|
||||
[ab@test debug]$ ./rexec -u ab -k -c uptime -e admin.* -f
|
||||
[ab@test]$ ./rexec -u ab -k -c uptime -e admin.* -f
|
||||
[INFO ] Matched hosts:
|
||||
[INFO ] admin-gce-sc-1.lca-prod.** [35.211.27.195]
|
||||
[INFO ] admin-gce-sc-1.mmk-prod.** [35.211.79.202]
|
||||
@ -36,27 +77,18 @@ Options:
|
||||
|
||||
[INFO ] Run command on 3 servers.
|
||||
|
||||
|
||||
[INFO ] admin.gnb-prod.**
|
||||
Code 0
|
||||
STDOUT:
|
||||
23:31:21 up 294 days, 14:14, 0 users, load average: 0.53, 0.64, 0.52
|
||||
|
||||
STDERR:
|
||||
|
||||
[INFO ] admin.abe-prod.**
|
||||
Code 0
|
||||
STDOUT:
|
||||
23:31:22 up 154 days, 9:24, 0 users, load average: 0.31, 0.25, 0.18
|
||||
|
||||
STDERR:
|
||||
|
||||
[INFO ] admin-gce-be-1.toy-prod.**
|
||||
Code 0
|
||||
STDOUT:
|
||||
23:31:22 up 98 days, 6:20, 0 users, load average: 0.88, 0.74, 0.80
|
||||
|
||||
STDERR:
|
||||
no server running on /tmp/tmux-1019/default
|
||||
open terminal failed: not a terminal
|
||||
```
|
||||
|
51
src/main.rs
51
src/main.rs
@ -9,7 +9,6 @@ use std::process;
|
||||
|
||||
use clap::Parser;
|
||||
use colored::*;
|
||||
//use dialoguer::Confirm;
|
||||
use dns_lookup::lookup_host;
|
||||
use env_logger::Env;
|
||||
use itertools::Itertools;
|
||||
@ -234,9 +233,7 @@ fn main() {
|
||||
_ => unreachable!(),
|
||||
})
|
||||
{
|
||||
info!("\n");
|
||||
info!("Run command on {} servers.", &config.hosts.len());
|
||||
info!("\n");
|
||||
|
||||
// Run a command on all the configured hosts.
|
||||
// Receive the result of the command for each host and print its output.
|
||||
@ -248,8 +245,8 @@ fn main() {
|
||||
.collect::<Vec<_>>()[0]
|
||||
.to_string();
|
||||
let ip = ip.parse::<IpAddr>().unwrap();
|
||||
info!(
|
||||
"{}",
|
||||
println!(
|
||||
"\n{}",
|
||||
hosts_and_ips
|
||||
.get(&ip)
|
||||
.unwrap_or(&"Couldn't parse IP".to_string())
|
||||
@ -265,14 +262,48 @@ fn main() {
|
||||
continue;
|
||||
}
|
||||
};
|
||||
if output.exit_status == 0 {
|
||||
println!("Code {}", output.exit_status);
|
||||
let code_string = if output.exit_status == 0 {
|
||||
format!("{}", output.exit_status.to_string().green())
|
||||
} else {
|
||||
error!("Code {}", output.exit_status);
|
||||
format!("{}", output.exit_status.to_string().red())
|
||||
};
|
||||
println!(
|
||||
"{}",
|
||||
format!(
|
||||
"Exit code [{}] / stdout {} bytes / stderr {} bytes",
|
||||
code_string,
|
||||
output.stdout.len(),
|
||||
output.stderr.len()
|
||||
)
|
||||
.bold()
|
||||
);
|
||||
|
||||
if !args.code {
|
||||
println!("STDOUT:\n{}", String::from_utf8(output.stdout).unwrap());
|
||||
println!("STDERR:\n{}", String::from_utf8(output.stderr).unwrap());
|
||||
match String::from_utf8(output.stdout) {
|
||||
Ok(stdout) => match stdout.as_str() {
|
||||
"" => {}
|
||||
_ => {
|
||||
println!("{}", "STDOUT".bold().blue());
|
||||
|
||||
for line in stdout.lines() {
|
||||
println!("{} {}", "║".green(), line);
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(_) => {}
|
||||
}
|
||||
match String::from_utf8(output.stderr) {
|
||||
Ok(stderr) => match stderr.as_str() {
|
||||
"" => {}
|
||||
_ => {
|
||||
println!("{}", "STDERR".bold().bright_red());
|
||||
for line in stderr.lines() {
|
||||
println!("{} {}", "║".red(), line);
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user