From e6a6ef67b7854919288c27d681b9383e9e9fc0cd Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Wed, 29 Oct 2025 11:39:17 +0100 Subject: [PATCH] Temporarily reintroduce the safe_dbus module Related: RHEL-115005 --- ...ily-reintroduce-the-safe_dbus-module.patch | 252 ++++++++++++++++++ python-blivet.spec | 8 +- 2 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 0002-Temporarily-reintroduce-the-safe_dbus-module.patch diff --git a/0002-Temporarily-reintroduce-the-safe_dbus-module.patch b/0002-Temporarily-reintroduce-the-safe_dbus-module.patch new file mode 100644 index 0000000..83fe383 --- /dev/null +++ b/0002-Temporarily-reintroduce-the-safe_dbus-module.patch @@ -0,0 +1,252 @@ +From 3a35d48fb823bae87d044234b199e1dde64e7666 Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Wed, 29 Oct 2025 11:00:41 +0100 +Subject: [PATCH] Temporarily reintroduce the safe_dbus module + +Anaconda imports SafeDBusError from this and doing a joint release +in RHEL would be too complicated. + +Related: RHEL-115005 +--- + blivet/safe_dbus.py | 229 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 229 insertions(+) + create mode 100644 blivet/safe_dbus.py + +diff --git a/blivet/safe_dbus.py b/blivet/safe_dbus.py +new file mode 100644 +index 00000000..1bade46b +--- /dev/null ++++ b/blivet/safe_dbus.py +@@ -0,0 +1,229 @@ ++# ++# Copyright (C) 2013-2015 Red Hat, Inc. ++# ++# This copyrighted material is made available to anyone wishing to use, ++# modify, copy, or redistribute it subject to the terms and conditions of ++# the GNU General Public License v.2, or (at your option) any later version. ++# This program is distributed in the hope that it will be useful, but WITHOUT ++# ANY WARRANTY expressed or implied, including the implied warranties of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General ++# Public License for more details. You should have received a copy of the ++# GNU General Public License along with this program; if not, write to the ++# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the ++# source code or documentation are not subject to the GNU General Public ++# License and may only be used or replicated with the express permission of ++# Red Hat, Inc. ++# ++# Red Hat Author(s): Vratislav Podzimek ++# ++# This module was taken from the sources of the Anaconda installer. ++# ++ ++"""Module providing thread-safe and mainloop-safe DBus operations.""" ++ ++import gi ++gi.require_version("GLib", "2.0") ++gi.require_version("Gio", "2.0") ++ ++from gi.repository import GLib, Gio ++ ++import os ++ ++DEFAULT_DBUS_TIMEOUT = -1 ++DBUS_PROPS_IFACE = "org.freedesktop.DBus.Properties" ++DBUS_INTRO_IFACE = "org.freedesktop.DBus.Introspectable" ++ ++ ++class SafeDBusError(Exception): ++ """Class for exceptions defined in this module.""" ++ ++ ++class DBusCallError(SafeDBusError): ++ """Class for the errors related to calling methods over DBus.""" ++ ++ ++class DBusPropertyError(DBusCallError): ++ """Class for the errors related to getting property values over DBus.""" ++ ++ ++def get_new_system_connection(): ++ """Return a new connection to the system bus.""" ++ ++ return Gio.DBusConnection.new_for_address_sync( ++ Gio.dbus_address_get_for_bus_sync(Gio.BusType.SYSTEM, None), ++ Gio.DBusConnectionFlags.AUTHENTICATION_CLIENT | ++ Gio.DBusConnectionFlags.MESSAGE_BUS_CONNECTION, ++ None, None) ++ ++ ++def get_new_session_connection(): ++ """ ++ Get a connection handle for the per-user-login-session message bus. ++ ++ !!! RUN THIS EARLY !!! like, before any other threads start. Connections to ++ the session bus must be made with the effective UID of the login user, ++ which in live installs is not the UID of anaconda. This means we need to ++ call seteuid in this method, and doing that after threads have started will ++ probably do something weird. ++ ++ Live installs use consolehelper to run as root, which sets the original ++ UID in $USERHELPER_UID. ++ ++ :return: the session connection handle ++ :rtype: Gio.DBusConnection ++ :raise DBusCallError: if some DBus related error appears ++ :raise OSError: if unable to set the effective UID ++ """ ++ ++ old_euid = None ++ if "USERHELPER_UID" in os.environ: ++ old_euid = os.geteuid() ++ os.seteuid(int(os.environ["USERHELPER_UID"])) ++ ++ try: ++ connection = Gio.DBusConnection.new_for_address_sync( ++ Gio.dbus_address_get_for_bus_sync(Gio.BusType.SESSION, None), ++ Gio.DBusConnectionFlags.AUTHENTICATION_CLIENT | ++ Gio.DBusConnectionFlags.MESSAGE_BUS_CONNECTION, ++ None, None) ++ except GLib.GError as gerr: ++ raise DBusCallError("Unable to connect to session bus: %s" % gerr) ++ finally: ++ if old_euid is not None: ++ os.seteuid(old_euid) ++ ++ if connection.is_closed(): ++ raise DBusCallError("Connection is closed") ++ ++ return connection ++ ++ ++def call_sync(service, obj_path, iface, method, args, ++ connection=None, fds=None, timeout=DEFAULT_DBUS_TIMEOUT): ++ """ ++ Safely call a given method on a given object of a given service over DBus ++ passing given arguments. If a connection is given, it is used, otherwise a ++ new connection is established. Safely means that it is a synchronous, ++ thread-safe call not using any main loop. ++ ++ :param service: DBus service to use ++ :type service: str ++ :param obj_path: object path of the object to call method on ++ :type obj_path: str ++ :param iface: interface to use ++ :type iface: str ++ :param method: name of the method to call ++ :type method: str ++ :param args: arguments to pass to the method ++ :type args: GVariant ++ :param connection: connection to use (if None, a new connection is ++ established) ++ :type connection: Gio.DBusConnection ++ :param fds: list of file descriptors for the call ++ :type: Gio.UnixFDList ++ :param timeout: timeout in milliseconds for the call (-1 for default timeout) ++ :type timeout: int ++ :return: unpacked value returned by the method ++ :rtype: tuple with elements that depend on the method ++ :raise DBusCallError: if some DBus related error appears ++ ++ """ ++ ++ if not connection: ++ try: ++ connection = get_new_system_connection() ++ except GLib.GError as gerr: ++ raise DBusCallError("Unable to connect to system bus: %s" % gerr) ++ ++ if connection.is_closed(): ++ raise DBusCallError("Connection is closed") ++ ++ try: ++ ret = connection.call_with_unix_fd_list_sync(service, obj_path, iface, method, args, ++ None, Gio.DBusCallFlags.NONE, ++ timeout, fds, None) ++ except GLib.GError as gerr: ++ msg = "Failed to call %s method on %s with %s arguments: %s" % \ ++ (method, obj_path, args, gerr.message) # pylint: disable=no-member ++ raise DBusCallError(msg) ++ ++ if ret is None: ++ msg = "No return from %s method on %s with %s arguments" % (method, obj_path, args) ++ raise DBusCallError(msg) ++ ++ return ret[0].unpack() ++ ++ ++def get_property_sync(service, obj_path, iface, prop_name, ++ connection=None): ++ """ ++ Get value of a given property of a given object provided by a given service. ++ ++ :param service: DBus service to use ++ :type service: str ++ :param obj_path: object path ++ :type obj_path: str ++ :param iface: interface to use ++ :type iface: str ++ :param prop_name: name of the property ++ :type prop_name: str ++ :param connection: connection to use (if None, a new connection is ++ established) ++ :type connection: Gio.DBusConnection ++ :return: unpacked value of the property ++ :rtype: tuple with elements that depend on the type of the property ++ :raise DBusCallError: when the internal dbus_call_safe_sync invocation ++ raises an exception ++ :raise DBusPropertyError: when the given object doesn't have the given ++ property ++ ++ """ ++ ++ args = GLib.Variant('(ss)', (iface, prop_name)) ++ ret = call_sync(service, obj_path, DBUS_PROPS_IFACE, "Get", args, ++ connection) ++ if ret is None: ++ msg = "No value for the %s object's property %s" % (obj_path, prop_name) ++ raise DBusPropertyError(msg) ++ ++ return ret ++ ++ ++def get_properties_sync(service, obj_path, iface, connection=None): ++ """ ++ Get all properties of a given object provided by a given service. ++ ++ :param service: DBus service to use ++ :type service: str ++ :param obj_path: object path ++ :type obj_path: str ++ :param iface: interface to use ++ :type iface: str ++ :param connection: connection to use (if None, a new connection is ++ established) ++ :type connection: Gio.DBusConnection ++ :return: unpacked value of the property ++ :rtype: tuple with elements that depend on the type of the property ++ :raise DBusCallError: when the internal dbus_call_safe_sync invocation ++ raises an exception ++ ++ """ ++ ++ args = GLib.Variant('(s)', (iface,)) ++ ret = call_sync(service, obj_path, DBUS_PROPS_IFACE, "GetAll", args, ++ connection) ++ ++ return ret ++ ++ ++def check_object_available(service, obj_path, iface=None): ++ intro_data = call_sync(service, obj_path, DBUS_INTRO_IFACE, "Introspect", None) ++ node_info = Gio.DBusNodeInfo.new_for_xml(intro_data[0]) ++ if not iface: ++ # just check if any interface is available (there are none for ++ # non-existing objects) ++ return bool(node_info.interfaces) ++ else: ++ return any(intface.name == iface for intface in node_info.interfaces) ++ +-- +2.51.0 + diff --git a/python-blivet.spec b/python-blivet.spec index 5b69e70..47b4cae 100644 --- a/python-blivet.spec +++ b/python-blivet.spec @@ -5,7 +5,7 @@ Version: 3.13.0 #%%global prerelease .b2 # prerelease, if defined, should be something like .a1, .b1, .b2.dev1, or .c2 -Release: 1%{?prerelease}%{?dist} +Release: 2%{?prerelease}%{?dist} Epoch: 1 License: LGPL-2.1-or-later %global realname blivet @@ -17,6 +17,8 @@ Source1: http://github.com/storaged-project/blivet/releases/download/%{realname} Patch0: 0001-remove-btrfs-plugin.patch %endif +Patch1: 0002-Temporarily-reintroduce-the-safe_dbus-module.patch + # Versions of required components (done so we make sure the buildrequires # match the requires versions of things). %global partedver 1.8.1 @@ -113,6 +115,10 @@ make DESTDIR=%{buildroot} install %{python3_sitelib}/* %changelog +* Wed Oct 29 2025 Vojtech Trefny - 3.13.0-2 +- Temporarily reintroduce the safe_dbus module + Related: RHEL-115005 + * Wed Oct 08 2025 Vojtech Trefny - 3.13.0-1 - Update to blivet 3.13.0 upstream release Resolves: RHEL-115005