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 detection for ostree-based systems and warn users about losing changes #2053

Merged
merged 1 commit into from
Apr 24, 2024
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions dnf/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,15 @@ def do_transaction(self, display=()):
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."))
Expand Down
31 changes: 31 additions & 0 deletions dnf/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@
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
Expand Down Expand Up @@ -639,3 +641,32 @@ def _is_file_pattern_present(specs):
if subj._filename_pattern:
return True
return False


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