1#!/usr/bin/env python3 2# 3# SPDX-License-Identifier: GPL-2.0-or-later 4# 5# Functional test that checks the pxelinux.cfg network booting of a s390x VM 6# (TFTP booting without config file is already tested by the pxe qtest, so 7# we don't repeat that here). 8 9import os 10import shutil 11 12from qemu_test import QemuSystemTest, Asset, wait_for_console_pattern 13 14 15pxelinux_cfg_contents='''# pxelinux.cfg style config file 16default Debian 17label Nonexisting 18kernel kernel.notavailable 19initrd initrd.notavailable 20label Debian 21kernel kernel.debian 22initrd initrd.debian 23append testoption=teststring 24label Fedora 25kernel kernel.fedora 26''' 27 28class S390PxeLinux(QemuSystemTest): 29 30 ASSET_DEBIAN_KERNEL = Asset( 31 ('https://snapshot.debian.org/archive/debian/' 32 '20201126T092837Z/dists/buster/main/installer-s390x/' 33 '20190702+deb10u6/images/generic/kernel.debian'), 34 'd411d17c39ae7ad38d27534376cbe88b68b403c325739364122c2e6f1537e818') 35 36 ASSET_DEBIAN_INITRD = Asset( 37 ('https://snapshot.debian.org/archive/debian/' 38 '20201126T092837Z/dists/buster/main/installer-s390x/' 39 '20190702+deb10u6/images/generic/initrd.debian'), 40 '836bbd0fe6a5ca81274c28c2b063ea315ce1868660866e9b60180c575fef9fd5') 41 42 ASSET_FEDORA_KERNEL = Asset( 43 ('https://archives.fedoraproject.org/pub/archive' 44 '/fedora-secondary/releases/31/Server/s390x/os' 45 '/images/kernel.img'), 46 '480859574f3f44caa6cd35c62d70e1ac0609134e22ce2a954bbed9b110c06e0b') 47 48 def pxelinux_launch(self, pl_name='default', extra_opts=None): 49 self.require_netdev('user') 50 self.set_machine('s390-ccw-virtio') 51 52 debian_kernel = self.ASSET_DEBIAN_KERNEL.fetch() 53 debian_initrd = self.ASSET_DEBIAN_INITRD.fetch() 54 fedora_kernel = self.ASSET_FEDORA_KERNEL.fetch() 55 56 # Prepare a folder for the TFTP "server": 57 tftpdir = self.scratch_file('tftp') 58 shutil.rmtree(tftpdir, ignore_errors=True) # Remove stale stuff 59 os.mkdir(tftpdir) 60 shutil.copy(debian_kernel, os.path.join(tftpdir, 'kernel.debian')) 61 shutil.copy(debian_initrd, os.path.join(tftpdir, 'initrd.debian')) 62 shutil.copy(fedora_kernel, os.path.join(tftpdir, 'kernel.fedora')) 63 64 pxelinuxdir = self.scratch_file('tftp', 'pxelinux.cfg') 65 os.mkdir(pxelinuxdir) 66 67 cfg_fname = self.scratch_file('tftp', 'pxelinux.cfg', pl_name) 68 with open(cfg_fname, 'w', encoding='utf-8') as f: 69 f.write(pxelinux_cfg_contents) 70 71 virtio_net_dev = 'virtio-net-ccw,netdev=n1,bootindex=1' 72 if extra_opts: 73 virtio_net_dev += ',' + extra_opts 74 75 self.vm.add_args('-m', '384', 76 '-netdev', f'user,id=n1,tftp={tftpdir}', 77 '-device', virtio_net_dev) 78 self.vm.set_console() 79 self.vm.launch() 80 81 82 def test_default(self): 83 self.pxelinux_launch() 84 # The kernel prints its arguments to the console, so we can use 85 # this to check whether the kernel parameters are correctly handled: 86 wait_for_console_pattern(self, 'testoption=teststring') 87 # Now also check that we've successfully loaded the initrd: 88 wait_for_console_pattern(self, 'Unpacking initramfs...') 89 wait_for_console_pattern(self, 'Run /init as init process') 90 91 def test_mac(self): 92 self.pxelinux_launch(pl_name='01-02-ca-fe-ba-be-42', 93 extra_opts='mac=02:ca:fe:ba:be:42,loadparm=3') 94 wait_for_console_pattern(self, 'Linux version 5.3.7-301.fc31.s390x') 95 96 def test_uuid(self): 97 # Also add a non-bootable disk to check the fallback to network boot: 98 self.vm.add_args('-blockdev', 'null-co,size=65536,node-name=d1', 99 '-device', 'virtio-blk,drive=d1,bootindex=0,loadparm=1', 100 '-uuid', '550e8400-e29b-11d4-a716-446655441234') 101 self.pxelinux_launch(pl_name='550e8400-e29b-11d4-a716-446655441234') 102 wait_for_console_pattern(self, 'Debian 4.19.146-1 (2020-09-17)') 103 104 def test_ip(self): 105 self.vm.add_args('-M', 'loadparm=3') 106 self.pxelinux_launch(pl_name='0A00020F') 107 wait_for_console_pattern(self, 'Linux version 5.3.7-301.fc31.s390x') 108 109 def test_menu(self): 110 self.vm.add_args('-boot', 'menu=on,splash-time=10') 111 self.pxelinux_launch(pl_name='0A00') 112 wait_for_console_pattern(self, '[1] Nonexisting') 113 wait_for_console_pattern(self, '[2] Debian') 114 wait_for_console_pattern(self, '[3] Fedora') 115 wait_for_console_pattern(self, 'Debian 4.19.146-1 (2020-09-17)') 116 117 118if __name__ == '__main__': 119 QemuSystemTest.main() 120