1use anyhow::Result;
2use camino::Utf8Path;
3use cap_std_ext::cap_std::fs::Dir;
4use serde::Deserialize;
5
6pub(crate) const CONTAINER_STORAGE: &str = "/var/lib/containers";
9
10#[derive(Deserialize)]
11#[serde(rename_all = "PascalCase")]
12pub(crate) struct Inspect {
13 pub(crate) digest: String,
14}
15
16#[derive(Deserialize)]
18#[serde(rename_all = "PascalCase")]
19pub(crate) struct ImageListEntry {
20 pub(crate) id: String,
21 pub(crate) names: Option<Vec<String>>,
22}
23
24pub(crate) fn imageid_to_digest(imgid: &str) -> Result<String> {
26 use bootc_utils::CommandRunExt;
27 let o: Vec<Inspect> = crate::install::run_in_host_mountns("podman")?
28 .args(["inspect", imgid])
29 .run_and_parse_json()?;
30 let i = o
31 .into_iter()
32 .next()
33 .ok_or_else(|| anyhow::anyhow!("No images returned for inspect"))?;
34 Ok(i.digest)
35}
36
37pub(crate) fn storage_exists(root: &Dir, path: impl AsRef<Utf8Path>) -> Result<bool> {
39 fn impl_storage_exists(root: &Dir, path: &Utf8Path) -> Result<bool> {
40 let lock = "storage.lock";
41 root.try_exists(path.join(lock)).map_err(Into::into)
42 }
43 impl_storage_exists(root, path.as_ref())
44}
45
46pub(crate) fn storage_exists_default(root: &Dir) -> Result<bool> {
52 storage_exists(root, CONTAINER_STORAGE.trim_start_matches('/'))
53}