From: Daan De Meyer Date: Sun, 19 Mar 2023 11:30:45 +0000 (+0100) Subject: Replace --qemu-headless with --qemu-gui X-Git-Tag: v15~273 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=36638fb37e0ccbb97bbaa573d158dcea3a5f9bde;p=thirdparty%2Fmkosi.git Replace --qemu-headless with --qemu-gui We add extra kernel command line arguments that configure term and the tty size at runtime. We start qemu in the terminal on a serial tty by default now as well. We introduce --qemu-gui to still allow booting qemu in a graphical interface We also pass the host environment to qemu and nspawn to mimick what we do with ssh and because qemu needs the host environment to initialize gtk properly. --- diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f5a1df1da..d0c24314a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -194,7 +194,6 @@ jobs: [Host] Autologin=yes - QemuHeadless=yes [Content] ExtraTrees=.github/mkosi.extra diff --git a/NEWS.md b/NEWS.md index c9ad915e3..0127a568e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -54,6 +54,8 @@ `machinectl` to access images booted with `mkosi boot`. Use --extra-tree or --credential with the `.ssh.authorized_keys.root` credentials as alternatives for provisioning the public key inside the image. - Only configuration files matching `*.conf` are parsed in dropin directories now. +- Removed `--qemu-headless`, we now start qemu in the terminal by default and configure the serial console at + runtime. Use the new `--qemu-gui` option to start qemu in its graphical interface. ## v14 diff --git a/mkosi.md b/mkosi.md index 24f072021..7bd1e4d79 100644 --- a/mkosi.md +++ b/mkosi.md @@ -672,8 +672,7 @@ a boolean argument: either "1", "yes", or "true" to enable, or "0", `Autologin=`, `--autologin` : Enable autologin for the `root` user on `/dev/pts/0` (nspawn), - `/dev/tty1` (QEMU) and `/dev/ttyS0` (QEMU with `QemuHeadless=yes`) - by patching `/etc/pam.d/login`. + `/dev/tty1` and `/dev/ttyS0` by patching `/etc/pam.d/login`. `BuildScript=`, `--build-script=` @@ -784,20 +783,10 @@ a boolean argument: either "1", "yes", or "true" to enable, or "0", : List of colon-separated paths to look for tools in, before using the regular `$PATH` search path. -`QemuHeadless=`, `--qemu-headless=` +`QemuGui=`, `--qemu-gui=` -: When used with the `build` verb, this option adds `console=ttyS0` to - the image's kernel command line and sets the terminal type of the - serial console in the image to the terminal type of the host (more - specifically, the value of the `$TERM` environment variable passed - to mkosi). This makes sure that all terminal features such as colors - and shortcuts still work as expected when connecting to the qemu VM - over the serial console (for example via `-nographic`). - -: When used with the `qemu` verb, this option adds the `-nographic` - option to `qemu`'s command line so qemu starts a headless vm and - connects to its serial console from the current terminal instead of - launching the VM in a separate window. +: If enabled, qemu is executed with its graphical interface instead of + with a serial console. `QemuSmp=`, `--qemu-smp=` diff --git a/mkosi/__init__.py b/mkosi/__init__.py index 01ef45c82..7a006ea93 100644 --- a/mkosi/__init__.py +++ b/mkosi/__init__.py @@ -57,7 +57,6 @@ from mkosi.backend import ( tmp_dir, ) from mkosi.install import ( - add_dropin_config, add_dropin_config_from_resource, copy_path, flock, @@ -496,25 +495,6 @@ def configure_autologin(state: MkosiState) -> None: pam_add_autologin(state.root, ttys) -def configure_serial_terminal(state: MkosiState) -> None: - """Override TERM for the serial console with the terminal type from the host.""" - - if not state.config.qemu_headless or state.for_cache: - return - - with complete_step("Configuring serial tty (/dev/ttyS0)…"): - columns, lines = shutil.get_terminal_size(fallback=(80, 24)) - add_dropin_config(state.root, "serial-getty@ttyS0.service", "term", - f"""\ - [Service] - Environment=TERM={os.getenv('TERM', 'vt220')} - Environment=COLUMNS={columns} - Environment=LINES={lines} - TTYColumns={columns} - TTYRows={lines} - """) - - def mount_build_overlay(state: MkosiState) -> ContextManager[Path]: return mount_overlay(state.root, state.build_overlay, state.workdir, state.root) @@ -855,15 +835,6 @@ def install_unified_kernel(state: MkosiState, roothash: Optional[str]) -> None: cmdline += state.config.kernel_command_line - if state.config.qemu_headless and not any("console=ttyS0" in x for x in cmdline): - cmdline += ["console=ttyS0"] - - # By default, the serial console gets spammed with kernel log messages. - # Let's up the log level to only show warning and error messages when - # --qemu-headless is enabled to avoid this spam. - if state.config.qemu_headless and not any("loglevel" in x for x in cmdline): - cmdline += ["loglevel=4"] - # Older versions of systemd-stub expect the cmdline section to be null terminated. We can't embed # nul terminators in argv so let's communicate the cmdline via a file instead. state.workspace.joinpath("cmdline").write_text(f"{' '.join(cmdline).strip()}\x00") @@ -1883,10 +1854,10 @@ def create_parser() -> ArgumentParserMkosi: help=argparse.SUPPRESS, ) group.add_argument( - "--qemu-headless", + "--qemu-gui", metavar="BOOL", action=BooleanAction, - help="Configure image for qemu's -nographic mode", + help="Start QEMU in graphical mode", ) group.add_argument( "--qemu-smp", @@ -2370,6 +2341,27 @@ def load_credentials(args: argparse.Namespace) -> dict[str, str]: return creds +def load_kernel_command_line_extra(args: argparse.Namespace) -> list[str]: + cmdline = [] + + for s in args.kernel_command_line_extra: + key, sep, value = s.partition("=") + if " " in value: + value = f'"{value}"' + cmdline += [key if not sep else f"{key}={value}"] + + columns, lines = shutil.get_terminal_size() + + cmdline += [ + f"systemd.tty.term.ttyS0={os.getenv('TERM', 'vt220')}", + f"systemd.tty.columns.ttyS0={columns}", + f"systemd.tty.rows.ttyS0={lines}", + "console=ttyS0", + ] + + return cmdline + + def load_args(args: argparse.Namespace) -> MkosiConfig: ARG_DEBUG.update(args.debug) @@ -2520,6 +2512,7 @@ def load_args(args: argparse.Namespace) -> MkosiConfig: args.environment = {} args.credentials = load_credentials(args) + args.kernel_command_line_extra = load_kernel_command_line_extra(args) if args.cache_path is not None: args.cache_path = args.cache_path.absolute() @@ -2853,7 +2846,6 @@ def print_summary(config: MkosiConfig) -> None: print("\nHOST CONFIGURATION:") print(" Extra search paths:", line_join_list(config.extra_search_paths)) - print(" QEMU Headless:", yes_no(config.qemu_headless)) print(" QEMU Extra Arguments:", line_join_list(config.qemu_args)) print(" Netdev:", yes_no(config.netdev)) @@ -3186,7 +3178,6 @@ def build_image(state: MkosiState, *, manifest: Optional[Manifest] = None) -> No configure_locale(state) configure_hostname(state) configure_root_password(state) - configure_serial_terminal(state) configure_autologin(state) configure_dracut(state, cached) configure_netdev(state) @@ -3445,7 +3436,7 @@ def run_shell(config: MkosiConfig) -> None: acl_toggle_remove(config, config.output, uid, allow=False) try: - run(cmdline, stdout=sys.stdout) + run(cmdline, stdout=sys.stdout, env=os.environ) finally: if config.output_format == OutputFormat.directory: acl_toggle_remove(config, config.output, uid, allow=True) @@ -3623,12 +3614,12 @@ def run_qemu(config: MkosiConfig) -> None: cmdline += ["-cpu", "max"] - if config.qemu_headless: + if config.qemu_gui: + cmdline += ["-vga", "virtio"] + else: # -nodefaults removes the default CDROM device which avoids an error message during boot # -serial mon:stdio adds back the serial device removed by -nodefaults. cmdline += ["-nographic", "-nodefaults", "-serial", "mon:stdio"] - else: - cmdline += ["-vga", "virtio"] if config.netdev: cmdline += ["-nic", "user,model=virtio-net-pci"] @@ -3701,7 +3692,7 @@ def run_qemu(config: MkosiConfig) -> None: cmdline += config.cmdline print_running_cmd(cmdline) - run(cmdline, stdout=sys.stdout) + run(cmdline, stdout=sys.stdout, env=os.environ) def run_ssh(config: MkosiConfig) -> None: diff --git a/mkosi/backend.py b/mkosi/backend.py index 94233e425..584134023 100644 --- a/mkosi/backend.py +++ b/mkosi/backend.py @@ -310,7 +310,7 @@ class MkosiConfig: acl: bool # QEMU-specific options - qemu_headless: bool + qemu_gui: bool qemu_smp: str qemu_mem: str qemu_kvm: bool diff --git a/mkosi/install.py b/mkosi/install.py index d681115fb..b95e3e067 100644 --- a/mkosi/install.py +++ b/mkosi/install.py @@ -8,7 +8,6 @@ import shutil import stat from collections.abc import Iterator from pathlib import Path -from textwrap import dedent from typing import Optional from mkosi.backend import MkosiState @@ -32,14 +31,6 @@ def write_resource( make_executable(where) -def add_dropin_config(root: Path, unit: str, name: str, content: str) -> None: - """Add a dropin config `name.conf` in /etc/systemd/system for `unit`.""" - dropin = root / f"etc/systemd/system/{unit}.d/{name}.conf" - dropin.parent.mkdir(mode=0o755, parents=True, exist_ok=True) - dropin.write_text(dedent(content)) - dropin.chmod(0o644) - - def add_dropin_config_from_resource( root: Path, unit: str, name: str, resource: str, key: str ) -> None: