mirror of
https://github.com/chipsenkbeil/distant.git
synced 2024-11-05 12:00:36 +00:00
Rename format to mode; remove unsupported --detach option on proc-run
This commit is contained in:
parent
b9cec3399b
commit
c7b8db517c
@ -133,10 +133,6 @@ pub enum RequestPayload {
|
||||
|
||||
/// Arguments for the command
|
||||
args: Vec<String>,
|
||||
|
||||
/// Whether or not to detach from the running process without killing it
|
||||
#[structopt(long)]
|
||||
detach: bool,
|
||||
},
|
||||
|
||||
/// Kills a process running on the remote machine
|
||||
|
39
src/opt.rs
39
src/opt.rs
@ -8,6 +8,7 @@ use std::{
|
||||
str::FromStr,
|
||||
};
|
||||
use structopt::StructOpt;
|
||||
use strum::{EnumString, EnumVariantNames, VariantNames};
|
||||
|
||||
lazy_static! {
|
||||
static ref USERNAME: String = whoami::username();
|
||||
@ -83,34 +84,18 @@ pub enum SessionSubcommand {
|
||||
Clear,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Display, PartialEq, Eq, IsVariant)]
|
||||
pub enum ResponseFormat {
|
||||
/// Output responses in JSON format
|
||||
#[display(fmt = "json")]
|
||||
/// Represents the communication medium used for the send command
|
||||
#[derive(Copy, Clone, Debug, Display, PartialEq, Eq, IsVariant, EnumString, EnumVariantNames)]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum SendMode {
|
||||
/// Sends and receives data in JSON format
|
||||
Json,
|
||||
|
||||
/// Output responses in a manner that makes sense from a shell
|
||||
#[display(fmt = "shell")]
|
||||
/// Commands are traditional shell commands and output responses are
|
||||
/// inline with what is expected of a program's output in a shell
|
||||
Shell,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Display, From, Error, PartialEq, Eq)]
|
||||
pub enum ResponseFormatParseError {
|
||||
InvalidVariant(#[error(not(source))] String),
|
||||
}
|
||||
|
||||
impl FromStr for ResponseFormat {
|
||||
type Err = ResponseFormatParseError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s.trim() {
|
||||
"json" => Ok(Self::Json),
|
||||
"shell" => Ok(Self::Shell),
|
||||
x => Err(ResponseFormatParseError::InvalidVariant(x.to_string())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents subcommand to execute some operation remotely
|
||||
#[derive(Debug, StructOpt)]
|
||||
#[structopt(verbatim_doc_comment)]
|
||||
@ -123,11 +108,11 @@ pub struct SendSubcommand {
|
||||
#[structopt(
|
||||
short,
|
||||
long,
|
||||
value_name = "json|shell",
|
||||
default_value = "shell",
|
||||
possible_values = &["json", "shell"]
|
||||
case_insensitive = true,
|
||||
default_value = "Shell",
|
||||
possible_values = SendMode::VARIANTS
|
||||
)]
|
||||
pub format: ResponseFormat,
|
||||
pub mode: SendMode,
|
||||
|
||||
#[structopt(subcommand)]
|
||||
pub operation: RequestPayload,
|
||||
|
@ -37,8 +37,8 @@ pub(super) async fn process(
|
||||
RequestPayload::Remove { path, force } => remove(path, force).await,
|
||||
RequestPayload::Copy { src, dst } => copy(src, dst).await,
|
||||
RequestPayload::Rename { src, dst } => rename(src, dst).await,
|
||||
RequestPayload::ProcRun { cmd, args, detach } => {
|
||||
proc_run(client_id, state, tx, cmd, args, detach).await
|
||||
RequestPayload::ProcRun { cmd, args } => {
|
||||
proc_run(client_id, state, tx, cmd, args).await
|
||||
}
|
||||
RequestPayload::ProcKill { id } => proc_kill(state, id).await,
|
||||
RequestPayload::ProcStdin { id, data } => proc_stdin(state, id, data).await,
|
||||
@ -192,7 +192,6 @@ async fn proc_run(
|
||||
tx: Reply,
|
||||
cmd: String,
|
||||
args: Vec<String>,
|
||||
detach: bool,
|
||||
) -> Result<ResponsePayload, Box<dyn Error>> {
|
||||
let id = rand::random();
|
||||
|
||||
@ -327,16 +326,13 @@ async fn proc_run(
|
||||
};
|
||||
state.lock().await.processes.insert(id, process);
|
||||
|
||||
// If we are not detaching from process, we want to associate it with our client
|
||||
if !detach {
|
||||
state
|
||||
.lock()
|
||||
.await
|
||||
.client_processes
|
||||
.entry(client_id)
|
||||
.or_insert(Vec::new())
|
||||
.push(id);
|
||||
}
|
||||
state
|
||||
.lock()
|
||||
.await
|
||||
.client_processes
|
||||
.entry(client_id)
|
||||
.or_insert(Vec::new())
|
||||
.push(id);
|
||||
|
||||
Ok(ResponsePayload::ProcStart { id })
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
data::{Request, RequestPayload, Response, ResponsePayload},
|
||||
net::{Client, TransportError},
|
||||
opt::{CommonOpt, ResponseFormat, SendSubcommand},
|
||||
opt::{CommonOpt, SendMode, SendSubcommand},
|
||||
utils::{Session, SessionError},
|
||||
};
|
||||
use derive_more::{Display, Error, From};
|
||||
@ -30,11 +30,6 @@ async fn run_async(cmd: SendSubcommand, _opt: CommonOpt) -> Result<(), Error> {
|
||||
|
||||
// Special conditions for continuing to process responses
|
||||
let is_proc_req = req.payload.is_proc_run();
|
||||
let not_detach = if let RequestPayload::ProcRun { detach, .. } = req.payload {
|
||||
!detach
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
let res = client.send(req).await?;
|
||||
|
||||
@ -44,11 +39,11 @@ async fn run_async(cmd: SendSubcommand, _opt: CommonOpt) -> Result<(), Error> {
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
format_response(cmd.format, res)?.print();
|
||||
format_response(cmd.mode, res)?.print();
|
||||
|
||||
// If we are executing a process and not detaching, we want to continue receiving
|
||||
// responses sent to us
|
||||
if is_proc_req && not_detach {
|
||||
if is_proc_req {
|
||||
let mut stream = client.to_response_stream();
|
||||
|
||||
// We also want to spawn a task to handle sending stdin to the remote process
|
||||
@ -80,7 +75,7 @@ async fn run_async(cmd: SendSubcommand, _opt: CommonOpt) -> Result<(), Error> {
|
||||
})?;
|
||||
let done = res.payload.is_proc_done();
|
||||
|
||||
format_response(cmd.format, res)?.print();
|
||||
format_response(cmd.mode, res)?.print();
|
||||
|
||||
if done {
|
||||
break;
|
||||
@ -134,13 +129,13 @@ impl ResponseOut {
|
||||
}
|
||||
}
|
||||
|
||||
fn format_response(fmt: ResponseFormat, res: Response) -> io::Result<ResponseOut> {
|
||||
Ok(match fmt {
|
||||
ResponseFormat::Json => ResponseOut::Stdout(
|
||||
fn format_response(mode: SendMode, res: Response) -> io::Result<ResponseOut> {
|
||||
Ok(match mode {
|
||||
SendMode::Json => ResponseOut::Stdout(
|
||||
serde_json::to_string(&res)
|
||||
.map_err(|x| io::Error::new(io::ErrorKind::InvalidData, x))?,
|
||||
),
|
||||
ResponseFormat::Shell => format_shell(res),
|
||||
SendMode::Shell => format_shell(res),
|
||||
})
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user