Enable Anaconda Text install via serial console.
This adds the Anaconda text installation test over serial console and FIXES #115.
This commit is contained in:
parent
0722cc5bcf
commit
b93a197c22
@ -120,6 +120,14 @@ sub root_console {
|
||||
if (get_var("LIVE") && get_var("DESKTOP") eq "gnome") {
|
||||
send_key "ctrl-alt-f3";
|
||||
}
|
||||
elsif (get_var("SERIAL_CONSOLE")) {
|
||||
# select first virtio terminal, we rely on anaconda having run
|
||||
# a root shell on it for us
|
||||
select_console("root-virtio-terminal");
|
||||
# as we don't have any live image serial install tests, we
|
||||
# know we don't need to login
|
||||
return;
|
||||
}
|
||||
else {
|
||||
send_key "ctrl-alt-f2";
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package fedoradistribution;
|
||||
use base 'distribution';
|
||||
use Cwd;
|
||||
|
||||
# Fedora distribution class
|
||||
|
||||
@ -15,12 +16,19 @@ use base 'distribution';
|
||||
|
||||
# importing whole testapi creates circular dependency, so import only
|
||||
# necessary functions from testapi
|
||||
use testapi qw(send_key type_string wait_idle assert_screen);
|
||||
use testapi qw(check_var get_var send_key type_string wait_idle assert_screen);
|
||||
|
||||
sub init() {
|
||||
my ($self) = @_;
|
||||
|
||||
$self->SUPER::init();
|
||||
# This initiates the serial console as "root-virtio-terminal".
|
||||
if (check_var('BACKEND', 'qemu')) {
|
||||
$self->add_console('root-virtio-terminal', 'virtio-terminal', {});
|
||||
for (my $num = 1; $num < get_var('VIRTIO_CONSOLE_NUM', 1); $num++) {
|
||||
$self->add_console('root-virtio-terminal' . $num, 'virtio-terminal', {socked_path => cwd() . '/virtio_console' . $num});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub x11_start_program {
|
||||
|
@ -15,9 +15,16 @@ sub root_console {
|
||||
my %args = (
|
||||
tty => 1, # what TTY to login to
|
||||
@_);
|
||||
|
||||
if (get_var("SERIAL_CONSOLE")) {
|
||||
# select the first virtio terminal, for now we assume we can
|
||||
# always use that (we may have to make this smarter in future)
|
||||
select_console("root-virtio-terminal");
|
||||
}
|
||||
else {
|
||||
# For normal terminal emulation, use key combo to reach a tty
|
||||
send_key "ctrl-alt-f$args{tty}";
|
||||
console_login;
|
||||
}
|
||||
console_login; # Do the login.
|
||||
}
|
||||
|
||||
sub post_fail_hook {
|
||||
|
59
lib/utils.pm
59
lib/utils.pm
@ -15,10 +15,22 @@ our @application_list;
|
||||
|
||||
sub run_with_error_check {
|
||||
my ($func, $error_screen) = @_;
|
||||
# Check screen does not work for serial console, so we need to use
|
||||
# different checking mechanism for it.
|
||||
if (testapi::is_serial_terminal) {
|
||||
# by using 'unless' and 'expect_not_found=>1' here we avoid
|
||||
# the web UI showing each failure to see the error message as
|
||||
# a 'failed match'
|
||||
die "Error screen appeared" unless (wait_serial($error_screen, timeout=>5, expect_not_found=>1));
|
||||
$func->();
|
||||
die "Error screen appeared" unless (wait_serial($error_screen, timeout=>5, expect_not_found=>1));
|
||||
}
|
||||
else {
|
||||
die "Error screen appeared" if (check_screen $error_screen, 5);
|
||||
$func->();
|
||||
die "Error screen appeared" if (check_screen $error_screen, 5);
|
||||
}
|
||||
}
|
||||
|
||||
# high-level 'type this string quite safely but reasonably fast'
|
||||
# function whose specific implementation may vary
|
||||
@ -78,9 +90,17 @@ sub desktop_vt {
|
||||
sub boot_to_login_screen {
|
||||
my %args = @_;
|
||||
$args{timeout} //= 300;
|
||||
if (testapi::is_serial_terminal) {
|
||||
# For serial console, just wait for the login prompt
|
||||
unless (wait_serial "login:", timeout=>$args{timeout}) {
|
||||
die "No login prompt shown on serial console.";
|
||||
}
|
||||
}
|
||||
else {
|
||||
# we may start at a screen that matches one of the needles; if so,
|
||||
# wait till we don't (e.g. when rebooting at end of live install,
|
||||
# we match text_console_login until the console disappears)
|
||||
# we match text_console_login until the console disappears).
|
||||
# The following is true for non-serial console.
|
||||
my $count = 5;
|
||||
while (check_screen("login_screen", 3) && $count > 0) {
|
||||
sleep 5;
|
||||
@ -92,6 +112,7 @@ sub boot_to_login_screen {
|
||||
assert_screen "login_screen";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Switch keyboard layouts at a console
|
||||
sub console_switch_layout {
|
||||
@ -128,10 +149,18 @@ sub desktop_switch_layout {
|
||||
# failed (the prompt looks different in this case). We treat this as
|
||||
# a soft failure.
|
||||
sub _console_login_finish {
|
||||
# The check differs according to the console used.
|
||||
if (testapi::is_serial_terminal) {
|
||||
unless (wait_serial("-bash-.*[#\$]", timeout=>5, expect_not_found=>1)) {
|
||||
record_soft_failure "It looks like profile sourcing failed";
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (match_has_tag "bash_noprofile") {
|
||||
record_soft_failure "It looks like profile sourcing failed";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# this subroutine handles logging in as a root/specified user into console
|
||||
# it requires TTY to be already displayed (handled by the root_console()
|
||||
@ -145,6 +174,33 @@ sub console_login {
|
||||
@_);
|
||||
$args{timeout} ||= 10;
|
||||
|
||||
# Since we do not test many serial console tests, and we probably
|
||||
# only want to test serial console on a minimal installation only,
|
||||
# let us not do all the magic to handle different console logins
|
||||
# and let us simplify the process.
|
||||
# We will check if we are logged in, and if so, we will log out to
|
||||
# enable a new proper login based on the user variable.
|
||||
if (get_var("SERIAL_CONSOLE")) {
|
||||
# Check for the usual prompt.
|
||||
if (wait_serial("~\][#\$]", timeout=>5, quiet=>1)) {
|
||||
type_string "logout\n";
|
||||
# Wait a bit to let the logout properly finish.
|
||||
sleep 10;
|
||||
}
|
||||
# Do the new login.
|
||||
type_string $args{user};
|
||||
type_string "\n";
|
||||
sleep 2;
|
||||
type_string $args{password};
|
||||
type_string "\n";
|
||||
# Let's perform a simple login test. This is the same as
|
||||
# whoami, but has the advantage of existing in installer env
|
||||
assert_script_run "id -un";
|
||||
unless (wait_serial $args{user}, timeout=>5) {
|
||||
die "Logging onto the serial console has failed.";
|
||||
}
|
||||
}
|
||||
else {
|
||||
# There's a timing problem when we switch from a logged-in console
|
||||
# to a non-logged in console and immediately call this function;
|
||||
# if the switch lags a bit, this function will match one of the
|
||||
@ -206,6 +262,7 @@ sub console_login {
|
||||
$timeout = 90 if (get_var("ARCH") eq "aarch64");
|
||||
assert_screen($good, $timeout);
|
||||
}
|
||||
}
|
||||
_console_login_finish();
|
||||
}
|
||||
|
||||
|
48
templates
48
templates
@ -700,6 +700,17 @@
|
||||
},
|
||||
test_suite => { name => "install_anaconda_text" },
|
||||
},
|
||||
{
|
||||
machine => { name => "64bit" },
|
||||
prio => 30,
|
||||
product => {
|
||||
arch => "x86_64",
|
||||
distri => "fedora",
|
||||
flavor => "universal",
|
||||
version => "*",
|
||||
},
|
||||
test_suite => { name => "install_anaconda_serial_console" },
|
||||
},
|
||||
{
|
||||
machine => { name => "64bit" },
|
||||
prio => 31,
|
||||
@ -2386,6 +2397,18 @@
|
||||
},
|
||||
test_suite => { name => "install_anaconda_text" },
|
||||
},
|
||||
{
|
||||
group_name => "Fedora PowerPC",
|
||||
machine => { name => "ppc64le" },
|
||||
prio => 30,
|
||||
product => {
|
||||
arch => "ppc64le",
|
||||
distri => "fedora",
|
||||
flavor => "universal",
|
||||
version => "*",
|
||||
},
|
||||
test_suite => { name => "install_anaconda_serial_console" },
|
||||
},
|
||||
{
|
||||
group_name => "Fedora PowerPC",
|
||||
machine => { name => "ppc64le" },
|
||||
@ -3474,6 +3497,18 @@
|
||||
},
|
||||
test_suite => { name => "install_anaconda_text" },
|
||||
},
|
||||
{
|
||||
group_name => "Fedora AArch64",
|
||||
machine => { name => "aarch64" },
|
||||
prio => 30,
|
||||
product => {
|
||||
arch => "aarch64",
|
||||
distri => "fedora",
|
||||
flavor => "universal",
|
||||
version => "*",
|
||||
},
|
||||
test_suite => { name => "install_anaconda_serial_console" },
|
||||
},
|
||||
{
|
||||
group_name => "Fedora AArch64",
|
||||
machine => { name => "aarch64" },
|
||||
@ -4685,6 +4720,19 @@
|
||||
{ key => "ANACONDA_TEXT", value => "1" },
|
||||
],
|
||||
},
|
||||
{
|
||||
name => "install_anaconda_serial_console",
|
||||
settings => [
|
||||
{ key => "ANACONDA_TEXT", value => "1" },
|
||||
{ key => "SERIAL_CONSOLE", value => "1" },
|
||||
# we want one console for anaconda and one for a root
|
||||
# terminal
|
||||
{ key => "VIRTIO_CONSOLE_NUM", value => "2" },
|
||||
# we don't need to check this here and it doesn't work
|
||||
# with serial console
|
||||
{ key => "NO_UEFI_POST", value => "1" },
|
||||
],
|
||||
},
|
||||
{
|
||||
name => "install_rescue_encrypted",
|
||||
settings => [
|
||||
|
@ -37,8 +37,30 @@ sub run {
|
||||
}
|
||||
if (get_var("ANACONDA_TEXT")) {
|
||||
$params .= "inst.text ";
|
||||
# we need this on aarch64 till #1594402 is resolved
|
||||
# we need this on aarch64 till #1594402 is resolved,
|
||||
# and we also can utilize this if we want to run this
|
||||
# over the serial console.
|
||||
$params .= "console=tty0 " if (get_var("ARCH") eq "aarch64");
|
||||
# when the text installation should run over the serial console,
|
||||
# we have to add some more parametres to grub. Although, the written
|
||||
# test case recommends using ttyS0, OpenQA only uses that console for
|
||||
# displaying information but does not accept key strokes. Therefore,
|
||||
# let us use a real virtio console here.
|
||||
if (get_var("SERIAL_CONSOLE")) {
|
||||
# this is icky. on ppc64 (OFW), virtio-terminal is hvc1 and
|
||||
# virtio-terminal1 is hvc2, because the 'standard' serial
|
||||
# terminal is hvc0 (the firmware does this or something).
|
||||
# On other arches, the 'standard' serial terminal is ttyS0,
|
||||
# so virtio-terminal becomes hvc0 and virtio-terminal1 is
|
||||
# hvc1. We want anaconda to wind up on the console that is
|
||||
# virtio-terminal1 in both cases
|
||||
if (get_var("OFW")) {
|
||||
$params .= "console=hvc2 ";
|
||||
}
|
||||
else {
|
||||
$params .= "console=hvc1 ";
|
||||
}
|
||||
}
|
||||
}
|
||||
# inst.debug enables memory use tracking
|
||||
$params .= "debug" if get_var("MEMCHECK");
|
||||
@ -73,11 +95,21 @@ sub run {
|
||||
else {
|
||||
if (get_var("ANACONDA_TEXT")) {
|
||||
# select that we don't want to start VNC; we want to run in text mode
|
||||
if (get_var("SERIAL_CONSOLE")) {
|
||||
# we direct the installer to virtio-terminal1, and use
|
||||
# virtio-terminal as a root console
|
||||
select_console('root-virtio-terminal1');
|
||||
unless (wait_serial "Use text mode", timeout=>120) { die "Anaconda has not started."; }
|
||||
type_string "2\n";
|
||||
unless (wait_serial "Installation") { die "Text version of Anaconda has not started."; }
|
||||
}
|
||||
else {
|
||||
assert_screen "anaconda_use_text_mode", 300;
|
||||
type_string "2\n";
|
||||
# wait for text version of Anaconda main hub
|
||||
assert_screen "anaconda_main_hub_text", 300;
|
||||
}
|
||||
}
|
||||
else {
|
||||
# on lives, we have to explicitly launch anaconda
|
||||
if (get_var('LIVE')) {
|
||||
|
@ -20,7 +20,11 @@ sub run {
|
||||
|
||||
# do user login unless USER_LOGIN is set to string 'false'
|
||||
unless (get_var("USER_LOGIN") eq "false") {
|
||||
# this avoids us waiting 90 seconds for a # to show up
|
||||
my $origprompt = $self->{serial_term_prompt};
|
||||
$testapi::distri->{serial_term_prompt} = '$ ';
|
||||
console_login(user=>get_var("USER_LOGIN", "test"), password=>get_var("USER_PASSWORD", "weakpassword"));
|
||||
$testapi::distri->{serial_term_prompt} = $origprompt;
|
||||
}
|
||||
if (get_var("ROOT_PASSWORD")) {
|
||||
console_login(user=>"root", password=>get_var("ROOT_PASSWORD"));
|
||||
|
@ -3,11 +3,38 @@ use strict;
|
||||
use testapi;
|
||||
use utils;
|
||||
|
||||
|
||||
# this enables you to send a command and some post-command wait time
|
||||
# in one step and also distinguishes between serial console and normal
|
||||
# VNC based console and handles the wait times differently.
|
||||
sub console_type_wait {
|
||||
my ($string, $wait) = @_;
|
||||
$wait ||= 5;
|
||||
type_string $string;
|
||||
if (testapi::is_serial_terminal) {
|
||||
sleep $wait;
|
||||
}
|
||||
else {
|
||||
wait_still_screen $wait;
|
||||
}
|
||||
}
|
||||
|
||||
sub run {
|
||||
my $self = shift;
|
||||
|
||||
# First, preset the environment according to the chosen console. This test
|
||||
# can run both on a VNC based console, or a serial console.
|
||||
if (get_var("SERIAL_CONSOLE")) {
|
||||
select_console('root-virtio-terminal1');
|
||||
unless (testapi::is_serial_terminal) {
|
||||
die "The test does not run on a serial console when it should.";
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert_screen "anaconda_main_hub_text";
|
||||
# IMHO it's better to use sleeps than to have needle for every text screen
|
||||
wait_still_screen 5;
|
||||
}
|
||||
|
||||
# prepare for different number of spokes (e. g. as in Atomic DVD)
|
||||
my %spoke_number = (
|
||||
@ -21,77 +48,76 @@ sub run {
|
||||
"user" => 8
|
||||
);
|
||||
|
||||
# The error message that we are going to check for in the text installation
|
||||
# must be different for serial console and a VNC terminal emulator.
|
||||
my $error = "";
|
||||
if (testapi::is_serial_terminal) {
|
||||
$error = "unknown error has occured";
|
||||
}
|
||||
else {
|
||||
$error = "anaconda_text_error";
|
||||
}
|
||||
|
||||
# Set timezone
|
||||
run_with_error_check(sub {type_string $spoke_number{"timezone"} . "\n"}, "anaconda_text_error");
|
||||
wait_still_screen 5;
|
||||
type_string "1\n"; # Set timezone
|
||||
wait_still_screen 5;
|
||||
type_string "1\n"; # Europe
|
||||
wait_still_screen 5;
|
||||
type_string "37\n"; # Prague
|
||||
wait_still_screen 7;
|
||||
run_with_error_check(sub {console_type_wait($spoke_number{"timezone"} . "\n")}, $error);
|
||||
console_type_wait("1\n"); # Set timezone
|
||||
console_type_wait("1\n"); # Europe
|
||||
console_type_wait("37\n", 7); # Prague
|
||||
|
||||
# Select disk
|
||||
run_with_error_check(sub {type_string $spoke_number{"destination"} . "\n"}, "anaconda_text_error");
|
||||
wait_still_screen 5;
|
||||
type_string "c\n"; # first disk selected, continue
|
||||
wait_still_screen 5;
|
||||
type_string "c\n"; # use all space selected, continue
|
||||
wait_still_screen 5;
|
||||
type_string "c\n"; # LVM selected, continue
|
||||
wait_still_screen 7;
|
||||
run_with_error_check(sub {console_type_wait($spoke_number{"destination"} . "\n")}, $error);
|
||||
console_type_wait("c\n"); # first disk selected, continue
|
||||
console_type_wait("c\n"); # use all space selected, continue
|
||||
console_type_wait("c\n", 7); # LVM selected, continue
|
||||
|
||||
# Set root password
|
||||
run_with_error_check(sub {type_string $spoke_number{"rootpwd"} . "\n"}, "anaconda_text_error");
|
||||
wait_still_screen 5;
|
||||
type_string get_var("ROOT_PASSWORD", "weakpassword");
|
||||
send_key "ret";
|
||||
wait_still_screen 5;
|
||||
type_string get_var("ROOT_PASSWORD", "weakpassword");
|
||||
send_key "ret";
|
||||
wait_still_screen 7;
|
||||
my $rootpwd = get_var("ROOT_PASSWORD", "weakpassword");
|
||||
run_with_error_check(sub {console_type_wait($spoke_number{"rootpwd"} . "\n")}, $error);
|
||||
console_type_wait("$rootpwd\n");
|
||||
console_type_wait("$rootpwd\n");
|
||||
|
||||
# Create user
|
||||
run_with_error_check(sub {type_string $spoke_number{"user"} . "\n"}, "anaconda_text_error");
|
||||
wait_still_screen 5;
|
||||
type_string "1\n"; # create new
|
||||
wait_still_screen 5;
|
||||
type_string "3\n"; # set username
|
||||
wait_still_screen 5;
|
||||
type_string get_var("USER_LOGIN", "test");
|
||||
send_key "ret";
|
||||
wait_still_screen 5;
|
||||
my $userpwd = get_var("USER_PASSWORD", "weakpassword");
|
||||
my $username = get_var("USER_LOGIN", "test");
|
||||
run_with_error_check(sub {console_type_wait($spoke_number{"user"} . "\n")}, $error);
|
||||
console_type_wait("1\n"); # create new
|
||||
console_type_wait("3\n"); # set username
|
||||
console_type_wait("$username\n");
|
||||
# from Rawhide-20190503.n.0 (F31) onwards, 'use password' is default
|
||||
if (get_release_number() < 31) {
|
||||
# typing "4\n" on abrt screen causes system to reboot, so be careful
|
||||
run_with_error_check(sub {type_string "4\n"}, "anaconda_text_error"); # use password
|
||||
run_with_error_check(sub {console_type_wait("4\n")}, $error); # use password
|
||||
}
|
||||
wait_still_screen 5;
|
||||
type_string "5\n"; # set password
|
||||
wait_still_screen 5;
|
||||
type_string get_var("USER_PASSWORD", "weakpassword");
|
||||
send_key "ret";
|
||||
wait_still_screen 5;
|
||||
type_string get_var("USER_PASSWORD", "weakpassword");
|
||||
send_key "ret";
|
||||
wait_still_screen 5;
|
||||
type_string "6\n"; # make him an administrator
|
||||
wait_still_screen 5;
|
||||
type_string "c\n";
|
||||
wait_still_screen 7;
|
||||
console_type_wait("5\n"); # set password
|
||||
console_type_wait("$userpwd\n");
|
||||
console_type_wait("$userpwd\n");
|
||||
console_type_wait("6\n"); # make him an administrator
|
||||
console_type_wait("c\n", 7);
|
||||
|
||||
my $counter = 0;
|
||||
if (testapi::is_serial_terminal) {
|
||||
while (wait_serial("[!]", timeout=>5, quiet=>1)) {
|
||||
if ($counter > 10) {
|
||||
die "There are unfinished spokes in Anaconda";
|
||||
}
|
||||
sleep 10;
|
||||
$counter++;
|
||||
console_type_wait("r\n"); # refresh
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (check_screen "anaconda_main_hub_text_unfinished", 2) {
|
||||
if ($counter > 10) {
|
||||
die "There are unfinished spokes in Anaconda";
|
||||
}
|
||||
sleep 10;
|
||||
$counter++;
|
||||
type_string "r\n"; # refresh
|
||||
console_type_wait("r\n"); # refresh
|
||||
}
|
||||
}
|
||||
|
||||
# begin installation
|
||||
type_string "b\n";
|
||||
console_type_wait("b\n");
|
||||
|
||||
# Wait for install to end. Give Rawhide a bit longer, in case
|
||||
# we're on a debug kernel, debug kernel installs are really slow.
|
||||
@ -99,8 +125,23 @@ sub run {
|
||||
if (lc(get_var('VERSION')) eq "rawhide") {
|
||||
$timeout = 2400;
|
||||
}
|
||||
|
||||
if (testapi::is_serial_terminal) {
|
||||
wait_serial("Installation complete", timeout=>$timeout);
|
||||
if (get_var("SERIAL_CONSOLE") && get_var("OFW")) {
|
||||
$self->root_console();
|
||||
# we need to force the system to load a console on both hvc1
|
||||
# and hvc2 for ppc64 serial console post-install tests
|
||||
assert_script_run 'chroot /mnt/sysimage systemctl enable serial-getty@hvc1';
|
||||
assert_script_run 'chroot /mnt/sysimage systemctl enable serial-getty@hvc2';
|
||||
# back to anaconda ui
|
||||
select_console("root-virtio-terminal1");
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert_screen "anaconda_install_text_done", $timeout;
|
||||
type_string "\n";
|
||||
}
|
||||
console_type_wait("\n");
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user