mirror of
				https://github.com/vyos/vyos-build.git
				synced 2025-10-01 20:28:40 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			591 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			591 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env python3
 | 
						|
#
 | 
						|
# Copyright (C) 2019-2021, VyOS maintainers and contributors
 | 
						|
#
 | 
						|
# This program is free software; you can redistribute it and/or modify
 | 
						|
# it under the terms of the GNU General Public License version 2 or later as
 | 
						|
# published by the Free Software Foundation.
 | 
						|
#
 | 
						|
# 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 <http://www.gnu.org/licenses/>.
 | 
						|
#
 | 
						|
# File: check-qemu-install
 | 
						|
# Purpose:
 | 
						|
#  This script installs a system on a emulated qemu host to verify
 | 
						|
#  that the iso produced is installable and boots.
 | 
						|
#  after the iso is booted from disk it also tries to execute the
 | 
						|
#  vyos-smoketest script to verify checks there.
 | 
						|
#
 | 
						|
#  For now it will not fail on failed smoketest but will fail on
 | 
						|
#  install and boot errors.
 | 
						|
#  Arguments:
 | 
						|
#    iso            iso image to install
 | 
						|
#    [disk]         disk filename to use, if none is provided it
 | 
						|
#                   is autogenerated
 | 
						|
#    [--keep]       Keep the disk image after completion
 | 
						|
#    [--logfile]    name of logfile to save, defaulting to stdout
 | 
						|
#    [--silent]     only print on errors
 | 
						|
#    [--debug]      print all communication with the device
 | 
						|
 | 
						|
import pexpect
 | 
						|
import sys
 | 
						|
import os
 | 
						|
import time
 | 
						|
import argparse
 | 
						|
import subprocess
 | 
						|
import random
 | 
						|
import traceback
 | 
						|
import logging
 | 
						|
import re
 | 
						|
import json
 | 
						|
 | 
						|
from io import BytesIO
 | 
						|
from io import StringIO
 | 
						|
from datetime import datetime
 | 
						|
 | 
						|
EXCEPTION = 0
 | 
						|
now = datetime.now()
 | 
						|
 | 
						|
parser = argparse.ArgumentParser(description='Install and start a test VyOS vm.')
 | 
						|
parser.add_argument('iso', help='ISO file to install')
 | 
						|
parser.add_argument('disk', help='name of disk image file', nargs='?',
 | 
						|
                            default='testinstall-{}-{}.img'.format(now.strftime('%Y%m%d-%H%M%S'),
 | 
						|
                                                                   "%04x" % random.randint(0,65535)))
 | 
						|
parser.add_argument('--keep', help='Do not remove disk-image after installation',
 | 
						|
                              action='store_true', default=False)
 | 
						|
parser.add_argument('--silent', help='Do not show output on stdout unless an error has occured',
 | 
						|
                              action='store_true', default=False)
 | 
						|
parser.add_argument('--debug', help='Send all debug output to stdout',
 | 
						|
                               action='store_true', default=False)
 | 
						|
parser.add_argument('--logfile', help='Log to file')
 | 
						|
parser.add_argument('--uefi', help='Boot using UEFI', action='store_true', default=False)
 | 
						|
parser.add_argument('--raid', help='Perform a RAID-1 install', action='store_true', default=False)
 | 
						|
parser.add_argument('--no-kvm', help='Disable use of kvm', action='store_true', default=False)
 | 
						|
parser.add_argument('--configd', help='Execute testsuite with config daemon', action='store_true',
 | 
						|
				default=False)
 | 
						|
parser.add_argument('--no-interfaces', help='Execute testsuite without interface tests to save time',
 | 
						|
                action='store_true', default=False)
 | 
						|
parser.add_argument('--configtest', help='Execute load/commit config tests',
 | 
						|
				action='store_true', default=False)
 | 
						|
 | 
						|
args = parser.parse_args()
 | 
						|
 | 
						|
with open('data/defaults.json') as f:
 | 
						|
    vyos_defaults = json.load(f)
 | 
						|
 | 
						|
class StreamToLogger(object):
 | 
						|
    """
 | 
						|
    Fake file-like stream object that redirects writes to a logger instance.
 | 
						|
    """
 | 
						|
    def __init__(self, logger, log_level=logging.INFO):
 | 
						|
        self.logger = logger
 | 
						|
        self.log_level = log_level
 | 
						|
        self.linebuf = b''
 | 
						|
        self.ansi_escape = re.compile(r'\x1B[@-_][0-?]*[ -/]*[@-~]')
 | 
						|
 | 
						|
    def write(self, buf):
 | 
						|
        self.linebuf += buf
 | 
						|
        #print('.')
 | 
						|
        while b'\n' in self.linebuf:
 | 
						|
            f = self.linebuf.split(b'\n', 1)
 | 
						|
            if len(f) == 2:
 | 
						|
                self.logger.debug(self.ansi_escape.sub('', f[0].decode(errors="replace").rstrip()))
 | 
						|
                self.linebuf = f[1]
 | 
						|
            #print(f)
 | 
						|
 | 
						|
 | 
						|
    def flush(self):
 | 
						|
        pass
 | 
						|
 | 
						|
def get_half_cpus():
 | 
						|
    """ return 1/2 of the numbers of available CPUs """
 | 
						|
    cpu = os.cpu_count()
 | 
						|
    if cpu > 1:
 | 
						|
        cpu /= 2
 | 
						|
    return int(cpu)
 | 
						|
 | 
						|
def get_qemu_cmd(name, enable_kvm, enable_uefi, disk_img, raid=None, iso_img=None):
 | 
						|
    kvm = "-enable-kvm"
 | 
						|
    cpu = "-cpu host"
 | 
						|
    if not enable_kvm:
 | 
						|
        kvm = "--no-kvm"
 | 
						|
        cpu = ""
 | 
						|
 | 
						|
    uefi = ""
 | 
						|
    uuid = "f48b60b2-e6ad-49ef-9d09-4245d0585e52"
 | 
						|
    if enable_uefi:
 | 
						|
        uefi = "-bios /usr/share/OVMF/OVMF_CODE.fd"
 | 
						|
        name = f"{name}-UEFI"
 | 
						|
        uuid = "d27cf29e-4419-4407-8f82-dc73d1acd184"
 | 
						|
 | 
						|
    cdrom = ""
 | 
						|
    if iso_img:
 | 
						|
        cdrom = f"-boot d -cdrom {iso_img}"
 | 
						|
 | 
						|
    # test using half of the available CPUs on the system
 | 
						|
    cpucount = get_half_cpus()
 | 
						|
 | 
						|
    macbase = '52:54:00:00:00'
 | 
						|
    cmd = f'qemu-system-x86_64 \
 | 
						|
        -name "{name}" \
 | 
						|
        -smp sockets=1,cpus={cpucount},cores=1 \
 | 
						|
        -cpu host \
 | 
						|
        {uefi} \
 | 
						|
        -m 1G \
 | 
						|
        -vga none \
 | 
						|
        -netdev user,id=n0 -device virtio-net-pci,netdev=n0,mac={macbase}:00,romfile="" \
 | 
						|
        -netdev user,id=n1 -device virtio-net-pci,netdev=n1,mac={macbase}:01,romfile="" \
 | 
						|
        -netdev user,id=n2 -device virtio-net-pci,netdev=n2,mac={macbase}:02,romfile="" \
 | 
						|
        -netdev user,id=n3 -device virtio-net-pci,netdev=n3,mac={macbase}:03,romfile="" \
 | 
						|
        -netdev user,id=n4 -device virtio-net-pci,netdev=n4,mac={macbase}:04,romfile="" \
 | 
						|
        -netdev user,id=n5 -device virtio-net-pci,netdev=n5,mac={macbase}:05,romfile="" \
 | 
						|
        -netdev user,id=n6 -device virtio-net-pci,netdev=n6,mac={macbase}:06,romfile="" \
 | 
						|
        -netdev user,id=n7 -device virtio-net-pci,netdev=n7,mac={macbase}:07,romfile="" \
 | 
						|
        -machine accel=kvm \
 | 
						|
        -uuid {uuid} \
 | 
						|
        -nographic {cpu} {cdrom} {kvm} \
 | 
						|
        -device virtio-scsi-pci,id=scsi0 \
 | 
						|
        -drive format=raw,file={disk_img},if=none,media=disk,id=drive-hd1,readonly=off \
 | 
						|
        -device scsi-hd,bus=scsi0.0,drive=drive-hd1,id=hd1,bootindex=1'
 | 
						|
 | 
						|
    if raid:
 | 
						|
        cmd += f' -drive format=raw,file={raid},if=none,media=disk,id=drive-hd2,readonly=off \
 | 
						|
                  -device scsi-hd,bus=scsi0.0,drive=drive-hd2,id=hd2,bootindex=2'
 | 
						|
 | 
						|
    return cmd
 | 
						|
 | 
						|
def shutdownVM(c, log, message=''):
 | 
						|
    #################################################
 | 
						|
    # Powering off system
 | 
						|
    #################################################
 | 
						|
    if message:
 | 
						|
        log.info(message)
 | 
						|
 | 
						|
    c.sendline('poweroff now')
 | 
						|
    log.info('Shutting down virtual machine')
 | 
						|
    for i in range(30):
 | 
						|
        log.info('Waiting for shutdown...')
 | 
						|
        if not c.isalive():
 | 
						|
            log.info('VM is shut down!')
 | 
						|
            break
 | 
						|
        time.sleep(10)
 | 
						|
    else:
 | 
						|
        tmp = 'VM Did not shut down after 300sec'
 | 
						|
        log.error(tmp)
 | 
						|
        raise Exception(tmp)
 | 
						|
 | 
						|
def loginVM(c, log):
 | 
						|
    log.info('Waiting for login prompt')
 | 
						|
    c.expect('[Ll]ogin:', timeout=600)
 | 
						|
    c.sendline(default_user)
 | 
						|
    c.expect('[Pp]assword:')
 | 
						|
    c.sendline(default_password)
 | 
						|
    c.expect(op_mode_prompt)
 | 
						|
    log.info('Logged in!')
 | 
						|
 | 
						|
# Setting up logger
 | 
						|
log = logging.getLogger()
 | 
						|
log.setLevel(logging.DEBUG)
 | 
						|
 | 
						|
stl = StreamToLogger(log)
 | 
						|
formatter = logging.Formatter('%(levelname)5s - %(message)s')
 | 
						|
 | 
						|
handler = logging.StreamHandler(sys.stdout)
 | 
						|
if args.silent:
 | 
						|
    handler.setLevel(logging.ERROR)
 | 
						|
elif args.debug:
 | 
						|
    handler.setLevel(logging.DEBUG)
 | 
						|
else:
 | 
						|
    handler.setLevel(logging.INFO)
 | 
						|
 | 
						|
handler.setFormatter(formatter)
 | 
						|
log.addHandler(handler)
 | 
						|
 | 
						|
if args.logfile:
 | 
						|
    filehandler = logging.FileHandler(args.logfile)
 | 
						|
    filehandler.setLevel(logging.DEBUG)
 | 
						|
    filehandler.setFormatter(formatter)
 | 
						|
    log.addHandler(filehandler)
 | 
						|
 | 
						|
if args.silent:
 | 
						|
    output = BytesIO()
 | 
						|
else:
 | 
						|
    output = sys.stdout.buffer
 | 
						|
 | 
						|
if not os.path.isfile(args.iso):
 | 
						|
    log.error('Unable to find iso image to install')
 | 
						|
    sys.exit(1)
 | 
						|
 | 
						|
if args.no_kvm:
 | 
						|
    log.error('KVM forced off by command line')
 | 
						|
    kvm=False
 | 
						|
elif not os.path.exists('/dev/kvm'):
 | 
						|
    log.error('KVM not enabled on host, proceeding with software emulation')
 | 
						|
    kvm=False
 | 
						|
else:
 | 
						|
    kvm=True
 | 
						|
 | 
						|
# Creating diskimage!!
 | 
						|
diskname_raid = None
 | 
						|
def gen_disk(name):
 | 
						|
    if not os.path.isfile(name):
 | 
						|
        log.info(f'Creating Disk image {name}')
 | 
						|
        c = subprocess.check_output(['qemu-img', 'create', name, '1G'])
 | 
						|
        log.debug(c.decode())
 | 
						|
    else:
 | 
						|
        log.info(f'Diskimage "{name}" already exists, using the existing one.')
 | 
						|
 | 
						|
if args.raid:
 | 
						|
    filename, ext = os.path.splitext(args.disk)
 | 
						|
    diskname_raid = f'{filename}_disk1{ext}'
 | 
						|
    # change primary diskname, too
 | 
						|
    args.disk = f'{filename}_disk0{ext}'
 | 
						|
    gen_disk(diskname_raid)
 | 
						|
 | 
						|
# must be called after the raid disk as args.disk name is altered in the RAID path
 | 
						|
gen_disk(args.disk)
 | 
						|
 | 
						|
test_timeout = 3 *3600 # 3 hours (in seconds)
 | 
						|
try:
 | 
						|
    #################################################
 | 
						|
    # Installing image to disk
 | 
						|
    #################################################
 | 
						|
    log.info('Installing system')
 | 
						|
    cmd = get_qemu_cmd('TESTVM', kvm, args.uefi, args.disk, diskname_raid, args.iso)
 | 
						|
    log.debug(f'Executing command: {cmd}')
 | 
						|
    c = pexpect.spawn(cmd, logfile=stl, timeout=60)
 | 
						|
 | 
						|
    #################################################
 | 
						|
    # Logging into VyOS system
 | 
						|
    #################################################
 | 
						|
    op_mode_prompt = r'vyos@vyos:~\$'
 | 
						|
    cfg_mode_prompt = r'vyos@vyos#'
 | 
						|
    default_user = 'vyos'
 | 
						|
    default_password = 'vyos'
 | 
						|
 | 
						|
    try:
 | 
						|
        c.expect('Automatic boot in', timeout=10)
 | 
						|
        c.sendline('')
 | 
						|
    except pexpect.TIMEOUT:
 | 
						|
        log.warning('Did not find GRUB countdown window, ignoring')
 | 
						|
 | 
						|
    loginVM(c, log)
 | 
						|
 | 
						|
    #################################################
 | 
						|
    # Installing into VyOS system
 | 
						|
    #################################################
 | 
						|
    log.info('Starting installer')
 | 
						|
    c.sendline('install image')
 | 
						|
    c.expect('\nWould you like to continue?.*:')
 | 
						|
    c.sendline('yes')
 | 
						|
 | 
						|
    if args.raid:
 | 
						|
        c.expect('\nWould you like to configure RAID-1 mirroring on them?.*:')
 | 
						|
        c.sendline('yes')
 | 
						|
        # Erase all data on disks
 | 
						|
        c.expect('\nAre you sure you want to do this?.*:')
 | 
						|
        c.sendline('yes')
 | 
						|
    else:
 | 
						|
        log.info('Partitioning disk')
 | 
						|
        c.expect('\nPartition.*:')
 | 
						|
        c.sendline('')
 | 
						|
        c.expect('\nInstall the image on.*:')
 | 
						|
        c.sendline('')
 | 
						|
        c.expect(r'\nContinue\?.*:')
 | 
						|
        c.sendline('Yes')
 | 
						|
        c.expect('\nHow big of a root partition should I create?.*:')
 | 
						|
        c.sendline('')
 | 
						|
 | 
						|
    log.info('Disk(s) partitioned, installing...')
 | 
						|
    c.expect('\nWhat would you like to name this image?.*:', timeout=600)
 | 
						|
    c.sendline('')
 | 
						|
    log.info('Copying files')
 | 
						|
    c.expect('\nWhich one should I copy to.*:', timeout=600)
 | 
						|
    c.sendline('')
 | 
						|
    log.info('Files Copied!')
 | 
						|
    c.expect('\nEnter password for user.*:')
 | 
						|
    c.sendline(default_user)
 | 
						|
    c.expect('\nRetype password for user.*:')
 | 
						|
    c.sendline(default_password)
 | 
						|
 | 
						|
    if not args.raid:
 | 
						|
        c.expect('\nWhich drive should GRUB modify the boot partition on.*:')
 | 
						|
        c.sendline('')
 | 
						|
        c.expect(op_mode_prompt)
 | 
						|
 | 
						|
    log.info('system installed, shutting down')
 | 
						|
 | 
						|
    #################################################
 | 
						|
    # Powering down installer
 | 
						|
    #################################################
 | 
						|
    shutdownVM(c, log, 'Shutting down installation system')
 | 
						|
    c.close()
 | 
						|
 | 
						|
    #################################################
 | 
						|
    # Booting installed system
 | 
						|
    #################################################
 | 
						|
    log.info('Booting installed system')
 | 
						|
    cmd = get_qemu_cmd('TESTVM', kvm, args.uefi, args.disk, diskname_raid)
 | 
						|
    log.debug(f'Executing command: {cmd}')
 | 
						|
    c = pexpect.spawn(cmd, logfile=stl)
 | 
						|
 | 
						|
    #################################################
 | 
						|
    # Logging into VyOS system
 | 
						|
    #################################################
 | 
						|
    try:
 | 
						|
        c.expect('The highlighted entry will be executed automatically in', timeout=10)
 | 
						|
        c.sendline('')
 | 
						|
    except pexpect.TIMEOUT:
 | 
						|
        log.warning('Did not find GRUB countdown window, ignoring')
 | 
						|
 | 
						|
    loginVM(c, log)
 | 
						|
 | 
						|
    ################################################
 | 
						|
    # Always load the WiFi simulation module
 | 
						|
    ################################################
 | 
						|
    c.sendline('sudo modprobe mac80211_hwsim')
 | 
						|
    c.expect(op_mode_prompt)
 | 
						|
 | 
						|
    #################################################
 | 
						|
    # Start/stop config daemon
 | 
						|
    #################################################
 | 
						|
    if args.configd:
 | 
						|
        c.sendline('sudo systemctl start vyos-configd.service &> /dev/null')
 | 
						|
    else:
 | 
						|
        c.sendline('sudo systemctl stop vyos-configd.service &> /dev/null')
 | 
						|
    c.expect(op_mode_prompt)
 | 
						|
 | 
						|
    #################################################
 | 
						|
    # Basic Configmode/Opmode switch
 | 
						|
    #################################################
 | 
						|
    log.info('Basic CLI configuration mode test')
 | 
						|
    c.sendline('configure')
 | 
						|
    c.expect(cfg_mode_prompt)
 | 
						|
    c.sendline('exit')
 | 
						|
    c.expect(op_mode_prompt)
 | 
						|
    c.sendline('show version')
 | 
						|
    c.expect(op_mode_prompt)
 | 
						|
    c.sendline('show version kernel')
 | 
						|
    c.expect(f'{vyos_defaults["kernel_version"]}-{vyos_defaults["kernel_flavor"]}')
 | 
						|
    c.expect(op_mode_prompt)
 | 
						|
    c.sendline('show version frr')
 | 
						|
    c.expect(op_mode_prompt)
 | 
						|
    c.sendline('show interfaces')
 | 
						|
    c.expect(op_mode_prompt)
 | 
						|
 | 
						|
    #################################################
 | 
						|
    # Executing test-suite
 | 
						|
    #################################################
 | 
						|
    if args.raid:
 | 
						|
        # Verify RAID subsystem - by deleting a disk and re-create the array
 | 
						|
        # from scratch
 | 
						|
        c.sendline('cat /proc/mdstat')
 | 
						|
        c.expect(op_mode_prompt)
 | 
						|
 | 
						|
        shutdownVM(c, log, f'Shutdown VM and start with empty RAID member "{args.disk}"')
 | 
						|
 | 
						|
        if os.path.exists(args.disk):
 | 
						|
            os.unlink(args.disk)
 | 
						|
 | 
						|
        gen_disk(args.disk)
 | 
						|
 | 
						|
        #################################################
 | 
						|
        # Booting RAID-1 system with one missing disk
 | 
						|
        #################################################
 | 
						|
        log.info('Booting RAID-1 system')
 | 
						|
        cmd = get_qemu_cmd('TESTVM', kvm, args.uefi, args.disk, diskname_raid)
 | 
						|
 | 
						|
        # We need to swap boot indexes to boot from second harddisk so we can
 | 
						|
        # recreate the RAID on the first disk
 | 
						|
        cmd = cmd.replace('bootindex=1', 'bootindex=X')
 | 
						|
        cmd = cmd.replace('bootindex=2', 'bootindex=1')
 | 
						|
        cmd = cmd.replace('bootindex=X', 'bootindex=2')
 | 
						|
 | 
						|
        log.debug(f'Executing command: {cmd}')
 | 
						|
        c = pexpect.spawn(cmd, logfile=stl)
 | 
						|
 | 
						|
 | 
						|
        #################################################
 | 
						|
        # Logging into VyOS system
 | 
						|
        #################################################
 | 
						|
        try:
 | 
						|
            c.expect('The highlighted entry will be executed automatically in', timeout=10)
 | 
						|
            c.sendline('')
 | 
						|
        except pexpect.TIMEOUT:
 | 
						|
            log.warning('Did not find GRUB countdown window, ignoring')
 | 
						|
 | 
						|
        loginVM(c, log)
 | 
						|
 | 
						|
        c.sendline('cat /proc/mdstat')
 | 
						|
        c.expect(op_mode_prompt)
 | 
						|
 | 
						|
        log.info('Re-format new RAID member')
 | 
						|
        c.sendline('format disk sda like sdb')
 | 
						|
        c.sendline('yes')
 | 
						|
        c.expect(op_mode_prompt)
 | 
						|
 | 
						|
        log.info('Add member to RAID1 (md0)')
 | 
						|
        c.sendline('add raid md0 member sda1')
 | 
						|
        c.expect(op_mode_prompt)
 | 
						|
 | 
						|
        log.info('Now we need to wait for re-sync to complete')
 | 
						|
 | 
						|
        start_time = time.time()
 | 
						|
        timeout = 60
 | 
						|
        while True:
 | 
						|
            if (start_time + timeout) < time.time():
 | 
						|
                break
 | 
						|
            c.sendline('cat /proc/mdstat')
 | 
						|
            c.expect(op_mode_prompt)
 | 
						|
            time.sleep(20)
 | 
						|
 | 
						|
        # Reboot system with new primary RAID1 disk
 | 
						|
        shutdownVM(c, log, f'Shutdown VM and start from recovered RAID member "{args.disk}"')
 | 
						|
 | 
						|
        log.info('Booting RAID-1 system')
 | 
						|
        cmd = get_qemu_cmd('TESTVM', kvm, args.uefi, args.disk, diskname_raid)
 | 
						|
        log.debug(f'Executing command: {cmd}')
 | 
						|
        c = pexpect.spawn(cmd, logfile=stl)
 | 
						|
 | 
						|
        loginVM(c, log)
 | 
						|
 | 
						|
        c.sendline('cat /proc/mdstat')
 | 
						|
        c.expect(op_mode_prompt)
 | 
						|
 | 
						|
    elif not args.configtest:
 | 
						|
        # run default smoketest suite
 | 
						|
        if args.no_interfaces:
 | 
						|
            # remove interface tests as they consume a lot of time
 | 
						|
            c.sendline('sudo rm -f /usr/libexec/vyos/tests/smoke/cli/test_interfaces_*')
 | 
						|
            c.expect(op_mode_prompt)
 | 
						|
 | 
						|
        log.info('Executing VyOS smoketests')
 | 
						|
        c.sendline('/usr/bin/vyos-smoketest')
 | 
						|
        i = c.expect(['\n +Invalid command:', '\n +Set failed',
 | 
						|
                      'No such file or directory', r'\n\S+@\S+[$#]'], timeout=test_timeout)
 | 
						|
 | 
						|
        if i == 0:
 | 
						|
            raise Exception('Invalid command detected')
 | 
						|
        elif i == 1:
 | 
						|
            raise Exception('Set syntax failed :/')
 | 
						|
        elif i == 2:
 | 
						|
            tmp = '(W)hy (T)he (F)ace? VyOS smoketest not found!'
 | 
						|
            log.error(tmp)
 | 
						|
            raise Exception(tmp)
 | 
						|
 | 
						|
        c.sendline('echo EXITCODE:$\x16?')
 | 
						|
        i = c.expect(['EXITCODE:0', 'EXITCODE:\d+'])
 | 
						|
        if i == 0:
 | 
						|
            log.info('Smoketest finished successfully!')
 | 
						|
            pass
 | 
						|
        elif i == 1:
 | 
						|
            log.error('Smoketest failed :/')
 | 
						|
            raise Exception("Smoketest-failed, please look into debug output")
 | 
						|
 | 
						|
    # else, run configtest suite
 | 
						|
    else:
 | 
						|
        log.info('Adding a legacy WireGuard default keypair for migrations')
 | 
						|
        c.sendline('sudo mkdir -p /config/auth/wireguard/default')
 | 
						|
        c.expect(op_mode_prompt)
 | 
						|
        c.sendline('echo "aGx+fvW916Ej7QRnBbW3QMoldhNv1u95/WHz45zDmF0=" | sudo tee /config/auth/wireguard/default/private.key')
 | 
						|
        c.expect(op_mode_prompt)
 | 
						|
        c.sendline('echo "x39C77eavJNpvYbNzPSG3n1D68rHYei6q3AEBEyL1z8=" | sudo tee /config/auth/wireguard/default/public.key')
 | 
						|
        c.expect(op_mode_prompt)
 | 
						|
 | 
						|
        log.info('Generating some OpenVPN keys')
 | 
						|
        subject = '/C=DE/ST=BY/O=VyOS/localityName=Cloud/commonName=vyos/' \
 | 
						|
                  'organizationalUnitName=VyOS/emailAddress=maintainers@vyos.io/'
 | 
						|
        ca_cert  = '/config/auth/ovpn_test_ca.pem'
 | 
						|
        ssl_cert = '/config/auth/ovpn_test_server.pem'
 | 
						|
        ssl_key  = '/config/auth/ovpn_test_server.key'
 | 
						|
        dh_pem   = '/config/auth/ovpn_test_dh.pem'
 | 
						|
        s2s_key  = '/config/auth/ovpn_test_site2site.key'
 | 
						|
        auth_key = '/config/auth/ovpn_test_tls_auth.key'
 | 
						|
 | 
						|
        c.sendline(f'openssl req -newkey rsa:4096 -new -nodes -x509 -days 3650 '\
 | 
						|
                   f'-keyout {ssl_key} -out {ssl_cert} -subj {subject}')
 | 
						|
        c.expect(op_mode_prompt, timeout=600)
 | 
						|
        c.sendline(f'openssl req -new -x509 -key {ssl_key} -out {ca_cert} -subj {subject}')
 | 
						|
        c.expect(op_mode_prompt, timeout=600)
 | 
						|
        c.sendline(f'openssl dhparam -out {dh_pem} 2048')
 | 
						|
        c.expect(op_mode_prompt, timeout=600)
 | 
						|
        c.sendline(f'openvpn --genkey secret {s2s_key}')
 | 
						|
        c.expect(op_mode_prompt)
 | 
						|
        c.sendline(f'openvpn --genkey secret {auth_key}')
 | 
						|
        c.expect(op_mode_prompt)
 | 
						|
 | 
						|
        script_file = '/config/scripts/vyos-foo-update.script'
 | 
						|
        c.sendline(f'echo "#!/bin/sh" > {script_file}; chmod 775 {script_file}')
 | 
						|
        c.expect(op_mode_prompt)
 | 
						|
 | 
						|
        for file in [ca_cert, ssl_cert, ssl_key, dh_pem, s2s_key, auth_key]:
 | 
						|
            c.sendline(f'sudo chown openvpn:openvpn {file}')
 | 
						|
            c.expect(op_mode_prompt)
 | 
						|
 | 
						|
        log.info('Executing load config tests')
 | 
						|
        c.sendline('/usr/bin/vyos-configtest')
 | 
						|
        i = c.expect(['\n +Invalid command:', 'No such file or directory',
 | 
						|
                     r'\n\S+@\S+[$#]'], timeout=test_timeout)
 | 
						|
 | 
						|
        if i==0:
 | 
						|
            raise Exception('Invalid command detected')
 | 
						|
        elif i==1:
 | 
						|
            tmp = '(W)hy (T)he (F)ace? VyOS smoketest not found!'
 | 
						|
            log.error(tmp)
 | 
						|
            raise Exception(tmp)
 | 
						|
 | 
						|
        c.sendline('echo EXITCODE:$\x16?')
 | 
						|
        i = c.expect(['EXITCODE:0', 'EXITCODE:\d+'])
 | 
						|
        if i == 0:
 | 
						|
            log.info('Configtest finished successfully!')
 | 
						|
            pass
 | 
						|
        elif i == 1:
 | 
						|
            tmp = 'Configtest failed :/ - check debug output'
 | 
						|
            log.error(tmp)
 | 
						|
            raise Exception(tmp)
 | 
						|
 | 
						|
    shutdownVM(c, log, 'Powering off system')
 | 
						|
    c.close()
 | 
						|
 | 
						|
except pexpect.exceptions.TIMEOUT:
 | 
						|
    log.error('Timeout waiting for VyOS system')
 | 
						|
    log.error(traceback.format_exc())
 | 
						|
    EXCEPTION = 1
 | 
						|
 | 
						|
except pexpect.exceptions.ExceptionPexpect:
 | 
						|
    log.error('Exeption while executing QEMU')
 | 
						|
    log.error('Is qemu working on this system?')
 | 
						|
    log.error(traceback.format_exc())
 | 
						|
    EXCEPTION = 1
 | 
						|
 | 
						|
except Exception:
 | 
						|
    log.error('Unknown error occured while VyOS!')
 | 
						|
    traceback.print_exc()
 | 
						|
    EXCEPTION = 1
 | 
						|
 | 
						|
#################################################
 | 
						|
# Cleaning up
 | 
						|
#################################################
 | 
						|
log.info("Cleaning up")
 | 
						|
 | 
						|
if not args.keep:
 | 
						|
    log.info(f'Removing disk file: {args.disk}')
 | 
						|
    try:
 | 
						|
        os.remove(args.disk)
 | 
						|
        if diskname_raid:
 | 
						|
            os.remove(diskname_raid)
 | 
						|
    except Exception:
 | 
						|
        log.error('Exception while removing diskimage!')
 | 
						|
        log.error(traceback.format_exc())
 | 
						|
        EXCEPTION = 1
 | 
						|
 | 
						|
if EXCEPTION:
 | 
						|
    log.error('Hmm... system got an exception while processing.')
 | 
						|
    log.error('The ISO image is not considered usable!')
 | 
						|
    sys.exit(1)
 |