From 06933ed3a2b069bad1f9a002452e2e025a48c0ba Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 6 Mar 2025 17:01:59 -0500 Subject: [PATCH] ostree-ext: Update parser to honor `composefs=verity` We have duplicate code to parse this between C and Rust unfortunately; update the Rust side to honor what landed in https://github.com/ostreedev/ostree/pull/3354 Signed-off-by: Colin Walters --- ostree-ext/src/ostree_prepareroot.rs | 30 ++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/ostree-ext/src/ostree_prepareroot.rs b/ostree-ext/src/ostree_prepareroot.rs index e806073a..25f01dcb 100644 --- a/ostree-ext/src/ostree_prepareroot.rs +++ b/ostree-ext/src/ostree_prepareroot.rs @@ -9,6 +9,7 @@ use std::str::FromStr; use anyhow::{Context, Result}; use camino::Utf8Path; use cap_std_ext::dirext::CapStdExtDirExt; +use fn_error_context::context; use ocidir::cap_std::fs::Dir; use ostree::glib::object::Cast; use ostree::prelude::FileExt; @@ -21,7 +22,8 @@ use crate::utils::ResultExt; /// The relative path to ostree-prepare-root's config. pub const CONF_PATH: &str = "ostree/prepare-root.conf"; -pub(crate) fn load_config(root: &ostree::RepoFile) -> Result> { +/// Load the ostree prepare-root config from the given ostree repository. +pub fn load_config(root: &ostree::RepoFile) -> Result> { let cancellable = gio::Cancellable::NONE; let kf = glib::KeyFile::new(); for path in ["etc", "usr/lib"].into_iter().map(Utf8Path::new) { @@ -66,7 +68,7 @@ pub fn require_config_from_root(root: &Dir) -> Result { /// Query whether the target root has the `root.transient` key /// which sets up a transient overlayfs. -pub(crate) fn overlayfs_root_enabled(root: &ostree::RepoFile) -> Result { +pub fn overlayfs_root_enabled(root: &ostree::RepoFile) -> Result { if let Some(config) = load_config(root)? { overlayfs_enabled_in_config(&config) } else { @@ -74,10 +76,14 @@ pub(crate) fn overlayfs_root_enabled(root: &ostree::RepoFile) -> Result { } } -#[derive(Debug, PartialEq, Eq)] -enum Tristate { +/// An option which can be enabled, disabled, or possibly enabled. +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum Tristate { + /// Enabled Enabled, + /// Disabled Disabled, + /// Maybe Maybe, } @@ -111,9 +117,14 @@ impl Tristate { } } +/// The state of a composefs for ostree #[derive(Debug, PartialEq, Eq)] -enum ComposefsState { +pub enum ComposefsState { + /// The composefs must be signed and use fsverity Signed, + /// The composefs must use fsverity + Verity, + /// The composefs may or may not be enabled. Tristate(Tristate), } @@ -126,9 +137,11 @@ impl Default for ComposefsState { impl FromStr for ComposefsState { type Err = anyhow::Error; + #[context("Parsing composefs.enabled value {s}")] fn from_str(s: &str) -> Result { let r = match s { "signed" => Self::Signed, + "verity" => Self::Verity, o => Self::Tristate(Tristate::from_str(o)?), }; Ok(r) @@ -138,10 +151,15 @@ impl FromStr for ComposefsState { impl ComposefsState { pub(crate) fn maybe_enabled(&self) -> bool { match self { - ComposefsState::Signed => true, + ComposefsState::Signed | ComposefsState::Verity => true, ComposefsState::Tristate(t) => t.maybe_enabled(), } } + + /// This configuration requires fsverity on the target filesystem. + pub fn requires_fsverity(&self) -> bool { + matches!(self, ComposefsState::Signed | ComposefsState::Verity) + } } /// Query whether the config uses an overlayfs model (composefs or plain overlayfs).