use crate::keyfileext::KeyFileExt;
use anyhow::Result;
use ostree::glib;
use std::io::Read;
use std::path::Path;
const V0_REPO_CONFIG: &str = "/sysroot/config";
const V1_REPO_CONFIG: &str = "/sysroot/ostree/repo/config";
pub fn running_in_container() -> bool {
if std::env::var_os("container").is_some() {
return true;
}
for p in ["/run/.containerenv", "/.dockerenv"] {
if std::path::Path::new(p).exists() {
return true;
}
}
false
}
pub(crate) fn open_optional(path: impl AsRef<Path>) -> std::io::Result<Option<std::fs::File>> {
match std::fs::File::open(path.as_ref()) {
Ok(r) => Ok(Some(r)),
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(None),
Err(e) => Err(e),
}
}
pub fn is_bare_split_xattrs() -> Result<bool> {
if let Some(configf) = open_optional(V1_REPO_CONFIG)
.transpose()
.or_else(|| open_optional(V0_REPO_CONFIG).transpose())
{
let configf = configf?;
let mut bufr = std::io::BufReader::new(configf);
let mut s = String::new();
bufr.read_to_string(&mut s)?;
let kf = glib::KeyFile::new();
kf.load_from_data(&s, glib::KeyFileFlags::NONE)?;
let r = if let Some(mode) = kf.optional_string("core", "mode")? {
mode == crate::tar::BARE_SPLIT_XATTRS_MODE
} else {
false
};
Ok(r)
} else {
Ok(false)
}
}
pub fn is_ostree_container() -> Result<bool> {
let is_container_ostree = is_bare_split_xattrs()?;
let running_in_systemd = std::env::var_os("INVOCATION_ID").is_some();
let maybe_container = running_in_container()
|| (!running_in_systemd && !Path::new("/run/ostree-booted").exists());
Ok(is_container_ostree && maybe_container)
}
pub fn require_ostree_container() -> Result<()> {
if !is_ostree_container()? {
anyhow::bail!("Not in an ostree-based container environment");
}
Ok(())
}