diff --git a/0027-Add-detection-for-ostree-based-systems-and-warn-user.patch b/0027-Add-detection-for-ostree-based-systems-and-warn-user.patch new file mode 100644 index 0000000..725f2fb --- /dev/null +++ b/0027-Add-detection-for-ostree-based-systems-and-warn-user.patch @@ -0,0 +1,99 @@ +From 6af6633b3e1e92405ec63ef4d3d697891213f8cb Mon Sep 17 00:00:00 2001 +From: David Cantrell +Date: Thu, 15 Feb 2024 14:03:32 -0500 +Subject: [PATCH 1/4] Add detection for ostree-based systems and warn users + about losing changes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Upstream commit: 5c050ba2324c5fb95bf0e0501c7925f38f6a09dc + +On ostree-based systems, users can use dnf to customize the +environment but those changes will be lost at the next ostree-based +image update. If you want to retain changes between ostree-updates +you need to make use of rpm-ostree right now. + +Signed-off-by: David Cantrell +Resolves: https://issues.redhat.com/browse/RHEL-49670 +Signed-off-by: Petr Písař +--- + dnf/cli/cli.py | 9 +++++++++ + dnf/util.py | 31 +++++++++++++++++++++++++++++++ + 2 files changed, 40 insertions(+) + +diff --git a/dnf/cli/cli.py b/dnf/cli/cli.py +index 0c4f4c6ad..1fd0e96c3 100644 +--- a/dnf/cli/cli.py ++++ b/dnf/cli/cli.py +@@ -214,6 +214,15 @@ class BaseCli(dnf.Base): + elif 'test' in self.conf.tsflags: + logger.info(_("{prog} will only download packages, install gpg keys, and check the " + "transaction.").format(prog=dnf.util.MAIN_PROG_UPPER)) ++ if dnf.util.is_container(): ++ _container_msg = _(""" ++*** This system is managed with ostree. Changes to the system ++*** made with dnf will be lost with the next ostree-based update. ++*** If you do not want to lose these changes, use 'rpm-ostree'. ++""") ++ logger.info(_container_msg) ++ raise CliError(_("Operation aborted.")) ++ + if self._promptWanted(): + if self.conf.assumeno or not self.output.userconfirm(): + raise CliError(_("Operation aborted.")) +diff --git a/dnf/util.py b/dnf/util.py +index 16c5bc89c..9909f8fea 100644 +--- a/dnf/util.py ++++ b/dnf/util.py +@@ -33,11 +33,13 @@ import errno + import functools + import hawkey + import itertools ++import json + import locale + import logging + import os + import pwd + import shutil ++import subprocess + import sys + import tempfile + import time +@@ -631,3 +633,32 @@ def _post_transaction_output(base, transaction, action_callback): + def _name_unset_wrapper(input_name): + # returns for everything that evaluates to False (None, empty..) + return input_name if input_name else _("") ++ ++ ++def is_container(): ++ """Returns true is the system is managed as an immutable container, ++ false otherwise. If msg is True, a warning message is displayed ++ for the user. ++ """ ++ ++ bootc = '/usr/bin/bootc' ++ ostree = '/sysroot/ostree' ++ ++ if os.path.isfile(bootc) and os.access(bootc, os.X_OK): ++ p = subprocess.Popen([bootc, "status", "--json"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) ++ (out, err) = p.communicate() ++ ++ if p.returncode == 0: ++ # check the output of 'bootc status' ++ j = json.loads(out) ++ ++ # XXX: the API from bootc status is evolving ++ status = j.get("status", "") ++ kind = j.get("kind", "") ++ ++ if kind.lower() == "bootchost" and bool(status.get("isContainer", None)): ++ return True ++ elif os.path.isdir(ostree): ++ return True ++ ++ return False +\ No newline at end of file +-- +2.46.2 + diff --git a/0028-Update-ostree-bootc-host-system-check.patch b/0028-Update-ostree-bootc-host-system-check.patch new file mode 100644 index 0000000..e3ba74c --- /dev/null +++ b/0028-Update-ostree-bootc-host-system-check.patch @@ -0,0 +1,107 @@ +From 6157248a5035a7752115143d8d29773384c1db3f Mon Sep 17 00:00:00 2001 +From: Joseph Marrero +Date: Tue, 16 Jul 2024 15:48:41 -0400 +Subject: [PATCH 2/4] Update ostree/bootc host system check. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Upstream commit: 6120fe52511775b60b6031d4169988c025610ab5 + +This changes the is_container() func for _is_bootc_host() +and updates the logic and message. This should detect on +all ostree and bootc hosts to date that are not using +bootc usroverlay or ostree admin unlock for development +purposes. + +Resolves: https://issues.redhat.com/browse/RHEL-49670 +Signed-off-by: Petr Písař +--- + dnf/cli/cli.py | 11 +++++------ + dnf/util.py | 33 ++++++++------------------------- + 2 files changed, 13 insertions(+), 31 deletions(-) + +diff --git a/dnf/cli/cli.py b/dnf/cli/cli.py +index 1fd0e96c3..8521dd351 100644 +--- a/dnf/cli/cli.py ++++ b/dnf/cli/cli.py +@@ -214,13 +214,12 @@ class BaseCli(dnf.Base): + elif 'test' in self.conf.tsflags: + logger.info(_("{prog} will only download packages, install gpg keys, and check the " + "transaction.").format(prog=dnf.util.MAIN_PROG_UPPER)) +- if dnf.util.is_container(): +- _container_msg = _(""" +-*** This system is managed with ostree. Changes to the system +-*** made with dnf will be lost with the next ostree-based update. +-*** If you do not want to lose these changes, use 'rpm-ostree'. ++ if dnf.util._is_bootc_host(): ++ _bootc_host_msg = _(""" ++*** Error: system is configured to be read-only; for more ++*** information run `bootc status` or `ostree admin status`. + """) +- logger.info(_container_msg) ++ logger.info(_bootc_host_msg) + raise CliError(_("Operation aborted.")) + + if self._promptWanted(): +diff --git a/dnf/util.py b/dnf/util.py +index 9909f8fea..e8f587a03 100644 +--- a/dnf/util.py ++++ b/dnf/util.py +@@ -33,13 +33,11 @@ import errno + import functools + import hawkey + import itertools +-import json + import locale + import logging + import os + import pwd + import shutil +-import subprocess + import sys + import tempfile + import time +@@ -635,30 +633,15 @@ def _name_unset_wrapper(input_name): + return input_name if input_name else _("") + + +-def is_container(): ++def _is_bootc_host(): + """Returns true is the system is managed as an immutable container, + false otherwise. If msg is True, a warning message is displayed + for the user. + """ +- +- bootc = '/usr/bin/bootc' +- ostree = '/sysroot/ostree' +- +- if os.path.isfile(bootc) and os.access(bootc, os.X_OK): +- p = subprocess.Popen([bootc, "status", "--json"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) +- (out, err) = p.communicate() +- +- if p.returncode == 0: +- # check the output of 'bootc status' +- j = json.loads(out) +- +- # XXX: the API from bootc status is evolving +- status = j.get("status", "") +- kind = j.get("kind", "") +- +- if kind.lower() == "bootchost" and bool(status.get("isContainer", None)): +- return True +- elif os.path.isdir(ostree): +- return True +- +- return False +\ No newline at end of file ++ ostree_booted = '/run/ostree-booted' ++ usr = '/usr/' ++ # Check if usr is writtable and we are in a running ostree system. ++ # We want this code to return true only when the system is in locked state. If someone ran ++ # bootc overlay or ostree admin unlock we would want normal DNF path to be ran as it will be ++ # temporary changes (until reboot). ++ return os.path.isfile(ostree_booted) and not os.access(usr, os.W_OK) +-- +2.46.2 + diff --git a/0029-Update-bootc-hosts-message-to-point-to-bootc-help.patch b/0029-Update-bootc-hosts-message-to-point-to-bootc-help.patch new file mode 100644 index 0000000..0adda93 --- /dev/null +++ b/0029-Update-bootc-hosts-message-to-point-to-bootc-help.patch @@ -0,0 +1,32 @@ +From 0bab6b9620f9872271c9458212538eb03b8b085c Mon Sep 17 00:00:00 2001 +From: Joseph Marrero +Date: Mon, 22 Jul 2024 15:33:32 -0400 +Subject: [PATCH 3/4] Update bootc hosts message to point to bootc --help +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Upstream commit: e2535589ce16bc36b96b37369502a3c312f6056a +Resolves: https://issues.redhat.com/browse/RHEL-49670 + +Signed-off-by: Petr Písař +--- + dnf/cli/cli.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dnf/cli/cli.py b/dnf/cli/cli.py +index 8521dd351..99af9069b 100644 +--- a/dnf/cli/cli.py ++++ b/dnf/cli/cli.py +@@ -217,7 +217,7 @@ class BaseCli(dnf.Base): + if dnf.util._is_bootc_host(): + _bootc_host_msg = _(""" + *** Error: system is configured to be read-only; for more +-*** information run `bootc status` or `ostree admin status`. ++*** information run `bootc --help`. + """) + logger.info(_bootc_host_msg) + raise CliError(_("Operation aborted.")) +-- +2.46.2 + diff --git a/0030-Allow-installroot-on-read-only-bootc-system.patch b/0030-Allow-installroot-on-read-only-bootc-system.patch new file mode 100644 index 0000000..c73c8c0 --- /dev/null +++ b/0030-Allow-installroot-on-read-only-bootc-system.patch @@ -0,0 +1,47 @@ +From ca4c52214b16fe298c44939cd7aaccd9b7549869 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= +Date: Thu, 15 Aug 2024 14:04:55 +0200 +Subject: [PATCH 4/4] Allow --installroot on read-only bootc system +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Upstream commit: a1aa8d0e048751859a2bec1b2fb12fcca93c6e83 + +Some people use --installroot on a read-only bootc system to install +a system into a chroot subtree. However, current bootc check did not +take into account --installroot and rejected the operation. + +This patch augments the check for the installroot being different +from /. + +It's pointless to check for installroot writability here because +installroot is written before this check when updating the +repositories and computing a transaction. Moving this check sooner +would not help because some directories (/opt, /) are kept read-only +even on writable bootc. + +Resolves: #2108 +Resolves: https://issues.redhat.com/browse/RHEL-49670 +Signed-off-by: Petr Písař +--- + dnf/cli/cli.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/dnf/cli/cli.py b/dnf/cli/cli.py +index 99af9069b..36cfa74b5 100644 +--- a/dnf/cli/cli.py ++++ b/dnf/cli/cli.py +@@ -214,7 +214,8 @@ class BaseCli(dnf.Base): + elif 'test' in self.conf.tsflags: + logger.info(_("{prog} will only download packages, install gpg keys, and check the " + "transaction.").format(prog=dnf.util.MAIN_PROG_UPPER)) +- if dnf.util._is_bootc_host(): ++ if dnf.util._is_bootc_host() and \ ++ os.path.realpath(self.conf.installroot) == "/": + _bootc_host_msg = _(""" + *** Error: system is configured to be read-only; for more + *** information run `bootc --help`. +-- +2.46.2 + diff --git a/dnf.spec b/dnf.spec index 02d6ec9..1c47a88 100644 --- a/dnf.spec +++ b/dnf.spec @@ -69,7 +69,7 @@ It supports RPMs, modules and comps groups & environments. Name: dnf Version: 4.14.0 -Release: 17%{?dist} +Release: 18%{?dist} Summary: %{pkg_summary} # For a breakdown of the licensing, see PACKAGE-LICENSING License: GPLv2+ @@ -101,6 +101,11 @@ Patch23: 0023-Limit-queries-to-nevra-forms-when-provided-by-comman.patch Patch24: 0024-doc-Remove-provide-of-spec-definition-for-repoquery-.patch Patch25: 0025-man-Improve-upgrade-minimal-command-docs-RHEL-6417.patch Patch26: 0026-doc-Makecache-with-timer-tries-only-one-mirror.patch +Patch27: 0027-Add-detection-for-ostree-based-systems-and-warn-user.patch +Patch28: 0028-Update-ostree-bootc-host-system-check.patch +Patch29: 0029-Update-bootc-hosts-message-to-point-to-bootc-help.patch +Patch30: 0030-Allow-installroot-on-read-only-bootc-system.patch + BuildArch: noarch BuildRequires: cmake @@ -389,6 +394,10 @@ popd %{python3_sitelib}/%{name}/automatic/ %changelog +* Tue Oct 01 2024 Petr Pisar - 4.14.0-18 +- More specific error message on a locked OSTree system or a bootc system + without a usr-overlay (RHEL-49670) + * Tue Aug 06 2024 Petr Pisar - 4.14.0-17 - Revert more specific error message on a locked OSTree system or a bootc system without a usr-overlay (RHEL-49670)