From 838d8450033d80fd285f99979f95107a3c20a60f Mon Sep 17 00:00:00 2001 From: Justin Cormack Date: Mon, 22 May 2017 17:43:43 +0100 Subject: [PATCH] Clean up of Qemu run For all output formats except kernel+initrd, you must use the full path of the file they want to run. Make the options auto detect. Split the uefi option to mean "use uefi firmware" not be ISO specific. Allow specifying a bootable disk image, so we can test disk image output formats with qemu too. Add a test case for qcow2 boot under qemu. Signed-off-by: Justin Cormack --- src/cmd/linuxkit/run_qemu.go | 82 ++++++++++++------- .../000_qemu/000_run_kernel/test.sh | 2 +- .../000_qemu/010_run_iso/test.sh | 2 +- .../000_qemu/020_run_efi/test.sh | 2 +- .../000_qemu/030_run_qcow/test.sh | 25 ++++++ .../000_qemu/030_run_qcow/test.yml | 16 ++++ .../cases/020_kernel/000_config_4.4.x/test.sh | 2 +- test/cases/040_packages/000_sysctl/test.sh | 2 +- 8 files changed, 97 insertions(+), 36 deletions(-) create mode 100644 test/cases/010_platforms/000_qemu/030_run_qcow/test.sh create mode 100644 test/cases/010_platforms/000_qemu/030_run_qcow/test.yml diff --git a/src/cmd/linuxkit/run_qemu.go b/src/cmd/linuxkit/run_qemu.go index 251c86cc9..1ba384e7e 100644 --- a/src/cmd/linuxkit/run_qemu.go +++ b/src/cmd/linuxkit/run_qemu.go @@ -19,7 +19,7 @@ const QemuImg = "linuxkit/qemu:17f052263d63c8a2b641ad91c589edcbb8a18c82" // QemuConfig contains the config for Qemu type QemuConfig struct { - Prefix string + Path string ISO bool UEFI bool Kernel bool @@ -42,18 +42,20 @@ func runQemu(args []string) { invoked := filepath.Base(os.Args[0]) flags := flag.NewFlagSet("qemu", flag.ExitOnError) flags.Usage = func() { - fmt.Printf("USAGE: %s run qemu [options] prefix\n\n", invoked) - fmt.Printf("'prefix' specifies the path to the VM image.\n") + fmt.Printf("USAGE: %s run qemu [options] path\n\n", invoked) + fmt.Printf("'path' specifies the path to the VM image.\n") fmt.Printf("\n") fmt.Printf("Options:\n") flags.PrintDefaults() } - // Determine Flags + // Display flags enableGUI := flags.Bool("gui", false, "Set qemu to use video output instead of stdio") - uefiBoot := flags.Bool("uefi", false, "Set UEFI boot from 'prefix'-efi.iso") - isoBoot := flags.Bool("iso", false, "Set Legacy BIOS boot from 'prefix'.iso") - kernelBoot := flags.Bool("kernel", true, "Set boot using 'prefix'-kernel/-initrd/-cmdline") + + // Boot type; we try to determine automatically + uefiBoot := flags.Bool("uefi", false, "Use UEFI boot") + isoBoot := flags.Bool("iso", false, "Boot image is an ISO") + kernelBoot := flags.Bool("kernel", false, "Boot image is kernel+initrd+cmdline 'path'-kernel/-initrd/-cmdline") // Paths and settings for disks disk := flags.String("disk", "", "Path to disk image to use") @@ -80,19 +82,45 @@ func runQemu(args []string) { remArgs := flags.Args() if len(remArgs) == 0 { - fmt.Println("Please specify the prefix to the image to boot") + fmt.Println("Please specify the path to the image to boot") flags.Usage() os.Exit(1) } - prefix := remArgs[0] + path := remArgs[0] - // Print warning if conflicting UEFI and ISO flags are set - if *uefiBoot && *isoBoot { - log.Warnf("Both -iso and -uefi have been used") + _, err := os.Stat(path) + stat := err == nil + + // if the path does not exist, must be trying to do a kernel boot + if !stat { + _, err = os.Stat(path + "-kernel") + statKernel := err == nil + if statKernel { + *kernelBoot = true + } + // we will error out later if neither found + } else { + // if path ends in .iso they meant an ISO + if strings.HasSuffix(path, ".iso") { + *isoBoot = true + } + // autodetect EFI ISO from our default naming + if strings.HasSuffix(path, "-efi.iso") { + *uefiBoot = true + } + } + + // user not trying to boot off ISO or kernel, so assume booting from a disk image + if !*kernelBoot && !*isoBoot { + if *disk != "" { + // Need to add multiple disk support to do this + log.Fatalf("Cannot boot from disk and specify a disk as well at present") + } + *disk = path } config := QemuConfig{ - Prefix: prefix, + Path: path, ISO: *isoBoot, UEFI: *uefiBoot, Kernel: *kernelBoot, @@ -110,7 +138,6 @@ func runQemu(args []string) { config = discoverBackend(config) - var err error if config.Containerized { err = runQemuContainer(config) } else { @@ -169,10 +196,10 @@ func runQemuLocal(config QemuConfig) error { func runQemuContainer(config QemuConfig) error { var wd string - if filepath.IsAbs(config.Prefix) { + if filepath.IsAbs(config.Path) { // Split the path - wd, config.Prefix = filepath.Split(config.Prefix) - log.Debugf("Prefix: %s", config.Prefix) + wd, config.Path = filepath.Split(config.Path) + log.Debugf("Path: %s", config.Path) } else { var err error wd, err = os.Getwd() @@ -267,33 +294,26 @@ func buildQemuCmdline(config QemuConfig) (QemuConfig, []string) { qemuArgs = append(qemuArgs, "-drive", "file="+config.DiskPath+",format="+config.DiskFormat+",index=0,media=disk") } - // Check flags for iso/uefi boot and if so disable kernel boot if config.ISO { - config.Kernel = false - qemuIsoPath := buildPath(config.Prefix, ".iso") - qemuArgs = append(qemuArgs, "-cdrom", qemuIsoPath) + qemuArgs = append(qemuArgs, "-cdrom", config.Path) + qemuArgs = append(qemuArgs, "-boot", "d") } if config.UEFI { - config.Kernel = false - qemuIsoPath := buildPath(config.Prefix, "-efi.iso") qemuArgs = append(qemuArgs, "-pflash", config.FWPath) - qemuArgs = append(qemuArgs, "-cdrom", qemuIsoPath) - qemuArgs = append(qemuArgs, "-boot", "d") } // build kernel boot config from kernel/initrd/cmdline if config.Kernel { - qemuKernelPath := buildPath(config.Prefix, "-kernel") - qemuInitrdPath := buildPath(config.Prefix, "-initrd.img") + qemuKernelPath := buildPath(config.Path, "-kernel") + qemuInitrdPath := buildPath(config.Path, "-initrd.img") qemuArgs = append(qemuArgs, "-kernel", qemuKernelPath) qemuArgs = append(qemuArgs, "-initrd", qemuInitrdPath) - consoleString, err := ioutil.ReadFile(config.Prefix + "-cmdline") + cmdlineString, err := ioutil.ReadFile(config.Path + "-cmdline") if err != nil { - log.Infof(" %s\n defaulting to console output", err.Error()) - qemuArgs = append(qemuArgs, "-append", "console=ttyS0 console=tty0 page_poison=1") + log.Errorf("Cannot open cmdline file: %v", err) } else { - qemuArgs = append(qemuArgs, "-append", string(consoleString)) + qemuArgs = append(qemuArgs, "-append", string(cmdlineString)) } } diff --git a/test/cases/010_platforms/000_qemu/000_run_kernel/test.sh b/test/cases/010_platforms/000_qemu/000_run_kernel/test.sh index a9ebb6823..d0a4d0730 100644 --- a/test/cases/010_platforms/000_qemu/000_run_kernel/test.sh +++ b/test/cases/010_platforms/000_qemu/000_run_kernel/test.sh @@ -23,5 +23,5 @@ moby build -name "${NAME}" test.yml [ -f "${NAME}-kernel" ] || exit 1 [ -f "${NAME}-initrd.img" ] || exit 1 [ -f "${NAME}-cmdline" ]|| exit 1 -linuxkit run qemu "${NAME}" | grep -q "Welcome to LinuxKit" +linuxkit run qemu -kernel "${NAME}" | grep -q "Welcome to LinuxKit" exit 0 diff --git a/test/cases/010_platforms/000_qemu/010_run_iso/test.sh b/test/cases/010_platforms/000_qemu/010_run_iso/test.sh index b660acda3..5c31b2002 100644 --- a/test/cases/010_platforms/000_qemu/010_run_iso/test.sh +++ b/test/cases/010_platforms/000_qemu/010_run_iso/test.sh @@ -20,5 +20,5 @@ trap clean_up EXIT moby build -name "${NAME}" test.yml [ -f "${NAME}.iso" ] || exit 1 -linuxkit run qemu -iso "${NAME}" | grep -q "Welcome to LinuxKit" +linuxkit run qemu -iso "${NAME}.iso" | grep -q "Welcome to LinuxKit" exit 0 diff --git a/test/cases/010_platforms/000_qemu/020_run_efi/test.sh b/test/cases/010_platforms/000_qemu/020_run_efi/test.sh index 93e885a47..9402d3b1d 100644 --- a/test/cases/010_platforms/000_qemu/020_run_efi/test.sh +++ b/test/cases/010_platforms/000_qemu/020_run_efi/test.sh @@ -27,5 +27,5 @@ fi moby build -name "${NAME}" test.yml [ -f "${NAME}-efi.iso" ] || exit 1 -linuxkit run qemu -uefi "${NAME}" | grep -q "Welcome to LinuxKit" +linuxkit run qemu -iso -uefi "${NAME}-efi.iso" | grep -q "Welcome to LinuxKit" exit 0 diff --git a/test/cases/010_platforms/000_qemu/030_run_qcow/test.sh b/test/cases/010_platforms/000_qemu/030_run_qcow/test.sh new file mode 100644 index 000000000..b76dfe509 --- /dev/null +++ b/test/cases/010_platforms/000_qemu/030_run_qcow/test.sh @@ -0,0 +1,25 @@ +#!/bin/sh +# SUMMARY: Check that qcow2 image boots in qemu +# LABELS: +# AUTHOR: Dave Tucker +# AUTHOR: Justin Cormack + +set -e + +# Source libraries. Uncomment if needed/defined +#. "${RT_LIB}" +. "${RT_PROJECT_ROOT}/_lib/lib.sh" + +NAME=qemu-qcow2 + +clean_up() { + # remove any files, containers, images etc + rm -rf ${NAME}* || true +} + +trap clean_up EXIT + +moby build -name "${NAME}" test.yml +[ -f "${NAME}.qcow2" ] || exit 1 +linuxkit run qemu -disk-format qcow2 "${NAME}.qcow2" | grep -q "Welcome to LinuxKit" +exit 0 diff --git a/test/cases/010_platforms/000_qemu/030_run_qcow/test.yml b/test/cases/010_platforms/000_qemu/030_run_qcow/test.yml new file mode 100644 index 000000000..ef9a6961e --- /dev/null +++ b/test/cases/010_platforms/000_qemu/030_run_qcow/test.yml @@ -0,0 +1,16 @@ +kernel: + image: "linuxkit/kernel:4.9.x" + cmdline: "console=ttyS0 console=tty0 page_poison=1" +init: + - linuxkit/init:f71c3b30ac1ba4ef16c160c89610fa4976f9752f + - linuxkit/runc:b0fb122e10dbb7e4e45115177a61a3f8d68c19a9 + - linuxkit/containerd:60e2486a74c665ba4df57e561729aec20758daed +onboot: + - name: poweroff + image: "linuxkit/poweroff:a8f1e4ad8d459f1fdaad9e4b007512cb3b504ae8" + command: ["/bin/sh", "/poweroff.sh", "10"] +trust: + image: + - linuxkit/kernel +outputs: + - format: qcow2 diff --git a/test/cases/020_kernel/000_config_4.4.x/test.sh b/test/cases/020_kernel/000_config_4.4.x/test.sh index 7883df33b..5027c0de2 100644 --- a/test/cases/020_kernel/000_config_4.4.x/test.sh +++ b/test/cases/020_kernel/000_config_4.4.x/test.sh @@ -17,7 +17,7 @@ trap clean_up EXIT # Test code goes here moby build test-kernel-config -RESULT="$(linuxkit run qemu test-kernel-config)" +RESULT="$(linuxkit run qemu -kernel test-kernel-config)" echo "${RESULT}" | grep -q "suite PASSED" exit 0 diff --git a/test/cases/040_packages/000_sysctl/test.sh b/test/cases/040_packages/000_sysctl/test.sh index 30d0ed43a..660bca548 100644 --- a/test/cases/040_packages/000_sysctl/test.sh +++ b/test/cases/040_packages/000_sysctl/test.sh @@ -17,7 +17,7 @@ trap clean_up EXIT # Test code goes here moby build test-sysctl -RESULT="$(linuxkit run qemu test-sysctl)" +RESULT="$(linuxkit run qemu -kernel test-sysctl)" echo "${RESULT}" | grep -q "suite PASSED" exit 0