-
Notifications
You must be signed in to change notification settings - Fork 283
/
Copy pathbootloader_setup.pm
1705 lines (1471 loc) · 57.6 KB
/
bootloader_setup.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# SUSE's openQA tests
#
# Copyright 2016-2021 SUSE LLC
# SPDX-License-Identifier: FSFAP
package bootloader_setup;
use base Exporter;
use Exporter;
use strict;
use warnings;
use File::Basename 'basename';
use Mojo::Util 'trim';
use Time::HiRes 'sleep';
use testapi;
use Utils::Architectures;
use utils;
use version_utils qw(is_opensuse is_microos is_sle_micro is_jeos is_leap is_sle is_selfinstall is_transactional is_leap_micro);
use mm_network;
use Utils::Backends;
use backend::svirt qw(SERIAL_TERMINAL_DEFAULT_DEVICE SERIAL_TERMINAL_DEFAULT_PORT SERIAL_CONSOLE_DEFAULT_DEVICE SERIAL_CONSOLE_DEFAULT_PORT SERIAL_USER_TERMINAL_DEFAULT_DEVICE SERIAL_USER_TERMINAL_DEFAULT_PORT);
our @EXPORT = qw(
add_custom_grub_entries
autoyast_boot_params
boot_grub_item
stop_grub_timeout
boot_local_disk
boot_into_snapshot
compare_bootparams
create_encrypted_part
parse_bootparams_in_serial
select_bootmenu_more
select_bootmenu_option
uefi_bootmenu_params
bootmenu_default_params
get_hyperv_fb_video_resolution
bootmenu_network_source
bootmenu_remote_target
specific_bootmenu_params
remote_install_bootmenu_params
select_bootmenu_video_mode
select_bootmenu_language
tianocore_enter_menu
tianocore_select_bootloader
tianocore_set_svga_resolution
tianocore_http_boot
zkvm_add_disk
zkvm_add_interface
zkvm_add_pty
$zkvm_img_path
set_framebuffer_resolution
set_extrabootparams_grub_conf
ensure_shim_import
GRUB_CFG_FILE
GRUB_DEFAULT_FILE
add_grub_cmdline_settings
add_grub_xen_replace_cmdline_settings
change_grub_config
grep_grub_cmdline_settings
grep_grub_settings
grub_mkconfig
remove_grub_cmdline_settings
replace_grub_cmdline_settings
mimic_user_to_import
tianocore_disable_secureboot
prepare_disks
get_scsi_id
sync_time
);
our $zkvm_img_path = "/var/lib/libvirt/images";
my $in_grub_edit = 0;
use constant GRUB_CFG_FILE => "/boot/grub2/grub.cfg";
use constant GRUB_DEFAULT_FILE => "/etc/default/grub";
use constant GRUB_CMDLINE_VAR => "GRUB_CMDLINE_LINUX_DEFAULT";
# prevent grub2 timeout; 'esc' would be cleaner, but grub2-efi falls to the menu then
# 'up' also works in textmode and UEFI menues.
sub stop_grub_timeout {
send_key 'up';
}
=head2 add_custom_grub_entries
Add custom grub entries with extra kernel parameters.
It adds 3rd line with default options + 4th line with advanced options.
Extra kernel parameters are taken in C<GRUB_PARAM> variable
(a semicolon-separated list).
e.g. grub entries before:
* SLES 15
* Advanced options for SLES 15
* Start bootloader from a read-only snapshot
grub entries with C<GRUB_PARAM='ima_policy=tcb'> and calling add_custom_grub_entries:
* SLES 15
* Advanced options for SLES 15
* SLES 15 (ima_policy=tcb)
* Advanced options for SLES 15 (ima_policy=tcb)
* Start bootloader from a read-only snapshot
And of course the new entries have C<ima_policy=tcb> added to kernel parameters.
=cut
sub add_custom_grub_entries {
# grep: ignore empty items (helps to avoid trailing semicolon)
my @grub_params = grep { /\S/ } split(/\s*;\s*/, trim(get_var('GRUB_PARAM', '')));
bmwqemu::fctinfo("Number of GRUB_PARAM params (empty skipped): " . $#grub_params);
return unless $#grub_params >= 0;
my $script_old = "/etc/grub.d/10_linux";
my $script_old_esc = $script_old =~ s~/~\\/~rg;
my $cfg_old = 'grub.cfg.old';
my $distro = "openSUSE" . ' \\?' . get_required_var('VERSION');
# LTSS is supported only on aarch64 HPC 12-SP4
if (check_var('VERSION', '12-SP4') && is_aarch64) {
$distro = 'SLE-HPC' . ' \\?' . get_required_var('VERSION');
}
elsif (is_sle_micro('<6.0')) {
$distro = "SLE Micro";
}
elsif (is_sle_micro()) {
$distro = "SL Micro";
}
elsif (check_var('SLE_PRODUCT', 'slert')) {
$distro = "SLE_RT" . ' \\?' . get_required_var('VERSION');
}
elsif (is_sle()) {
$distro = "SLES" . ' \\?' . get_required_var('VERSION');
}
bmwqemu::diag("Trying to trigger purging old kernels before changing grub menu (if /sbin/purge-kernels installed)");
script_run('[ -x /sbin/purge-kernels ] && /sbin/purge-kernels');
assert_script_run("cp " . GRUB_CFG_FILE . " $cfg_old");
upload_logs($cfg_old, failok => 1);
my $section_old = "sed -e '1,/$script_old_esc/d' -e '/$script_old_esc/,\$d' $cfg_old";
my $cnt_old = script_output("$section_old | grep -c 'menuentry .$distro'");
my $run_cmd = is_transactional ? 'transactional-update -c -d --quiet run' : '';
my $i = 10;
foreach my $grub_param (@grub_params) {
$i++;
my $script_new = "/etc/grub.d/${i}_linux_openqa";
bmwqemu::fctinfo("Processing script '$script_new'");
my $script_new_esc = $script_new =~ s~/~\\/~rg;
assert_script_run("cp -v $script_old $script_new");
my $cmd = "sed -i -e 's/\\(args=.\\)\\(\\\$4[^\"]*\\)/\\1\\2 $grub_param/'";
$cmd .= " -e 's/\\(Advanced options for %s\\)/\\1 ($grub_param)/'";
$cmd .= " -e 's/\\(menuentry .\\\$(echo .\\\$title\\)/\\1 ($grub_param)/'";
$cmd .= " -e 's/\\(menuentry .\\\$(echo .\\\$os\\)/\\1 ($grub_param)/' $script_new";
assert_script_run($cmd);
upload_logs($script_new, failok => 1);
grub_mkconfig();
upload_logs(GRUB_CFG_FILE, failok => 1);
my $section_new = "sed -e '1,/$script_new_esc/d' -e '/$script_new_esc/,\$d' " . GRUB_CFG_FILE;
my $cnt_new = script_output("$run_cmd $section_new | grep -c 'menuentry .$distro'");
die("Unexpected number of grub entries: $cnt_new, expected: $cnt_old") if ($cnt_old != $cnt_new);
$cnt_new = script_output("$run_cmd grep -c 'menuentry .$distro.*($grub_param)' " . GRUB_CFG_FILE);
die("Unexpected number of new grub entries: $cnt_new, expected: " . ($cnt_old)) if ($cnt_old != $cnt_new);
$cnt_new = script_output("$run_cmd grep -c -E 'linux.*(/boot|/vmlinu[xz]-).* $grub_param' " . GRUB_CFG_FILE);
die("Unexpected number of new grub entries with '$grub_param': $cnt_new, expected: " . ($cnt_old)) if ($cnt_old != $cnt_new);
}
}
sub grub_key_down {
if (get_var('S390_ZKVM')) {
type_line_svirt(q(-en '\\e[B'));
}
else {
wait_screen_change { send_key 'down' };
}
}
sub grub_key_enter {
if (get_var('S390_ZKVM')) {
type_line_svirt('');
}
else {
send_key('ret');
}
}
=head2 boot_grub_item
boot_grub_item([ $menu1, [ $menu2 ] ]);
Choose custom boot menu entry in grub.
C<$menu1> defines which entry to choose in first boot menu,
optional C<$menu2> defines which entry to choose in second boot menu (makes
sense only when C<$menu1> selects "Advanced options", otherwise it's ignored).
Default value is C<$menu1 = 3, $menu2 = 1>, which boots kernel with extra
parameters (generated by add_custom_grub_entries()) or 3rd option whatever it
is other OS (given that 1st and 2nd grub options are for the default kernel):
Examples:
Boot kernel with extra parameters (generated with add_custom_grub_entries())
or 3rd option whatever it is other OS:
boot_grub_item();
boot_grub_item(3);
Boot the default kernel:
boot_grub_item(1);
Boot the default kernel recovery mode (selected in the "Advanced options ..."):
boot_grub_item(2, 2);
=cut
sub boot_grub_item {
my ($menu1, $menu2) = @_;
$menu1 //= 3;
$menu2 //= 1;
die((caller(0))[3] . " expects integer arguments ($menu1, $menu2)") unless ($menu1 =~ /^\d+\z/ && $menu2 =~ /^\d+\z/);
# boot_grub_item in bootloader_zkvm cannot use needles
assert_screen "grub2" if !get_var('S390_ZKVM');
for (1 .. ($menu1 - 1)) {
grub_key_down;
}
save_screenshot;
send_key 'ret';
for (1 .. ($menu2 - 1)) {
grub_key_down;
}
save_screenshot;
grub_key_enter;
}
sub get_scsi_id {
my $sid;
type_string_very_slow "devalias";
send_key 'ret';
save_screenshot;
my $file = './serial0';
open(my $fh, '<', $file) or die $!;
while (my $line = <$fh>) {
if ($line =~ /^disk : \/pci/) {
$sid = ($line =~ m/scsi@(\d+)/)[0];
last;
}
}
close($fh);
return $sid;
}
sub boot_local_disk {
if (get_var('OFW')) {
# TODO use bootindex to properly boot from disk when first in boot order is cd-rom
wait_screen_change { send_key 'ret' };
# Currently the bootloader would bounce back to inst-bootmenu screen after pressing 'ret'
# on 'local' menu-item, we have to check it and send 'ret' again to make booting properly
if (check_screen(['bootloader', 'inst-bootmenu'], 30)) {
record_info 'bounce back to inst-bootmenu, send ret again';
send_key 'ret';
}
my @tags = qw(inst-slof grub2);
push @tags, 'encrypted-disk-password-prompt' if (get_var('ENCRYPT'));
# Workaround for poo#118336
if (is_ppc64le && is_qemu) {
push @tags, 'linux-login' if check_var('DESKTOP', 'textmode');
push @tags, 'displaymanager' if check_var('DESKTOP', 'gnome');
}
assert_screen(\@tags, 120);
if (match_has_tag 'grub2') {
diag 'already in grub2, returning from boot_local_disk';
stop_grub_timeout;
return;
}
if (match_has_tag 'inst-slof') {
diag 'specifying local disk for boot from slof';
my $slof = 5;
$slof = get_scsi_id if (get_var('VIRTIO_CONSOLE'));
type_string_very_slow "boot /pci\t/sc\t$slof";
save_screenshot;
}
if (match_has_tag 'encrypted-disk-password-prompt') {
# It is possible to show encrypted prompt directly by pressing 'local' boot-menu
# Simply return and do enter passphrase operation in checking block of sub wait_boot
return;
}
if (match_has_tag('linux-login') or match_has_tag('displaymanager')) {
return;
}
}
send_key 'ret';
}
sub boot_into_snapshot {
send_key_until_needlematch('boot-menu-snapshot', 'down', 11, 5);
send_key 'ret';
# assert needle to make sure grub2 page show up
assert_screen('grub2-page', 60);
# assert needle to avoid send down key early in grub_test_snapshot.
if (get_var('OFW') || is_pvm || check_var('SLE_PRODUCT', 'hpc')) {
send_key_until_needlematch('snap-default', 'down', 61, 5);
}
# in upgrade/migration scenario, we want to boot from snapshot 1 before migration.
if ((get_var('UPGRADE') && !get_var('ONLINE_MIGRATION', 0)) || get_var('ZDUP')) {
send_key_until_needlematch('snap-before-update', 'down', 61, 5);
save_screenshot;
}
# in an online migration
send_key_until_needlematch('snap-before-migration', 'down', 61, 5) if (get_var('ONLINE_MIGRATION'));
save_screenshot;
send_key 'ret';
# avoid timeout for booting to HDD
save_screenshot;
send_key 'ret';
}
sub select_bootmenu_option {
my ($timeout) = @_;
assert_screen 'inst-bootmenu', $timeout;
# Special handling for Agama
if (get_var('AGAMA')) {
send_key_until_needlematch 'boot-agama-installation', 'up', 11, 5;
return 0;
}
if (get_var('LIVECD')) {
# live CDs might have a very short timeout of the initial bootmenu
# (1-2s with recent kiwi versions) so better stop the timeout
# immediately before checking more and having an opportunity to type
# more boot parameters.
stop_grub_timeout;
}
if (get_var('ZDUP') || get_var('ONLINE_MIGRATION')) {
boot_local_disk;
return 3;
}
if (get_var('UPGRADE')) {
# OFW has contralily oriented menu behavior
send_key_until_needlematch 'inst-onupgrade', get_var('OFW') ? 'up' : 'down', 11, 5;
}
else {
if (get_var('PROMO') || get_var('LIVETEST') || get_var('LIVE_INSTALLATION') || get_var('LIVE_UPGRADE')) {
send_key_until_needlematch 'boot-live-' . get_var('DESKTOP'), 'down', 11, 5;
}
elsif (get_var('OFW')) {
send_key_until_needlematch 'inst-oninstallation', 'up', 11, 5;
}
elsif (!get_var('JEOS')) {
send_key_until_needlematch 'inst-oninstallation', 'down', 11, 5;
}
}
return 0;
}
sub get_extra_boot_params {
my @params = split ' ', trim(get_var('EXTRABOOTPARAMS', ''));
return @params;
}
sub get_bootmenu_console_params {
my ($baud_rate) = shift // '';
my @params;
$baud_rate = $baud_rate ? ",$baud_rate" : '';
# To get crash dumps as text
push @params, "console=${serialdev}${baud_rate}";
# See bsc#1011815, last console set as boot parameter is linked to /dev/console
# and doesn't work if set to serial device. Don't want this on some backends.
push @params, "console=tty" unless (get_var('BACKEND', '') =~ /ipmi|spvm|pvm_hmc/);
return @params;
}
sub uefi_bootmenu_params {
# assume bios+grub+anim already waited in start.sh
# in grub2 it's tricky to set the screen resolution
send_key 'e';
assert_screen("grub2-enter-edit-mode", 30) if (is_jeos || is_usb_boot);
# Workaround for sle micro 6 baremetal installation with SelfInstall ISO on USB.
# See details in https://bugzilla.suse.com/show_bug.cgi?id=1218095#c69.
# - remove from kernel command line `console=tty0`, to let installation shown in sol
# - add in kernel command line `rd.kiwi.term=linux`, to let installation dialog
# have proper background color
# - set serial console in kernel command line
if (is_ipmi && is_selfinstall && is_usb_boot) {
my $counter = 0;
my $max_tries = 5;
my $delete_key = get_var('DELETE_KEY', '') ? get_var('DELETE_KEY') : 'delete';
while (!check_screen('pass-bootparam-to-firstboot', 2) && $counter++ < $max_tries) {
# Re-enter grub edit by discarding changes for 2+ round
if ($counter > 1) {
send_key_until_needlematch('bootloader-grub2', 'esc', 3, 2);
send_key_until_needlematch('grub2-enter-edit-mode', 'e', 3, 2);
}
record_info("Doing round $counter of grub editing...");
# Go to linux line
# For efficiency, use send_key with wait_screen_change
send_key('down', wait_screen_change => 1) for (1 .. 3);
# To mitigate sol unstability, use below while loop.
# Can't use send_key_until_needlematch because it will die.
my $_counter = 0;
my $_max = 5;
while (!check_screen('grub2-edit-linux-line', 2) && $_counter++ < $_max) {
send_key('down', wait_screen_change => 1);
}
next if (!check_screen('grub2-edit-linux-line', 2));
# Move cursor to `console=ttyS0`
send_key('right', wait_screen_change => 1) for (1 .. 60);
$_counter = 0;
$_max = 10;
while (!check_screen('on-linux-console-ttyS0', 2) && $_counter++ < $_max) {
send_key('right', wait_screen_change => 1);
}
next if (!check_screen('on-linux-console-ttyS0', 2));
# Delete `ttyS0`
send_key($delete_key, wait_screen_change => 1) for (1 .. 5);
$_counter = 0;
$_max = 3;
while (!check_screen('deleted-ttyS0', 2) && $_counter++ < $_max) {
send_key($delete_key, wait_screen_change => 1);
}
next if (!check_screen('deleted-ttyS0', 2));
# Add serial console
type_string_very_slow(get_required_var('SERIALCONSOLE'));
next if (!check_screen("serial-console-exists", 2));
# Move cursor to `console=tty0`
send_key('right', wait_screen_change => 1) for (1 .. 7);
$_counter = 0;
$_max = 5;
while (!check_screen('on-linux-console=tty0', 2) && $_counter++ < $_max) {
send_key('right', wait_screen_change => 1);
}
next if (!check_screen('on-linux-console=tty0', 2));
# Delete `console=tty0`
send_key($delete_key, wait_screen_change => 1) for (1 .. 12);
$_counter = 0;
$_max = 5;
while (!check_screen('deleted-console=tty0', 2) && $_counter++ < $_max) {
send_key($delete_key, wait_screen_change => 1);
}
next if (!check_screen('deleted-console=tty0', 2));
# Add term setting
type_string_very_slow(" rd.kiwi.term=linux ");
next if (!check_screen("no-tty0-but-term-linux", 2));
# Pass bootparam to firstboot
type_string_very_slow(" rd.kiwi.install.pass.bootparam ");
next if (!check_screen('pass-bootparam-to-firstboot', 2));
# Set disk to install
my $_disk = get_var('INSTALL_DISK_WWN', '');
record_info("INSTALL_DISK_WWN is $_disk.");
if ($_disk) {
type_string_very_slow(" rd.kiwi.oem.installdevice=/dev/disk/by-id/$_disk ");
save_screenshot;
}
# All editing done
record_info('Successfully finished grub2 editing.');
return;
}
die "Failed to edit grub2 after $max_tries tries.";
}
# Kiwi in TW uses grub2-mkconfig instead of the custom kiwi config
# Locate gfxpayload parameter and update it
# The main branch should be used only for bootable pre-installed images that contain already full
# grub2 configuration
my $linux = 0;
if (get_var('BOOT_HDD_IMAGE') && (is_jeos || is_leap_micro || is_microos || is_sle_micro)) {
# there is always a blank line
# sle 12-sp5 has no load_video
# if there is a healthchecker, skip it
my $gfx = 2;
if (is_leap_micro || is_microos || is_sle_micro) {
$gfx += 5;
} elsif (is_sle('=12-SP5')) {
;
} else {
$gfx++;
}
# navigate to gfxpayload=keep and change its settings
# OFW images do not have any gfxpayload, so jump over load_video
send_key "down" for (1 .. $gfx);
if (get_var('OFW')) {
$linux = -1;
} else {
wait_screen_change(sub { send_key "end"; }, 5);
# delete "keep" word
send_key "backspace" for (1 .. 4);
# hardcoded the value of gfxpayload to 1024x768
type_string "1024x768";
assert_screen "gfxpayload_changed", 10;
}
# navigate to the beginning of the line containing *linux* command
wait_screen_change(sub { send_key "home"; }, 5);
$linux += is_sle('=12-SP5') ? 2 : 6;
# On Leap/SLE we need to move down (grub 2.04)
# skip additional movement downwards in
# sle15sp4+, leap15.4+ and TW (grub 2.06)
$linux += 4 if is_sle('>12-SP5') && is_sle('<15-SP4');
if (get_var('FLAVOR', '') =~ /encrypt/i) {
$linux += is_sle_micro('6.1+') ? 11 : 10;
}
}
else {
$linux = 4;
for (1 .. 2) { send_key "down"; }
send_key "end";
# delete "keep" word
for (1 .. 4) { send_key "backspace"; }
# hardcoded the value of gfxpayload to 1024x768
type_string "1024x768";
assert_screen "gfxpayload_changed", 10;
# back to the entry position
send_key "home";
for (1 .. 2) { send_key "up"; }
sleep 5;
}
# flag, in order to skip more movement in grub2 submenu in case of powerPC
$in_grub_edit = 1 if (get_var('OFW') && is_sle_micro);
# jump to linux kernel bootparams
wait_screen_change(sub {
send_key "down" for (1 .. $linux);
}, 3);
send_key "end";
save_screenshot();
if (get_var("NETBOOT")) {
type_string_slow " install=" . get_netboot_mirror;
save_screenshot();
}
send_key "spc";
# if(get_var("PROMO")) {
# for(1..2) {send_key "down";} # select KDE Live
# }
if (!is_jeos && check_var('VIDEOMODE', "text")) {
type_string_slow "textmode=1 ";
}
# changed the line before typing video params
wait_screen_change(sub { enter_cmd " \\"; }, 3);
save_screenshot;
}
# Returns kernel framebuffer configuration we have to
# explicitly set on Hyper-V to get 1024x768 resolution.
sub get_hyperv_fb_video_resolution {
return 'video=hyperv_fb:1024x768';
}
=head2 get_linuxrc_boot_params
get_linuxrc_boot_params();
Returns array of strings C<@params> with linurc boot options to enable logging to the serial
console, enable core dumps and set debug level for logging.
=cut
sub get_linuxrc_boot_params {
my @params;
push @params, "linuxrc.log=/dev/$serialdev";
# Enable linuxrc core dumps https://en.opensuse.org/SDB:Linuxrc#p_linuxrccore
push @params, "linuxrc.core=/dev/$serialdev";
push @params, "linuxrc.debug=4,trace";
return @params;
}
sub bootmenu_default_params {
my (%args) = @_;
my @params;
if (get_var('OFW')) {
if (!$in_grub_edit) {
# edit menu, wait until we get to grub edit
wait_screen_change { send_key "e" };
# go down to kernel entry
send_key "down";
send_key "down";
send_key "down";
wait_screen_change { send_key "end" };
wait_still_screen(1);
}
# load kernel manually with append
if (check_var('VIDEOMODE', 'text')) {
push @params, "textmode=1";
}
push @params, "Y2DEBUG=1";
}
elsif (get_var('AGAMA')) {
wait_screen_change { send_key "e" };
send_key "down";
send_key "down";
send_key "down";
send_key "down";
wait_screen_change { send_key "end" };
# REPO_0 should be set everywhere where we rsync repo (aside from iso)
if (get_var('REPO_0')) {
my $host = get_var('OPENQA_HOST', 'https://openqa.opensuse.org');
my $repo = get_var('REPO_0');
# Split repodata functionality in Leap 16.0
# https://code.opensuse.org/leap/features/issue/193
if (get_var('SPLIT_REPODATA')) {
$repo .= "/\$basearch";
}
# inst.install_url supports comma separated list if more repos are needed ...
push @params, "inst.install_url=$host/assets/repo/$repo";
}
push @params, "live.password=$testapi::password";
}
else {
# On JeOS and MicroOS we don't have YaST installer.
push @params, "Y2DEBUG=1" unless is_jeos || is_microos || is_selfinstall || (is_sle_micro && get_var('BOOT_HDD_IMAGE'));
# gfxpayload variable replaced vga option in grub2
if (!(is_sle_micro && get_var('BOOT_HDD_IMAGE')) && !is_jeos && !is_microos && !is_selfinstall && (is_i586 || is_x86_64)) {
push @params, "vga=791";
my $video = 'video=1024x768';
$video .= '-16' if check_var('QEMUVGA', 'cirrus');
push @params, $video;
}
}
if (!get_var("NICEVIDEO")) {
if (is_microos || is_selfinstall) {
push @params, get_bootmenu_console_params $args{baud_rate};
}
elsif (!is_jeos && !(is_sle_micro && get_var('BOOT_HDD_IMAGE'))) {
# make plymouth go graphical
push @params, "plymouth.ignore-serial-consoles" unless $args{pxe};
push @params, get_bootmenu_console_params $args{baud_rate};
# Enable linuxrc logging
push @params, get_linuxrc_boot_params;
}
push @params, get_extra_boot_params();
}
push @params, 'reboot_timeout=' . get_var('REBOOT_TIMEOUT', 0) unless (is_leap('<15.2') || is_sle('<15-SP2'));
# https://wiki.archlinux.org/index.php/Kernel_Mode_Setting#Forcing_modes_and_EDID
# Default namescheme 'by-id' for devices is broken on Hyper-V (bsc#1029303),
# we have to use something else.
if (check_var('VIRSH_VMM_FAMILY', 'hyperv')) {
push @params, get_hyperv_fb_video_resolution;
push @params, 'namescheme=by-label' unless is_jeos or is_microos;
}
type_boot_parameters(" @params ") if @params;
return @params;
}
sub bootmenu_network_source {
my @params;
# set HTTP-source to not use factory-snapshot
if (get_var("NETBOOT")) {
if (get_var('OFW')) {
if (get_var("SUSEMIRROR")) {
push @params, 'install=http://' . get_var("SUSEMIRROR");
}
else {
push @params, ('kernel=1', 'insecure=1');
}
}
else {
my $m_protocol = get_var('INSTALL_SOURCE', 'http');
my $m_mirror = get_netboot_mirror;
die "No mirror defined, please set MIRROR_$m_protocol variable" unless $m_mirror;
# In case of https we have to use boot options and not UI
if ($m_protocol eq "https") {
push @params, "install=$m_mirror";
# Ignore certificate validation
push @params, 'ssl.certs=0' if (get_var('SKIP_CERT_VALIDATION'));
# As we use boot options, no extra action is required
type_boot_parameters(" @params ") if @params;
return @params;
}
# fate#322276
# Point linuxrc to a repomd repository and load the installation system from local medium
if (($m_protocol eq "http") && (get_var('REMOTE_REPOINST'))) {
push @params, "install=$m_mirror";
# Specifies the installation system to use, e.g. from where to load installer
my $arch = get_var('ARCH');
push @params, "instsys=disk:/boot/$arch/root";
type_boot_parameters(" @params ") if @params;
return @params;
}
select_installation_source({m_protocol => $m_protocol, m_mirror => $m_mirror});
}
}
type_boot_parameters(" @params ") if @params;
return @params;
}
sub bootmenu_remote_target {
my @params;
my $remote = get_var("REMOTE_TARGET");
if ($remote) {
my $dns = get_host_resolv_conf()->{nameserver};
push @params, get_var("NETSETUP") if get_var("NETSETUP");
push @params, "nameserver=" . join(",", @$dns);
push @params, ("$remote=1", "${remote}password=$password");
}
type_boot_parameters(" @params ") if @params;
return @params;
}
sub select_installation_source {
my ($args_ref) = @_;
my $m_protocol = $args_ref->{m_protocol};
my $m_mirror = $args_ref->{m_mirror};
my ($m_server, $m_share, $m_directory);
# Parse SUSEMIRROR into variables
if ($m_mirror =~ m{^[a-z]+://(?<server>[a-zA-Z0-9.-]*)/(?<dir>.*)$}) {
($m_server, $m_directory) = ($+{server}, $+{dir});
if ($m_protocol eq "smb") {
($m_share, $m_directory) = split(/\//, $m_directory, 2);
}
}
# select installation source (http, ftp, nfs, smb)
send_key "f4";
assert_screen "inst-instsourcemenu";
send_key_until_needlematch "inst-instsourcemenu-$m_protocol", 'down';
send_key "ret";
assert_screen "inst-instsourcedialog-$m_protocol";
# Clean server name and path
if ($m_protocol eq "http") {
for (1 .. 2) {
# just type enough backspaces
for (1 .. 34) { send_key "backspace" }
send_key "tab";
}
}
# Type variables into fields
type_string_slow "$m_server\t";
type_string_slow "$m_share\t" if $m_protocol eq "smb";
enter_cmd_slow "$m_directory";
save_screenshot;
# HTTP-proxy
if (get_var("HTTPPROXY", '') =~ m/([0-9.]+):(\d+)/) {
my ($proxyhost, $proxyport) = ($1, $2);
send_key "f4";
for (1 .. 4) {
send_key "down";
}
send_key "ret";
enter_cmd_slow "$proxyhost\t$proxyport";
assert_screen "inst-proxy_is_setup";
# add boot parameters
# ZYPP... enables proxy caching
}
}
sub select_bootmenu_more {
my ($tag, $more) = @_;
my @params;
# do not waste time waiting when we already matched
assert_screen 'inst-bootmenu', 15 unless match_has_tag 'inst-bootmenu';
stop_grub_timeout;
# after installation-images 14.210 added a submenu
if ($more && check_screen 'inst-submenu-more', 0) {
send_key_until_needlematch('inst-onmore', get_var('OFW') ? 'up' : 'down', 11, 5);
send_key "ret";
}
send_key_until_needlematch($tag, get_var('OFW') ? 'up' : 'down', 11, 3);
# Redirect linuxrc logs to console when booting from menu: "boot linux system"
push @params, get_linuxrc_boot_params if get_var('LINUXRC_BOOT');
# Make sure to use the correct repo for testing
push(@params, "install=" . get_netboot_mirror) if (get_var("NETBOOT") && $tag =~ /rescue/);
if (get_var('UEFI')) {
send_key 'e';
send_key 'down' for (1 .. 4);
send_key 'end';
# newer versions of qemu on arch automatically add 'console=ttyS0' so
# we would end up nowhere. Setting console parameter explicitly
# See https://bugzilla.suse.com/show_bug.cgi?id=1032335 for details
push @params, 'console=tty1' if get_var('MACHINE') =~ /aarch64|aarch32/;
# Hyper-V defaults to 1280x1024, we need to fix it here
push @params, get_hyperv_fb_video_resolution if check_var('VIRSH_VMM_FAMILY', 'hyperv');
type_boot_parameters(" @params ") if @params;
save_screenshot;
send_key 'f10';
}
else {
push @params, get_hyperv_fb_video_resolution if check_var('VIRSH_VMM_FAMILY', 'hyperv');
type_boot_parameters(" @params ") if @params;
save_screenshot;
send_key 'ret';
}
return @params;
}
sub autoyast_boot_params {
my @params;
my $ay_var = get_var("AUTOYAST");
return @params unless $ay_var;
my $autoyast_args = 'autoyast=';
# In case of SUPPORT_SERVER, profiles are available on another VM
if (get_var('USE_SUPPORT_SERVER')) {
my $proto = get_var("PROTO") || 'http';
$autoyast_args .= "$proto://10.0.2.1/";
$autoyast_args .= 'data/' if $ay_var !~ /^aytests\//;
$autoyast_args .= $ay_var;
}
elsif ($ay_var =~ /^ASSET_\d+$/) {
# In case profile is uploaded as an ASSET we need just filename
$ay_var = basename(get_required_var($ay_var));
$autoyast_args .= autoinst_url("/assets/other/$ay_var");
}
elsif ($ay_var !~ /^slp$|:\/\//) {
# Getting profile from the worker as openQA asset
$autoyast_args .= data_url($ay_var);
}
else {
# Getting profile by direct url or slp
$autoyast_args .= $ay_var;
}
push @params, split ' ', $autoyast_args;
$autoyast_args =~ /autoyast=(?<url>\S+)/;
set_var('AUTOYAST', $+{url});
return @params;
}
sub specific_bootmenu_params {
my @params;
if (!is_s390x) {
my @netsetup;
my $autoyast = get_var("AUTOYAST", "");
if ($autoyast || get_var("AUTOUPGRADE") && get_var("AUTOUPGRADE") ne 'local') {
# We need to use 'ifcfg=*=dhcp' instead of 'netsetup=dhcp' as a default
# due to BSC#932692 (SLE-12). 'SetHostname=0' has to be set because autoyast
# profile has DHCLIENT_SET_HOSTNAME="yes" in /etc/sysconfig/network/dhcp,
# 'ifcfg=*=dhcp' sets this variable in ifcfg-eth0 as well and we can't
# have them both as it's not deterministic. Don't set on IPMI with net interface defined in SUT_NETDEVICE.
my $ifcfg = is_ipmi ? '' : 'ifcfg=*=dhcp SetHostname=0';
@netsetup = split ' ', get_var("NETWORK_INIT_PARAM", "$ifcfg");
push @params, @netsetup;
push @params, autoyast_boot_params;
}
else {
@netsetup = split ' ', get_var("NETWORK_INIT_PARAM") if defined get_var("NETWORK_INIT_PARAM"); #e.g netsetup=dhcp,all
push @params, @netsetup;
}
}
if (get_var("AUTOUPGRADE") || get_var("AUTOYAST") && (get_var("UPGRADE_FROM_AUTOYAST") || get_var("UPGRADE"))) {
push @params, "autoupgrade=1";
}
if (my $agama_auto = get_var('AGAMA_AUTO')) {
my $url = autoyast::expand_agama_profile($agama_auto);
$url = shorten_url($url) if (is_backend_s390x && !is_opensuse);
# Workaround for bsc#1238581, will remove it once the bug is fixed
push @params, "agama.auto=$url agama.finish=stop";
}
if (my $agama_install_url = get_var('AGAMA_INSTALL_URL')) {
if (get_var('SPLIT_REPODATA')) {
$agama_install_url .= "/\$basearch";
}
push @params, "inst.install_url=$agama_install_url";
}
# Boot the system with the debug options if shutdown takes suspiciously long time.
# Please, see https://freedesktop.org/wiki/Software/systemd/Debugging/#index2h1 for the details.
# Further actions for saving debug logs are done in 'shutdown/cleanup_before_shutdown' module.
if (get_var('DEBUG_SHUTDOWN')) {
push @params, ('systemd.log_level=debug', 'systemd.log_target=kmsg', 'log_buf_len=1M', 'printk.devkmsg=on', 'enforcing=0', 'plymouth.enable=0');
}
if (get_var("IBFT") or get_var("WITHISCSI")) {
push @params, "withiscsi=1";
}
if (check_var("INSTALLER_NO_SELF_UPDATE", 1)) {
diag "Disabling installer self update";
push @params, "self_update=0";
}
elsif (my $self_update_repo = get_var("INSTALLER_SELF_UPDATE")) {
push @params, "self_update=$self_update_repo";
diag "Explicitly enabling installer self update with $self_update_repo";
}
if (get_var("FIPS_INSTALLATION")) {
push @params, "fips=1";
}
if (get_var("LUKS2_ENCRYPT")) {
push @params, "YAST_LUKS2_AVAILABLE=1";
}
if (my $kexec_value = get_var("LINUXRC_KEXEC")) {
push @params, "kexec=$kexec_value";
record_info('Info', 'boo#990374 - pass kexec to installer to use initrd from FTP');
}
if (get_var('DUD')) {
my @duds = split(/,/, get_var('DUD'));
foreach my $dud (@duds) {
if ($dud =~ /^(http|https|ftp):\/\//) {
push @params, "dud=$dud";
}
elsif ($dud =~ /^ASSET_\d+$/) {
# In case dud is uploaded as an ASSET we need just filename
$dud = basename(get_required_var($dud));
if (check_var('DUD_NO_SHORTEN_URL', '1')) {
push @params, 'dud=' . autoinst_url("/assets/other/$dud");
}
else {
push @params, 'dud=' . shorten_url(autoinst_url("/assets/other/$dud"));
}
}
else {
push @params, 'dud=' . data_url($dud);
}
}
push @params, 'insecure=1';
}
# For leap 42.3 we don't have addon_products screen
if (addon_products_is_applicable() && is_leap('42.3+')) {
my $addon_url = get_var("ADDONURL");
$addon_url =~ s/\+/,/g;
push @params, "addon=$addon_url";
}
if (get_var('ISO_IN_EXTERNAL_DRIVE')) {
push @params, "install=hd:/install.iso";
}
# Return parameters as string of space-separated values, because s390x test
# modules are using strings but not arrays to combine bootloader parameters.
if (is_s390x) {
return " @params ";
}
# Enable kernel.softlockup_panic, unless explicitly disabled
# See bsc#1126782
push @params, 'kernel.softlockup_panic=1' unless get_var('SOFTLOCKUP_PANIC_DISABLED', 0);
type_boot_parameters(" @params ") if (@params);
save_screenshot;
return @params;
}
sub remote_install_bootmenu_params {
my $params = "";
if (check_var("VIDEOMODE", "text") || check_var("VIDEOMODE", "ssh-x")) {
$params .= " ssh=1 "; # trigger ssh-text installation
}
else {
if (is_sle('=11-sp4')) {
#11-SP4 only support ssh=1
$params .= " ssh=1 VNC=1 VNCSize=1024x768 VNCPassword=$testapi::password ";
}