Compare commits
2 Commits
df26eb435f
...
a4d7fd7506
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a4d7fd7506 | ||
|
|
952ca847cd |
10
Cargo.toml
10
Cargo.toml
@ -1,10 +1,10 @@
|
||||
[package]
|
||||
name = "multi-ssh"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.5.23", features = ["derive"] }
|
||||
lazy-regex = "3.3.0"
|
||||
shell-words = "1.1.0"
|
||||
homedir = "0.3.4"
|
||||
clap = { version = "4.6.6", features = ["derive"] }
|
||||
lazy-regex = "3.6.1"
|
||||
shell-words = "1.1.1"
|
||||
homedir = "0.3.6"
|
||||
14
flake.lock
14
flake.lock
@ -2,16 +2,16 @@
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1759580034,
|
||||
"narHash": "sha256-YWo57PL7mGZU7D4WeKFMiW4ex/O6ZolUS6UNBHTZfkI=",
|
||||
"lastModified": 1787962033,
|
||||
"narHash": "sha256-u6z9VTZA4Kf3RkHQo9sQI7NI4Ei/uiU9vrMqOiwWP1Y=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "3bcc93c5f7a4b30335d31f21e2f1281cba68c318",
|
||||
"rev": "c5c4a43b0e8056328ec4529f735cabdb8f1942bb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-25.05",
|
||||
"ref": "nixos-26.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
@ -43,11 +43,11 @@
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1759631821,
|
||||
"narHash": "sha256-V8A1L0FaU/aSXZ1QNJScxC12uP4hANeRBgI4YdhHeRM=",
|
||||
"lastModified": 1788165049,
|
||||
"narHash": "sha256-en4IoUeCqvq9F66YhwOrUFw1nc70OBhrJwrzfalezvY=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "1d7cbdaad90f8a5255a89a6eddd8af24dc89cafe",
|
||||
"rev": "d03cd474bd97389dcc2e8cd3b3bb6b8c6e346b1a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
description = "Flake of https://dev.stupstech.de/Mr_Steppy/multi-ssh";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";
|
||||
rust-overlay.url = "github:oxalica/rust-overlay";
|
||||
};
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use crate::shell_interface::{
|
||||
build_command_from_shell_command, CommandOutput, CommandResult, ExitStatus, ShellCommand,
|
||||
ShellInterface, StartError,
|
||||
use crate::shell_interface::{CommandOutput, CommandResult, ExitStatus, ShellCommand,
|
||||
ShellInterface, StartError,
|
||||
build_command_from_shell_command,
|
||||
};
|
||||
use std::env::VarError;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
@ -60,7 +60,10 @@ impl Environment for Prod {
|
||||
K: AsRef<OsStr>,
|
||||
V: AsRef<OsStr>,
|
||||
{
|
||||
env::set_var(key, value);
|
||||
unsafe {
|
||||
//multi-ssh is single threaded
|
||||
env::set_var(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_home_directory(&self) -> Option<PathBuf> {
|
||||
|
||||
44
src/main.rs
44
src/main.rs
@ -170,6 +170,30 @@ where
|
||||
},
|
||||
};
|
||||
|
||||
macro_rules! start_ssh_agent {
|
||||
() => {
|
||||
self.start_ssh_agent(&logger)?;
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! ssh {
|
||||
($($field:ident $(: $value:expr)?$(,)? )*) => {{
|
||||
start_ssh_agent!();
|
||||
ShellCommand::Ssh {
|
||||
$( $field $(: $value)? ),*
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! scp {
|
||||
($($field:ident $(: $value:expr)?$(,)? )*) => {{
|
||||
start_ssh_agent!();
|
||||
ShellCommand::Scp {
|
||||
$( $field $(: $value)? ),*
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
let mut configured_servers = LazyCell::new(|| self.parse_server_configuration_from_env());
|
||||
let servers = args
|
||||
.servers
|
||||
@ -223,8 +247,6 @@ where
|
||||
None => None,
|
||||
};
|
||||
|
||||
self.start_ssh_agent(&logger)?;
|
||||
|
||||
//make sure files exist
|
||||
match &file_server {
|
||||
Some(file_server) => match &file_server.address {
|
||||
@ -233,7 +255,7 @@ where
|
||||
files = files
|
||||
.iter()
|
||||
.map(|file| {
|
||||
let output = ShellCommand::Ssh {
|
||||
let output = ssh! {
|
||||
address: ssh_address.to_string(),
|
||||
server_command: ServerCommand::Realpath {
|
||||
path: file_server.server_directory_path.join(file),
|
||||
@ -313,7 +335,7 @@ where
|
||||
server,
|
||||
actions: {
|
||||
let present_file_names: Vec<OsString> = match &server.address {
|
||||
ServerAddress::Ssh { ssh_address } => ShellCommand::Ssh {
|
||||
ServerAddress::Ssh { ssh_address } => ssh! {
|
||||
address: ssh_address.to_string(),
|
||||
server_command: ServerCommand::Ls {
|
||||
dir: working_directory.clone(),
|
||||
@ -472,7 +494,7 @@ where
|
||||
None => ScpParam::from(file_action.file.as_path()),
|
||||
};
|
||||
let destination = ScpParam::from((server, &server_actions.working_directory));
|
||||
ShellCommand::Scp {
|
||||
scp! {
|
||||
source,
|
||||
destination,
|
||||
}
|
||||
@ -484,7 +506,7 @@ where
|
||||
}
|
||||
Action::Delete => match &server.address {
|
||||
ServerAddress::Ssh { ssh_address } => {
|
||||
ShellCommand::Ssh {
|
||||
ssh! {
|
||||
address: ssh_address.to_string(),
|
||||
server_command: ServerCommand::Rm {
|
||||
file: server_actions.working_directory.join(&file_action.file),
|
||||
@ -503,7 +525,7 @@ where
|
||||
},
|
||||
Action::Rename { new_name } => match &server.address {
|
||||
ServerAddress::Ssh { ssh_address } => {
|
||||
ShellCommand::Ssh {
|
||||
ssh! {
|
||||
address: ssh_address.to_string(),
|
||||
server_command: ServerCommand::Mv {
|
||||
source: server_actions.working_directory.join(&file_action.file),
|
||||
@ -529,13 +551,12 @@ where
|
||||
log!(logger, "Done!");
|
||||
}
|
||||
Command::Command { command } => {
|
||||
self.start_ssh_agent(&logger)?;
|
||||
Self::require_non_empty_servers(&servers)?;
|
||||
for server in servers {
|
||||
log!(logger, "Running command on '{}'...", server.get_name());
|
||||
match &server.address {
|
||||
ServerAddress::Ssh { ssh_address } => {
|
||||
ShellCommand::Ssh {
|
||||
ssh! {
|
||||
address: ssh_address.to_string(),
|
||||
server_command: ServerCommand::Execute {
|
||||
working_directory: server.server_directory_path.clone(),
|
||||
@ -625,12 +646,11 @@ where
|
||||
}
|
||||
|
||||
Self::require_non_empty_servers(&servers)?;
|
||||
self.start_ssh_agent(&logger)?;
|
||||
|
||||
for server in servers {
|
||||
log!(logger, "Getting file from {}...", server.get_name());
|
||||
let source = ScpParam::from((&server, server.server_directory_path.join(&file)));
|
||||
ShellCommand::Scp {
|
||||
scp! {
|
||||
source: source.clone(),
|
||||
destination: ScpParam::from(download_directory.as_path()),
|
||||
}
|
||||
@ -657,7 +677,7 @@ where
|
||||
.map_err(|e| format!("failed to open file in editor: {e}"))?;
|
||||
|
||||
//upload file again
|
||||
ShellCommand::Scp {
|
||||
scp! {
|
||||
source: ScpParam::from(download_directory.join(file_name).as_path()),
|
||||
destination: source,
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ pub enum ShellCommand {
|
||||
}
|
||||
|
||||
impl ShellCommand {
|
||||
pub fn in_env<E>(self, environment: &mut E) -> EnvCommand<E> {
|
||||
pub fn in_env<E>(self, environment: &mut E) -> EnvCommand<'_, E> {
|
||||
EnvCommand {
|
||||
command: self,
|
||||
environment,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user