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

Add support for --remove-installed-kernel #4322

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
8 changes: 8 additions & 0 deletions ci/test-container.sh
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,14 @@ rpm -q ignition
dnf -y uninstall kexec-tools
if rpm -q kexec-tools; then fatal "failed to remove kexec-tools"; fi

rpm -q kernel
# Fedora doesn't ship kernel variants, so we just install some other package
rpm-ostree install --remove-installed-kernel strace
if rpm -qa |grep -E '^kernel'; then
fatal "Found installed kernel after --remove-installed-kernel"
fi
rpm -e strace

# test replacement by Koji URL
rpm-ostree override replace $koji_url |& tee out.txt
n_downloaded=$(grep Downloading out.txt | wc -l)
Expand Down
20 changes: 20 additions & 0 deletions rpmostree-cxxrs.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -1703,6 +1703,8 @@ struct Treefile final : public ::rust::Opaque
bool remove_package_override_remove (::rust::Str package) noexcept;
bool has_packages_override_remove_name (::rust::Str name) const noexcept;
bool remove_all_overrides () noexcept;
bool has_remove_kernel () const noexcept;
bool set_remove_kernel (bool remove) noexcept;
::rust::Vec< ::rust::String> get_modules_enable () const noexcept;
bool has_modules_enable () const noexcept;
::rust::Vec< ::rust::String> get_modules_install () const noexcept;
Expand Down Expand Up @@ -2487,6 +2489,12 @@ extern "C"
bool
rpmostreecxx$cxxbridge1$Treefile$remove_all_overrides (::rpmostreecxx::Treefile &self) noexcept;

bool rpmostreecxx$cxxbridge1$Treefile$has_remove_kernel (
const ::rpmostreecxx::Treefile &self) noexcept;

bool rpmostreecxx$cxxbridge1$Treefile$set_remove_kernel (::rpmostreecxx::Treefile &self,
bool remove) noexcept;

void rpmostreecxx$cxxbridge1$Treefile$get_modules_enable (
const ::rpmostreecxx::Treefile &self, ::rust::Vec< ::rust::String> *return$) noexcept;

Expand Down Expand Up @@ -4902,6 +4910,18 @@ Treefile::remove_all_overrides () noexcept
return rpmostreecxx$cxxbridge1$Treefile$remove_all_overrides (*this);
}

bool
Treefile::has_remove_kernel () const noexcept
{
return rpmostreecxx$cxxbridge1$Treefile$has_remove_kernel (*this);
}

bool
Treefile::set_remove_kernel (bool remove) noexcept
{
return rpmostreecxx$cxxbridge1$Treefile$set_remove_kernel (*this, remove);
}

::rust::Vec< ::rust::String>
Treefile::get_modules_enable () const noexcept
{
Expand Down
2 changes: 2 additions & 0 deletions rpmostree-cxxrs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1485,6 +1485,8 @@ struct Treefile final : public ::rust::Opaque
bool remove_package_override_remove (::rust::Str package) noexcept;
bool has_packages_override_remove_name (::rust::Str name) const noexcept;
bool remove_all_overrides () noexcept;
bool has_remove_kernel () const noexcept;
bool set_remove_kernel (bool remove) noexcept;
::rust::Vec< ::rust::String> get_modules_enable () const noexcept;
bool has_modules_enable () const noexcept;
::rust::Vec< ::rust::String> get_modules_install () const noexcept;
Expand Down
2 changes: 2 additions & 0 deletions rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,8 @@ pub mod ffi {
fn remove_package_override_remove(&mut self, package: &str) -> bool;
fn has_packages_override_remove_name(&self, name: &str) -> bool;
fn remove_all_overrides(&mut self) -> bool;
fn has_remove_kernel(&self) -> bool;
fn set_remove_kernel(&mut self, remove: bool) -> bool;
fn get_modules_enable(&self) -> Vec<String>;
fn has_modules_enable(&self) -> bool;
fn get_modules_install(&self) -> Vec<String>;
Expand Down
39 changes: 39 additions & 0 deletions rust/src/treefile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,10 @@ fn treefile_merge(dest: &mut TreeComposeConfig, src: &mut TreeComposeConfig) {
&mut dest.derive.override_replace,
&mut src.derive.override_replace,
);
merge_basic_field(
&mut dest.derive.override_remove_kernel,
&mut src.derive.override_remove_kernel,
);
dest.handle_repo_packages_override_replacements();
merge_map_field(
&mut dest.derive.override_replace_local,
Expand Down Expand Up @@ -1040,6 +1044,15 @@ impl Treefile {
.unwrap_or_default()
}

/// Kernel removal is configured
pub(crate) fn has_remove_kernel(&self) -> bool {
self.parsed
.derive
.override_remove_kernel
.clone()
.unwrap_or_default()
}

// Check that the same overrides don't already exist. Of course, in the local replace
// case, this doesn't catch same pkg name but different EVRA; we'll just barf at that
// later on in the core. This is an early easy sanity check.
Expand Down Expand Up @@ -1135,6 +1148,21 @@ impl Treefile {
Some(old_map) != self.parsed.derive.override_replace
}

/// Change the state of kernel removal for derived images
pub(crate) fn set_remove_kernel(&mut self, remove: bool) -> bool {
let current = self
.parsed
.derive
.override_remove_kernel
.take()
.unwrap_or_default();
// Note we did .take() above, so this also canonicalizes false -> None
if remove {
self.parsed.derive.override_remove_kernel = Some(true);
}
current != remove
}

pub(crate) fn remove_package_override_replace(&mut self, package: &str) -> bool {
self.parsed
.derive
Expand Down Expand Up @@ -1196,6 +1224,7 @@ impl Treefile {
.map(|x| !x.is_empty())
.unwrap_or_default()
|| changed;
changed = self.set_remove_kernel(false) || changed;
changed
}

Expand Down Expand Up @@ -1621,6 +1650,7 @@ impl Treefile {
clone.override_replace.take();
clone.override_remove.take();
clone.override_replace_local.take();
clone.override_remove_kernel.take();
if clone != Default::default() {
let j = serde_json::to_string_pretty(&clone)?;
bail!(
Expand Down Expand Up @@ -1894,6 +1924,12 @@ impl Treefile {
.as_ref()
.and_then(|m| m.install.as_ref().map(|i| !i.is_empty()))
.unwrap_or_default()
|| self
.parsed
.derive
.override_remove_kernel
.clone()
.unwrap_or_default()
}

/// Derive RPM importer flags for a given package and treefile settings.
Expand Down Expand Up @@ -2714,6 +2750,9 @@ pub(crate) struct DeriveConfigFields {
pub(crate) packages_local_fileoverride: Option<BTreeMap<String, String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) override_remove: Option<BTreeSet<String>>,
/// Remove the kernel
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) override_remove_kernel: Option<bool>,
#[serde(rename = "ex-override-replace")]
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) override_replace: Option<Vec<RemoteOverrideReplace>>,
Expand Down
6 changes: 6 additions & 0 deletions src/app/rpmostree-pkg-builtins.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ static gboolean opt_apply_live;
static gboolean opt_idempotent;
static gchar **opt_install;
static gboolean opt_assumeyes;
static gboolean opt_remove_kernel;
static gchar **opt_uninstall;
static gboolean opt_cache_only;
static gboolean opt_download_only;
Expand Down Expand Up @@ -90,6 +91,9 @@ static GOptionEntry install_option_entry[]
"Just download latest ostree and RPM data, don't deploy", NULL },
{ "apply-live", 'A', 0, G_OPTION_ARG_NONE, &opt_apply_live,
"Apply changes to both pending deployment and running filesystem tree", NULL },
{ "remove-installed-kernel", 0, 0, G_OPTION_ARG_NONE, &opt_remove_kernel,
"Remove the installed kernel packages (usually helpful to install a different kernel)",
NULL },
{ "force-replacefiles", 0, 0, G_OPTION_ARG_NONE, &opt_force_replacefiles,
"Allow package to replace files from other packages", NULL },
{ NULL } };
Expand Down Expand Up @@ -260,6 +264,8 @@ rpmostree_builtin_install (int argc, char **argv, RpmOstreeCommandInvocation *in
auto ver = rust::Str (*it);
treefile->set_releasever (ver);
}
if (opt_remove_kernel)
treefile->set_remove_kernel (true);
return rpmostree_container_rebuild (*treefile, cancellable, error);
}

Expand Down
29 changes: 29 additions & 0 deletions src/libpriv/rpmostree-core.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@
#define RPMOSTREE_MESSAGE_PKG_IMPORT \
SD_ID128_MAKE (df, 8b, b5, 4f, 04, fa, 47, 08, ac, 16, 11, 1b, bf, 4b, a3, 52)

// This is a copy of the defaults from libdnf because it's not public API
// see INSTALLONLYPKGS there.
static const char *KERNEL_PACKAGES[] = { "kernel",
"kernel-PAE",
"installonlypkg(kernel)",
"installonlypkg(kernel-module)",
"installonlypkg(vm)",
"multiversion(kernel)" };

static OstreeRepo *get_pkgcache_repo (RpmOstreeContext *self);

static int
Expand Down Expand Up @@ -1734,6 +1743,7 @@ rpmostree_context_prepare (RpmOstreeContext *self, GCancellable *cancellable, GE
auto exclude_packages = self->treefile_rs->get_exclude_packages ();
auto modules_enable = self->treefile_rs->get_modules_enable ();
auto modules_install = self->treefile_rs->get_modules_install ();
auto remove_kernel = self->treefile_rs->has_remove_kernel ();

/* we only support pure installs for now (compose case) */
if (self->lockfile)
Expand Down Expand Up @@ -1945,6 +1955,25 @@ rpmostree_context_prepare (RpmOstreeContext *self, GCancellable *cancellable, GE
g_ptr_array_add (removed_pkgnames, (gpointer)pkgname);
}

if (remove_kernel)
{
for (guint i = 0; i < G_N_ELEMENTS (KERNEL_PACKAGES); i++)
{
const char *pkg = KERNEL_PACKAGES[i];
hy_autoquery HyQuery query = hy_query_create (sack);
hy_query_filter (query, HY_PKG_REPONAME, HY_EQ, HY_SYSTEM_REPO_NAME);
hy_query_filter (query, HY_PKG_PROVIDES, HY_EQ, pkg);
g_autoptr (GPtrArray) packages = hy_query_run (query);
for (guint i = 0; i < packages->len; i++)
{
auto pkg = static_cast<DnfPackage *> (g_ptr_array_index (packages, i));
g_printerr ("Removing kernel pkg: %s\n", dnf_package_get_name (pkg));
g_ptr_array_add (removed_pkgnames, (gpointer)dnf_package_get_name (pkg));
hy_goal_erase (goal, pkg);
}
}
}

/* Then, handle local packages to install */
GLNX_HASH_TABLE_FOREACH_V (local_pkgs_to_install, DnfPackage *, pkg)
hy_goal_install (goal, pkg);
Expand Down