Skip to content

Commit

Permalink
kargs: Use merge deployment
Browse files Browse the repository at this point in the history
This is in general for us right now a no-op, but is closer
to technically correct. In ostree the "merge deployment"
concept started out as "deployment we use for the original /etc"
which *may be different* from the booted deployment. For example,
when one wants to do a "factory reset", we want to start
from a fresh /etc.

The other important case here is when we're doing a fresh
install (or into a new stateroot) there may be no merge
deployment at all! It wouldn't be correct to look at `/`.

We only sidestep this issue right now because the install
logic bypasses this to directly gather kargs...and doesn't
use the same `deploy` API as inplace updates. But we
want to get closer to doing things that way.

Signed-off-by: Colin Walters <[email protected]>
  • Loading branch information
cgwalters committed Jul 11, 2024
1 parent 7d91ed9 commit 46516cd
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 13 deletions.
6 changes: 1 addition & 5 deletions lib/src/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,11 +335,7 @@ async fn deploy(
// is a distinct minor issue, but not super important as right now the install path
// doesn't use this API).
let override_kargs = if let Some(deployment) = merge_deployment {
Some(crate::kargs::get_kargs(
&sysroot.repo(),
&deployment,
image,
)?)
Some(crate::kargs::get_kargs(sysroot, &deployment, image)?)
} else {
None
};
Expand Down
18 changes: 10 additions & 8 deletions lib/src/kargs.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use anyhow::{Context, Result};
use camino::Utf8Path;
use cap_std_ext::cap_std;
use cap_std_ext::cap_std::fs::Dir;
use cap_std_ext::dirext::CapStdExtDirExt;
use ostree::gio;
Expand All @@ -9,6 +8,7 @@ use ostree_ext::ostree::Deployment;
use ostree_ext::prelude::Cast;
use ostree_ext::prelude::FileEnumeratorExt;
use ostree_ext::prelude::FileExt;
use ostree_ext::sysroot::SysrootLock;
use serde::Deserialize;

use crate::deploy::ImageState;
Expand Down Expand Up @@ -101,25 +101,26 @@ fn get_kargs_from_ostree(
/// karg, but applies the diff between the bootc karg files in /usr/lib/bootc/kargs.d
/// between the booted deployment and the new one.
pub(crate) fn get_kargs(
repo: &ostree::Repo,
booted_deployment: &Deployment,
sysroot: &SysrootLock,
merge_deployment: &Deployment,
fetched: &ImageState,
) -> Result<Vec<String>> {
let cancellable = gio::Cancellable::NONE;
let repo = &sysroot.repo();
let mut kargs: Vec<String> = vec![];
let sys_arch = std::env::consts::ARCH;

// Get the running kargs of the booted system
if let Some(bootconfig) = ostree::Deployment::bootconfig(booted_deployment) {
// Get the kargs used for the merge in the bootloader config
if let Some(bootconfig) = ostree::Deployment::bootconfig(merge_deployment) {
if let Some(options) = ostree::BootconfigParser::get(&bootconfig, "options") {
let options = options.split_whitespace().map(|s| s.to_owned());
kargs.extend(options);
}
};

// Get the kargs in kargs.d of the booted system
let root = &cap_std::fs::Dir::open_ambient_dir("/", cap_std::ambient_authority())?;
let existing_kargs: Vec<String> = get_kargs_in_root(root, sys_arch)?;
// Get the kargs in kargs.d of the merge
let merge_root = &crate::utils::deployment_fd(sysroot, merge_deployment)?;
let existing_kargs: Vec<String> = get_kargs_in_root(merge_root, sys_arch)?;

// Get the kargs in kargs.d of the pending image
let (fetched_tree, _) = repo.read_commit(fetched.ostree_commit.as_str(), cancellable)?;
Expand Down Expand Up @@ -179,6 +180,7 @@ fn parse_kargs_toml(contents: &str, sys_arch: &str) -> Result<Vec<String>> {

#[cfg(test)]
mod tests {
use cap_std_ext::cap_std;
use fn_error_context::context;
use rustix::fd::{AsFd, AsRawFd};

Expand Down
20 changes: 20 additions & 0 deletions lib/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use std::future::Future;
use std::io::Write;
use std::os::fd::BorrowedFd;
use std::process::Command;
use std::time::Duration;

use anyhow::{Context, Result};
use cap_std_ext::cap_std::fs::Dir;
use ostree::glib;
use ostree_ext::container::SignatureSource;
use ostree_ext::ostree;
Expand All @@ -21,6 +23,24 @@ pub(crate) fn origin_has_rpmostree_stuff(kf: &glib::KeyFile) -> bool {
false
}

// Access the file descriptor for a sysroot
#[allow(unsafe_code)]
pub(crate) fn sysroot_fd(sysroot: &ostree::Sysroot) -> BorrowedFd {
unsafe { BorrowedFd::borrow_raw(sysroot.fd()) }
}

// Return a cap-std `Dir` type for a deployment.
// TODO: in the future this should perhaps actually mount via composefs
#[allow(unsafe_code)]
pub(crate) fn deployment_fd(
sysroot: &ostree::Sysroot,
deployment: &ostree::Deployment,
) -> Result<Dir> {
let sysroot_dir = &Dir::reopen_dir(&sysroot_fd(sysroot))?;
let dirpath = sysroot.deployment_dirpath(deployment);
sysroot_dir.open_dir(&dirpath).map_err(Into::into)
}

/// Given an mount option string list like foo,bar=baz,something=else,ro parse it and find
/// the first entry like $optname=
/// This will not match a bare `optname` without an equals.
Expand Down

0 comments on commit 46516cd

Please sign in to comment.