diff options
author | Steve McIntyre <steve.mcintyre@pexip.com> | 2023-05-03 18:21:22 +0100 |
---|---|---|
committer | Steve McIntyre <steve.mcintyre@pexip.com> | 2023-05-03 18:21:22 +0100 |
commit | 08fa9cff955b683d4106a2e742a69a0aa197fb12 (patch) | |
tree | 3056fd3f3908fb46cbd7827475875c3cda7a76cb | |
parent | 031f3454137fc5954c74c4c277ea2f8b0fe7c221 (diff) | |
download | steve-scripts-08fa9cff955b683d4106a2e742a69a0aa197fb12.zip |
Massive revamp of the run-ova script
* Add support for EFI boot, but still default to BIOS
* Add support for an additional disk image
* Add support for an additional rescue image
* Switch to getopts, and add usage help!
* Support for different qemu models, as needed for newer OVMF builds
-rwxr-xr-x | run-ova | 279 |
1 files changed, 228 insertions, 51 deletions
@@ -1,79 +1,256 @@ -#!/bin/sh +#!/bin/bash # # Run a Pexip VM with kvm and some simple options # -DISK=$1 -NODE=$2 +# Default settings +ARCH="x86_64" +BOOT_TYPE="bios" +CPUS=4 +EXTRA_DISK="" +IMAGE="" +MEM=4096 # MiB +NODE="mgr" +QEMU_MODEL="new" +RESCUE="" -if [ "$DISK"x = ""x ] || [ "$NODE"x = ""x ]; then - echo "$0: <disk file> <node name>" +usage () { + cat <<EOF + +run-ova: wrapper script for QEMU/KVM for running infinity VMs + +Usage: + run-ova [<options>] -i <image> + + -i <image> - The path to the image, in either ova format or qcow2; + if an OVA is specified, the script will extract and + convert to a qcow2 in the current directory. No default, + this is required. + +Optional arguments: + + -b <boot_type> - Either "efi" or "bios", default is "bios". + "efi" needs extra firmware image files - see the + comments in the script for more details. + + -e <extra_image> - (Optionally) attach an extra named disk image. + + -n <node> - The name of the node, so that unique MAC address and + UUID can be derived. Default is "mgr". + + -q <qemu_model> - Either "old" (pc-i440fx-2.8) or "new" (q35). Used to + determine the model used for qemu, and hence also + the supporte EFI OVMF code supported. It should not + really affect much else. Default is $QEMU_MODEL. + + -r <rescue_image> - (Optionally) attach an extra named rescue image, + and attempt to boot it first. Useful for fixing a + non-bootable disk image. +EOF +} + +validate_arg() { + local VAR=$1 + local VAROPTS="$(echo $2 | tr ':' ' ')" + + for OPT in $VAROPTS; do + if [ "${!VAR}"x = "$OPT"x ]; then + return + fi + done + # else + echo "$VAR ${!VAR} not supported - use one of $VAROPTS" + exit 1 +} + +while getopts ":b:e:i:n:q:r:" o; do + case "${o}" in + b) + BOOT_TYPE="${OPTARG}" + ;; + e) + EXTRA_IMAGE="${OPTARG}" + ;; + i) + IMAGE="${OPTARG}" + ;; + n) + NODE="${OPTARG}" + ;; + q) + QEMU_MODEL="${OPTARG}" + ;; + r) + RESCUE="${OPTARG}" + ;; + *) + echo "Unknown option ${o}" + usage + exit 1 + ;; + esac +done +shift $((OPTIND-1)) + +validate_arg BOOT_TYPE "bios:efi" +if [ "$IMAGE"x = ""x ]; then + echo "No image specified! Abort." + exit 1 +fi +if [ ! -f "$IMAGE" ]; then + echo "Can't find image $IMAGE! Abort." exit 1 fi +validate_arg NODE "pexep:mgr:conf1:conf2:conf3:conf4:conf5:conf6" +validate_arg QEMU_MODEL "old:new" + +if [ "$QEMU_MODEL" = "old" ]; then + #QEMU_MACH_TYPE="pc-i440fx-2.8" + QEMU_MACH_TYPE="pc" +else + QEMU_MACH_TYPE="q35" +fi case $NODE in mgr) - UUID=b1eec732-dd7d-11ea-92c8-d31d043c6c1e - INCR=0 - ;; + UUID=b1eec732-dd7d-11ea-92c8-d31d043c6c1e + INCR=0 + ;; conf1) - UUID=0e429dd2-32f7-11eb-a0af-c74b38b343b0 - INCR=1 - ;; + UUID=0e429dd2-32f7-11eb-a0af-c74b38b343b0 + INCR=1 + ;; conf2) - UUID=eea38d78-33c4-11eb-9be6-d72307ffa49c - INCR=2 - ;; + UUID=eea38d78-33c4-11eb-9be6-d72307ffa49c + INCR=2 + ;; conf3) - UUID=fa03eb04-33c4-11eb-a0f9-0f653954190b - INCR=3 - ;; + UUID=fa03eb04-33c4-11eb-a0f9-0f653954190b + INCR=3 + ;; conf4) - UUID=397cc814-33c5-11eb-843e-87cace3dc8e5 - INCR=4 - ;; + UUID=397cc814-33c5-11eb-843e-87cace3dc8e5 + INCR=4 + ;; conf5) - UUID=901be3de-7084-11eb-8c7d-6be9963ee3a2 - INCR=5 - ;; + UUID=901be3de-7084-11eb-8c7d-6be9963ee3a2 + INCR=5 + ;; conf6) - UUID=94f43cbc-7084-11eb-be47-2bdcd2e37134 - INCR=6 - ;; + UUID=94f43cbc-7084-11eb-be47-2bdcd2e37134 + INCR=6 + ;; pexep) - UUID=489983b4-3ef6-11eb-ba47-cff163112579 - INCR=7 - ;; + UUID=489983b4-3ef6-11eb-ba47-cff163112579 + INCR=7 + ;; esac LAST_HEX="2"${INCR} MAC="00:02:02:de:00:$LAST_HEX" TAP="tap"${INCR} -case $DISK in +case $IMAGE in *.ova) - VMDK=$(tar tf $DISK | grep \\.vmdk) - if [ "$VMDK"x = ""x ]; then - echo "Can't find a VMDK in $DISK, ABORT" - exit 1 - fi - echo "Extracting $VMDK" - tar xvf $DISK $VMDK - BASE=$(basename $VMDK .vmdk) - echo "Converting to $BASE.qcow2" - qemu-img convert $VMDK $BASE.qcow2 - rm -vf $VMDK - DISK=$BASE.qcow2 - ;; + VMDK=$(tar tf $IMAGE | grep \\.vmdk) + if [ "$VMDK"x = ""x ]; then + echo "Can't find a VMDK in $IMAGE, ABORT" + exit 1 + fi + echo "Extracting $VMDK" + tar xvf $IMAGE $VMDK + BASE=$(basename $VMDK .vmdk) + echo "Converting to $BASE.qcow2" + qemu-img convert $VMDK $BASE.qcow2 + rm -vf $VMDK + IMAGE=$BASE.qcow2 + ;; esac -echo "Running image in $DISK" +echo "Running image in $IMAGE" + +# Now build up the command line in sections + +# *If* we're doing EFI boot, we'll need to specify the two 'pflash' +# files: one for the firmware code and the second for storage of +# config / variables. These can be found in the "ovmf" Debian package +# for the amd64 architecture. Copy a matching pair of files into the +# local working directory: +# +# OVMF_CODE.fd ---> x86_64-OVMF_CODE.fd.$QEMU_MODEL +# OVMF_VARS.fd ---> x86_64-OVMF_VARS.fd.$QEMU_MODEL +# +# The qemu model matters here - current (bullseye) and newer versions +# of OVMF seem to only work with "new" qemu, so we default to that. + +EFI_ARGS="" +if [ "$BOOT_TYPE"x = "efi"x ]; then + EFI_FILES="$ARCH-OVMF_CODE.fd.$QEMU_MODEL $ARCH-OVMF_VARS.fd.$QEMU_MODEL" + for file in $EFI_FILES; do + if [ ! -f $file ]; then + echo "Missing needed EFI startup file $file, exit!" + exit 1 + fi +# EFI_ARGS="$EFI_ARGS -pflash $file" + EFI_ARGS="$EFI_ARGS -drive file=$file,if=pflash,format=raw" + done +fi + +# Bridged networking config +SCRIPTS="script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown" +NET="-device virtio-net-pci,netdev=nic0,mac=$MAC" +NET="$NET -netdev tap,id=nic0,ifname=$TAP,$SCRIPTS" + +# Log serial output +SERIAL="-serial file:serial.txt" + +# Now work out a list of disk image(s) to connect, starting with the +# one specified +IMAGES="$IMAGE" + +# Should we add an extra disk image for testing? +if [ "$EXTRA_IMAGE"x != ""x ]; then + if [ ! -f "$EXTRA_IMAGE" ]; then + echo "Can't find the extra disk image specified ($EXTRA_IMAGE). ABORT" + exit 1 + fi + # else + IMAGES="$IMAGE $EXTRA_IMAGE" +fi + +# For each disk in the list, fully specify it +DISKS="" +for DISK in $IMAGES; do + if [ "$QEMU_MODEL" = "old" ]; then + DISKS="$DISKS -drive driver=file,cache.direct,filename=$DISK" + else + DISKS="$DISKS -drive driver=file,cache.direct,filename=$DISK,if=virtio" + fi +done + +# Add an ISO image for a rescue fallback? +if [ "$RESCUE"x != ""x ]; then + RESCUE="-cdrom $RESCUE -boot d" +fi -DISK="-drive driver=file,cache.direct,filename=$DISK" +echo sudo qemu-system-$ARCH \ + --uuid $UUID \ + -smp $CPUS \ + -m $MEM \ + -machine $QEMU_MACH_TYPE,accel=kvm -cpu host \ + $NET \ + $SERIAL \ + $EFI_ARGS \ + $DISKS \ + $RESCUE -sudo qemu-system-x86_64 --uuid $UUID \ - -smp 4 \ - -m 4096 -machine pc-i440fx-2.8,accel=kvm -cpu host \ - -net nic,macaddr=$MAC \ - -net tap,ifname=$TAP,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown \ - $DISK +sudo qemu-system-$ARCH \ + --uuid $UUID \ + -smp $CPUS \ + -m $MEM \ + -machine $QEMU_MACH_TYPE,accel=kvm -cpu host \ + $NET \ + $SERIAL \ + $EFI_ARGS \ + $DISKS \ + $RESCUE |