From c6d8235fa6dd7fc117a0152b985ac51a8220c138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Sch=C3=A4fer?= Date: Mon, 8 Jan 2024 17:26:00 +0100 Subject: [PATCH] Fixed grub terminal setup The grub terminal setup is divided into the setting for the output and the input console. For both settings different parameters exists. So far kiwi did not differentiate between the two parts of the console setup and that could lead to a wrong setting if only one value is provided in kiwi's console= attribute which lead to the grub setting, GRUB_TERMINAL=value. If value is set to e.g gfxterm grub takes this for both input and output and it's obviously wrong for the input. To make this less error prune the kiwi code changes with this commit to set GRUB_TERMINAL_INPUT and GRUB_TERMINAL_OUTPUT rather than GRUB_TERMINAL and also runs sanity checks on the provided values if they are applicable. The information for setting up the console in the schema stays untouched though. That's because it's used for all bootloaders and also because grub supports multiple values for the console in/out setting in one GRUB_TERMINAL variable even though kiwi does no longer use it. To make this clear for the users also the documentation for the console attribute setup has been updated. If we want to wish two distinct attributes for input and output console settings a schema change and also differentiation between bootloaders is needed and that I only see for the kiwi-10 branch if at all. This Fixes #2419 --- .../test-image-qcow-openstack/appliance.kiwi | 2 +- doc/source/image_description/elements.rst | 21 +++++- kiwi/bootloader/config/grub2.py | 75 ++++++++++++++----- kiwi/bootloader/config/isolinux.py | 2 +- kiwi/bootloader/template/grub2.py | 62 ++++++++------- kiwi/schema/kiwi.rnc | 4 +- kiwi/schema/kiwi.rng | 4 +- kiwi/system/profile.py | 6 +- kiwi/xml_parse.py | 4 +- kiwi/xml_state.py | 20 +++-- test/unit/bootloader/config/grub2_test.py | 39 ++++++---- test/unit/bootloader/config/isolinux_test.py | 12 +-- test/unit/bootloader/template/grub2_test.py | 67 +++++++++++------ test/unit/system/profile_test.py | 4 +- test/unit/xml_state_test.py | 2 +- 15 files changed, 216 insertions(+), 108 deletions(-) diff --git a/build-tests/x86/tumbleweed/test-image-qcow-openstack/appliance.kiwi b/build-tests/x86/tumbleweed/test-image-qcow-openstack/appliance.kiwi index a4e349639f1..21607497afc 100644 --- a/build-tests/x86/tumbleweed/test-image-qcow-openstack/appliance.kiwi +++ b/build-tests/x86/tumbleweed/test-image-qcow-openstack/appliance.kiwi @@ -11,7 +11,7 @@ false - + 10240 0.3.10 diff --git a/doc/source/image_description/elements.rst b/doc/source/image_description/elements.rst index 7febc773a6f..9ffc25f0b28 100644 --- a/doc/source/image_description/elements.rst +++ b/doc/source/image_description/elements.rst @@ -1019,9 +1019,24 @@ attributes are supported: console="none|console|gfxterm|serial": Specifies the bootloader console. The attribute is available for the - grub and isolinux bootloader types. Specifying none here will - translate to setting console to an empty string. By default, the - gfxterm (graphical terminal) option is used. + `grub` and `isolinux` bootloader types. The behavior for setting up + the console is different per bootloader: + + For `isolinux` the console setting is taken as provided, whereas + only the values `serial` and `console` are taken into account. + + For `grub` the console setting is split into the setting for the + output and the input console: + + * A single console value is provided. In this case the same value + is used for the output and input console and applied if possible. + Providing the `none` value will skip the console setup for both. + + * Two values separated by a space are provided. In this case the + first value configures the output console and the second value + configures the input console. The `none` value can be used to skip + one or the other console setup. More than two space separated + values will be ignored. grub_template="filename": Specifies a custom grub bootloader template file which will be used diff --git a/kiwi/bootloader/config/grub2.py b/kiwi/bootloader/config/grub2.py index fe6da8cb9e1..2b9d69c3218 100644 --- a/kiwi/bootloader/config/grub2.py +++ b/kiwi/bootloader/config/grub2.py @@ -102,11 +102,28 @@ def post_init(self, custom_args): if self.custom_args and 'config_options' in self.custom_args: self.config_options = self.custom_args['config_options'] - self.terminal = self.xml_state.get_build_type_bootloader_console() - if self.terminal is None: - self.terminal = 'gfxterm' - else: - self.terminal = self.terminal.replace('none', '').lstrip() + terminal_output = self.xml_state.get_build_type_bootloader_console()[0] + terminal_input = self.xml_state.get_build_type_bootloader_console()[1] + terminal_input_grub = [ + 'console', + 'serial', + 'at_keyboard', + 'usb_keyboard' + ] + terminal_output_grub = [ + 'console', + 'serial', + 'gfxterm', + 'vga_text', + 'mda_text', + 'morse', + 'spkmodem' + ] + + self.terminal_output = \ + terminal_output if terminal_output in terminal_output_grub else '' + self.terminal_input = \ + terminal_input if terminal_input in terminal_input_grub else '' self.gfxmode = self.get_gfxmode('grub2') self.theme = self.get_boot_theme() @@ -318,6 +335,12 @@ def setup_install_image_config( """ log.info('Creating grub2 install config file from template') self.iso_boot = True + has_graphics = False + has_serial = False + if 'gfxterm' in self.terminal_output: + has_graphics = True + if 'serial' in self.terminal_output or 'serial' in self.terminal_input: + has_serial = True parameters = { 'search_params': '--file --set=root /boot/' + mbrid.get_id(), 'default_boot': self.get_install_image_boot_default(), @@ -338,7 +361,8 @@ def setup_install_image_config( 'bootpath': self.get_boot_path('iso'), 'boot_directory_name': self.boot_directory_name, 'efi_image_name': Defaults.get_efi_image_name(self.arch), - 'terminal_setup': self.terminal + 'terminal_input': self.terminal_input, + 'terminal_output': self.terminal_output } custom_template_path = self._get_custom_template() if custom_template_path: @@ -349,14 +373,14 @@ def setup_install_image_config( log.info('--> Using multiboot install template') parameters['hypervisor'] = hypervisor template = self.grub2.get_multiboot_install_template( - self.failsafe_boot, self.terminal, + self.failsafe_boot, has_graphics, has_serial, self.continue_on_timeout ) else: log.info('--> Using standard boot install template') hybrid_boot = True template = self.grub2.get_install_template( - self.failsafe_boot, hybrid_boot, self.terminal, + self.failsafe_boot, hybrid_boot, has_graphics, has_serial, self.continue_on_timeout ) try: @@ -383,6 +407,12 @@ def setup_live_image_config( """ log.info('Creating grub2 live ISO config file from template') self.iso_boot = True + has_graphics = False + has_serial = False + if 'gfxterm' in self.terminal_output: + has_graphics = True + if 'serial' in self.terminal_output or 'serial' in self.terminal_input: + has_serial = True parameters = { 'search_params': '--file --set=root /boot/' + mbrid.get_id(), 'default_boot': '0', @@ -403,7 +433,8 @@ def setup_live_image_config( 'bootpath': self.get_boot_path('iso'), 'boot_directory_name': self.boot_directory_name, 'efi_image_name': Defaults.get_efi_image_name(self.arch), - 'terminal_setup': self.terminal + 'terminal_input': self.terminal_input, + 'terminal_output': self.terminal_output } custom_template_path = self._get_custom_template() if custom_template_path: @@ -414,14 +445,15 @@ def setup_live_image_config( log.info('--> Using multiboot template') parameters['hypervisor'] = hypervisor template = self.grub2.get_multiboot_iso_template( - self.failsafe_boot, self.terminal, self.mediacheck_boot + self.failsafe_boot, has_graphics, has_serial, + self.mediacheck_boot ) else: log.info('--> Using standard boot template') hybrid_boot = True template = self.grub2.get_iso_template( self.failsafe_boot, hybrid_boot, - self.terminal, self.mediacheck_boot + has_graphics, has_serial, self.mediacheck_boot ) try: self.config = template.substitute(parameters) @@ -687,7 +719,8 @@ def _setup_default_grub(self): * GRUB_CMDLINE_LINUX * GRUB_CMDLINE_LINUX_DEFAULT * GRUB_GFXMODE - * GRUB_TERMINAL + * GRUB_TERMINAL_INPUT + * GRUB_TERMINAL_OUTPUT * GRUB_DISTRIBUTOR * GRUB_DISABLE_LINUX_UUID * GRUB_DISABLE_LINUX_PARTUUID @@ -700,9 +733,16 @@ def _setup_default_grub(self): # elements to set in any case grub_default_entries = { 'GRUB_TIMEOUT': self.timeout, - 'GRUB_GFXMODE': self.gfxmode, - 'GRUB_TERMINAL': '"{0}"'.format(self.terminal) + 'GRUB_GFXMODE': self.gfxmode } + if self.terminal_input: + grub_default_entries['GRUB_TERMINAL_INPUT'] = '"{0}"'.format( + self.terminal_input + ) + if self.terminal_output: + grub_default_entries['GRUB_TERMINAL_OUTPUT'] = '"{0}"'.format( + self.terminal_output + ) grub_final_cmdline = re.sub( r'(^root=[^\s]+)|( root=[^\s]+)', '', self.cmdline ).strip() @@ -730,8 +770,8 @@ def _setup_default_grub(self): grub_default_entries['GRUB_CMDLINE_LINUX_DEFAULT'] = '"{0}"'.format( grub_final_cmdline ) - if self.terminal and 'serial' in self.terminal and \ - self.serial_line_setup: + if self.serial_line_setup and \ + 'serial' in self.terminal_input or 'serial' in self.terminal_output: grub_default_entries['GRUB_SERIAL_COMMAND'] = '"{0}"'.format( self.serial_line_setup ) @@ -1301,7 +1341,8 @@ def _check_boot_theme_exists(self): if not os.path.exists(theme_dir): log.warning('Theme %s not found', theme_dir) log.warning('Set bootloader terminal to console mode') - self.terminal = 'console' + self.terminal_input = 'console' + self.terminal_output = 'console' def _setup_EFI_path(self, lookup_path): """ diff --git a/kiwi/bootloader/config/isolinux.py b/kiwi/bootloader/config/isolinux.py index f278a27ea89..8cd86616c63 100644 --- a/kiwi/bootloader/config/isolinux.py +++ b/kiwi/bootloader/config/isolinux.py @@ -69,7 +69,7 @@ def post_init(self, custom_args): self.xml_state.build_type.get_hybridpersistent_filesystem() ) - self.terminal = self.xml_state.get_build_type_bootloader_console() + self.terminal = self.xml_state.get_build_type_bootloader_console()[0] self.gfxmode = self.get_gfxmode('isolinux') # isolinux counts the timeout in units of 1/10 sec self.timeout = self.get_boot_timeout_seconds() * 10 diff --git a/kiwi/bootloader/template/grub2.py b/kiwi/bootloader/template/grub2.py index 04f90f3b51d..52b1c407b71 100644 --- a/kiwi/bootloader/template/grub2.py +++ b/kiwi/bootloader/template/grub2.py @@ -61,7 +61,7 @@ def __init__(self): export linux initrd ''').strip() + os.linesep - self.header_gfxterm = dedent(''' + self.header_gfxmode = dedent(''' if [ "$${grub_platform}" = "efi" ]; then echo "Please press 't' to show the boot menu on this console" fi @@ -73,8 +73,8 @@ def __init__(self): ''').strip() + os.linesep self.header_terminal_setup = dedent(''' - terminal_input ${terminal_setup} - terminal_output ${terminal_setup} + terminal_input ${terminal_input} + terminal_output ${terminal_output} ''').strip() + os.linesep self.fonts = dedent(''' @@ -310,14 +310,16 @@ def __init__(self): ''').strip() + os.linesep def get_iso_template( - self, failsafe=True, hybrid=True, terminal='gfxterm', checkiso=False + self, failsafe=True, hybrid=True, + has_graphics=True, has_serial=False, checkiso=False ): """ Bootloader configuration template for live ISO media :param bool failsafe: with failsafe true|false :param bool hybrid: with hybrid true|false - :param string terminal: output terminal name + :param bool has_graphics: supports graphics terminal + :param bool has_serial: supports serial terminal :return: instance of :class:`Template` @@ -328,10 +330,10 @@ def get_iso_template( template_data += self.timeout_style if hybrid: template_data += self.header_hybrid - if 'gfxterm' in terminal: - template_data += self.header_gfxterm + if has_graphics: + template_data += self.header_gfxmode template_data += self.header_theme_iso - if 'serial' in terminal: + if has_serial: template_data += self.header_serial template_data += self.header_terminal_setup if hybrid: @@ -348,19 +350,21 @@ def get_iso_template( template_data += self.menu_mediacheck_entry template_data += self.menu_iso_harddisk_entry template_data += self.menu_entry_boot_snapshots - if 'gfxterm' in terminal: + if has_graphics: template_data += self.menu_entry_console_switch return Template(template_data) def get_multiboot_iso_template( - self, failsafe=True, terminal='gfxterm', checkiso=False + self, failsafe=True, + has_graphics=True, has_serial=False, checkiso=False ): """ Bootloader configuration template for live ISO media with hypervisor, e.g Xen dom0 :param bool failsafe: with failsafe true|false - :param string terminal: output terminal name + :param bool has_graphics: supports graphics terminal + :param bool has_serial: supports serial terminal :return: instance of :class:`Template` @@ -369,10 +373,10 @@ def get_multiboot_iso_template( template_data = self.header template_data += self.timeout template_data += self.timeout_style - if 'gfxterm' in terminal: - template_data += self.header_gfxterm + if has_graphics: + template_data += self.header_gfxmode template_data += self.header_theme_iso - if 'serial' in terminal: + if has_serial: template_data += self.header_serial template_data += self.header_terminal_setup template_data += self.menu_entry_multiboot @@ -382,19 +386,21 @@ def get_multiboot_iso_template( template_data += self.menu_mediacheck_entry_multiboot template_data += self.menu_iso_harddisk_entry template_data += self.menu_entry_boot_snapshots - if 'gfxterm' in terminal: + if has_graphics: template_data += self.menu_entry_console_switch return Template(template_data) def get_install_template( - self, failsafe=True, hybrid=True, terminal='gfxterm', with_timeout=True + self, failsafe=True, hybrid=True, + has_graphics=True, has_serial=False, with_timeout=True ): """ Bootloader configuration template for install media :param bool failsafe: with failsafe true|false :param bool hybrid: with hybrid true|false - :param string terminal: output terminal name + :param bool has_graphics: supports graphics terminal + :param bool has_serial: supports serial terminal :return: instance of :class:`Template` @@ -406,10 +412,10 @@ def get_install_template( template_data += self.timeout_style if hybrid: template_data += self.header_hybrid - if 'gfxterm' in terminal: - template_data += self.header_gfxterm + if has_graphics: + template_data += self.header_gfxmode template_data += self.header_theme_iso - if 'serial' in terminal: + if has_serial: template_data += self.header_serial template_data += self.header_terminal_setup template_data += self.menu_iso_harddisk_entry @@ -422,19 +428,21 @@ def get_install_template( if failsafe: template_data += self.menu_install_entry_failsafe template_data += self.menu_entry_boot_snapshots - if 'gfxterm' in terminal: + if has_graphics: template_data += self.menu_entry_console_switch return Template(template_data) def get_multiboot_install_template( - self, failsafe=True, terminal='gfxterm', with_timeout=True + self, failsafe=True, + has_graphics=True, has_serial=False, with_timeout=True ): """ Bootloader configuration template for install media with hypervisor, e.g Xen dom0 :param bool failsafe: with failsafe true|false - :param string terminal: output terminal name + :param bool has_graphics: supports graphics terminal + :param bool has_serial: supports serial terminal :return: instance of :class:`Template` @@ -444,10 +452,10 @@ def get_multiboot_install_template( if with_timeout: template_data += self.timeout template_data += self.timeout_style - if 'gfxterm' in terminal: - template_data += self.header_gfxterm + if has_graphics: + template_data += self.header_gfxmode template_data += self.header_theme_iso - if 'serial' in terminal: + if has_serial: template_data += self.header_serial template_data += self.header_terminal_setup template_data += self.menu_iso_harddisk_entry @@ -455,6 +463,6 @@ def get_multiboot_install_template( if failsafe: template_data += self.menu_install_entry_failsafe_multiboot template_data += self.menu_entry_boot_snapshots - if 'gfxterm' in terminal: + if has_graphics: template_data += self.menu_entry_console_switch return Template(template_data) diff --git a/kiwi/schema/kiwi.rnc b/kiwi/schema/kiwi.rnc index 128f036d930..129b87390c0 100644 --- a/kiwi/schema/kiwi.rnc +++ b/kiwi/schema/kiwi.rnc @@ -37,7 +37,7 @@ vhd-tag-type = xsd:token {pattern = "[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}"} groups-list = xsd:token {pattern = "[a-zA-Z0-9_\-\.:]+(,[a-zA-Z0-9_\-\.:]+)*"} arch-name = xsd:token {pattern = "(x86_64|i586|i686|ix86|aarch64|arm64|armv5el|armv5tel|armv6hl|armv6l|armv7hl|armv7l|ppc|ppc64|ppc64le|s390|s390x|riscv64)(,(x86_64|i586|i686|ix86|aarch64|arm64|armv5el|armv5tel|armv6hl|armv6l|armv7hl|armv7l|ppc|ppc64|ppc64le|s390|s390x|riscv64))*"} portnum-type = xsd:token {pattern = "(\d+|\d+/(udp|tcp))"} -grub_console = xsd:token {pattern = "(none|console|gfxterm|serial)( (console|gfxterm|serial))*"} +grub_console = xsd:token {pattern = "(none|console|gfxterm|serial|vga_text|mda_text|morse|spkmodem)( (none|console|serial|at_keyboard|usb_keyboard))*"} fs_attributes = xsd:token {pattern = "(no-copy-on-write|synchronous-updates)(,(no-copy-on-write|synchronous-updates))*"} package-version-type = xsd:token {pattern = "(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(\.(0|[1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])){3}"} simple-uri-type = xsd:token {pattern = "(file:|https:|http:|ftp:).*"} @@ -2762,7 +2762,7 @@ div { k.bootloader.console.attribute = ## Specifies the bootloader console. ## The value is available for grub and isolinux bootloader - ## types. By default a graphics console setup is used + ## types. attribute console { grub_console } >> sch:pattern [ id = "loader_console" is-a = "bootloader_name_type" sch:param [ name = "attr" value = "console" ] diff --git a/kiwi/schema/kiwi.rng b/kiwi/schema/kiwi.rng index 3b81b25f649..6566184f474 100644 --- a/kiwi/schema/kiwi.rng +++ b/kiwi/schema/kiwi.rng @@ -88,7 +88,7 @@ - (none|console|gfxterm|serial)( (console|gfxterm|serial))* + (none|console|gfxterm|serial|vga_text|mda_text|morse|spkmodem)( (none|console|serial|at_keyboard|usb_keyboard))* @@ -4136,7 +4136,7 @@ setting only affects the oem and iso image types. Specifies the bootloader console. The value is available for grub and isolinux bootloader -types. By default a graphics console setup is used +types. diff --git a/kiwi/system/profile.py b/kiwi/system/profile.py index 5ea5af362c4..0ee5f7ed6e5 100644 --- a/kiwi/system/profile.py +++ b/kiwi/system/profile.py @@ -318,8 +318,10 @@ def _type_to_profile(self): type_section.get_firmware() self.dot_profile['kiwi_bootloader'] = \ self.xml_state.get_build_type_bootloader_name() - self.dot_profile['kiwi_bootloader_console'] = \ - self.xml_state.get_build_type_bootloader_console() + self.dot_profile['kiwi_bootloader_console'] = "{}:{}".format( + self.xml_state.get_build_type_bootloader_console()[0] or 'default', + self.xml_state.get_build_type_bootloader_console()[1] or 'default' + ) self.dot_profile['kiwi_btrfs_root_is_snapshot'] = \ type_section.get_btrfs_root_is_snapshot() self.dot_profile['kiwi_gpt_hybrid_mbr'] = \ diff --git a/kiwi/xml_parse.py b/kiwi/xml_parse.py index 2b2e4997656..2b08da52f28 100644 --- a/kiwi/xml_parse.py +++ b/kiwi/xml_parse.py @@ -3,7 +3,7 @@ # # Generated by generateDS.py version 2.29.24. -# Python 3.11.3 (main, Jun 03 2023, 22:12:18) [GCC] +# Python 3.11.5 (main, Sep 06 2023, 11:21:05) [GCC] # # Command line options: # ('-f', '') @@ -5606,7 +5606,7 @@ def validate_grub_console(self, value): if not self.gds_validate_simple_patterns( self.validate_grub_console_patterns_, value): warnings_.warn('Value "%s" does not match xsd pattern restrictions: %s' % (value.encode('utf-8'), self.validate_grub_console_patterns_, )) - validate_grub_console_patterns_ = [['^(none|console|gfxterm|serial)( (console|gfxterm|serial))*$']] + validate_grub_console_patterns_ = [['^(none|console|gfxterm|serial|vga_text|mda_text|morse|spkmodem)( (none|console|serial|at_keyboard|usb_keyboard))*$']] def hasContent_(self): if ( self.bootloadersettings is not None diff --git a/kiwi/xml_state.py b/kiwi/xml_state.py index 96cfc04592f..58581ad7acc 100644 --- a/kiwi/xml_state.py +++ b/kiwi/xml_state.py @@ -976,18 +976,28 @@ def get_build_type_bootloader_name(self) -> str: return bootloader.get_name() if bootloader else \ Defaults.get_default_bootloader() - def get_build_type_bootloader_console(self) -> Optional[str]: + def get_build_type_bootloader_console(self) -> List[str]: """ Return bootloader console setting for selected build type - :return: console string + :return: + list of console settings for output (first element) + and input (second element) - :rtype: str + :rtype: list """ + result = ['', ''] bootloader = self.get_build_type_bootloader_section() if bootloader: - return bootloader.get_console() - return None + combined_console = bootloader.get_console() + if combined_console: + console_out, *console_in = combined_console.split(' ')[:2] + console_in = console_out if not console_in else console_in[0] + result = [ + console_out if console_out != 'none' else '', + console_in if console_in != 'none' else '' + ] + return result def get_build_type_bootloader_serial_line_setup(self) -> Optional[str]: """ diff --git a/test/unit/bootloader/config/grub2_test.py b/test/unit/bootloader/config/grub2_test.py index e3b72bc642e..c047bd17514 100644 --- a/test/unit/bootloader/config/grub2_test.py +++ b/test/unit/bootloader/config/grub2_test.py @@ -578,7 +578,8 @@ def test_setup_default_grub( grub_default.write = Mock() mock_sysconfig.return_value = grub_default mock_exists.return_value = True - self.bootloader.terminal = 'serial' + self.bootloader.terminal_input = 'serial' + self.bootloader.terminal_output = 'gfxterm' self.bootloader.theme = 'openSUSE' self.bootloader.displayname = 'Bob' self.firmware.efi_mode.return_value = 'efi' @@ -596,7 +597,8 @@ def test_setup_default_grub( 'GRUB_ENABLE_CRYPTODISK': 'y', 'GRUB_GFXMODE': '800x600', 'GRUB_SERIAL_COMMAND': '"serial --speed=38400"', - 'GRUB_TERMINAL': '"serial"', + 'GRUB_TERMINAL_INPUT': '"serial"', + 'GRUB_TERMINAL_OUTPUT': '"gfxterm"', 'GRUB_THEME': '/boot/grub2/themes/openSUSE/theme.txt', 'GRUB_TIMEOUT': 10, 'GRUB_TIMEOUT_STYLE': 'countdown', @@ -618,7 +620,8 @@ def test_setup_default_grub_empty_kernelcmdline( grub_default = MagicMock() mock_sysconfig.return_value = grub_default mock_exists.return_value = True - self.bootloader.terminal = 'serial' + self.bootloader.terminal_input = 'serial' + self.bootloader.terminal_output = 'serial' self.bootloader.theme = 'openSUSE' self.bootloader.displayname = 'Bob' self.bootloader.cmdline = 'root=LABEL=some-label' @@ -642,7 +645,8 @@ def test_setup_default_grub_empty_kernelcmdline( call( 'GRUB_SERIAL_COMMAND', '"serial --speed=38400"' ), - call('GRUB_TERMINAL', '"serial"'), + call('GRUB_TERMINAL_INPUT', '"serial"'), + call('GRUB_TERMINAL_OUTPUT', '"serial"'), call('GRUB_THEME', '/boot/grub2/themes/openSUSE/theme.txt'), call('GRUB_TIMEOUT', 10), call('GRUB_TIMEOUT_STYLE', 'countdown'), @@ -662,7 +666,8 @@ def test_setup_default_grub_use_of_by_partuuid( grub_default = MagicMock() mock_sysconfig.return_value = grub_default mock_exists.return_value = True - self.bootloader.terminal = 'serial' + self.bootloader.terminal_input = 'serial' + self.bootloader.terminal_output = 'serial' self.bootloader.theme = 'openSUSE' self.bootloader.displayname = 'Bob' self.bootloader.cmdline = 'root=UUID=foo' @@ -684,7 +689,8 @@ def test_setup_default_grub_use_of_by_partuuid( call( 'GRUB_SERIAL_COMMAND', '"serial --speed=38400"' ), - call('GRUB_TERMINAL', '"serial"'), + call('GRUB_TERMINAL_INPUT', '"serial"'), + call('GRUB_TERMINAL_OUTPUT', '"serial"'), call('GRUB_THEME', '/boot/grub2/themes/openSUSE/theme.txt'), call('GRUB_TIMEOUT', 10), call('GRUB_TIMEOUT_STYLE', 'countdown'), @@ -703,7 +709,8 @@ def test_setup_default_grub_use_of_by_label( grub_default = MagicMock() mock_sysconfig.return_value = grub_default mock_exists.return_value = True - self.bootloader.terminal = 'serial' + self.bootloader.terminal_input = 'serial' + self.bootloader.terminal_output = 'serial' self.bootloader.theme = 'openSUSE' self.bootloader.displayname = 'Bob' self.bootloader.cmdline = 'abcd root=LABEL=foo console=tty0' @@ -727,7 +734,8 @@ def test_setup_default_grub_use_of_by_label( call( 'GRUB_SERIAL_COMMAND', '"serial --speed=38400"' ), - call('GRUB_TERMINAL', '"serial"'), + call('GRUB_TERMINAL_INPUT', '"serial"'), + call('GRUB_TERMINAL_OUTPUT', '"serial"'), call('GRUB_THEME', '/boot/grub2/themes/openSUSE/theme.txt'), call('GRUB_TIMEOUT', 10), call('GRUB_TIMEOUT_STYLE', 'countdown'), @@ -881,7 +889,7 @@ def test_setup_live_image_config_multiboot(self): self.bootloader.multiboot = True self.bootloader.setup_live_image_config(self.mbrid) self.grub2.get_multiboot_iso_template.assert_called_once_with( - True, 'gfxterm', None + True, False, False, None ) @patch.object(BootLoaderConfigGrub2, '_copy_grub_config_to_efi_path') @@ -891,21 +899,25 @@ def test_setup_live_image_config_standard( self.firmware.efi_mode = Mock( return_value='uefi' ) + self.bootloader.terminal_input = 'serial' + self.bootloader.terminal_output = 'gfxterm' self.bootloader.early_boot_script_efi = 'earlyboot.cfg' self.bootloader.multiboot = False self.bootloader.setup_live_image_config(self.mbrid) self.grub2.get_iso_template.assert_called_once_with( - True, True, 'gfxterm', None + True, True, True, True, None ) mock_copy_grub_config_to_efi_path.assert_called_once_with( 'root_dir', 'earlyboot.cfg', 'iso' ) def test_setup_install_image_config_multiboot(self): + self.bootloader.terminal_input = 'serial' + self.bootloader.terminal_output = 'gfxterm' self.bootloader.multiboot = True self.bootloader.setup_install_image_config(self.mbrid) self.grub2.get_multiboot_install_template.assert_called_once_with( - True, 'gfxterm', True + True, True, True, True ) @patch.object(BootLoaderConfigGrub2, '_mount_system') @@ -1104,7 +1116,7 @@ def test_setup_install_image_config_standard( self.bootloader.multiboot = False self.bootloader.setup_install_image_config(self.mbrid) self.grub2.get_install_template.assert_called_once_with( - True, True, 'gfxterm', True + True, True, False, False, True ) mock_copy_grub_config_to_efi_path.assert_called_once_with( 'root_dir', 'earlyboot.cfg', 'iso' @@ -2134,7 +2146,8 @@ def side_effect(arg): with patch('builtins.open'): with self._caplog.at_level(logging.WARNING): self.bootloader.setup_install_boot_images(self.mbrid) - assert self.bootloader.terminal == 'console' + assert self.bootloader.terminal_input == 'console' + assert self.bootloader.terminal_output == 'console' @patch.object(BootLoaderConfigGrub2, 'setup_install_boot_images') def test_setup_live_boot_images(self, mock_setup_install_boot_images): diff --git a/test/unit/bootloader/config/isolinux_test.py b/test/unit/bootloader/config/isolinux_test.py index 7ec767986c1..570f86876ee 100644 --- a/test/unit/bootloader/config/isolinux_test.py +++ b/test/unit/bootloader/config/isolinux_test.py @@ -23,7 +23,7 @@ def setup(self, mock_exists): mock_exists.return_value = True self.state = mock.Mock() self.state.get_build_type_bootloader_console = mock.Mock( - return_value=None + return_value=['', ''] ) self.state.build_type.get_mediacheck = mock.Mock( return_value=None @@ -139,7 +139,7 @@ def test_setup_install_image_config(self): self.bootloader.setup_install_image_config(mbrid=None) self.isolinux.get_install_template.assert_called_once_with( - True, False, None, True + True, False, '', True ) self.isolinux.get_install_message_template.assert_called_once_with() assert template_cfg.substitute.called @@ -150,7 +150,7 @@ def test_setup_install_image_config_multiboot(self): self.bootloader.setup_install_image_config(mbrid=None) self.isolinux.get_multiboot_install_template.assert_called_once_with( - True, False, None, True + True, False, '', True ) @patch('os.path.exists') @@ -159,7 +159,7 @@ def test_setup_install_image_config_with_theme(self, mock_exists): self.bootloader.setup_install_image_config(mbrid=None) self.isolinux.get_install_template.assert_called_once_with( - True, True, None, True + True, True, '', True ) def test_setup_install_image_config_invalid_template(self): @@ -200,7 +200,7 @@ def test_setup_live_image_config(self): self.bootloader.setup_live_image_config(mbrid=None) self.isolinux.get_template.assert_called_once_with( - True, False, None, None + True, False, '', None ) self.isolinux.get_message_template.assert_called_once_with() template_cfg.substitute.assert_called_once_with(template_parameters) @@ -211,5 +211,5 @@ def test_setup_live_image_config_multiboot(self): self.bootloader.setup_live_image_config(mbrid=None) self.isolinux.get_multiboot_template.assert_called_once_with( - True, False, None, None + True, False, '', None ) diff --git a/test/unit/bootloader/template/grub2_test.py b/test/unit/bootloader/template/grub2_test.py index d199e0a246f..6007b8e98fa 100644 --- a/test/unit/bootloader/template/grub2_test.py +++ b/test/unit/bootloader/template/grub2_test.py @@ -26,12 +26,13 @@ def test_get_multiboot_install_template(self): boot_directory_name='grub2', hypervisor='xen.gz', efi_image_name='bootx64.efi', - terminal_setup='console' + terminal_input='console', + terminal_output='console' ) def test_get_multiboot_install_template_console(self): assert self.grub2.get_multiboot_install_template( - terminal='console' + has_graphics=False ).substitute( search_params='--fs-uuid --set=root 0815', default_boot='0', @@ -46,12 +47,13 @@ def test_get_multiboot_install_template_console(self): bootpath='/boot', hypervisor='xen.gz', efi_image_name='bootx64.efi', - terminal_setup='console' + terminal_input='console', + terminal_output='console' ) def test_get_multiboot_install_template_serial(self): assert self.grub2.get_multiboot_install_template( - terminal='serial' + has_graphics=False, has_serial=True ).substitute( search_params='--fs-uuid --set=root 0815', default_boot='0', @@ -66,11 +68,14 @@ def test_get_multiboot_install_template_serial(self): bootpath='/boot', hypervisor='xen.gz', efi_image_name='bootx64.efi', - terminal_setup='serial' + terminal_input='serial', + terminal_output='serial' ) def test_get_install_template(self): - assert self.grub2.get_install_template().substitute( + assert self.grub2.get_install_template( + has_serial=True + ).substitute( search_params='--file --set=root /boot/0xd305fb7d', default_boot='0', kernel_file='boot/linux.vmx', @@ -86,12 +91,13 @@ def test_get_install_template(self): bootpath='/boot', boot_directory_name='grub2', efi_image_name='bootx64.efi', - terminal_setup='console' + terminal_input='console', + terminal_output='console' ) def test_get_install_template_console_no_hybrid(self): assert self.grub2.get_install_template( - terminal='console', + has_graphics=False, hybrid=False ).substitute( search_params='--file --set=root /boot/0xd305fb7d', @@ -106,12 +112,13 @@ def test_get_install_template_console_no_hybrid(self): title='LimeJeOS-SLE12-Community [ VMX ]', bootpath='/boot', efi_image_name='bootx64.efi', - terminal_setup='console' + terminal_input='console', + terminal_output='console' ) def test_get_install_template_serial_no_hybrid(self): assert self.grub2.get_install_template( - terminal='serial', + has_graphics=False, hybrid=False ).substitute( search_params='--file --set=root /boot/0xd305fb7d', @@ -126,7 +133,8 @@ def test_get_install_template_serial_no_hybrid(self): title='LimeJeOS-SLE12-Community [ VMX ]', bootpath='/boot', efi_image_name='bootx64.efi', - terminal_setup='serial' + terminal_input='serial', + terminal_output='serial' ) def test_get_iso_template(self): @@ -146,12 +154,13 @@ def test_get_iso_template(self): bootpath='/boot', boot_directory_name='grub2', efi_image_name='bootx64.efi', - terminal_setup='console' + terminal_input='console', + terminal_output='console' ) def test_get_iso_template_console_no_hybrid(self): assert self.grub2.get_iso_template( - terminal='console', + has_graphics=False, hybrid=False ).substitute( search_params='--file --set=root /boot/0xd305fb7d', @@ -166,12 +175,14 @@ def test_get_iso_template_console_no_hybrid(self): title='LimeJeOS-SLE12-Community', bootpath='/boot', efi_image_name='bootx64.efi', - terminal_setup='console' + terminal_input='console', + terminal_output='console' ) def test_get_iso_template_serial_no_hybrid(self): assert self.grub2.get_iso_template( - terminal='serial', + has_graphics=False, + has_serial=True, hybrid=False ).substitute( search_params='--file --set=root /boot/0xd305fb7d', @@ -186,7 +197,8 @@ def test_get_iso_template_serial_no_hybrid(self): title='LimeJeOS-SLE12-Community', bootpath='/boot', efi_image_name='bootx64.efi', - terminal_setup='serial' + terminal_input='serial', + terminal_output='serial' ) def test_get_iso_template_checkiso_no_hybrid(self): @@ -208,7 +220,8 @@ def test_get_iso_template_checkiso_no_hybrid(self): bootpath='/boot', boot_directory_name='grub2', efi_image_name='bootx64.efi', - terminal_setup='console' + terminal_input='console', + terminal_output='console' ) def test_get_iso_template_checkiso(self): @@ -228,7 +241,8 @@ def test_get_iso_template_checkiso(self): bootpath='/boot', boot_directory_name='grub2', efi_image_name='bootx64.efi', - terminal_setup='console' + terminal_input='console', + terminal_output='console' ) def test_get_multiboot_iso_template(self): @@ -249,12 +263,13 @@ def test_get_multiboot_iso_template(self): boot_directory_name='grub2', hypervisor='xen.gz', efi_image_name='bootx64.efi', - terminal_setup='console' + terminal_input='console', + terminal_output='console' ) def test_get_multiboot_iso_template_console(self): assert self.grub2.get_multiboot_iso_template( - terminal='console' + has_graphics=False ).substitute( search_params='--fs-uuid --set=root 0815', default_boot='0', @@ -269,12 +284,14 @@ def test_get_multiboot_iso_template_console(self): bootpath='/boot', hypervisor='xen.gz', efi_image_name='bootx64.efi', - terminal_setup='console' + terminal_input='console', + terminal_output='console' ) def test_get_multiboot_iso_template_serial(self): assert self.grub2.get_multiboot_iso_template( - terminal='serial' + has_graphics=False, + has_serial=True ).substitute( search_params='--fs-uuid --set=root 0815', default_boot='0', @@ -289,7 +306,8 @@ def test_get_multiboot_iso_template_serial(self): bootpath='/boot', hypervisor='xen.gz', efi_image_name='bootx64.efi', - terminal_setup='serial' + terminal_input='serial', + terminal_output='serial' ) def test_get_multiboot_iso_template_checkiso(self): @@ -310,5 +328,6 @@ def test_get_multiboot_iso_template_checkiso(self): boot_directory_name='grub2', hypervisor='xen.gz', efi_image_name='bootx64.efi', - terminal_setup='console' + terminal_input='console', + terminal_output='console' ) diff --git a/test/unit/system/profile_test.py b/test/unit/system/profile_test.py index 31147437f4d..0e8a31c0af7 100644 --- a/test/unit/system/profile_test.py +++ b/test/unit/system/profile_test.py @@ -48,7 +48,7 @@ def test_create_live(self, mock_which): 'kiwi_cmdline': 'console=ttyS0', 'kiwi_firmware': 'bios', 'kiwi_bootloader': 'grub2', - 'kiwi_bootloader_console': None, + 'kiwi_bootloader_console': 'default:default', 'kiwi_btrfs_root_is_snapshot': None, 'kiwi_gpt_hybrid_mbr': None, 'kiwi_devicepersistency': None, @@ -95,7 +95,7 @@ def test_create_oem(self, mock_which): 'kiwi_compressed': None, 'kiwi_delete': '', 'kiwi_devicepersistency': None, - 'kiwi_bootloader_console': None, + 'kiwi_bootloader_console': 'default:default', 'kiwi_displayname': 'schäfer', 'kiwi_drivers': '', 'kiwi_firmware': 'efi', diff --git a/test/unit/xml_state_test.py b/test/unit/xml_state_test.py index 1c77d372a6b..aeb0b2529be 100644 --- a/test/unit/xml_state_test.py +++ b/test/unit/xml_state_test.py @@ -1036,7 +1036,7 @@ def test_get_build_type_bootloader_use_disk_password(self, mock_bootloader): def test_get_build_type_bootloader_console(self, mock_bootloader): mock_bootloader.return_value = [self.bootloader] assert self.state.get_build_type_bootloader_console() == \ - 'some-console' + ['some-console', 'some-console'] @patch('kiwi.xml_parse.type_.get_bootloader') def test_get_build_type_bootloader_serial_line_setup(self, mock_bootloader):