diff --git a/neon/data/setup_journald_ttyS1.rb b/neon/data/setup_journald_ttyS1.rb index 5a52cbf..30f86d0 100644 --- a/neon/data/setup_journald_ttyS1.rb +++ b/neon/data/setup_journald_ttyS1.rb @@ -1,41 +1,33 @@ #!/usr/bin/env ruby -# -# Copyright (C) 2018 Harald Sitter -# -# This program is free software) || raise you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation) || raise either version 2 of -# the License or (at your option) version 3 or any later version -# accepted by the membership of KDE e.V. (or its successor approved -# by the membership of KDE e.V.), which shall act as a proxy -# defined in Section 14 of version 3 of the license. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY) || raise without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# SPDX-FileCopyrightText: 2018-2020 Harald Sitter +# SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL + +# On newer openqa's there'll be a builtin virtioconsole we can utilize. +# Indicator will be a virtio port. +dev = if Dir.glob('/dev/virtio-ports/org.openqa.console.*').empty? + '/dev/ttyS1' + else + '/dev/hvc0' + end # ttyS1 is set up by our kvm wrapper, it ordinarily isn't available # Also see bin/kvm_arg_injector for additional information. -puts "#{$0} Letting systemd-journald log to ttyS1." +puts "#{$0} Letting systemd-journald log to #{dev}." system 'sed -i "s%.*ForwardToConsole=.*%ForwardToConsole=yes%g" /etc/systemd/journald.conf' || raise -system 'sed -i "s%.*TTYPath=.*%TTYPath=/dev/ttyS1%g" /etc/systemd/journald.conf' || raise +system "sed -i 's%.*TTYPath=.*%TTYPath=#{dev}%g' /etc/systemd/journald.conf" || raise system 'sed -i "s%.*MaxLevelConsole=.*%MaxLevelConsole=debug%g" /etc/systemd/journald.conf' || raise system 'systemctl restart systemd-journald' || raise # Ubuntu by default is hardened. To ease debugging we'll want full sysrq access. # This is done in here since this is the only helpe rurn by both regular tests # and live tests. puts "#{$0} Enabling sysrq." system 'sysctl kernel.sysrq=1' || raise; # Turn on more systemd and kernel debuggyness to get more data should # reboot fail to excute properly. puts "#{$0} Enabling systemd and kernel debugging." system '/bin/kill -SIGRTMIN+20 1' || raise; # systemd.show_status=1 system '/bin/kill -SIGRTMIN+22 1' || raise; # systemd.log_level=debug system 'sysctl kernel.printk_devkmsg=on' || raise; # unlimited logging from userspace system 'sysctl kernel.printk="7 7 7 7"' || raise; # kernel debug diff --git a/neon/lib/livetest_neon.pm b/neon/lib/livetest_neon.pm index 08d894c..76d6ae0 100644 --- a/neon/lib/livetest_neon.pm +++ b/neon/lib/livetest_neon.pm @@ -1,328 +1,329 @@ # Copyright (C) 2017-2018 Harald Sitter # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License or (at your option) version 3 or any later version # accepted by the membership of KDE e.V. (or its successor approved # by the membership of KDE e.V.), which shall act as a proxy # defined in Section 14 of version 3 of the license. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . package livetest_neon; use base 'basetest_neon'; use testapi; use strict; sub new { my ($class, $args) = @_; my $self = $class->SUPER::new($args); # OPENQA_IS_OFFLINE is an env var used by online/offline. return $self; } sub post_fail_hook { my ($self, $args) = @_; # Make sure networking is on (we disable it during installation). $self->online; # Base test handles everything we need handling return $self->SUPER::post_fail_hook; } sub login { die 'not implemented' } sub maybe_login { die 'not implemented' } sub boot_to_dm { die 'not possible for live sessions' } sub _archive_iso_artifacts { upload_logs '/cdrom/.disk/info', log_name => 'metadata'; upload_logs '/cdrom/casper/filesystem.manifest', log_name => 'metadata'; } sub _secureboot { if (!get_var('SECUREBOOT')) { return } assert_script_sudo 'apt install -y mokutil', 60; assert_script_sudo 'mokutil --sb-state', 16; assert_screen 'mokutil-sb-on'; } sub offline { my ($self, $args) = @_; if (!get_var('OPENQA_INSTALLATION_OFFLINE')) { return; } if (defined $ENV{'OPENQA_IS_OFFLINE'}) { return; } my $previous_console = current_console; select_console 'log-console'; { assert_script_sudo 'nmcli networking off'; } select_console $previous_console; $ENV{'OPENQA_IS_OFFLINE'} = '1'; } sub online { my ($self, $args) = @_; if (!get_var('OPENQA_INSTALLATION_OFFLINE')) { return; } if (!defined $ENV{'OPENQA_IS_OFFLINE'}) { return; } my $previous_console = current_console; select_console 'log-console'; assert_script_sudo 'nmcli networking on'; select_console $previous_console; delete $ENV{'OPENQA_IS_OFFLINE'}; } sub maybe_switch_offline { my ($self, $args) = @_; if (!get_var('OPENQA_INSTALLATION_OFFLINE')) { print "staying online!\n"; # Run the early first start script to install coredumpd. # Only when NOT offline! # This runs apt update which would otherwise break the offline testing # with an update apt cache. # FIXME: we should possibly preseed the coredumpd into the ISO repo # so we can install it even without internet in the tests. # The package is fairly small and has no extra deps. select_console 'log-console'; { assert_script_run 'wget ' . data_url('early_first_start.rb'), 16; assert_script_sudo 'ruby early_first_start.rb', 60 * 5; } select_console 'x11'; return 0; } select_console 'log-console'; { print "going offline!\n"; $self->offline; # TODO: This isn't the most reliable assertion. # Ideally we'd have a list of all packages simulate them to make # sure all deps are installed. Or maybe even install them one # by one to make sure they actually work? # Make sure the preinstalled repo is actually being used. assert_script_sudo 'DEBIAN_FRONTEND=noninteractive apt-get install -y bcmwl-kernel-source', 10 * 60; } select_console 'x11'; assert_screen 'plasma-nm-offline'; return 1; } sub bootloader_secureboot { if (!get_var('SECUREBOOT')) { return; } # Enable scureboot first. When in secureboot mode we expect a second # ISO to be attached for uefi fs1 where we can run a efi program to # enroll the default keys to enable secureboot. # In the core.pm we'll then assert that secureboot is on. # In first_start.pm we'll further assert that secureboot is still on. # Use a fairly low timeout for the f2 trigger. The default 1 second # timeout might well cause us to shoot past tianocore and into the ISO. # Checking more often is more expensive, but should prevent this from # failing. Try this for only 10 seconds. If we aren't in OVMF by then # something definitely went wrong. send_key_until_needlematch 'ovmf', 'f2', 10 * 4, 0.25; send_key_until_needlematch 'ovmf-select-bootmgr', 'down'; send_key 'ret'; send_key_until_needlematch 'ovmf-bootmgr-shell', 'up'; # up is faster send_key 'ret'; assert_screen 'uefi-shell', 30; type_string 'fs1:'; send_key 'ret'; assert_screen 'uefi-shell-fs1'; type_string 'EnrollDefaultKeys.efi'; send_key 'ret'; type_string 'reset'; send_key 'ret'; reset_consoles; } sub bootloader { my ($self, $args) = @_; $self->bootloader_secureboot; # Wait for installation bootloader. This is either isolinux for BIOS or # GRUB for UEFI. # When it is grub we need to hit enter to proceed. assert_screen 'bootloader', 60; if (match_has_tag('live-bootloader-uefi')) { if (testapi::get_var("INSTALLATION_OEM")) { send_key 'down'; assert_screen('live-bootloader-uefi-oem'); } # Hack to force kmsg onto ttyS1 to debug shutdown problems. This hack # can be dropped once neon properly shuts down all the time again! # Edits grub entry to add more kernel cmdlines. send_key 'e'; my $counter = 8; while (!check_screen('live-grub-linux', 1)) { if (!$counter--) { last; } send_key 'down'; sleep 1; } send_key 'end'; if (testapi::get_var("INSTALLATION_OEM")) { foreach my $i (0..25) { send_key 'left'; } } else { send_key 'left'; send_key 'left'; send_key 'left'; } + # FIXME: should use hvc0 with modern openqa! # Set the kmsg target to ttyS1. We then also need to force plymouth as # it'd not do anything if console= is set. type_string 'console=ttyS1 plymouth.force-splash plymouth.ignore-serial-consoles '; send_key 'ctrl-x'; send_key 'ret'; } } # Waits for system to boot to desktop. sub boot { my ($self, $args) = @_; my $user = $testapi::username; my $password = $testapi::password; $testapi::username = 'neon'; $testapi::password = ''; $self->bootloader; # We better be at the desktop now. assert_screen 'live-desktop', 360; select_console 'log-console'; { # We previously forced evdev by default even on 18.04. Make sure this # was transitioned away from. https://phabricator.kde.org/T10938 validate_script_output 'grep -e "Using input driver" /var/log/Xorg.0.log', sub { m/.+libinput.+/ }; $self->_archive_iso_artifacts; $self->_secureboot; $self->_upgrade; assert_script_run 'wget ' . data_url('permissions_check.rb'), 16; assert_script_run 'ruby permissions_check.rb', 16; # This primarily to set up journald console output for /dev/ttyS1. # This script will also be run for the final system on first start and # retained in the image. assert_script_run 'wget ' . data_url('setup_journald_ttyS1.rb'), 16; assert_script_sudo 'ruby setup_journald_ttyS1.rb', 60 * 5; # See above about libinput. validate_script_output 'grep -e "Using input driver" /var/log/Xorg.0.log', sub { m/.+libinput.+/ }; # TODO: maybe control via env var? # assert_script_run 'wget ' . data_url('enable_qdebug.rb'), 16; # assert_script_run 'ruby enable_qdebug.rb', 16; } select_console 'x11'; # Leave system as we have found it. assert_screen 'live-desktop', 5 * 60; $testapi::username = $user; $testapi::password = $password; } # TODO: could maybe be renamed to reboot and also grow an impl in basetest, then # use them interchangably. However, this doesn't actually trigger a reboot, # but conducts it, so it's somewhat different from a regular reboot in # basetest. Muse on this a bit. sub live_reboot { # On focal plymouth isn't working at all. From local testing I'd say because # of the VNC+qxl combo openqa uses. Somehow nothing renders but I expect # the theme is actually loaded and all something is just going very wrong # and I have no clue what to do about it. Simply skip over remove medium # if it doesn't appear within 16 seconds (on focal). if (testapi::get_var('OPENQA_SERIES') eq 'focal') { if (!check_screen("live-remove-medium", 16)) { reset_consoles; return; } } assert_screen("live-remove-medium", 60); # The message actually comes up before input is read, make sure to send rets # until the system reboots or we've waited a bit of time. We'll then # continue and would fail on the first start test if the system in fact # never rebooted. my $counter = 20; while (check_screen('live-remove-medium', 1)) { if (!$counter--) { last; } eject_cd; send_key 'ret'; sleep 1; } # There's a bug in the unit ordering which prevents reboot from working # every once in a while. I utterly failed to debug what exactly is wrong, # but it sucks enormously in code that isn't even maintained by us. # So, to mitigate this problem w'll force a reset if the remove medium # screen is still up after having tried to reboot nicely. # - sitter, Sept. 2018 if (check_screen('live-remove-medium', 1)) { eject_cd; sleep 1; power 'reset'; } reset_consoles; } 1;