initial commit

This commit is contained in:
mykola2312 2024-12-02 03:25:37 +02:00
commit 7fdbc06ca4
3 changed files with 343 additions and 0 deletions

25
LICENSE Normal file
View file

@ -0,0 +1,25 @@
BSD 2-Clause License
Copyright (c) 2024, mykola2312.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.

93
README.md Normal file
View file

@ -0,0 +1,93 @@
# kuemu
Bash declarative QEMU tool
## Documentation
### Config
```KUEMU_DISK_PATH``` - set this to your appropriate location of virtual machine images.
```QEMU_BIOS_ROM```, ```QEMU_UEFI_ROM```, ```QEMU_UEFI_NVRAM``` - ensure they exist in your filesystem. If not, install required packages and firmware, for example for UEFI ROMs You need OVMF EDK2.
### Syntax
```name "name of virtual machine``` - set the name of VM. This also will be used in calculation of disk path
```arch "arch-suffix``` - will be translated into qemu-system-<arch>, like ```qemu-system-x86_64```
```machine "machine"``` - QEMU uses machine presets, that populates buses, devices and such. Recommended: q35
```cpu "cpu"``` - host, or custom cpu config
```smp num-cores``` - refers to amount of cores
```ram 1024m``` - same as -m parameter of QEMU. For example, 1G or 1024M are accepted.
```vga vga-type``` - VGA device. Recommended: qxl
```monitor``` - spawn QEMU monitor, useful for troubleshooting
```spice``` or ```spice <port>``` - spawn SPICE graphics server. Connect with ```spicy```
```no_acpi``` - disables ACPI. Needed for running old operating systems.
Path calculation:
"name" translates to ```$KUEMU_DISK_PATH/name.img```, "name" "fd" - ```$KUEMU_DISK_PATH/name.fd```
```uefi``` - loads UEFI ROMs, populates NVRAM variables into VM images path, like ```$KUEMU_DISK_PATH/name-nvram.fd```
```bios``` - loads BIOS ROM. Better don't use it, since QEMU has its own defaults.
```ide_disk "disk-name"```, ```sata_disk "name"```, ```virtio_disk "name"``` - creates IDE/SATA/Virtio disk drives, where ```name``` translates to ```$KUEMU_DISK_PATH/vm_name-name.img```. When ```name``` is empty string, it will translate just to virtual machine's name, like ```$KUEMU_DISK_PATH/vm_name.img```
```ide_cdrom "path"```, ```sata_cdrom "path"```, ```virtio_cdrom "path"``` - creates IDE/SATA/Virtio CDROMs, where "path" must be full path to file.
```network "device-model" "type" "name"``` - create network device. For model, you either specify ```e1000```, when guest doesn't have virtio drivers, or ```virtio-net``` for virtio network device. Type only supports ```tap```, where name is name of the tap (that You probably want to add to bridge)
```kuemu_start``` - finishes QEMU argument building and spawns virtual machine.
## Examples
### Full virtio guest
```
#!/usr/bin/env bash
source kuemu.sh
name "freebsd-dev"
arch "x86_64"
machine "q35"
smp 4
ram "4G"
vga "qxl"
monitor
spice
uefi
virtio_disk ""
network "virtio-net" "tap" "vnet0tap1"
kuemu_start
```
### Windows 7
```
#!/usr/bin/env bash
source kuemu.sh
name "win7"
arch "x86_64"
machine "q35"
smp 4
ram "4G"
vga "qxl"
monitor
spice
uefi
sata_disk ""
network "e1000" "tap" "vnet0tap1"
kuemu_start
```

225
kuemu.sh Normal file
View file

@ -0,0 +1,225 @@
KUEMU_DISK_PATH="/drive/virtual-machines"
QEMU_BIOS_ROM="/usr/share/qemu/bios-microvm.bin"
QEMU_UEFI_ROM="/usr/share/OVMF/OVMF_CODE.fd"
QEMU_UEFI_NVRAM="/usr/share/OVMF/OVMF_VARS.fd"
QEMU_ACCEL="kvm"
QEMU_MODEL_IDE_BUS="piix3-ide"
QEMU_MODEL_AHCI_BUS="ahci"
vm_name=""
cmdline_file=$(mktemp)
model_ide_bus="$QEMU_MODEL_IDE_BUS"
model_ahci_bus="$QEMU_MODEL_AHCI_BUS"
function append() {
printf "%s " "$1" >> "$cmdline_file"
}
function counter_create() {
counter=$(mktemp)
echo "$1" > "$counter"
echo "$counter"
}
function counter_read() {
cat "$1"
}
function counter_increment() {
echo $(( $(cat "$1") + 1 )) > "$1"
}
function counter_decrement() {
echo $(( $(cat "$1") - 1 )) > "$1"
}
function counter_delete() {
rm "$1"
}
function path_disk() {
#
# disk_name
# disk_name, ext
if [ ! -z "$2" ]; then
echo "$KUEMU_DISK_PATH/$vm_name-$1.$2"
elif [ ! -z "$1" ]; then
echo "$KUEMU_DISK_PATH/$vm_name-$1.img"
else
echo "$KUEMU_DISK_PATH/$vm_name.img"
fi
}
function name() {
vm_name="$1"
}
function arch() {
append "qemu-system-$1"
}
function machine() {
append "-machine type=$1,accel=$QEMU_ACCEL"
}
function cpu() {
if [ ! -z "$1" ]; then
append "-cpu $1"
else
append "-cpu host"
fi
}
function smp() {
append "-smp $1"
}
function ram() {
append "-m $1"
}
function vga() {
append "-vga $1"
}
function monitor() {
append "-monitor stdio"
}
function spice() {
# port
if [ ! -z "$1" ]; then
append "-spice port=$1,disable-ticketing=on"
else
append "-spice port=5924,disable-ticketing=on"
fi
}
function no_acpi() {
append "-no-acpi"
}
function uefi() {
append "-drive if=pflash,format=raw,file=$QEMU_UEFI_ROM"
nvram=$(path_disk "nvram" "fd")
if [ ! -f "$nvram" ]; then
# create nvram
cp "$QEMU_UEFI_NVRAM" "$nvram"
fi
append "-drive if=pflash,format=raw,file=$nvram"
}
function bios() {
append "-bios $QEMU_BIOS_ROM"
}
function boot() {
append "-boot $1"
}
bus_ide="ide"
bus_ide_counter=$(counter_create 0)
drive_counter=$(counter_create 0)
function _ide_disk() {
# disk type, type, path
unit=$(counter_read $bus_ide_counter)
counter_increment $bus_ide_counter
drive="drive-$(counter_read $drive_counter)"
counter_increment $drive_counter
append "-drive id=$drive,format=raw,media=$2,file=$3,if=none"
append "-device $1,drive=$drive,bus=$bus_ide.$unit"
}
function ide_disk() {
# name
_ide_disk "ide-hd" "disk" $(path_disk "$1")
}
function ide_cdrom() {
# path
_ide_disk "ide-cd" "cdrom" "$1"
}
bus_ahci=""
bus_ahci_counter=$(counter_create 0)
function _sata_disk() {
# disk type, media type, path
if [ -z "$bus_ahci" ]; then
append "-device $model_ahci_bus,id=ahci"
bus_ahci="ahci"
fi
unit=$(counter_read $bus_ide_counter)
counter_increment $bus_ahci_counter
drive="drive-$(counter_read $drive_counter)"
counter_increment $drive_counter
append "-drive id=$drive,format=raw,media=$2,file=$3,if=none"
append "-device $1,drive=$drive,bus=$bus_ahci.$unit"
}
function sata_disk() {
# name
_sata_disk "ide-hd" "disk" $(path_disk "$1")
}
function sata_cdrom() {
# path
_sata_disk "ide-cd" "cdrom" "$1"
}
function _virtio_disk() {
# scsi type, media type, path
drive="drive-$(counter_read $drive_counter)"
counter_increment $drive_counter
append "-drive id=$drive,format=raw,media=$2,file=$3,if=virtio"
}
function virtio_disk() {
# name
_virtio_disk "scsi-hd" "disk" $(path_disk "$1")
}
function virtio_cdrom() {
# path
_virtio_disk "scsi-cd" "cdrom" "$1"
}
nic_counter=$(counter_create 0)
function network() {
# model, mode (tap or bridge), tap name / bridge
nic="nic$(counter_read $nic_counter)"
counter_increment $nic_counter
append "-device $1,netdev=$nic"
case "$2" in
"tap")
append "-netdev tap,id=$nic,ifname=$3,script=no,downscript=no"
;;
*)
echo "unknown network type $2"
exit 1
;;
esac
}
function kuemu_start() {
append "-name $vm_name"
# cleanup counters
counter_delete $bus_ide_counter
counter_delete $drive_counter
counter_delete $bus_ahci_counter
counter_delete $nic_counter
# execute qemu command
bash $cmdline_file
}