From a78c9f94779a0aaf0184953f92b62d06ea4a0667 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 29 Sep 2023 16:50:20 -0400 Subject: [PATCH] install: Give better error if not run in a podman container (We should probably detect docker and error out nicely there too, or of course support docker too) Signed-off-by: Colin Walters --- lib/src/containerenv.rs | 20 ++++++++++++-------- lib/src/install.rs | 5 ++++- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/lib/src/containerenv.rs b/lib/src/containerenv.rs index 485bd0aa0..a79583a2b 100644 --- a/lib/src/containerenv.rs +++ b/lib/src/containerenv.rs @@ -1,12 +1,13 @@ //! Helpers for parsing the `/run/.containerenv` file generated by podman. -use std::fs::File; use std::io::{BufRead, BufReader}; -use anyhow::{Context, Result}; +use anyhow::Result; +use cap_std_ext::cap_std::fs::Dir; +use cap_std_ext::prelude::CapStdExtDirExt; use fn_error_context::context; -const PATH: &str = "/run/.containerenv"; +const PATH: &str = "run/.containerenv"; #[derive(Debug, Default)] pub(crate) struct ContainerExecutionInfo { @@ -18,11 +19,14 @@ pub(crate) struct ContainerExecutionInfo { } /// Load and parse the `/run/.containerenv` file. -#[context("Parsing {PATH}")] -pub(crate) fn get_container_execution_info() -> Result { - let f = File::open(PATH) - .with_context(|| format!("Opening {PATH}")) - .map(BufReader::new)?; +#[context("Querying container")] +pub(crate) fn get_container_execution_info(rootfs: &Dir) -> Result { + let f = match rootfs.open_optional(PATH)? { + Some(f) => BufReader::new(f), + None => { + anyhow::bail!("This command must be executed inside a podman container (missing {PATH}") + } + }; let mut r = ContainerExecutionInfo::default(); for line in f.lines() { let line = line?; diff --git a/lib/src/install.rs b/lib/src/install.rs index bfa1299e2..7ee652f31 100644 --- a/lib/src/install.rs +++ b/lib/src/install.rs @@ -770,8 +770,11 @@ async fn prepare_install( crate::cli::require_root()?; require_systemd_pid1()?; + let rootfs = cap_std::fs::Dir::open_ambient_dir("/", cap_std::ambient_authority()) + .context("Opening /")?; + // This command currently *must* be run inside a privileged container. - let container_info = crate::containerenv::get_container_execution_info()?; + let container_info = crate::containerenv::get_container_execution_info(&rootfs)?; let source = SourceInfo::from_container(&container_info)?; ensure_var()?;