#!/bin/bash set -e # main available options: # QEMU_CPU=n (cores) # QEMU_RAM=nnn (megabytes) # QEMU_HDA (filename) # QEMU_HDA_SIZE (bytes, suffixes like "G" allowed) # QEMU_CDROM (filename) # QEMU_BOOT (-boot) # QEMU_PORTS="xxx[ xxx ...]" (space separated port numbers) # QEMU_NET_USER_EXTRA="net=192.168.76.0/24,dhcpstart=192.168.76.9" (extra raw args for "-net user,...") # QEMU_NO_SSH=1 (suppress automatic port 22 forwarding) # QEMU_NO_SERIAL=1 (suppress automatic "-serial stdio") # QEMU_NO_VNC=1 (suppress automatic "-vnc ':0'") hostArch="$(uname -m)" qemuArch="${QEMU_ARCH:-$hostArch}" qemu="${QEMU_BIN:-qemu-system-$qemuArch}" qemuArgs=() qemuPorts=() if [ -z "${QEMU_NO_SSH:-}" ]; then qemuPorts+=( 22 ) fi qemuPorts+=( ${QEMU_PORTS:-} ) if [ -e /dev/kvm ] && sh -c 'echo -n > /dev/kvm' &> /dev/null; then # https://github.com/tianon/docker-qemu/issues/4 qemuArgs+=( -enable-kvm ) elif [ "$hostArch" = "$qemuArch" ]; then echo >&2 echo >&2 'warning: /dev/kvm not found' echo >&2 ' PERFORMANCE WILL SUFFER' echo >&2 ' (hint: docker run --device /dev/kvm ...)' echo >&2 sleep 3 fi qemuArgs+=( -smp "${QEMU_CPU:-1}" ) qemuArgs+=( -m "${QEMU_RAM:-512}" ) if [ -n "${QEMU_HDA:-}" ]; then if [ ! -f "$QEMU_HDA" -o ! -s "$QEMU_HDA" ]; then ( set -x qemu-img create -f qcow2 -o preallocation=off "$QEMU_HDA" "${QEMU_HDA_SIZE:-8G}" ) fi # http://wiki.qemu.org/download/qemu-doc.html#Invocation qemuScsiDevice='virtio-scsi-pci' case "$qemuArch" in arm | riscv64) qemuScsiDevice='virtio-scsi-device' ;; esac #qemuArgs+=( -hda "$QEMU_HDA" ) #qemuArgs+=( -drive file="$QEMU_HDA",index=0,media=disk,discard=unmap ) qemuArgs+=( -drive file="$QEMU_HDA",index=0,media=disk,discard=unmap,detect-zeroes=unmap,if=none,id=hda -device "$qemuScsiDevice" -device scsi-hd,drive=hda ) fi if [ -n "${QEMU_CDROM:-}" ]; then qemuArgs+=( -cdrom "$QEMU_CDROM" ) fi if [ -n "${QEMU_BOOT:-}" ]; then qemuArgs+=( -boot "$QEMU_BOOT" ) fi netArg='user' netArg+=",hostname=$(hostname)" if [ -n "${QEMU_NET_USER_EXTRA:-}" ]; then netArg+=",$QEMU_NET_USER_EXTRA" fi for port in "${qemuPorts[@]}"; do netArg+=",hostfwd=tcp::$port-:$port" netArg+=",hostfwd=udp::$port-:$port" done qemuNetDevice='virtio-net-pci' case "$qemuArch" in arm | riscv64) qemuNetDevice='virtio-net-device' ;; esac qemuArgs+=( -netdev "$netArg,id=net" -device "$qemuNetDevice,netdev=net" ) if [ -z "${QEMU_NO_SERIAL:-}" ]; then qemuArgs+=( -serial stdio ) fi if [ -z "${QEMU_NO_VNC:-}" ]; then qemuArgs+=( -vnc ':0' ) fi qemuArgs+=( "$@" ) set -x exec "$qemu" "${qemuArgs[@]}"