initial commit
This commit is contained in:
commit
7fdbc06ca4
3 changed files with 343 additions and 0 deletions
25
LICENSE
Normal file
25
LICENSE
Normal 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
93
README.md
Normal 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
225
kuemu.sh
Normal 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
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Add table
Reference in a new issue