Skip to main content

bsdkrun_sdk/
system.rs

1//! Host toolchain / image operations that aren't tied to a single machine.
2
3use crate::error::Result;
4use crate::process::{run, run_checked};
5
6/// Sanity-check the toolchain (libkrun links, a context is creatable).
7///
8/// Does not boot. `Ok(true)` on success; an `Err` only for host-side
9/// failures like a missing binary.
10pub fn probe() -> Result<bool> {
11    Ok(run(["probe"])?.exit_code == 0)
12}
13
14/// Download + prepare a BSD image ahead of time.
15///
16/// ```no_run
17/// bsdkrun_sdk::system::fetch_image("freebsd").version("14.3").run()?;
18/// # Ok::<(), bsdkrun_sdk::Error>(())
19/// ```
20pub fn fetch_image(os: impl Into<String>) -> FetchImageBuilder {
21    FetchImageBuilder {
22        os: os.into(),
23        version: None,
24        dir: None,
25        force: false,
26    }
27}
28
29/// A `bsdkrun fetch` invocation being assembled — see [`fetch_image`].
30#[derive(Debug, Clone)]
31pub struct FetchImageBuilder {
32    os: String,
33    version: Option<String>,
34    dir: Option<String>,
35    force: bool,
36}
37
38impl FetchImageBuilder {
39    /// The release to fetch (`--version`).
40    pub fn version(mut self, version: impl Into<String>) -> Self {
41        self.version = Some(version.into());
42        self
43    }
44
45    /// Download directory (`--dir`).
46    pub fn dir(mut self, dir: impl Into<String>) -> Self {
47        self.dir = Some(dir.into());
48        self
49    }
50
51    /// Re-download even if cached (`--force`).
52    pub fn force(mut self) -> Self {
53        self.force = true;
54        self
55    }
56
57    /// Fetch the image. Returns the command output.
58    pub fn run(self) -> Result<String> {
59        let mut args = vec!["fetch".to_string(), "--os".to_string(), self.os];
60        if let Some(version) = self.version {
61            args.push("--version".to_string());
62            args.push(version);
63        }
64        if let Some(dir) = self.dir {
65            args.push("--dir".to_string());
66            args.push(dir);
67        }
68        if self.force {
69            args.push("--force".to_string());
70        }
71        Ok(run_checked(args, "bsdkrun fetch")?.stdout)
72    }
73}
74
75/// List the arm64 builds available to fetch for a BSD (`"freebsd"`/`"netbsd"`).
76///
77/// Returns the non-empty output lines.
78pub fn versions(os: &str) -> Result<Vec<String>> {
79    let out = run_checked(["versions", "--os", os], "bsdkrun versions")?.stdout;
80    Ok(out
81        .split('\n')
82        .map(str::trim)
83        .filter(|line| !line.is_empty())
84        .map(str::to_string)
85        .collect())
86}
87
88/// Grow a raw disk image (the guest expands its root FS on next boot).
89pub fn grow_disk(disk: &str, size: &str) -> Result<()> {
90    run_checked(["grow", "--disk", disk, "--size", size], "bsdkrun grow")?;
91    Ok(())
92}