summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/activation-scripts/05-serial_console.py57
-rwxr-xr-xsrc/conf_mode/system_console.py26
-rwxr-xr-xsrc/op_mode/image_installer.py23
3 files changed, 87 insertions, 19 deletions
diff --git a/src/activation-scripts/05-serial_console.py b/src/activation-scripts/05-serial_console.py
new file mode 100755
index 000000000..93e381d17
--- /dev/null
+++ b/src/activation-scripts/05-serial_console.py
@@ -0,0 +1,57 @@
+# Copyright (C) VyOS Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library. If not, see <http://www.gnu.org/licenses/>.
+
+import re
+
+from typing import Optional
+from typing import Tuple
+
+from vyos.configtree import ConfigTree
+from vyos.utils.file import read_file
+from vyos.system.image import is_live_boot
+
+base = ['system', 'console', 'device']
+
+def get_kernel_serial_console() -> Tuple[Optional[str], Optional[str]]:
+ """
+ Extract the serial console device and speed setting from the kernel
+ command line.
+ """
+ device = speed = None
+ CMDLINE_CONSOLE_RE = re.compile(
+ r'(?:^|\s)console=(?P<device>tty(?:S|AMA)\d+),(?P<speed>\d+)(?=\s|$)'
+ )
+ kernel_cmdline = read_file('/proc/cmdline')
+ if m := CMDLINE_CONSOLE_RE.search(kernel_cmdline):
+ device = m.group("device") # "ttyS0"
+ speed = m.group("speed") # Baud rate/speed, e.g. "115200"
+
+ return (device, speed)
+
+def activate(config: ConfigTree):
+ # Configure the kernel serial console only once during live boot.
+ # During installation, the user can define the console. If this is not
+ # limited to live boot, the serial interface will always be re-added during
+ # system boot, even if it was removed from config.boot.
+ if not is_live_boot():
+ return
+
+ (device, speed) = get_kernel_serial_console()
+ if device and speed:
+ # The kernel was booted with a configured serial console, but no
+ # console is configured in the CLI; align/fix the CLI configuration.
+ if not config.exists(base + [device]):
+ config.set(base + [device, 'speed'], value=speed)
+ config.set_tag(base)
diff --git a/src/conf_mode/system_console.py b/src/conf_mode/system_console.py
index 4411257e3..5d89eeba7 100755
--- a/src/conf_mode/system_console.py
+++ b/src/conf_mode/system_console.py
@@ -68,7 +68,7 @@ def verify(console):
# and it can not be used as a serial interface
if not os.path.isdir(by_bus_dir) or not os.path.exists(by_bus_device):
raise ConfigError(f'Device {device} does not support being used as tty')
- if not is_tty(device):
+ if not is_tty(device, warning=True):
Warning(f'Device "{device}" used for console is not a TTY!')
return None
@@ -82,6 +82,7 @@ def generate(console):
os.unlink(os.path.join(root, basename))
if not console or 'device' not in console:
+ grub_util.update_serial_console('', '', '')
return None
# replace keys in the config for ttyUSB items to use them in `apply()` later
@@ -112,14 +113,17 @@ def generate(console):
render(config_file, 'getty/serial-getty.service.j2', device_config)
os.symlink(config_file, getty_wants_symlink)
- # GRUB
- # For existing serial line change speed (if necessary)
- # Only applies to ttyS0
- if 'ttyS0' not in console['device']:
- return None
+ # GRUB - use first defined serial console to populate Kernel console= parameter
+ device = None
+ if 'device' in console and len(console['device']) > 0:
+ # We use the first device for the Kernel console
+ console_device = next(iter(console['device']))
+ console_speed = console['device'][console_device]['speed']
- speed = console['device']['ttyS0']['speed']
- grub_util.update_console_speed(speed)
+ # get console type ("ttyS" or "ttyAMA") from console_device (e.g. "ttyS0")
+ console_type = console_device.translate(str.maketrans('', '', '0123456789'))
+ console_num = ''.join(ch for ch in console_device if ch.isdigit())
+ grub_util.update_serial_console(console_type, console_num, console_speed)
return None
@@ -127,9 +131,9 @@ def apply(console):
# Reset screen blanking
call('/usr/bin/setterm -blank 0 -powersave off -powerdown 0 -term linux </dev/tty1 >/dev/tty1 2>&1')
- # Service control moved to vyos.utils.serial to unify checks and prompts.
- # If users are connected, we want to show an informational message on completing
- # the process, but not halt configuration processing with an interactive prompt.
+ # Service control moved to vyos.utils.serial to unify checks and prompts.
+ # If users are connected, we want to show an informational message on completing
+ # the process, but not halt configuration processing with an interactive prompt.
restart_login_consoles(prompt_user=False, quiet=False)
if not console:
diff --git a/src/op_mode/image_installer.py b/src/op_mode/image_installer.py
index db9647782..fb3cdda9e 100755
--- a/src/op_mode/image_installer.py
+++ b/src/op_mode/image_installer.py
@@ -42,8 +42,10 @@ from psutil import disk_partitions
from vyos.base import Warning
from vyos.configtree import ConfigTree
+from vyos.config_mgmt import unsaved_commits
from vyos.defaults import base_dir
from vyos.defaults import directories
+from vyos.flavor import get_image_serial_console
from vyos.remote import download
from vyos.system import disk
from vyos.system import grub
@@ -69,7 +71,6 @@ from vyos.utils.process import cmd
from vyos.utils.process import run
from vyos.utils.process import rc_cmd
from vyos.version import get_version_data
-from vyos.config_mgmt import unsaved_commits
# define text messages
MSG_ERR_NOT_LIVE: str = 'The system is already installed. Please use "add system image" instead.'
@@ -143,16 +144,17 @@ ISO_DOWNLOAD_PATH: str = ''
external_download_script: str = f'{base_dir}/simple-download.py'
external_latest_image_url_script: str = f'{base_dir}/latest-image-url.py'
+(flavor_sercon_type, flavor_sercon_num, flavor_sercon_speed) = get_image_serial_console()
+
# default boot variables
DEFAULT_BOOT_VARS: dict[str, str] = {
'timeout': '5',
'console_type': 'tty',
- 'console_num': '0',
- 'console_speed': '115200',
+ 'console_num': flavor_sercon_num,
+ 'console_speed': flavor_sercon_speed,
'bootmode': 'normal'
}
-
def bytes_to_gb(size: int) -> float:
"""Convert Bytes to GBytes, rounded to 1 decimal number
@@ -767,12 +769,13 @@ def console_hint() -> str:
path = '/dev/tty'
name = Path(path).name
- if name in ['ttyS0', 'ttyAMA0']:
+ if name in ['ttyS0']:
return 'S'
+ elif name in ['ttyAMA0']:
+ return 'A'
else:
return 'K'
-
def cleanup(mounts: list[str] = [], remove_items: list[str] = []) -> None:
"""Clean up after installation
@@ -921,10 +924,14 @@ 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_type: str = ask_input(MSG_INPUT_CONSOLE_TYPE,
default=console_hint(),
- valid_responses=['K', 'S'])
- console_dict: dict[str, str] = {'K': 'tty', 'S': 'ttyS'}
+ valid_responses=console_dict.keys())
config_boot_list = [f'{DIR_CONFIG}/config.boot',
'/opt/vyatta/etc/config.boot.default']