use std::io::Read;
use supermachine::{Image, Vm, VmConfig};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut args = std::env::args().skip(1);
let image_ref = args
.next()
.ok_or("usage: exec IMAGE [-- argv...]")?;
let mut argv: Vec<String> = args.collect();
if argv.first().map(|s| s.as_str()) == Some("--") {
argv.remove(0);
}
if argv.is_empty() {
argv = vec!["/bin/sh".to_owned(), "-c".to_owned(), "echo hello && exit 0".to_owned()];
}
let image = Image::from_oci(&image_ref)?;
let vm = Vm::start(&image, &VmConfig::new())?;
let mut child = vm.exec_builder().argv(argv).spawn()?;
let mut stdout = child.stdout().expect("stdout taken");
let mut stderr = child.stderr().expect("stderr taken");
let so = std::thread::spawn(move || {
let mut buf = Vec::new();
let _ = stdout.read_to_end(&mut buf);
buf
});
let se = std::thread::spawn(move || {
let mut buf = Vec::new();
let _ = stderr.read_to_end(&mut buf);
buf
});
let status = child.wait()?;
let stdout_bytes = so.join().unwrap();
let stderr_bytes = se.join().unwrap();
print!("{}", String::from_utf8_lossy(&stdout_bytes));
if !stderr_bytes.is_empty() {
eprint!("{}", String::from_utf8_lossy(&stderr_bytes));
}
eprintln!("exit: {:?}", status.code());
vm.stop()?;
Ok(())
}