1extern crate openvmm_hypervisors as _;
13
14mod cpio;
15pub mod disk_image;
16mod linux_direct_serial_agent;
17#[expect(missing_docs)]
20pub mod openhcl_diag;
21pub mod requirements;
22mod test;
23mod tracing;
24mod vm;
25mod worker;
26
27pub use petri_artifacts_core::ArtifactHandle;
28pub use petri_artifacts_core::ArtifactResolver;
29pub use petri_artifacts_core::ArtifactSource;
30pub use petri_artifacts_core::AsArtifactHandle;
31pub use petri_artifacts_core::ErasedArtifactHandle;
32pub use petri_artifacts_core::RemoteAccess;
33pub use petri_artifacts_core::ResolveTestArtifact;
34pub use petri_artifacts_core::ResolvedArtifact;
35pub use petri_artifacts_core::ResolvedArtifactSource;
36pub use petri_artifacts_core::ResolvedOptionalArtifact;
37pub use petri_artifacts_core::TestArtifactRequirements;
38pub use petri_artifacts_core::TestArtifacts;
39pub use pipette_client as pipette;
40pub use test::PetriTestParams;
41pub use test::RunTest;
42pub use test::SimpleTest;
43pub use test::TestCase;
44pub use test::test_macro_support;
45pub use test::test_main;
46pub use tracing::*;
47pub use vm::*;
48
49use jiff::Timestamp;
50use std::process::Command;
51use std::process::Stdio;
52use thiserror::Error;
53
54pub const SIZE_1_KB: u64 = 1024;
56pub const SIZE_1_MB: u64 = 1024 * SIZE_1_KB;
58pub const SIZE_1_GB: u64 = 1024 * SIZE_1_MB;
60
61#[expect(missing_docs)] pub enum ShutdownKind {
64 Shutdown,
65 Reboot,
66 }
68
69#[derive(Error, Debug)]
71pub enum CommandError {
72 #[error("failed to launch command")]
74 Launch(#[from] std::io::Error),
75 #[error("command exited with non-zero status ({0}): {1}")]
77 Command(std::process::ExitStatus, String),
78}
79
80pub async fn run_host_cmd(mut cmd: Command) -> Result<String, CommandError> {
82 cmd.stderr(Stdio::piped()).stdin(Stdio::null());
83
84 let cmd_debug = format!("{cmd:?}");
85 ::tracing::debug!(cmd = cmd_debug, "executing command");
86
87 let start = Timestamp::now();
88 let output = blocking::unblock(move || cmd.output()).await?;
89 let time_elapsed = Timestamp::now() - start;
90
91 let stdout_str = String::from_utf8_lossy(&output.stdout).to_string();
92 let stderr_str = String::from_utf8_lossy(&output.stderr).to_string();
93 ::tracing::debug!(
94 cmd = cmd_debug,
95 stdout_str,
96 stderr_str,
97 "command exited in {:.3}s with status {}",
98 time_elapsed.total(jiff::Unit::Second).unwrap(),
99 output.status
100 );
101
102 if !output.status.success() {
103 return Err(CommandError::Command(output.status, stderr_str));
104 }
105
106 Ok(stdout_str.trim().to_owned())
107}