summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve McIntyre <steve.mcintyre@pexip.com>2023-05-03 18:21:22 +0100
committerSteve McIntyre <steve.mcintyre@pexip.com>2023-05-03 18:21:22 +0100
commit08fa9cff955b683d4106a2e742a69a0aa197fb12 (patch)
tree3056fd3f3908fb46cbd7827475875c3cda7a76cb
parent031f3454137fc5954c74c4c277ea2f8b0fe7c221 (diff)
downloadsteve-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-xrun-ova279
1 files changed, 228 insertions, 51 deletions
diff --git a/run-ova b/run-ova
index dcff494..2d9674d 100755
--- a/run-ova
+++ b/run-ova
@@ -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