Skip to content
Open
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
53 changes: 53 additions & 0 deletions crates/lib/src/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,12 @@ pub(crate) struct InstallConfigOpts {
#[clap(long)]
pub(crate) karg: Option<Vec<CmdlineOwned>>,

/// Remove a kernel argument. This option can be provided multiple times.
///
/// Example: --karg-delete=nosmt --karg=console=ttyS0,115200n8
#[clap(long)]
pub(crate) karg_delete: Option<Vec<String>>,

/// The path to an `authorized_keys` that will be injected into the `root` account.
///
/// The implementation of this uses systemd `tmpfiles.d`, writing to a file named
Expand Down Expand Up @@ -1124,13 +1130,18 @@ async fn install_container(

// Keep this in sync with install/completion.rs for the Anaconda fixups
let install_config_kargs = state.install_config.as_ref().and_then(|c| c.kargs.as_ref());
let install_config_karg_deletes = state
.install_config
.as_ref()
.and_then(|c| c.karg_deletes.as_ref());

// Final kargs, in order:
// - root filesystem kargs
// - install config kargs
// - kargs.d from container image
// - args specified on the CLI
let mut kargs = Cmdline::new();
let mut karg_deletes = Vec::<&str>::new();

kargs.extend(&root_setup.kargs);

Expand All @@ -1142,6 +1153,19 @@ async fn install_container(

kargs.extend(&kargsd);

// delete kargs before processing cli kargs, so cli kargs can override all other configs
if let Some(install_config_karg_deletes) = install_config_karg_deletes {
for karg_delete in install_config_karg_deletes {
karg_deletes.push(karg_delete);
}
}
if let Some(deletes) = state.config_opts.karg_delete.as_ref() {
for karg_delete in deletes {
karg_deletes.push(karg_delete);
}
}
delete_kargs(&mut kargs, &karg_deletes);

if let Some(cli_kargs) = state.config_opts.karg.as_ref() {
for karg in cli_kargs {
kargs.extend(karg);
Expand Down Expand Up @@ -1224,6 +1248,18 @@ async fn install_container(
Ok((deployment, aleph))
}

pub(crate) fn delete_kargs(existing: &mut Cmdline, deletes: &Vec<&str>) {
for delete in deletes {
if let Some(param) = utf8::Parameter::parse(&delete) {
if param.value().is_some() {
existing.remove_exact(&param);
} else {
existing.remove(&param.key());
}
}
}
}

/// Run a command in the host mount namespace
pub(crate) fn run_in_host_mountns(cmd: &str) -> Result<Command> {
let mut c = Command::new(bootc_utils::reexec::executable_path()?);
Expand Down Expand Up @@ -3085,4 +3121,21 @@ UUID=boot-uuid /boot ext4 defaults 0 0

Ok(())
}

#[test]
fn test_delete_kargs() -> Result<()> {
let mut cmdline = Cmdline::from("console=tty0 quiet debug nosmt foo=bar foo=baz bar=baz");

let deletions = vec!["foo=bar", "bar", "debug"];

delete_kargs(&mut cmdline, &deletions);

let result = cmdline.to_string();
assert!(!result.contains("foo=bar"));
assert!(!result.contains("bar"));
assert!(!result.contains("debug"));
assert!(result.contains("foo=baz"));

Ok(())
}
}
27 changes: 26 additions & 1 deletion crates/lib/src/install/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ pub(crate) struct InstallConfiguration {
/// Kernel arguments, applied at installation time
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) kargs: Option<Vec<String>>,
/// Deleting Kernel arguments, applied at installation time
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) karg_deletes: Option<Vec<String>>,
/// Supported architectures for this configuration
pub(crate) match_architectures: Option<Vec<String>>,
/// Ostree repository configuration
Expand Down Expand Up @@ -208,6 +211,11 @@ impl Mergeable for InstallConfiguration {
.get_or_insert_with(Default::default)
.extend(other_kargs)
}
if let Some(other_karg_deletes) = other.karg_deletes {
self.karg_deletes
.get_or_insert_with(Default::default)
.extend(other_karg_deletes)
}
}
}
}
Expand Down Expand Up @@ -242,6 +250,7 @@ impl InstallConfiguration {
// Remove all configuration which is handled by `install to-filesystem`.
pub(crate) fn filter_to_external(&mut self) {
self.kargs.take();
self.karg_deletes.take();
}

#[cfg(feature = "install-to-disk")]
Expand Down Expand Up @@ -346,6 +355,7 @@ root-fs-type = "xfs"
r##"[install]
root-fs-type = "ext4"
kargs = ["console=ttyS0", "foo=bar"]
karg-deletes = ["debug", "bar=baz"]
"##,
)
.unwrap();
Expand All @@ -359,6 +369,12 @@ kargs = ["console=ttyS0", "foo=bar"]
.map(ToOwned::to_owned)
.collect(),
),
karg_deletes: Some(
["baz", "bar=baz"]
.into_iter()
.map(ToOwned::to_owned)
.collect(),
),
..Default::default()
}),
};
Expand All @@ -372,7 +388,16 @@ kargs = ["console=ttyS0", "foo=bar"]
.map(ToOwned::to_owned)
.collect()
)
)
);
assert_eq!(
install.karg_deletes,
Some(
["debug", "bar=baz", "baz", "bar=baz"]
.into_iter()
.map(ToOwned::to_owned)
.collect()
)
);
}

#[test]
Expand Down
20 changes: 20 additions & 0 deletions crates/tests-integration/src/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,26 @@ pub(crate) fn run_alongside(image: &str, mut testargs: libtest_mimic::Arguments)
generic_post_install_verification()?;
Ok(())
}),
Trial::test("install with --karg-delete", move || {
let sh = &xshell::Shell::new()?;
reset_root(sh, image)?;
cmd!(sh, "sudo {BASE_ARGS...} {target_args...} {image} bootc install to-filesystem --acknowledge-destructive --karg-delete=localtestkarg --replace=alongside /target").run()?;
cmd!(
sh,
"sudo {BASE_ARGS...} {target_args...} {image} bootc install finalize /target"
)
.run()?;
let entries = cmd!(
sh,
"sudo /bin/sh -c 'grep localtestkarg /boot/loader/entries/*.conf'"
)
.ignore_status()
.read()?;

assert!(entries.is_empty());

Ok(())
}),
];

libtest_mimic::run(&testargs, tests.into()).exit()
Expand Down
4 changes: 4 additions & 0 deletions docs/src/man/bootc-install-to-disk.8.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ its DPS type GUID, without requiring an explicit `root=` kernel argument.

Add a kernel argument. This option can be provided multiple times

**--karg-delete**=*KARG_DELETE*

Remove a kernel argument. This option can be provided multiple times

**--root-ssh-authorized-keys**=*ROOT_SSH_AUTHORIZED_KEYS*

The path to an `authorized_keys` that will be injected into the `root` account
Expand Down
4 changes: 4 additions & 0 deletions docs/src/man/bootc-install-to-existing-root.8.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ of migrating the fstab entries. See the "Injecting kernel arguments" section abo

Add a kernel argument. This option can be provided multiple times

**--karg-delete**=*KARG_DELETE*

Remove a kernel argument. This option can be provided multiple times

**--root-ssh-authorized-keys**=*ROOT_SSH_AUTHORIZED_KEYS*

The path to an `authorized_keys` that will be injected into the `root` account
Expand Down
4 changes: 4 additions & 0 deletions docs/src/man/bootc-install-to-filesystem.8.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ is currently expected to be empty by default.

Add a kernel argument. This option can be provided multiple times

**--karg-delete**=*KARG_DELETE*

Remove a kernel argument. This option can be provided multiple times

**--root-ssh-authorized-keys**=*ROOT_SSH_AUTHORIZED_KEYS*

The path to an `authorized_keys` that will be injected into the `root` account
Expand Down
8 changes: 8 additions & 0 deletions tmt/plans/integration.fmf
Original file line number Diff line number Diff line change
Expand Up @@ -237,4 +237,12 @@ execute:
how: fmf
test:
- /tmt/tests/tests/test-39-upgrade-tag

/plan-40-install-karg-delete:
summary: Test bootc install --karg-delete
discover:
how: fmf
test:
- /tmt/tests/tests/test-40-install-karg-delete
extra-fixme_skip_if_composefs: true
# END GENERATED PLANS
47 changes: 47 additions & 0 deletions tmt/tests/booted/test-install-karg-delete.nu
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# number: 40
# tmt:
# summary: Test bootc install --karg-delete
# duration: 30m
# extra:
# fixme_skip_if_composefs: true
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should work for composefs backend as well since the config gathering in the install path is pretty much the same for ostree and composefs. Were you getting some sort of error when testing this for composefs backend?

#
use std assert
use tap.nu
#
# Use an OS-matched target image to avoid version mismatches
let target_image = (tap get_target_image)

# setup filesystem
mkdir /var/mnt
truncate -s 10G disk.img
mkfs.ext4 disk.img
mount -o loop disk.img /var/mnt

# Mask off the bootupd state to reproduce https://github.com/bootc-dev/bootc/issues/1778
# Also it turns out that installation outside of containers dies due to `error: Multiple commit objects found`
# so we mask off /sysroot/ostree
# And using systemd-run here breaks our install_t so we disable SELinux enforcement
setenforce 0

mkdir /etc/bootc/install
{ install: { kargs: ["foo=bar"] } } | to toml | save /etc/bootc/install/99-test.toml

tap run_install $"bootc install to-filesystem --disable-selinux --bootloader none --source-imgref ($target_image) --karg-delete localtestkarg --karg-delete foo /var/mnt"


# Verify the karg is gone from the bootloader entries
let entries = (glob /var/mnt/boot/loader/entries/*.conf
| each { open $in | lines }
| flatten)

let localtestkarg_found = ($entries | find "localtestkarg" | is-empty)
assert $localtestkarg_found "Found localtestkarg in bootloader entries, but it should have been deleted"

let foo_found = ($entries | find "foo" | is-empty)
assert $foo_found "Found foo in bootloader entries, but it should have been deleted"

# Clean up
umount /var/mnt
rm -rf disk.img

tap ok
5 changes: 5 additions & 0 deletions tmt/tests/tests.fmf
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,8 @@
summary: Test bootc upgrade --tag functionality with containers-storage
duration: 30m
test: nu booted/test-upgrade-tag.nu

/test-40-install-karg-delete:
summary: Test bootc install --karg-delete
duration: 30m
test: nu booted/test-install-karg-delete.nu