Skip to content

Commit

Permalink
Move dracut code from cliwrap to initramfs module
Browse files Browse the repository at this point in the history
Prep for handling kernel-install in a different way, where
we add a drop-in that is invoked by the existing binary instead
of intercepting it entirely.

No functional changes intended (yet).

Signed-off-by: Colin Walters <[email protected]>
  • Loading branch information
cgwalters committed Sep 13, 2024
1 parent 854b827 commit d8c8cf9
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 53 deletions.
54 changes: 2 additions & 52 deletions rust/src/cliwrap/kernel_install.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
// If not running on container continue the current path.
// SPDX-License-Identifier: Apache-2.0 OR MIT
use crate::cliwrap;
use crate::cliwrap::cliutil;
use anyhow::{anyhow, Context, Result};
use anyhow::Result;
use camino::Utf8Path;
use cap_std::fs::FileType;
use cap_std::fs_utf8::Dir as Utf8Dir;
use cap_std_ext::cap_std;
use fn_error_context::context;
use std::os::fd::AsRawFd;
use std::process::Command;

/// Primary entrypoint to running our wrapped `kernel-install` handling.
#[context("rpm-ostree kernel-install wrapper")]
Expand Down Expand Up @@ -42,7 +39,7 @@ pub(crate) fn main(argv: &[&str]) -> Result<()> {
}
if let Some(k) = new_kernel {
undo_systemctl_wrap()?;
run_dracut(&k)?;
crate::initramfs::run_dracut(&k)?;
redo_systemctl_wrap()?;
}
Ok(())
Expand All @@ -63,50 +60,3 @@ fn redo_systemctl_wrap() -> Result<()> {
bin_path.rename("systemctl.backup", &bin_path, "systemctl")?;
Ok(())
}

#[context("Running dracut")]
fn run_dracut(kernel_dir: &str) -> Result<()> {
let root_fs = Utf8Dir::open_ambient_dir("/", cap_std::ambient_authority())?;
let tmp_dir = tempfile::tempdir()?;
let tmp_initramfs_path = tmp_dir.path().join("initramfs.img");

let cliwrap_dracut = Utf8Path::new(cliwrap::CLIWRAP_DESTDIR).join("dracut");
let dracut_path = cliwrap_dracut
.exists()
.then(|| cliwrap_dracut)
.unwrap_or_else(|| Utf8Path::new("dracut").to_owned());
// If changing this, also look at changing rpmostree-kernel.cxx
let res = Command::new(dracut_path)
.args(&[
"--no-hostonly",
"--kver",
kernel_dir,
"--reproducible",
"-v",
"--add",
"ostree",
"-f",
])
.arg(&tmp_initramfs_path)
.status()?;
if !res.success() {
return Err(anyhow!(
"Failed to generate initramfs (via dracut) for kernel: {kernel_dir}: {:?}",
res
));
}
let f = std::fs::OpenOptions::new()
.write(true)
.append(true)
.open(&tmp_initramfs_path)?;
crate::initramfs::append_dracut_random_cpio(f.as_raw_fd())?;
drop(f);
let utf8_tmp_dir_path = Utf8Path::from_path(tmp_dir.path().strip_prefix("/")?)
.context("Error turning Path to Utf8Path")?;
root_fs.rename(
utf8_tmp_dir_path.join("initramfs.img"),
&root_fs,
(Utf8Path::new("lib/modules").join(kernel_dir)).join("initramfs.img"),
)?;
Ok(())
}
52 changes: 51 additions & 1 deletion rust/src/initramfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
// SPDX-License-Identifier: Apache-2.0 OR MIT

use crate::cxxrsutil::*;
use anyhow::{Context, Result};
use anyhow::{anyhow, Context, Result};
use camino::Utf8Path;
use cap_std::fs_utf8::Dir as Utf8Dir;
use cap_std::io_lifetimes::AsFilelike;
use cap_std_ext::cap_std;
use cap_std_ext::prelude::CapStdExtCommandExt;
Expand All @@ -13,9 +14,11 @@ use rustix::fd::BorrowedFd;
use std::collections::BTreeSet;
use std::collections::HashSet;
use std::io::prelude::*;
use std::os::fd::AsRawFd as _;
use std::os::unix::io::IntoRawFd;
use std::path::{Component, Path, PathBuf};
use std::pin::Pin;
use std::process::Command;
use std::{fs, io};

fn list_files_recurse<P: glib::IsA<gio::Cancellable>>(
Expand Down Expand Up @@ -181,6 +184,53 @@ pub(crate) fn initramfs_overlay_generate(
Ok(r.into_raw_fd())
}

#[context("Running dracut")]
pub(crate) fn run_dracut(kernel_dir: &str) -> Result<()> {
let root_fs = Utf8Dir::open_ambient_dir("/", cap_std::ambient_authority())?;
let tmp_dir = tempfile::tempdir()?;
let tmp_initramfs_path = tmp_dir.path().join("initramfs.img");

let cliwrap_dracut = Utf8Path::new(crate::cliwrap::CLIWRAP_DESTDIR).join("dracut");
let dracut_path = cliwrap_dracut
.exists()
.then(|| cliwrap_dracut)
.unwrap_or_else(|| Utf8Path::new("dracut").to_owned());
// If changing this, also look at changing rpmostree-kernel.cxx
let res = Command::new(dracut_path)
.args(&[
"--no-hostonly",
"--kver",
kernel_dir,
"--reproducible",
"-v",
"--add",
"ostree",
"-f",
])
.arg(&tmp_initramfs_path)
.status()?;
if !res.success() {
return Err(anyhow!(
"Failed to generate initramfs (via dracut) for kernel: {kernel_dir}: {:?}",
res
));
}
let f = std::fs::OpenOptions::new()
.write(true)
.append(true)
.open(&tmp_initramfs_path)?;
crate::initramfs::append_dracut_random_cpio(f.as_raw_fd())?;
drop(f);
let utf8_tmp_dir_path = Utf8Path::from_path(tmp_dir.path().strip_prefix("/")?)
.context("Error turning Path to Utf8Path")?;
root_fs.rename(
utf8_tmp_dir_path.join("initramfs.img"),
&root_fs,
(Utf8Path::new("lib/modules").join(kernel_dir)).join("initramfs.img"),
)?;
Ok(())
}

#[cfg(test)]
mod test {
use super::*;
Expand Down

0 comments on commit d8c8cf9

Please sign in to comment.