Skip to content
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
16 changes: 15 additions & 1 deletion crates/lib/src/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,21 @@ async fn initialize_ostree_root(state: &State, root_setup: &RootSetup) -> Result
crate::lsm::ensure_dir_labeled(rootfs_dir, "boot", None, 0o755.into(), sepolicy)?;
}

for (k, v) in DEFAULT_REPO_CONFIG.iter() {
// Build the list of ostree repo config options: defaults + install config
let ostree_opts = state
.install_config
.as_ref()
.and_then(|c| c.ostree.as_ref())
.into_iter()
.flat_map(|o| o.to_config_tuples());

let repo_config: Vec<_> = DEFAULT_REPO_CONFIG
.iter()
.copied()
.chain(ostree_opts)
.collect();

for (k, v) in repo_config.iter() {
Command::new("ostree")
.args(["config", "--repo", "ostree/repo", "set", k, v])
.cwd_dir(rootfs_dir.try_clone()?)
Expand Down
67 changes: 67 additions & 0 deletions crates/lib/src/install/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ pub(crate) struct BasicFilesystems {
// pub(crate) esp: Option<FilesystemCustomization>,
}

/// Configuration for ostree repository
pub(crate) type OstreeRepoOpts = ostree_ext::repo_options::RepoOptions;

/// The serialized [install] section
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(rename = "install", rename_all = "kebab-case", deny_unknown_fields)]
Expand All @@ -73,6 +76,8 @@ pub(crate) struct InstallConfiguration {
pub(crate) kargs: Option<Vec<String>>,
/// Supported architectures for this configuration
pub(crate) match_architectures: Option<Vec<String>>,
/// Ostree repository configuration
pub(crate) ostree: Option<OstreeRepoOpts>,
}

fn merge_basic<T>(s: &mut Option<T>, o: Option<T>, _env: &EnvProperties) {
Expand Down Expand Up @@ -119,6 +124,17 @@ impl Mergeable for BasicFilesystems {
}
}

impl Mergeable for OstreeRepoOpts {
/// Apply any values in other, overriding any existing values in `self`.
fn merge(&mut self, other: Self, env: &EnvProperties) {
merge_basic(
&mut self.bls_append_except_default,
other.bls_append_except_default,
env,
)
}
}

impl Mergeable for InstallConfiguration {
/// Apply any values in other, overriding any existing values in `self`.
fn merge(&mut self, other: Self, env: &EnvProperties) {
Expand All @@ -133,6 +149,7 @@ impl Mergeable for InstallConfiguration {
#[cfg(feature = "install-to-disk")]
merge_basic(&mut self.block, other.block, env);
self.filesystem.merge(other.filesystem, env);
self.ostree.merge(other.ostree, env);
if let Some(other_kargs) = other.kargs {
self.kargs
.get_or_insert_with(Default::default)
Expand Down Expand Up @@ -572,4 +589,54 @@ root-fs-type = "xfs"
)
);
}

#[test]
fn test_parse_ostree() {
let env = EnvProperties {
sys_arch: "x86_64".to_string(),
};

// Table-driven test cases for parsing bls-append-except-default
let parse_cases = [
("console=ttyS0", "console=ttyS0"),
("console=ttyS0,115200n8", "console=ttyS0,115200n8"),
("rd.lvm.lv=vg/root", "rd.lvm.lv=vg/root"),
];
for (input, expected) in parse_cases {
let toml_str = format!(
r#"[install.ostree]
bls-append-except-default = "{input}"
"#
);
let c: InstallConfigurationToplevel = toml::from_str(&toml_str).unwrap();
assert_eq!(
c.install
.unwrap()
.ostree
.unwrap()
.bls_append_except_default
.unwrap(),
expected
);
}

// Test merging: other config should override original
let mut install: InstallConfiguration = toml::from_str(
r#"[ostree]
bls-append-except-default = "console=ttyS0"
"#,
)
.unwrap();
let other = InstallConfiguration {
ostree: Some(OstreeRepoOpts {
bls_append_except_default: Some("console=tty0".to_string()),
}),
..Default::default()
};
install.merge(other, &env);
assert_eq!(
install.ostree.unwrap().bls_append_except_default.unwrap(),
"console=tty0"
);
}
}
1 change: 1 addition & 0 deletions crates/ostree-ext/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ pub mod ostree_prepareroot;
pub mod refescape;
#[doc(hidden)]
pub mod repair;
pub mod repo_options;
pub mod sysroot;
pub mod tar;
pub mod tokio_util;
Expand Down
30 changes: 30 additions & 0 deletions crates/ostree-ext/src/repo_options.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//! Configuration options for an ostree repository

use serde::{Deserialize, Serialize};

/// Configuration options for an ostree repository.
///
/// This struct represents configurable options for an ostree repository
/// that can be set via the `ostree config set` command.
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case", default)]
pub struct RepoOptions {
/// Boot Loader Spec entries that should append arguments only for non-default entries.
///
/// Corresponds to the `sysroot.bls-append-except-default` ostree config key.
#[serde(skip_serializing_if = "Option::is_none")]
pub bls_append_except_default: Option<String>,
}

impl RepoOptions {
/// Returns an iterator of (key, value) tuples for ostree repo configuration.
///
/// Each tuple represents an ostree config key and its value, suitable for
/// passing to `ostree config set`.
pub fn to_config_tuples(&self) -> impl Iterator<Item = (&'static str, &str)> {
self.bls_append_except_default
.as_ref()
.map(|v| ("sysroot.bls-append-except-default", v.as_str()))
.into_iter()
}
}
16 changes: 16 additions & 0 deletions crates/tests-integration/src/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,16 @@ pub(crate) fn test_bootc_install_config() -> Result<()> {
}

pub(crate) fn test_bootc_install_config_all() -> Result<()> {
#[derive(Deserialize)]
#[serde(rename_all = "kebab-case")]
struct TestOstreeConfig {
bls_append_except_default: Option<String>,
}

#[derive(Deserialize)]
struct TestInstallConfig {
kargs: Vec<String>,
ostree: Option<TestOstreeConfig>,
}

let config_d = std::path::Path::new("/run/bootc/install/");
Expand All @@ -113,6 +120,8 @@ pub(crate) fn test_bootc_install_config_all() -> Result<()> {
let content = indoc! {r#"
[install]
kargs = ["karg1=1", "karg2=2"]
[install.ostree]
bls-append-except-default = "grub_users=\"\""
"#};
std::fs::write(&test_toml_path, content)?;
defer! {
Expand All @@ -124,6 +133,13 @@ pub(crate) fn test_bootc_install_config_all() -> Result<()> {
let config: TestInstallConfig =
serde_json::from_str(&config).context("Parsing install config")?;
assert_eq! {config.kargs, vec!["karg1=1".to_string(), "karg2=2".to_string(), "localtestkarg=somevalue".to_string(), "otherlocalkarg=42".to_string()]};
assert_eq!(
config
.ostree
.as_ref()
.and_then(|o| o.bls_append_except_default.as_deref()),
Some("grub_users=\"\"")
);
Ok(())
}

Expand Down
13 changes: 12 additions & 1 deletion docs/src/man/bootc-install-config.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ that can be overridden in a derived container image.

This is the only defined toplevel table.

The `install` section supports two subfields:
The `install` section supports these subfields:

- `block`: An array of supported `to-disk` backends enabled by this base container image;
if not specified, this will just be `direct`. The only other supported value is `tpm2-luks`.
The first value specified will be the default. To enable both, use `block = ["direct", "tpm2-luks"]`.
- `filesystem`: See below.
- `kargs`: An array of strings; this will be appended to the set of kernel arguments.
- `match_architectures`: An array of strings; this filters the install config.
- `ostree`: See below.

# filesystem

Expand All @@ -37,13 +38,23 @@ There is one valid field:

`type`: This can be any basic Linux filesystem with a `mkfs.$fstype`. For example, `ext4`, `xfs`, etc.

# ostree

Configuration options for the ostree repository. There is one valid field:

- `bls-append-except-default`: A string of kernel arguments that will be appended to
Boot Loader Spec entries, except for the default entry. This is useful for configuring
arguments that should only apply to non-default deployments.

# Examples

```toml
[install.filesystem.root]
type = "xfs"
[install]
kargs = ["nosmt", "console=tty0"]
[install.ostree]
bls-append-except-default = 'grub_users=""'
```

# SEE ALSO
Expand Down
Loading