Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core/cliwrap: Fix is_ostree_layout() in unit tests #5241

Merged
merged 1 commit into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions rust/src/cliwrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ pub fn entrypoint(args: &[&str]) -> Result<()> {
return cliutil::exec_real_binary(name, args);
}

let root = Dir::open_ambient_dir("/", cap_std::ambient_authority())?;

let host_type = crate::get_system_host_type()?;
if matches!(
host_type,
Expand All @@ -78,7 +80,9 @@ pub fn entrypoint(args: &[&str]) -> Result<()> {
"yum" | "dnf" => Ok(self::yumdnf::main(host_type, args)?),
"dracut" => Ok(self::dracut::main(args)?),
"grubby" => Ok(self::grubby::main(args)?),
"kernel-install" if !is_ostree_layout()? => Ok(self::kernel_install_wrap::main(args)?),
"kernel-install" if !is_ostree_layout(&root)? => {
Ok(self::kernel_install_wrap::main(args)?)
}
_ => Err(anyhow!("Unknown wrapped binary: {}", name)),
}
} else {
Expand Down Expand Up @@ -163,7 +167,9 @@ fn write_wrappers(rootfs_dfd: &Dir, allowlist: Option<&HashSet<&str>>) -> Result
.map(|p| p.file_name().unwrap())
.collect::<HashSet<_>>();

if !is_ostree_layout()? {
let ostree_layout = is_ostree_layout(rootfs_dfd)?;

if !ostree_layout {
all_names.insert(Utf8Path::new(KERNEL_INSTALL).file_name().unwrap());
}

Expand All @@ -178,7 +184,7 @@ fn write_wrappers(rootfs_dfd: &Dir, allowlist: Option<&HashSet<&str>>) -> Result
let allowlist_contains =
|v: &(&Utf8Path, bool)| allowlist.map_or(true, |l| l.contains(v.0.file_name().unwrap()));

let final_binaries: Vec<&str> = if !is_ostree_layout()? {
let final_binaries: Vec<&str> = if !is_ostree_layout(rootfs_dfd)? {
let mut combined_bins = Vec::from(WRAPPED_BINARIES);
combined_bins.extend_from_slice(&[KERNEL_INSTALL]);
combined_bins
Expand Down
5 changes: 3 additions & 2 deletions rust/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ impl FilesystemScriptPrep {
rootfs.atomic_write_with_perms(path, contents, mode)?;
}
}
if !is_ostree_layout()? {
if !is_ostree_layout(&rootfs)? {
for &(path, contents) in Self::REPLACE_KERNEL_PATHS {
let mode = Permissions::from_mode(0o755);
let saved = &Self::saved_name(path);
Expand All @@ -217,6 +217,7 @@ impl FilesystemScriptPrep {
for &path in Self::OPTIONAL_PATHS
.iter()
.chain(Self::REPLACE_OPTIONAL_PATHS.iter().map(|x| &x.0))
.chain(Self::REPLACE_KERNEL_PATHS.iter().map(|x| &x.0))
{
let saved = &Self::saved_name(path);
if self.rootfs.try_exists(saved)? {
Expand Down Expand Up @@ -486,7 +487,7 @@ mod test {
}
// Replaced kernel-install.
{
if !is_ostree_layout()? {
if !is_ostree_layout(&d)? {
let original_kernel_install = "original kernel_install";
d.atomic_write_with_perms(
super::KERNEL_INSTALL_PATH,
Expand Down
59 changes: 46 additions & 13 deletions rust/src/kernel_install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@

// SPDX-License-Identifier: Apache-2.0 OR MIT

use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;
use std::process::Command;

use anyhow::{Context, Result};
Expand All @@ -35,21 +33,17 @@ const MODULES: &str = "usr/lib/modules";
/// The default name for the initramfs.
const INITRAMFS: &str = "initramfs.img";
/// The path to the instal.conf that sets layout.
const KERNEL_INSTALL_CONF: &str = "/usr/lib/kernel/install.conf";
const KERNEL_INSTALL_CONF: &str = "usr/lib/kernel/install.conf";

#[context("Verifying kernel-install layout file")]
pub fn is_ostree_layout() -> Result<bool> {
let install_conf = Path::new(KERNEL_INSTALL_CONF);
if !install_conf.is_file() {
tracing::debug!("can not read /usr/lib/kernel/install.conf");
pub fn is_ostree_layout(rootfs: &Dir) -> Result<bool> {
let Some(conf) = rootfs.open_optional(KERNEL_INSTALL_CONF)? else {
return Ok(false);
}
let buff = BufReader::new(
File::open(install_conf).context("Failed to open /usr/lib/kernel/install.conf")?,
);
};
let buf = BufReader::new(conf);
// Check for "layout=ostree" in the file
for line in buff.lines() {
let line = line.context("Failed to read line")?;
for line in buf.lines() {
let line = line?;
if line.trim() == "layout=ostree" {
return Ok(true);
}
Expand Down Expand Up @@ -118,3 +112,42 @@ pub fn main(argv: &[&str]) -> Result<u8> {
_ => Ok(0),
}
}

#[cfg(test)]
mod tests {
use std::path::Path;

use cap_std_ext::cap_tempfile;

use super::*;

#[test]
fn test_ostree_layout_parse() -> Result<()> {
let td = &cap_tempfile::tempdir(cap_std::ambient_authority())?;
assert!(!is_ostree_layout(&td).unwrap());
td.create_dir_all(Path::new(KERNEL_INSTALL_CONF).parent().unwrap())?;
td.write(KERNEL_INSTALL_CONF, "")?;
assert!(!is_ostree_layout(&td).unwrap());
td.write(
KERNEL_INSTALL_CONF,
indoc::indoc! { r#"
# some comments

layout=bacon
"# },
)?;
assert!(!is_ostree_layout(&td).unwrap());
td.write(
KERNEL_INSTALL_CONF,
indoc::indoc! { r#"
# this is an ostree layout
layout=ostree
# another comment
"# },
)?;

assert!(is_ostree_layout(&td).unwrap());

Ok(())
}
}
Loading