allow input in `trvmctl run`
This commit is contained in:
parent
cfe35b3edb
commit
bc41781df0
|
@ -56,6 +56,10 @@ pub enum Commands {
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Run a command in a currently running VM.
|
/// Run a command in a currently running VM.
|
||||||
|
///
|
||||||
|
/// If standard input is not a terminal, all standard input is collected before invoking the
|
||||||
|
/// program. All standard output is collected before returning from the function. Interactive
|
||||||
|
/// programs are not possible at this time..
|
||||||
Run {
|
Run {
|
||||||
/// The command to run.
|
/// The command to run.
|
||||||
command: String,
|
command: String,
|
||||||
|
|
24
src/main.rs
24
src/main.rs
|
@ -2,13 +2,14 @@
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use eyre::WrapErr;
|
use eyre::WrapErr;
|
||||||
use std::io::Write;
|
use std::io::{IsTerminal, Read, Write};
|
||||||
|
|
||||||
mod cli;
|
mod cli;
|
||||||
mod vm;
|
mod vm;
|
||||||
|
|
||||||
use vm::{SpawnArguments, VirtualMachine};
|
use vm::{SpawnArguments, VirtualMachine};
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_lines)]
|
||||||
fn main() -> eyre::Result<()> {
|
fn main() -> eyre::Result<()> {
|
||||||
color_eyre::install()?;
|
color_eyre::install()?;
|
||||||
|
|
||||||
|
@ -54,7 +55,7 @@ fn main() -> eyre::Result<()> {
|
||||||
.ok_or(eyre::eyre!("no hostname"))?
|
.ok_or(eyre::eyre!("no hostname"))?
|
||||||
.as_str()
|
.as_str()
|
||||||
.ok_or(eyre::eyre!("hostname is not str"))?;
|
.ok_or(eyre::eyre!("hostname is not str"))?;
|
||||||
let uptime = vm.run_command("uptime", [])?;
|
let uptime = vm.run_command("uptime", [], None)?;
|
||||||
eprintln!("hostname: {hostname}");
|
eprintln!("hostname: {hostname}");
|
||||||
eprint!("{}", String::from_utf8_lossy(&uptime.0));
|
eprint!("{}", String::from_utf8_lossy(&uptime.0));
|
||||||
}
|
}
|
||||||
|
@ -91,7 +92,24 @@ fn main() -> eyre::Result<()> {
|
||||||
cli::Commands::Run { command, args } => {
|
cli::Commands::Run { command, args } => {
|
||||||
let spawn_arguments = SpawnArguments::default();
|
let spawn_arguments = SpawnArguments::default();
|
||||||
let mut vm = VirtualMachine::load(spawn_arguments, None)?;
|
let mut vm = VirtualMachine::load(spawn_arguments, None)?;
|
||||||
let (response, exit_code) = vm.run_command(&command, args)?;
|
|
||||||
|
let mut stdin = std::io::stdin();
|
||||||
|
let buffered_stdin = if stdin.is_terminal() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let mut bytes = vec![];
|
||||||
|
stdin
|
||||||
|
.read_to_end(&mut bytes)
|
||||||
|
.context(eyre::eyre!("could not read input"))?;
|
||||||
|
if bytes.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(bytes)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let (response, exit_code) =
|
||||||
|
vm.run_command(&command, args, buffered_stdin.as_deref())?;
|
||||||
std::io::stdout().write_all(&response)?;
|
std::io::stdout().write_all(&response)?;
|
||||||
std::process::exit(
|
std::process::exit(
|
||||||
i32::try_from(exit_code).context(eyre::eyre!("bad PID: pid < i32::MAX << 1"))?,
|
i32::try_from(exit_code).context(eyre::eyre!("bad PID: pid < i32::MAX << 1"))?,
|
||||||
|
|
|
@ -574,13 +574,16 @@ impl VirtualMachine {
|
||||||
&mut self,
|
&mut self,
|
||||||
command: &str,
|
command: &str,
|
||||||
args: impl IntoIterator<Item = String>,
|
args: impl IntoIterator<Item = String>,
|
||||||
|
stdin: Option<&[u8]>,
|
||||||
) -> Result<(Vec<u8>, u64)> {
|
) -> Result<(Vec<u8>, u64)> {
|
||||||
let args = args.into_iter().collect::<Vec<_>>();
|
let args = args.into_iter().collect::<Vec<_>>();
|
||||||
|
let input = stdin.map(|bytes| BASE64_STANDARD.encode(bytes));
|
||||||
|
|
||||||
let payload = serde_json::json!({
|
let payload = serde_json::json!({
|
||||||
"path": command,
|
"path": command,
|
||||||
"arg": args,
|
"arg": args,
|
||||||
"capture-output": true,
|
"capture-output": true,
|
||||||
|
"input-data": input,
|
||||||
});
|
});
|
||||||
|
|
||||||
let bar = spinner(format!("Running: {command:?} {args:?}"));
|
let bar = spinner(format!("Running: {command:?} {args:?}"));
|
||||||
|
|
Loading…
Reference in New Issue