Skip to content

Instantly share code, notes, and snippets.

@henri
Last active August 14, 2026 05:13
Show Gist options
  • Select an option

  • Save henri/9f5fde073bf25af1bbdd22cae389f7b9 to your computer and use it in GitHub Desktop.

Select an option

Save henri/9f5fde073bf25af1bbdd22cae389f7b9 to your computer and use it in GitHub Desktop.
Quickly Setup KVM/QEMU libvert VM - Great for Testing
#!/usr/bin/env bash
#
#
# (C)2026 Henri Shustak, All Rights Reserved
# Licence : GNU GPLv3 or later
#
#
# new-vm.bash
# Interactively creates a KVM/QEMU libvirt VM with a configurable
# boot mode (BIOS or UEFI), generic "linux2022" OS variant, a
# configurable virtio disk size, and an install ISO of your choosing.
#
#
# Usage:
#
# ~/bin/create-vm.bash [path-to-iso]
# If the ISO path is omitted, you'll be prompted for it.
#
#
# Installation / Update :
#
# # download
# curl -o ~/bin/create-vm.bash https://gist.githubusercontent.com/henri/9f5fde073bf25af1bbdd22cae389f7b9/raw/create-vm.bash
#
# # set execute bit
# chmod +x ~/bin/create-vm.bash
#
#
# Purpose:
#
# Quickly setup new VM's with basic settings for testing things
#
#
# Version History:
#
# 1.0 : intial release
#
#
set -euo pipefail
# --- Prompt for inputs -------------------------------------------------
read -rp "Enter VM name: " VM_NAME
if [[ -z "$VM_NAME" ]]; then
echo "Error: VM name cannot be empty." >&2
exit 1
fi
ISO_PATH="${1:-}"
if [[ -z "$ISO_PATH" ]]; then
read -rp "Enter path to ISO file: " ISO_PATH
fi
if [[ ! -f "$ISO_PATH" ]]; then
echo "Error: ISO file not found at '$ISO_PATH'." >&2
exit 1
fi
# --- Optional overrides (press Enter to accept defaults) ---------------
read -rp "Memory in MB [4096]: " VM_MEMORY
VM_MEMORY="${VM_MEMORY:-4096}"
read -rp "Number of vCPUs [2]: " VM_VCPUS
VM_VCPUS="${VM_VCPUS:-2}"
read -rp "Disk size in GB [30]: " DISK_SIZE
DISK_SIZE="${DISK_SIZE:-30}"
if ! [[ "$DISK_SIZE" =~ ^[0-9]+$ ]]; then
echo "Error: Disk size must be a whole number of GB." >&2
exit 1
fi
read -rp "Boot mode - bios or uefi [uefi]: " BOOT_MODE
BOOT_MODE="${BOOT_MODE:-uefi}"
BOOT_MODE="$(echo "$BOOT_MODE" | tr '[:upper:]' '[:lower:]')"
case "$BOOT_MODE" in
uefi)
BOOT_ARGS=(--boot uefi)
;;
bios)
# There's no dedicated "--boot bios" flag in virt-install;
# BIOS (SeaBIOS) is simply the default when --boot uefi is omitted.
BOOT_ARGS=()
;;
*)
echo "Error: Boot mode must be 'bios' or 'uefi'." >&2
exit 1
;;
esac
# --- Create the VM -------------------------------------------------------
echo
echo "Creating VM '$VM_NAME' with:"
echo " ISO: $ISO_PATH"
echo " Memory: ${VM_MEMORY}MB"
echo " vCPUs: $VM_VCPUS"
echo " Disk: ${DISK_SIZE}GB (qcow2, virtio)"
echo " Boot: ${BOOT_MODE^^}"
echo " OS type: linux2022 (generic modern Linux)"
echo
virt-install \
--name "$VM_NAME" \
--memory "$VM_MEMORY" \
--vcpus "$VM_VCPUS" \
--disk size="$DISK_SIZE",format=qcow2,bus=virtio \
--network network=default,model=virtio \
--cdrom "$ISO_PATH" \
--os-variant linux2022 \
"${BOOT_ARGS[@]}" \
--graphics spice
echo
echo "VM '$VM_NAME' created. Manage it with:"
echo " virsh list --all"
echo " virsh start $VM_NAME"
echo " virsh console $VM_NAME"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment