Merge pull request '15-allow-uploading-files-from-another-server' (#18) from 15-allow-uploading-files-from-another-server into master
Reviewed-on: https://stupstech.de/dev/Mr_Steppy/multi-ssh/pulls/18
This commit is contained in:
commit
60f5055c5e
@ -47,14 +47,14 @@ Upload a new version of the MenuApi plugin and delete old versions from the serv
|
|||||||
multi-ssh crea sky city minez lobby -u target/MenuApi-3.4.2.jar
|
multi-ssh crea sky city minez lobby -u target/MenuApi-3.4.2.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
Upload a new version of the MineZ plugin but keep backups of the older versions:
|
Upload a new version of the MineZ plugin from the MineZ-Dev and keep backups of the older versions:
|
||||||
```bash
|
```bash
|
||||||
multi-ssh minez -u target/MineZ-3.0.jar -a
|
multi-ssh minez -u -S minez-dev plugins/MineZ-3.0.jar -a
|
||||||
```
|
```
|
||||||
|
|
||||||
The program will show you an overview of what it will be doing before actually performing any of the actions:
|
The program will show you an overview of what it will be doing before actually performing any of the actions:
|
||||||
```
|
```
|
||||||
minez:
|
minez (minez3/plugins):
|
||||||
* renaming MineZ-2.7.jar -> MineZ-2.7.jarr
|
* renaming MineZ-2.7.jar -> MineZ-2.7.jarr
|
||||||
+ adding MineZ-3.0.jar
|
+ adding MineZ-3.0.jar
|
||||||
Continue [Y|n]:
|
Continue [Y|n]:
|
||||||
|
|||||||
@ -19,10 +19,6 @@ impl TryFrom<PathBuf> for FileNameInfo {
|
|||||||
type Error = FileInfoError;
|
type Error = FileInfoError;
|
||||||
|
|
||||||
fn try_from(file: PathBuf) -> Result<Self, Self::Error> {
|
fn try_from(file: PathBuf) -> Result<Self, Self::Error> {
|
||||||
if !file.is_file() {
|
|
||||||
return Err(FileInfoError::NotAFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
let file_name = file.file_name().ok_or(FileInfoError::NotAFile)?;
|
let file_name = file.file_name().ok_or(FileInfoError::NotAFile)?;
|
||||||
let file_name = file_name
|
let file_name = file_name
|
||||||
.to_str()
|
.to_str()
|
||||||
|
|||||||
90
src/main.rs
90
src/main.rs
@ -6,7 +6,7 @@ mod os_string_builder;
|
|||||||
mod server;
|
mod server;
|
||||||
|
|
||||||
use crate::action::{Action, FileAction, ServerActions};
|
use crate::action::{Action, FileAction, ServerActions};
|
||||||
use crate::command::LogRunnable;
|
use crate::command::{ExecutionError, LogRunnable};
|
||||||
use crate::file::{FileMatcher, FileNameInfo};
|
use crate::file::{FileMatcher, FileNameInfo};
|
||||||
use crate::logger::{LogLevel, Logger};
|
use crate::logger::{LogLevel, Logger};
|
||||||
use crate::os_string_builder::ReplaceWithOsStr;
|
use crate::os_string_builder::ReplaceWithOsStr;
|
||||||
@ -18,7 +18,7 @@ use std::cell::LazyCell;
|
|||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::iter::once;
|
use std::iter::once;
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::{env, fs, io};
|
use std::{env, fs, io};
|
||||||
|
|
||||||
@ -63,6 +63,12 @@ enum Command {
|
|||||||
Upload {
|
Upload {
|
||||||
/// The file to upload
|
/// The file to upload
|
||||||
file: PathBuf,
|
file: PathBuf,
|
||||||
|
/// The ssh server to get the file from.
|
||||||
|
///
|
||||||
|
/// When this option is set, the file path must be absolute, or relative to the server directory.
|
||||||
|
/// The upload-directory has no influence on where the file will be taken from.
|
||||||
|
#[arg(short = 'S', long)]
|
||||||
|
file_server: Option<ServerReference>,
|
||||||
/// How to handle older versions of the file
|
/// How to handle older versions of the file
|
||||||
#[arg(short = 'a', long, default_value = "delete", default_missing_value = "archive", num_args = 0..=1)]
|
#[arg(short = 'a', long, default_value = "delete", default_missing_value = "archive", num_args = 0..=1)]
|
||||||
old_version_policy: OldVersionPolicy,
|
old_version_policy: OldVersionPolicy,
|
||||||
@ -157,14 +163,14 @@ fn main() -> Result<(), String> {
|
|||||||
.servers
|
.servers
|
||||||
.iter()
|
.iter()
|
||||||
.map(|server_reference| {
|
.map(|server_reference| {
|
||||||
let server_name = server_reference.get_identifier();
|
let server_identifier = server_reference.get_identifier();
|
||||||
server_reference
|
server_reference
|
||||||
.clone()
|
.clone()
|
||||||
.try_resolve_lazy(&mut configured_servers)
|
.try_resolve_lazy(&mut configured_servers)
|
||||||
.map_err(|msg| format!("Can't resolve server directory for '{server_name}': {msg}"))
|
.map_err(|msg| format!("Can't resolve server directory for '{server_identifier}': {msg}"))
|
||||||
.and_then(|opt_server| {
|
.and_then(|opt_server| {
|
||||||
opt_server.ok_or(format!(
|
opt_server.ok_or(format!(
|
||||||
"no server directory has been configured for server '{server_name}'"
|
"no server directory has been configured for server '{server_identifier}'"
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -173,6 +179,7 @@ fn main() -> Result<(), String> {
|
|||||||
match args.command {
|
match args.command {
|
||||||
Command::Upload {
|
Command::Upload {
|
||||||
file,
|
file,
|
||||||
|
file_server,
|
||||||
old_version_policy,
|
old_version_policy,
|
||||||
upload_directory,
|
upload_directory,
|
||||||
no_confirm,
|
no_confirm,
|
||||||
@ -181,6 +188,55 @@ fn main() -> Result<(), String> {
|
|||||||
require_non_empty_servers(&servers)?;
|
require_non_empty_servers(&servers)?;
|
||||||
start_ssh_agent(&logger)?;
|
start_ssh_agent(&logger)?;
|
||||||
|
|
||||||
|
//resolve file server
|
||||||
|
let file_server = match file_server {
|
||||||
|
Some(server_reference) => {
|
||||||
|
let file_server_identifier = server_reference.get_identifier().to_string();
|
||||||
|
let server = server_reference.try_resolve_lazy(&mut configured_servers)
|
||||||
|
.map_err(|e| format!("Can't resolve server directory for file-server '{file_server_identifier}': {e}"))?
|
||||||
|
.ok_or_else(|| format!("no server directory has been configured for file-server '{file_server_identifier}'"))?;
|
||||||
|
Some(server)
|
||||||
|
}
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
//make sure file exists and is a file
|
||||||
|
match &file_server {
|
||||||
|
Some(file_server) => {
|
||||||
|
match &file_server.address {
|
||||||
|
ServerAddress::Ssh { ssh_address } => {
|
||||||
|
match ShellCmd::new("ssh")
|
||||||
|
.arg(ssh_address)
|
||||||
|
.arg(osf!("test -f ") + file_server.server_directory_path.join(&file))
|
||||||
|
.collect_output()
|
||||||
|
{
|
||||||
|
Ok(_) => {} //file exists on file server
|
||||||
|
Err(e) => {
|
||||||
|
match &e.error {
|
||||||
|
ExecutionError::StartError(_) => {
|
||||||
|
//error occurred
|
||||||
|
Err(format!(
|
||||||
|
"Failed to check whether file exists on file-server: {e}"
|
||||||
|
))?;
|
||||||
|
}
|
||||||
|
ExecutionError::BadExitStatus(_) => {
|
||||||
|
//file does not exist on file server
|
||||||
|
Err("File doesn't exist on file server")?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
ServerAddress::Localhost => {
|
||||||
|
check_local_file_exists(file_server.server_directory_path.join(&file))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
check_local_file_exists(&file)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let file_name_info =
|
let file_name_info =
|
||||||
FileNameInfo::try_from(file.clone()).map_err(|e| format!("bad file: {e}"))?;
|
FileNameInfo::try_from(file.clone()).map_err(|e| format!("bad file: {e}"))?;
|
||||||
|
|
||||||
@ -294,12 +350,19 @@ fn main() -> Result<(), String> {
|
|||||||
for file_action in server_actions.actions {
|
for file_action in server_actions.actions {
|
||||||
match file_action.kind {
|
match file_action.kind {
|
||||||
Action::Add | Action::Replace => {
|
Action::Add | Action::Replace => {
|
||||||
|
let scp_source = match &file_server {
|
||||||
|
Some(file_server) => osf!(match &file_server.address {
|
||||||
|
ServerAddress::Ssh{ ssh_address } => format!("{ssh_address}:"),
|
||||||
|
ServerAddress::Localhost => "".to_string(),
|
||||||
|
}) + file_server.server_directory_path.join(&file),
|
||||||
|
None => osf!(&file),
|
||||||
|
};
|
||||||
let scp_target = osf!(match &server.address {
|
let scp_target = osf!(match &server.address {
|
||||||
ServerAddress::Ssh { ssh_address } => format!("{ssh_address}:"),
|
ServerAddress::Ssh { ssh_address } => format!("{ssh_address}:"),
|
||||||
ServerAddress::Localhost => "".to_string(),
|
ServerAddress::Localhost => "".to_string(),
|
||||||
}) + &server_actions.working_directory;
|
}) + &server_actions.working_directory;
|
||||||
ShellCmd::new("scp")
|
ShellCmd::new("scp")
|
||||||
.arg(file.clone())
|
.arg(scp_source)
|
||||||
.arg(scp_target)
|
.arg(scp_target)
|
||||||
.run(&logger)
|
.run(&logger)
|
||||||
.map_err(|e| format!("upload failure: {e}"))?;
|
.map_err(|e| format!("upload failure: {e}"))?;
|
||||||
@ -470,6 +533,21 @@ fn main() -> Result<(), String> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_local_file_exists<P>(path: P) -> Result<(), String>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
let path = path.as_ref();
|
||||||
|
if !path.is_file() {
|
||||||
|
return Err(format!(
|
||||||
|
"{} does not point to a file",
|
||||||
|
path.to_string_lossy()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn get_home_directory() -> Result<PathBuf, String> {
|
fn get_home_directory() -> Result<PathBuf, String> {
|
||||||
homedir::my_home()
|
homedir::my_home()
|
||||||
.map_err(|e| format!("Failed to determine home directory: {e}"))
|
.map_err(|e| format!("Failed to determine home directory: {e}"))
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user