initial commit

This commit is contained in:
Sebastian Hugentobler 2023-06-22 09:50:54 +02:00
commit 2628847676
Signed by: shu
GPG Key ID: BB32CF3CA052C2F0
3 changed files with 181 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
*~
.DS_Store
*.pkg.tar.zst
*.pkg.tar.zst.sig

20
PKGBUILD Normal file
View File

@ -0,0 +1,20 @@
# Maintainer: Sebastian Hugentobler <shu@vanwa.ch>
pkgname=vm
pkgver=0.1.0
pkgrel=1
pkgdesc="Run qemu vms from configurations."
arch=("any")
url="https://code.vanwa.ch"
license=('MIT')
depends=("qemu-full" "swtpm")
source=(
"vm"
)
sha256sums=("1a6ee0ee645689953226154c3d74d23e49f1b6a5609c3ed9b344c1f2c278f0c5")
package() {
cd "$srcdir/"
install -Dm 755 vm "$pkgdir/usr/bin/vm"
}

157
vm Executable file
View File

@ -0,0 +1,157 @@
#!/usr/bin/env sh
set -o errexit
: "${XDG_CONFIG_HOME:="$HOME/.config"}"
config_dir="$XDG_CONFIG_HOME/vm/"
tmpdir="${TMPDIR:-/tmp}"
check_mandatory_keys() {
mandatory_keys="emu_type memory cpu_cores disk"
for k in $mandatory_keys; do
if eval '[ -z "${'$k'+1}" ]'; then
echo "key \"$k\" is mandatory"
exit 1
fi
done
}
read_config() {
if [ -f "$config_file" ]; then
# shellcheck disable=1090
. "$config_file"
check_mandatory_keys
else
echo "$config_file not found"
exit 1
fi
}
display_help() {
echo "Usage: $0 [option...] " >&2
echo
echo " -c, configuration name (reads the config of a file \"name\" in the folder \"$config_dir\")"
echo " -f, configuration file (overrides any set \"-c\" option)"
echo " -h, display this help and exit"
echo
echo "configuration keys:"
echo "emu_type: which qemu emulator to use (for example \"x86_64\" would use \"qemu-system-x86_64\")"
echo "tpm: directory of the software tpm (created automatically if specified)"
echo "memory: amount of ram for the vm"
echo "cpu_cores: amount of cpu cores for the vm"
echo "efi_files_root: base path to efi files (using \"\${efi_file_root}_OVMF_CODE.fd and \${efi_file_root}_OVMF_VARS.fd\")"
echo "disk: path to vm disk image (gets created as cow if it does not exist)"
echo "disk_size: how big the created disk is"
echo "shared_dirs: pipe separated directories that will be shared from the host to the guest"
echo "port_forwards: port forwards between guest and host (format is protocol:host_port:guest_port)"
echo "cdrom: cd image that will be mounted into the guest"
}
parse_args() {
while getopts ":hc:f:" opt; do
case $opt in
h)
display_help
exit 0
;;
c)
config_file="$config_dir/$OPTARG"
;;
f)
config_file="$OPTARG"
;;
\?)
echo "Invalid option: -$OPTARG" >&2
display_help
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
display_help
exit 1
;;
esac
done
}
parse_args "$@"
read_config
if [ -n "$tpm" ]; then
tpm_dir="$tmpdir/$tpm"
tpm_socket="$tpm_dir/swtpm-sock"
mkdir -p "$tpm_dir"
swtpm socket --tpmstate dir="$tpm_dir" --ctrl type=unixio,path="$tpm_socket" --log level=20 --tpm2 --daemon
tpm_args="-tpmdev emulator,id=tpm0,chardev=chrtpm -device tpm-tis,tpmdev=tpm0 -chardev socket,id=chrtpm,path=$tpm_socket"
fi
if [ -n "$efi_files_root" ]; then
efi_code_path="${efi_files_root}_OVMF_CODE.fd"
efi_vars_path="${efi_files_root}_OVMF_VARS.fd"
if [ ! -f "$efi_code_path" ]; then
echo "$efi_code_path does not exist"
exit 1
fi
if [ ! -f "$efi_vars_path" ]; then
echo "$efi_vars_path does not exist"
exit 1
fi
efi_args="-drive if=pflash,format=raw,readonly=on,file=$efi_code_path -drive if=pflash,format=raw,file=$efi_vars_path"
fi
if [ -n "$cdrom" ]; then
if [ ! -f "$cdrom" ]; then
echo "$cdrom does not exist"
exit 1
fi
cdrom_args="-cdrom $cdrom"
fi
if [ ! -f "$disk" ]; then
qemu-img create -f qcow2 "$disk" "$disk_size"
fi
oldIFS=$IFS
IFS='|'
for dir in $shared_dirs; do
shared_dirs_args="$shared_dirs_args -net nic -net user,smb=$dir"
done
IFS=$oldIFS
oldIFS=$IFS
IFS='|'
for port_forward in $port_forwards; do
IFS=':' read -r protocol host_port guest_port <<_EOF_
$port_forward
_EOF_
port_forward_args="$port_forward_args -nic user,hostfwd=$protocol::$host_port-:$guest_port"
done
IFS=$oldIFS
# shellcheck disable=2086,2154
qemu-system-$emu_type \
-enable-kvm \
-machine q35,smm=on,accel=kvm \
-global ICH9-LPC.disable_s3=1 \
-device intel-iommu \
-m "$memory" \
-smp "$cpu_cores" \
-cpu host \
-vga qxl \
-device virtio-serial-pci \
-device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 \
-device intel-hda \
-device hda-duplex \
-chardev spicevmc,id=spicechannel0,name=vdagent \
-spice gl=on,unix=on,addr=/run/user/1000/spice.sock,disable-ticketing=on \
-drive file="$disk",index=0,media=disk,if=virtio \
-full-screen \
-boot menu=off \
-display spice-app \
-device nec-usb-xhci,id=usb \
-chardev spicevmc,name=usbredir,id=usbredirchardev1 \
-device usb-redir,chardev=usbredirchardev1,id=usbredirdev1 \
-device qemu-xhci,id=xhci $tpm_args $efi_args $shared_dirs_args $port_forward_args $cdrom_args