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
|
||||
```
|
||||
|
||||
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
|
||||
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:
|
||||
```
|
||||
minez:
|
||||
minez (minez3/plugins):
|
||||
* renaming MineZ-2.7.jar -> MineZ-2.7.jarr
|
||||
+ adding MineZ-3.0.jar
|
||||
Continue [Y|n]:
|
||||
|
||||
@ -19,10 +19,6 @@ impl TryFrom<PathBuf> for FileNameInfo {
|
||||
type Error = FileInfoError;
|
||||
|
||||
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_name
|
||||
.to_str()
|
||||
|
||||
90
src/main.rs
90
src/main.rs
@ -6,7 +6,7 @@ mod os_string_builder;
|
||||
mod server;
|
||||
|
||||
use crate::action::{Action, FileAction, ServerActions};
|
||||
use crate::command::LogRunnable;
|
||||
use crate::command::{ExecutionError, LogRunnable};
|
||||
use crate::file::{FileMatcher, FileNameInfo};
|
||||
use crate::logger::{LogLevel, Logger};
|
||||
use crate::os_string_builder::ReplaceWithOsStr;
|
||||
@ -18,7 +18,7 @@ use std::cell::LazyCell;
|
||||
use std::hash::Hash;
|
||||
use std::io::Write;
|
||||
use std::iter::once;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
use std::{env, fs, io};
|
||||
|
||||
@ -63,6 +63,12 @@ enum Command {
|
||||
Upload {
|
||||
/// The file to upload
|
||||
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
|
||||
#[arg(short = 'a', long, default_value = "delete", default_missing_value = "archive", num_args = 0..=1)]
|
||||
old_version_policy: OldVersionPolicy,
|
||||
@ -157,14 +163,14 @@ fn main() -> Result<(), String> {
|
||||
.servers
|
||||
.iter()
|
||||
.map(|server_reference| {
|
||||
let server_name = server_reference.get_identifier();
|
||||
let server_identifier = server_reference.get_identifier();
|
||||
server_reference
|
||||
.clone()
|
||||
.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| {
|
||||
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 {
|
||||
Command::Upload {
|
||||
file,
|
||||
file_server,
|
||||
old_version_policy,
|
||||
upload_directory,
|
||||
no_confirm,
|
||||
@ -181,6 +188,55 @@ fn main() -> Result<(), String> {
|
||||
require_non_empty_servers(&servers)?;
|
||||
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 =
|
||||
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 {
|
||||
match file_action.kind {
|
||||
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 {
|
||||
ServerAddress::Ssh { ssh_address } => format!("{ssh_address}:"),
|
||||
ServerAddress::Localhost => "".to_string(),
|
||||
}) + &server_actions.working_directory;
|
||||
ShellCmd::new("scp")
|
||||
.arg(file.clone())
|
||||
.arg(scp_source)
|
||||
.arg(scp_target)
|
||||
.run(&logger)
|
||||
.map_err(|e| format!("upload failure: {e}"))?;
|
||||
@ -470,6 +533,21 @@ fn main() -> Result<(), String> {
|
||||
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> {
|
||||
homedir::my_home()
|
||||
.map_err(|e| format!("Failed to determine home directory: {e}"))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user