mirror of
https://github.com/vhaudiquet/ecrou.git
synced 2026-11-12 22:22:44 +00:00
feat(cli): docker-style run flags and local rootfs references
The run interface read like a library's. `ecrou run -it alpine` now hands the guest a terminal: with no console output file, libkrun wires the guest console to the process's own stdio and raw-modes the tty. The parent saves and restores the termios around the run, because libkrun's own restore lives in the child's exit observers, which a SIGKILLed machine never runs. A tty run refuses to start without a terminal on stdin and stdout, and --capture refuses to combine with -t: the payload's streams cannot land in files and on the terminal at once. -i without -t keeps the machine's stdin open through pipes: libkrun exposes the non-tty streams as virtio console ports (krun-stdin, krun-stdout, krun-stderr), and the guest init points the payload's stdio at whichever port nodes exist. `echo hi | ecrou run -i alpine -- cat` crosses the machine; a stream the host left on a tty has no port node and stays on the console. -v (--volume HOST:GUEST[:ro]) replaces --share, and -w aliases --workdir. The global -v/--verbose loses its short flag to make room; verbose stays reachable by its long form. A reference starting with ./, ../ or / names a local rootfs archive: read in place on every run, never downloaded, never cached as a pristine entry. Provisioning over one persists into a derived cache entry keyed by size and mtime, so the caller's file is never overwritten and an edited archive lands in a fresh entry.
This commit is contained in:
1 parent
719a8209e0
commit
4a0c613ecb
9 files changed
+569
-72
No files matched your search
@@ -10,7 +10,7 @@ use clap::Parser;
|
||||
use ecrou::vm::RunOptions;
|
||||
use ecrou::{LogLevel, NoProgress, Progress};
|
||||
|
||||
use cli::{parse_env, parse_share, Cli, Command, RunArgs};
|
||||
use cli::{parse_env, parse_volume, Cli, Command, RunArgs};
|
||||
use progress::TermProgress;
|
||||
|
||||
fn main() -> std::process::ExitCode {
|
||||
@@ -157,6 +157,15 @@ fn cmd_provision(
|
||||
}
|
||||
|
||||
fn cmd_run(args: &RunArgs, cli_verbose: bool) -> std::process::ExitCode {
|
||||
// A tty drives the payload's output through the terminal while the
|
||||
// capture share points the same streams at files: one of them has
|
||||
// to lose, so the run refuses instead of picking.
|
||||
if args.tty && args.capture.is_some() {
|
||||
return fail(&anyhow::anyhow!(
|
||||
"--capture and --tty cannot be combined: the payload's output \
|
||||
cannot land in the capture files and on the terminal"
|
||||
));
|
||||
}
|
||||
let mut options = RunOptions {
|
||||
// Without a layer the image is required by clap; with one the
|
||||
// field is dead — the layer entry carries the rootfs.
|
||||
@@ -171,6 +180,8 @@ fn cmd_run(args: &RunArgs, cli_verbose: bool) -> std::process::ExitCode {
|
||||
} else {
|
||||
LogLevel::Normal
|
||||
},
|
||||
interactive: args.interactive,
|
||||
tty: args.tty,
|
||||
no_cache: args.no_cache,
|
||||
layer: args.layer.clone(),
|
||||
capture: args.capture.clone(),
|
||||
@@ -183,8 +194,8 @@ fn cmd_run(args: &RunArgs, cli_verbose: bool) -> std::process::ExitCode {
|
||||
}
|
||||
}
|
||||
let mut shares = Vec::new();
|
||||
for spec in &args.shares {
|
||||
match parse_share(spec) {
|
||||
for spec in &args.volumes {
|
||||
match parse_volume(spec) {
|
||||
Ok(share) => shares.push(share),
|
||||
Err(err) => return fail(&err),
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user