Blob Blame History Raw
#!/bin/bash

#
# deploy-qemu IMAGE USERDATA
#
# Starts an ephemeral virtual machine in qemu, injecting configuration via
# cloud-init. Stopping this script stops the VM and discards all data.
#
# IMAGE    -- An os image that can be booted by qemu and has cloud-init
#             installed and enabled. No changes are made to this file.
#
# USERDATA -- A cloud-init user-data config file, or a directory of
#             configuration as accepted by the `gen-user-data` tool.
#
# In addition, if the QEMU_EXTRA_ARGS environment variable is defined, it adds
# its content as additional arguments to qemu.

set -euo pipefail

if [[ "$#" != 2 ]]; then
  echo "usage: $0 IMAGE USERDATA"
  exit 1
fi

scriptdir=$(dirname "$0")
image=$1
userdata=$2
read -ra qemu_extra_args <<< "${QEMU_EXTRA_ARGS:-}"
workdir=$(mktemp -d "$scriptdir/qemu-tmp-XXXXXX")
function cleanup() {
  rm -rf "$workdir"
}
trap cleanup EXIT

mkdir "$workdir/cidata"

if [ -d "$userdata" ]; then
  "$scriptdir/gen-user-data" "$userdata" > "$workdir/cidata/user-data"
else
  cp "$userdata" "$workdir/cidata/user-data"
fi

echo -e "instance-id: nocloud\nlocal-hostname: vm\n" > "$workdir/cidata/meta-data"

case $(uname -s) in
  "Linux")
    genisoimage \
      -input-charset utf-8 \
      -output "$workdir/cloudinit.iso" \
      -volid cidata \
      -joliet \
      -rock \
      -quiet \
      -graft-points \
      "$workdir/cidata/user-data" \
      "$workdir/cidata/meta-data"
    ;;

  "Darwin")
    # conviently uses the last component of source as volumeid, which has to be cidata
    hdiutil makehybrid -iso -joliet -o "$workdir/cloudinit.iso" "$workdir/cidata"
    ;;
esac

qemu-system-x86_64 \
  -M accel=kvm:hvf \
  -m 1024 \
  -snapshot \
  -cpu host \
  -net nic,model=virtio \
  -net user,hostfwd=tcp::2222-:22,hostfwd=tcp::4430-:443 \
  -cdrom "$workdir/cloudinit.iso" \
  "${qemu_extra_args[@]}" "$image"