From 20c47489ee697c21370d50944718fab6345665a4 Mon Sep 17 00:00:00 2001 From: Jiri Konecny Date: Tue, 3 Sep 2024 10:31:58 +0200 Subject: [PATCH] Do not create GRDServer on Live ISO The GRDServer class have checks in the __init__ method which starts to complain about missing GRD in the system. That doesn't apply in Live environment where we don't support GRD in the first place. --- pyanaconda/core/configuration/system.py | 5 ++ pyanaconda/display.py | 21 +++--- pyanaconda/startup_utils.py | 17 +++++ .../core/test_startup_utils.py | 67 ++++++++++++++++++- 4 files changed, 98 insertions(+), 12 deletions(-) diff --git a/pyanaconda/core/configuration/system.py b/pyanaconda/core/configuration/system.py index caedd1e5fa3f..b1205ce8d6d8 100644 --- a/pyanaconda/core/configuration/system.py +++ b/pyanaconda/core/configuration/system.py @@ -73,6 +73,11 @@ def can_start_user_systemd(self): """Can we start the user instance of systemd?""" return self._is_boot_iso + @property + def can_start_compositor(self): + """Can we start our own Wayland session?""" + return self._is_boot_iso + @property def can_switch_tty(self): """Can we change the foreground virtual terminal?""" diff --git a/pyanaconda/display.py b/pyanaconda/display.py index b2f7fbaa0835..9ce71ace8810 100644 --- a/pyanaconda/display.py +++ b/pyanaconda/display.py @@ -22,7 +22,6 @@ import os import time import textwrap -import pkgutil import signal from pyanaconda.mutter_display import MutterDisplay, MutterConfigError @@ -37,8 +36,6 @@ from pyanaconda.modules.common.constants.services import NETWORK from pyanaconda.ui.tui.spokes.askrd import AskRDSpoke, RDPAuthSpoke from pyanaconda.ui.tui import tui_quit_callback -# needed for checking if the pyanaconda.ui.gui modules are available -import pyanaconda.ui import blivet @@ -279,6 +276,8 @@ def setup_display(anaconda, options): anaconda.display_mode = options.display_mode anaconda.interactive_mode = not options.noninteractive + # TODO: Refactor this method or maybe whole class, ideally this class should be usable only + # on boot.iso where compositor could be set if flags.rescue_mode: return @@ -287,6 +286,14 @@ def setup_display(anaconda, options): anaconda.initialize_interface() return + # we can't start compositor so not even RDP is supported, do only base initialization + if not conf.system.can_start_compositor: + anaconda.log_display_mode() + anaconda.initialize_interface() + startup_utils.fallback_to_tui_if_gtk_ui_is_not_available(anaconda) + startup_utils.check_memory(anaconda, options) + return + try: xtimeout = int(options.xtimeout) except ValueError: @@ -307,13 +314,7 @@ def setup_display(anaconda, options): rdp_credentials_sufficient = options.rdp_username and options.rdp_password # check if GUI without WebUI - if anaconda.gui_mode and not anaconda.is_webui_supported: - mods = (tup[1] for tup in pkgutil.iter_modules(pyanaconda.ui.__path__, "pyanaconda.ui.")) - if "pyanaconda.ui.gui" not in mods: - stdout_log.warning("Graphical user interface not available, falling back to text mode") - anaconda.display_mode = constants.DisplayModes.TUI - flags.use_rd = False - flags.rd_question = False + startup_utils.fallback_to_tui_if_gtk_ui_is_not_available(anaconda) # check if remote desktop mode can be started rd_can_be_started, rd_error_messages = check_rd_can_be_started(anaconda) diff --git a/pyanaconda/startup_utils.py b/pyanaconda/startup_utils.py index 4748c1a506e0..c7ceaa3a8746 100644 --- a/pyanaconda/startup_utils.py +++ b/pyanaconda/startup_utils.py @@ -20,6 +20,7 @@ import sys import time import os +import pkgutil from blivet.arch import is_s390 from blivet.util import total_memory from dasbus.typing import get_variant, Int @@ -175,6 +176,22 @@ def set_storage_checker_minimal_ram_size(display_mode): ) +def fallback_to_tui_if_gtk_ui_is_not_available(anaconda): + """Check if GTK UI is available in this environment and fallback to TUI if not. + + Also take into account Web UI. + """ + if anaconda.gui_mode and not anaconda.is_webui_supported: + import pyanaconda.ui + + mods = (tup[1] for tup in pkgutil.iter_modules(pyanaconda.ui.__path__, "pyanaconda.ui.")) + if "pyanaconda.ui.gui" not in mods: + stdout_log.warning("Graphical user interface not available, falling back to text mode") + anaconda.display_mode = DisplayModes.TUI + flags.use_rd = False + flags.rd_question = False + + def setup_logging_from_options(options): """Configure logging according to Anaconda command line/boot options. diff --git a/tests/unit_tests/pyanaconda_tests/core/test_startup_utils.py b/tests/unit_tests/pyanaconda_tests/core/test_startup_utils.py index c027e245654b..93de1b6fae45 100644 --- a/tests/unit_tests/pyanaconda_tests/core/test_startup_utils.py +++ b/tests/unit_tests/pyanaconda_tests/core/test_startup_utils.py @@ -26,8 +26,10 @@ from textwrap import dedent from pyanaconda.startup_utils import print_dracut_errors, check_if_geolocation_should_be_used, \ - start_geolocation_conditionally, wait_for_geolocation_and_use, apply_geolocation_result -from pyanaconda.core.constants import GEOLOC_CONNECTION_TIMEOUT, TIMEZONE_PRIORITY_GEOLOCATION + start_geolocation_conditionally, wait_for_geolocation_and_use, apply_geolocation_result, \ + fallback_to_tui_if_gtk_ui_is_not_available +from pyanaconda.core.constants import GEOLOC_CONNECTION_TIMEOUT, TIMEZONE_PRIORITY_GEOLOCATION, \ + DisplayModes from pyanaconda.modules.common.structures.timezone import GeolocationData class StartupUtilsTestCase(unittest.TestCase): @@ -303,3 +305,64 @@ def test_apply_tz_missing(self, has_trans_mock, setup_locale_mock, geodata_mock, assert tz_proxy.Timezone == "" setup_locale_mock.assert_called_once_with("es_ES.UTF-8", loc_proxy, text_mode=False) assert os.environ == {"LANG": "es_ES.UTF-8"} + + +class TestUIHelpers(unittest.TestCase): + + @patch("pyanaconda.startup_utils.pkgutil") + @patch("pyanaconda.startup_utils.flags") + def test_fallback_tui_when_gtk_ui_not_available(self, mocked_flags, mocked_pkgutil): + mocked_anaconda = Mock() + + def check_method(gui_mode, + webui_supported, + gtk_available, + expected_display_mode, + expected_rd_output): + mocked_anaconda.gui_mode = gui_mode + mocked_anaconda.is_webui_supported = webui_supported + + # prefilled values + mocked_anaconda.display_mode = "" + mocked_flags.use_rd = None + mocked_flags.rd_question = None + + if gtk_available: + mocked_pkgutil.iter_modules.return_value = [(None, "pyanaconda.ui.gui")] + else: + mocked_pkgutil.iter_modules.return_value = [(None, "pyanaconda.ui.webui")] + + fallback_to_tui_if_gtk_ui_is_not_available(mocked_anaconda) + + assert mocked_flags.use_rd is expected_rd_output + assert mocked_flags.rd_question is expected_rd_output + assert mocked_anaconda.display_mode == expected_display_mode + + + # UI is not wanted + check_method(gui_mode=False, + webui_supported=False, + gtk_available=True, + expected_display_mode="", + expected_rd_output=None) + + # check result when web ui is supported + check_method(gui_mode=True, + webui_supported=True, + gtk_available=True, + expected_display_mode="", + expected_rd_output=None) + + # check result when gtk UI is not available + check_method(gui_mode=True, + webui_supported=False, + gtk_available=False, + expected_display_mode=DisplayModes.TUI, + expected_rd_output=False) + + # check result when GTK is available + check_method(gui_mode=True, + webui_supported=False, + gtk_available=True, + expected_display_mode="", + expected_rd_output=None)