bootc_lib/
containerenv.rs1use std::io::{BufRead, BufReader};
4
5use anyhow::Result;
6use cap_std_ext::cap_std::fs::Dir;
7use cap_std_ext::prelude::CapStdExtDirExt;
8use fn_error_context::context;
9
10pub(crate) const PATH: &str = "run/.containerenv";
12
13#[derive(Debug, Default)]
14pub(crate) struct ContainerExecutionInfo {
15 pub(crate) engine: String,
16 pub(crate) name: String,
17 pub(crate) id: String,
18 pub(crate) image: String,
19 pub(crate) imageid: String,
20 pub(crate) rootless: Option<String>,
21}
22
23pub(crate) fn is_container(rootfs: &Dir) -> bool {
24 rootfs.exists(PATH)
25}
26
27#[context("Querying container")]
29pub(crate) fn get_container_execution_info(rootfs: &Dir) -> Result<ContainerExecutionInfo> {
30 let f = match rootfs.open_optional(PATH)? {
31 Some(f) => BufReader::new(f),
32 None => {
33 anyhow::bail!(
34 "This command must be executed inside a podman container (missing /{PATH})"
35 )
36 }
37 };
38 let mut r = ContainerExecutionInfo::default();
39 for line in f.lines() {
40 let line = line?;
41 let line = line.trim();
42 let Some((k, v)) = line.split_once('=') else {
43 continue;
44 };
45 let v = v.trim_start_matches('"').trim_end_matches('"');
47 match k {
48 "engine" => r.engine = v.to_string(),
49 "name" => r.name = v.to_string(),
50 "id" => r.id = v.to_string(),
51 "image" => r.image = v.to_string(),
52 "imageid" => r.imageid = v.to_string(),
53 "rootless" => r.rootless = Some(v.to_string()),
54 _ => {}
55 }
56 }
57 Ok(r)
58}