mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-22 08:53:29 +00:00
Make OSDK errors clear if commands don't exist
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
4a9977d9a7
commit
f3f0e9a244
53
osdk/Cargo.lock
generated
53
osdk/Cargo.lock
generated
@ -203,6 +203,7 @@ dependencies = [
|
||||
"shlex",
|
||||
"syn",
|
||||
"toml",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -380,6 +381,12 @@ dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_home"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7f84e12ccf0a7ddc17a6c41c93326024c42920d7ee630d04950e6926645c0fe"
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.11.8"
|
||||
@ -399,6 +406,16 @@ version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.3.3"
|
||||
@ -608,6 +625,12 @@ dependencies = [
|
||||
"xmas-elf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.12"
|
||||
@ -811,6 +834,19 @@ version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.20"
|
||||
@ -1063,6 +1099,17 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "8.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3fabb953106c3c8eea8306e4393700d7657561cb43122571b172bbfb7c7ba1d"
|
||||
dependencies = [
|
||||
"env_home",
|
||||
"rustix",
|
||||
"winsafe",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.61.0"
|
||||
@ -1204,6 +1251,12 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winsafe"
|
||||
version = "0.0.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904"
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rt"
|
||||
version = "0.39.0"
|
||||
|
@ -26,6 +26,7 @@ serde_json = "1.0.111"
|
||||
shlex = "1.3.0"
|
||||
syn = { version = "2.0.52", features = ["extra-traits", "full", "parsing", "printing"] }
|
||||
toml = { version = "0.8.8", features = ["preserve_order"] }
|
||||
which = "8.0.0"
|
||||
|
||||
[dev-dependencies]
|
||||
assert_cmd = "2.0.13"
|
||||
|
@ -80,7 +80,7 @@ impl Display for Arch {
|
||||
|
||||
/// Get the default architecture implied by the host rustc's default architecture.
|
||||
pub fn get_default_arch() -> Arch {
|
||||
let output = std::process::Command::new("rustc")
|
||||
let output = crate::util::new_command_checked_exists("rustc")
|
||||
.arg("-vV")
|
||||
.output()
|
||||
.expect("Failed to run rustc to get the host target");
|
||||
|
@ -11,7 +11,6 @@ use vm_image::{AsterVmImage, AsterVmImageType};
|
||||
|
||||
use std::{
|
||||
path::{Path, PathBuf},
|
||||
process::Command,
|
||||
time::SystemTime,
|
||||
};
|
||||
|
||||
@ -22,7 +21,7 @@ use crate::{
|
||||
},
|
||||
error::Errno,
|
||||
error_msg,
|
||||
util::DirGuard,
|
||||
util::{new_command_checked_exists, DirGuard},
|
||||
};
|
||||
|
||||
/// The osdk bundle artifact that stores as `bundle` directory.
|
||||
@ -199,8 +198,8 @@ impl Bundle {
|
||||
ActionChoice::Run => &config.run,
|
||||
ActionChoice::Test => &config.test,
|
||||
};
|
||||
let mut qemu_cmd = Command::new(&action.qemu.path);
|
||||
|
||||
let mut qemu_cmd = new_command_checked_exists(&action.qemu.path);
|
||||
qemu_cmd.current_dir(&config.work_dir);
|
||||
|
||||
match action.boot.method {
|
||||
|
@ -4,7 +4,6 @@ use std::{
|
||||
fs::{File, OpenOptions},
|
||||
io::{Read, Seek, SeekFrom, Write},
|
||||
path::{Path, PathBuf},
|
||||
process::Command,
|
||||
};
|
||||
|
||||
use linux_bzimage_builder::{
|
||||
@ -17,7 +16,7 @@ use crate::{
|
||||
bin::{AsterBin, AsterBinType, AsterBzImageMeta, AsterElfMeta},
|
||||
file::BundleFile,
|
||||
},
|
||||
util::{get_current_crates, hard_link_or_copy},
|
||||
util::{get_current_crates, hard_link_or_copy, new_command_checked_exists},
|
||||
};
|
||||
|
||||
pub fn make_install_bzimage(
|
||||
@ -95,7 +94,7 @@ pub fn make_elf_for_qemu(install_dir: impl AsRef<Path>, elf: &AsterBin, strip: b
|
||||
|
||||
if strip {
|
||||
// We use rust-strip to reduce the kernel image size.
|
||||
let status = Command::new("rust-strip")
|
||||
let status = new_command_checked_exists("rust-strip")
|
||||
.arg(elf.path())
|
||||
.arg("-o")
|
||||
.arg(result_elf_path.as_os_str())
|
||||
@ -170,7 +169,7 @@ fn install_setup_with_arch(
|
||||
}
|
||||
let target_dir = std::fs::canonicalize(target_dir).unwrap();
|
||||
|
||||
let mut cmd = Command::new("cargo");
|
||||
let mut cmd = new_command_checked_exists("cargo");
|
||||
let mut rustflags = vec![
|
||||
"-Cdebuginfo=2",
|
||||
"-Ccode-model=kernel",
|
||||
|
@ -16,7 +16,7 @@ use crate::{
|
||||
scheme::{ActionChoice, BootProtocol},
|
||||
Config,
|
||||
},
|
||||
util::{get_current_crates, hard_link_or_copy},
|
||||
util::{get_current_crates, hard_link_or_copy, new_command_checked_exists},
|
||||
};
|
||||
|
||||
pub fn create_bootdev_image(
|
||||
@ -84,7 +84,7 @@ pub fn create_bootdev_image(
|
||||
|
||||
// Make the boot device CDROM image using `grub-mkrescue`.
|
||||
let iso_path = &target_dir.as_ref().join(target_name.to_string() + ".iso");
|
||||
let mut grub_mkrescue_cmd = std::process::Command::new(action.grub.grub_mkrescue.as_os_str());
|
||||
let mut grub_mkrescue_cmd = new_command_checked_exists(action.grub.grub_mkrescue.as_os_str());
|
||||
grub_mkrescue_cmd
|
||||
.arg(iso_root.as_os_str())
|
||||
.arg("-o")
|
||||
@ -166,7 +166,7 @@ fn generate_grub_cfg(
|
||||
}
|
||||
|
||||
fn get_grub_mkrescue_version(grub_mkrescue: &PathBuf) -> String {
|
||||
let mut cmd = std::process::Command::new(grub_mkrescue);
|
||||
let mut cmd = new_command_checked_exists(grub_mkrescue);
|
||||
cmd.arg("--version");
|
||||
let output = cmd.output().unwrap();
|
||||
String::from_utf8(output.stdout).unwrap()
|
||||
|
@ -8,6 +8,7 @@ use crate::{
|
||||
vm_image::{AsterQcow2ImageMeta, AsterVmImage, AsterVmImageType},
|
||||
},
|
||||
error_msg,
|
||||
util::new_command_checked_exists,
|
||||
};
|
||||
|
||||
pub fn convert_iso_to_qcow2(iso: AsterVmImage) -> AsterVmImage {
|
||||
@ -17,7 +18,7 @@ pub fn convert_iso_to_qcow2(iso: AsterVmImage) -> AsterVmImage {
|
||||
let iso_path = iso.path();
|
||||
let qcow2_path = iso_path.with_extension("qcow2");
|
||||
// Convert the ISO to QCOW2 using `qemu-img`.
|
||||
let mut qemu_img = process::Command::new("qemu-img");
|
||||
let mut qemu_img = new_command_checked_exists("qemu-img");
|
||||
qemu_img.args([
|
||||
"convert",
|
||||
"-O",
|
||||
|
@ -3,9 +3,8 @@
|
||||
use crate::{
|
||||
cli::DebugArgs,
|
||||
commands::util::bin_file_name,
|
||||
util::{get_kernel_crate, get_target_directory},
|
||||
util::{get_kernel_crate, get_target_directory, new_command_checked_exists},
|
||||
};
|
||||
use std::process::Command;
|
||||
|
||||
pub fn execute_debug_command(_profile: &str, args: &DebugArgs) {
|
||||
let remote = &args.remote;
|
||||
@ -16,7 +15,7 @@ pub fn execute_debug_command(_profile: &str, args: &DebugArgs) {
|
||||
.join(bin_file_name());
|
||||
println!("Debugging {}", file_path.display());
|
||||
|
||||
let mut gdb = Command::new("gdb");
|
||||
let mut gdb = new_command_checked_exists("gdb");
|
||||
gdb.args([
|
||||
format!("{}", file_path.display()).as_str(),
|
||||
"-ex",
|
||||
@ -27,7 +26,7 @@ pub fn execute_debug_command(_profile: &str, args: &DebugArgs) {
|
||||
|
||||
#[test]
|
||||
fn have_gdb_installed() {
|
||||
let output = Command::new("gdb").arg("--version").output();
|
||||
let output = new_command_checked_exists("gdb").arg("--version").output();
|
||||
assert!(output.is_ok(), "Failed to run gdb");
|
||||
let stdout = String::from_utf8_lossy(&output.unwrap().stdout).to_string();
|
||||
assert!(stdout.contains("GNU gdb"));
|
||||
|
@ -13,7 +13,7 @@ use inferno::flamegraph;
|
||||
use crate::{
|
||||
cli::{ProfileArgs, ProfileFormat},
|
||||
commands::util::bin_file_name,
|
||||
util::{get_kernel_crate, get_target_directory},
|
||||
util::{get_kernel_crate, get_target_directory, new_command_checked_exists},
|
||||
};
|
||||
use regex::Regex;
|
||||
use std::{
|
||||
@ -21,7 +21,7 @@ use std::{
|
||||
fs::File,
|
||||
io::{BufRead, Write},
|
||||
path::PathBuf,
|
||||
process::{Command, Stdio},
|
||||
process::Stdio,
|
||||
thread, time,
|
||||
};
|
||||
|
||||
@ -92,7 +92,7 @@ fn do_collect_stack_traces(args: &ProfileArgs) {
|
||||
];
|
||||
gdb_args.append(&mut vec![backtrace_cmd_seq; *samples].concat());
|
||||
|
||||
Command::new("gdb")
|
||||
new_command_checked_exists("gdb")
|
||||
.args(gdb_args)
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
@ -119,7 +119,7 @@ fn do_collect_stack_traces(args: &ProfileArgs) {
|
||||
}
|
||||
gdb_output.clear();
|
||||
thread::sleep(time::Duration::from_secs_f64(*interval));
|
||||
let _ = Command::new("kill")
|
||||
let _ = new_command_checked_exists("kill")
|
||||
.args(["-INT", &format!("{}", gdb_process.id())])
|
||||
.output();
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use std::process::Command;
|
||||
|
||||
use crate::util::get_kernel_crate;
|
||||
use crate::util::{get_kernel_crate, new_command_checked_exists};
|
||||
|
||||
pub const COMMON_CARGO_ARGS: &[&str] = &[
|
||||
"-Zbuild-std=core,alloc,compiler_builtins",
|
||||
@ -12,7 +12,7 @@ pub const COMMON_CARGO_ARGS: &[&str] = &[
|
||||
pub const DEFAULT_TARGET_RELPATH: &str = "osdk";
|
||||
|
||||
pub fn cargo() -> Command {
|
||||
Command::new("cargo")
|
||||
new_command_checked_exists("cargo")
|
||||
}
|
||||
|
||||
pub fn profile_name_adapter(profile: &str) -> &str {
|
||||
|
@ -29,6 +29,7 @@ use crate::{
|
||||
config::unix_args::apply_kv_array,
|
||||
error::Errno,
|
||||
error_msg,
|
||||
util::new_command_checked_exists,
|
||||
};
|
||||
|
||||
/// The global configuration for the OSDK actions.
|
||||
@ -155,7 +156,7 @@ fn canonicalize_and_eval(action_scheme: &mut ActionScheme, workdir: &PathBuf) {
|
||||
/// This function is used to evaluate the string using the host's shell recursively
|
||||
/// in order.
|
||||
pub fn eval(cwd: impl AsRef<Path>, s: &String) -> io::Result<String> {
|
||||
let mut eval = process::Command::new("bash");
|
||||
let mut eval = new_command_checked_exists("bash");
|
||||
eval.arg("-c");
|
||||
eval.arg(format!("echo \"{}\"", s));
|
||||
eval.current_dir(cwd.as_ref());
|
||||
|
@ -14,6 +14,7 @@ pub enum Errno {
|
||||
BadCrateName = 9,
|
||||
NoKernelCrate = 10,
|
||||
TooManyCrates = 11,
|
||||
ExecutableNotFound = 12,
|
||||
}
|
||||
|
||||
/// Print error message to console
|
||||
|
@ -23,7 +23,7 @@ pub fn ostd_dep() -> String {
|
||||
}
|
||||
|
||||
fn cargo() -> Command {
|
||||
Command::new("cargo")
|
||||
new_command_checked_exists("cargo")
|
||||
}
|
||||
|
||||
/// Create a new library crate with cargo
|
||||
@ -163,6 +163,22 @@ pub fn get_kernel_crate() -> CrateInfo {
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if an OSDK dependent executable (e.g. QEMU) exists.
|
||||
///
|
||||
/// If it exists, create a command. If not, print an error message and exit the
|
||||
/// process.
|
||||
pub fn new_command_checked_exists(executable: impl AsRef<Path>) -> Command {
|
||||
let executable = executable.as_ref();
|
||||
if which::which(executable).is_err() {
|
||||
error_msg!(
|
||||
"Executable {:?} cannot be found in PATH, please install the corresponding package",
|
||||
executable
|
||||
);
|
||||
std::process::exit(Errno::ExecutableNotFound as _);
|
||||
}
|
||||
Command::new(executable)
|
||||
}
|
||||
|
||||
fn package_contains_ostd_main(package: &serde_json::Value) -> bool {
|
||||
let src_path = {
|
||||
let targets = package.get("targets").unwrap().as_array().unwrap();
|
||||
@ -262,13 +278,15 @@ pub fn trace_panic_from_log(qemu_log: File, bin_path: PathBuf) {
|
||||
let mut stack_num = 0;
|
||||
let pc_matcher = regex::Regex::new(r" - pc (0x[0-9a-fA-F]+)").unwrap();
|
||||
let exe = bin_path.to_string_lossy();
|
||||
let mut addr2line = Command::new("addr2line");
|
||||
|
||||
let mut addr2line = new_command_checked_exists("addr2line");
|
||||
addr2line.args(["-e", &exe]);
|
||||
let mut addr2line_proc = addr2line
|
||||
.stdin(std::process::Stdio::piped())
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
for line in lines.into_iter().rev() {
|
||||
if line.contains("Printing stack trace:") {
|
||||
println!("[OSDK] The kernel seems panicked. Parsing stack trace for source lines:");
|
||||
|
Reference in New Issue
Block a user