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