🏡 index : quine-global/quine-anaconda-webui.git

#!/usr/bin/python3 -u
#
# Copyright (C) 2022 Red Hat, Inc.
# SPDX-License-Identifier: LGPL-2.1-or-later

import argparse
import os
import signal
import subprocess

from anacondalib import INSTALLER_VM_MEMORY_MB
from machine_install import VirtInstallMachine


def cmd_cli():
    parser = argparse.ArgumentParser(description="Run a VM image until SIGTERM or SIGINT")
    parser.add_argument("image", help="Image name")
    parser.add_argument("--rsync", help="Rsync development files over on startup", action='store_true')
    parser.add_argument("--host", help="Hostname to rsync", default='test-updates')
    parser.add_argument("--bios", help="Start the VM with BIOS firmware (UEFI is the default)", action='store_true')
    parser.add_argument("--kickstart", help="Kickstart file name from test/kickstarts/", dest="kickstart_file_name")
    parser.add_argument("--pause-at-summary", help="Pause automated kickstart install at the review screen",
                        action='store_true', dest="pause_at_summary")
    parser.add_argument("--remote-pin", help="PIN for accessing the webui. Blank value defaults to inst.webui.remote.noauth",
                        dest="remote_pin")
    parser.add_argument("--payload", help="Payload type (liveimg or dnf)", default="liveimg",
                        choices=("liveimg", "dnf"), dest="payload_type")
    def positive_int(value):
        value = int(value)
        if value <= 0:
            raise argparse.ArgumentTypeError("must be a positive integer")
        return value

    parser.add_argument("--add-disk", help="Attach a virtual disk with the given size in GiB (e.g., --add-disk 15)",
                        type=positive_int, metavar="SIZE", dest="add_disk")
    args = parser.parse_args()

    if args.bios:
        os.environ["TEST_FIRMWARE"] = "bios"
    extra_disks = [args.add_disk] if args.add_disk is not None else []
    machine = VirtInstallMachine(image=args.image, memory_mb=INSTALLER_VM_MEMORY_MB,
                                 kickstart_file_name=args.kickstart_file_name,
                                 pause_at_summary=args.pause_at_summary, remote_pin=args.remote_pin,
                                 payload_type=args.payload_type, extra_disks=extra_disks)
    try:
        machine.start()

        live_os = machine.is_live()
        if not live_os:
            print("You can connect to the VM in the following ways:")
            # print ssh command
            ssh_args = f"-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p {machine.ssh_port}"
            print(
                f"ssh -o ControlPath={machine.ssh_control_path} {ssh_args} {machine.ssh_user}@{machine.ssh_address}"
            )
            # print Cockpit web address
            print(
                f"https://{machine.web_address}:{machine.web_port}/cockpit/@localhost/anaconda-webui/index.html"
            )

            # rsync development files over so /usr/local/share/cockpit is created with a development version
            if args.rsync:
                # Rather annoying the node_modules path needs to be explicitly added for webpack
                subprocess.check_call(["npm", "run", "build"], env={'RSYNC': args.host, "PATH": "/usr/bin/:node_modules/.bin"})
        else:
            print("You can start the installer by running the following command on the terminal in the test VM:")
            print(
                f"liveinst --graphical --updates=http://10.0.2.2:{machine.http_install_port}/updates.img"
            )

        # print marker that the VM is ready; tests can poll for this to wait for the VM
        print("RUNNING")

        signal.signal(signal.SIGTERM, lambda _, frame: machine.stop())
        signal.pause()
    except KeyboardInterrupt:
        pass
    finally:
        # Ignore additional Ctrl+C while cleaning up to avoid leaving disks behind.
        previous_sigint = signal.getsignal(signal.SIGINT)
        signal.signal(signal.SIGINT, signal.SIG_IGN)
        try:
            machine.stop()
        finally:
            # Restore previous SIGINT handler.
            signal.signal(signal.SIGINT, previous_sigint)


# This can be used as helper program for tests not written in Python: Run given
# image name until SIGTERM or SIGINT; the iso must exist in test/images/;
# $ webui_testvm.py fedora-rawhide-boot
if __name__ == "__main__":
    cmd_cli()