Prepare, configure, and manage Firecracker microVMs in seconds!
virtualization linux microvm firecracker
at main 58 lines 1.5 kB view raw
1use anyhow::{anyhow, Context, Result}; 2use std::process::{Command, Output, Stdio}; 3 4pub fn has_sudo() -> bool { 5 Command::new("sudo") 6 .arg("-h") 7 .output() 8 .map(|output| output.status.success()) 9 .unwrap_or(false) 10} 11 12pub fn is_root() -> bool { 13 unsafe { libc::getuid() == 0 } 14} 15 16pub fn run_command(command: &str, args: &[&str], use_sudo: bool) -> Result<Output> { 17 let mut cmd = if use_sudo { 18 if !has_sudo() && !is_root() { 19 return Err(anyhow!( 20 "sudo is required for command '{}', but not available", 21 command 22 )); 23 } 24 let mut c = Command::new("sudo"); 25 c.arg(command); 26 27 match is_root() { 28 true => Command::new(command), 29 false => c, 30 } 31 } else { 32 Command::new(command) 33 }; 34 35 let output = cmd 36 .args(args) 37 .stdin(Stdio::inherit()) 38 .stderr(Stdio::piped()) 39 .output() 40 .with_context(|| format!("Failed to execute {}", command))?; 41 42 if !output.status.success() { 43 let stderr = String::from_utf8_lossy(&output.stderr); 44 let stdout = String::from_utf8_lossy(&output.stdout); 45 return Err(anyhow!( 46 "Command {} failed: {} {} {} {}", 47 command, 48 stderr, 49 stdout, 50 args.iter() 51 .map(|s| s.to_string()) 52 .collect::<Vec<_>>() 53 .join(" "), 54 output.status.code().unwrap_or(-1), 55 )); 56 } 57 Ok(output) 58}