diff options
| author | Christian Breunig <christian@breunig.cc> | 2026-04-02 07:53:02 +0200 |
|---|---|---|
| committer | Christian Breunig <christian@breunig.cc> | 2026-04-09 20:54:06 +0200 |
| commit | 35db941bcf30f3fac5b1358aa1124f34f9808950 (patch) | |
| tree | 09db740466acd3d42037698ac4bf6d33100a50e4 /src/op_mode | |
| parent | 51922535b79529d603c3b7d52cde9da54c069d42 (diff) | |
| download | vyos-1x-35db941bcf30f3fac5b1358aa1124f34f9808950.tar.gz vyos-1x-35db941bcf30f3fac5b1358aa1124f34f9808950.zip | |
serial: T8375: add CLI option to explicitly set kernel console
Previously, VyOS hardcoded the kernel boot log console to either ttyS0 or
tty0, with no post-install CLI method to change it (manual GRUB edits
were required).
This commit adds a new CLI node:
system console device <name> kernel
When set, the selected serial console is used as the kernel boot console.
When removed, the kernel boot console falls back to tty0.
Diffstat (limited to 'src/op_mode')
| -rwxr-xr-x | src/op_mode/image_installer.py | 58 |
1 files changed, 49 insertions, 9 deletions
diff --git a/src/op_mode/image_installer.py b/src/op_mode/image_installer.py index fb3cdda9e..27d8214c3 100755 --- a/src/op_mode/image_installer.py +++ b/src/op_mode/image_installer.py @@ -17,7 +17,8 @@ # You should have received a copy of the GNU General Public License along with # VyOS. If not, see <https://www.gnu.org/licenses/>. -from argparse import ArgumentParser, Namespace +from argparse import ArgumentParser +from argparse import Namespace from pathlib import Path from shutil import copy from shutil import chown @@ -616,6 +617,49 @@ def configure_authentication(config_file: str, password: str) -> None: with open(config_file, 'w') as f: f.write(config.to_string()) +def configure_serial_console(config_file: str, console_type: str) -> None: + """Apply serial console settings to config.boot from kernel cmdline. + + This overlaps with 05-serial_console.py activation logic, but that script + only runs during live boot. During installation, the user may pick a + different source config, so serial console settings must be written to + the final target config explicitly. + + Behavior: + - Reads the kernel serial console device/speed from the current boot cmdline. + - If the detected device is a valid tty, writes: + system console device <TTY> speed <rate> + - If "console_type == 'S'", also writes: + system console device <TTY> kernel + + Args: + config_file (str): path of target config file + console_type (str): 'K' (KVM/tty) or 'S' (serial) + """ + from vyos.utils.serial import is_tty + from vyos.utils.kernel import get_kernel_serial_console + + # Parse current kernel cmdline and continue only for valid serial console + # data. Prevent writing incomplete/invalid console settings to config.boot. + k_console_type, k_console_num, k_console_speed = get_kernel_serial_console() + device = f'{k_console_type}{k_console_num}' + if not is_tty(device) or not k_console_speed: + return + + base = ['system', 'console', 'device'] + config_string = read_file(config_file) + config = ConfigTree(config_string) + config.set(base + [device, 'speed'], value=k_console_speed) + config.set_tag(base) + + # Only mark this device as kernel boot console when console_type 'S' for + # serial was defined by user. + if console_type == 'S': + config.set(base + [device, 'kernel']) + + with open(config_file, 'w') as f: + f.write(config.to_string()) + def validate_signature(file_path: str, sign_type: str) -> None: """Validate a file by signature and delete a signature file @@ -769,10 +813,8 @@ def console_hint() -> str: path = '/dev/tty' name = Path(path).name - if name in ['ttyS0']: + if name.startswith(('ttyS', 'ttyAMA')): return 'S' - elif name in ['ttyAMA0']: - return 'A' else: return 'K' @@ -924,11 +966,7 @@ def install_image() -> None: print(MSG_WARN_PASSWORD_CONFIRM) # ask for default console - console_dict: dict[str, str] = {'K': 'tty'} - if flavor_sercon_type: - tmp: str = flavor_sercon_type[-1] # get "S" from "ttyS" and "A" from "ttyAMA" - console_dict.update({tmp: flavor_sercon_type}) - + console_dict: dict[str, str] = {'K': 'tty', 'S': flavor_sercon_type} console_type: str = ask_input(MSG_INPUT_CONSOLE_TYPE, default=console_hint(), valid_responses=console_dict.keys()) @@ -977,6 +1015,8 @@ def install_image() -> None: copy(default_config, f'{target_config_dir}/config.boot') configure_authentication(f'{target_config_dir}/config.boot', user_password) + configure_serial_console(f'{target_config_dir}/config.boot', + console_type) Path(f'{target_config_dir}/.vyatta_config').touch() # create a persistence.conf |
