From ec1391809dcae7ee781aef608b755c58357909cb Mon Sep 17 00:00:00 2001 From: Kroese Date: Tue, 30 Apr 2024 03:54:25 +0200 Subject: [PATCH 01/12] fix: Ignore unbound variable --- src/reset.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/reset.sh b/src/reset.sh index ce500c0a..d98aab99 100644 --- a/src/reset.sh +++ b/src/reset.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash set -Eeuo pipefail -info () { printf "%b%s%b" "\E[1;34m❯ \E[1;36m" "$1" "\E[0m\n"; } -error () { printf "%b%s%b" "\E[1;31m❯ " "ERROR: $1" "\E[0m\n" >&2; } -warn () { printf "%b%s%b" "\E[1;31m❯ " "Warning: $1" "\E[0m\n" >&2; } +info () { printf "%b%s%b" "\E[1;34m❯ \E[1;36m" "${1:-}" "\E[0m\n"; } +error () { printf "%b%s%b" "\E[1;31m❯ " "ERROR: ${1:-}" "\E[0m\n" >&2; } +warn () { printf "%b%s%b" "\E[1;31m❯ " "Warning: ${1:-}" "\E[0m\n" >&2; } trap 'error "Status $? while: $BASH_COMMAND (line $LINENO/$BASH_LINENO)"' ERR From 1295714d64eef1c032d6a2146e008abb7b40ab5d Mon Sep 17 00:00:00 2001 From: Kroese Date: Tue, 30 Apr 2024 17:30:48 +0200 Subject: [PATCH 02/12] fix: Disable Hyper-V for legacy machines --- src/proc.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/proc.sh b/src/proc.sh index b482b8ed..a712edeb 100644 --- a/src/proc.sh +++ b/src/proc.sh @@ -9,7 +9,8 @@ set -Eeuo pipefail : "${CPU_MODEL:=""}" : "${DEF_MODEL:="qemu64"}" -[ "$ARCH" != "amd64" ] && KVM="N" +[[ "${ARCH,,}" != "amd64" ]] && KVM="N" +[[ "${MACHINE,,}" == "pc-q35-2"* ]] && HV="N" if [[ "$KVM" != [Nn]* ]]; then From c7f03c982e6d19063c375e3b82879d3e1ac5eaeb Mon Sep 17 00:00:00 2001 From: Kroese Date: Wed, 1 May 2024 00:00:05 +0200 Subject: [PATCH 03/12] feat: New pass-through method --- src/disk.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/disk.sh b/src/disk.sh index 971f648b..d34c96d9 100644 --- a/src/disk.sh +++ b/src/disk.sh @@ -512,6 +512,11 @@ fi : "${DEVICE3:=""}" : "${DEVICE4:=""}" +[ -z "$DEVICE" ] && [ -b "/dev/disk1" ] && DEVICE="/dev/disk1" +[ -z "$DEVICE2" ] && [ -b "/dev/disk2" ] && DEVICE2="/dev/disk2" +[ -z "$DEVICE3" ] && [ -b "/dev/disk3" ] && DEVICE3="/dev/disk3" +[ -z "$DEVICE4" ] && [ -b "/dev/disk4" ] && DEVICE4="/dev/disk4" + if [ -n "$DEVICE" ]; then addDevice "$DEVICE" "device" "3" "0xa" || exit $? else From ea2ac3d9089ba6efc52bb89ef84f5f677d98e071 Mon Sep 17 00:00:00 2001 From: Kroese Date: Wed, 1 May 2024 00:02:13 +0200 Subject: [PATCH 04/12] Update readme.md --- readme.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/readme.md b/readme.md index adcca7d2..93da5fe2 100644 --- a/readme.md +++ b/readme.md @@ -189,15 +189,12 @@ docker run -it --rm --name qemu -e "BOOT=http://example.com/image.iso" -p 8006:8 It is possible to pass-through disk devices directly by adding them to your compose file in this way: ```yaml - environment: - DEVICE: "/dev/sda" - DEVICE2: "/dev/sdb" devices: - - /dev/sda - - /dev/sdb + - /dev/sda:/dev/disk1 + - /dev/sdb:/dev/disk2 ``` - Use `DEVICE` if you want it to become your main drive, and use `DEVICE2` and higher to add them as secondary drives. + Use `/dev/disk1` if you want it to become your main drive, and use `/dev/disk2` and higher to add them as secondary drives. * ### How do I pass-through a USB device? From 62a100956e3ef67d949b45515f6c3dbb4a41d8be Mon Sep 17 00:00:00 2001 From: Kroese Date: Thu, 2 May 2024 00:16:11 +0200 Subject: [PATCH 05/12] docs: Readme --- readme.md | 71 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/readme.md b/readme.md index 93da5fe2..635e52d3 100644 --- a/readme.md +++ b/readme.md @@ -62,18 +62,17 @@ docker run -it --rm --name qemu -e "BOOT=http://example.com/image.iso" -p 8006:8 Enjoy your brand new machine, and don't forget to star this repo! -* ### How do I increase the amount of CPU or RAM? - - By default, a single CPU core and 1 GB of RAM are allocated to the container. +* ### How do I change the storage location? - To increase this, add the following environment variables: + To change the storage location, include the following bind mount in your compose file: ```yaml - environment: - RAM_SIZE: "4G" - CPU_CORES: "4" + volumes: + - /var/qemu:/storage ``` + Replace the example path `/var/qemu` with the desired storage folder. + * ### How do I change the size of the disk? To expand the default size of 16 GB, add the `DISK_SIZE` setting to your compose file and set it to your preferred capacity: @@ -84,21 +83,10 @@ docker run -it --rm --name qemu -e "BOOT=http://example.com/image.iso" -p 8006:8 ``` This can also be used to resize the existing disk to a larger capacity without any data loss. - -* ### How do I change the storage location? - - To change the storage location, include the following bind mount in your compose file: - - ```yaml - volumes: - - /var/qemu:/storage - ``` - - Replace the example path `/var/qemu` with the desired storage folder. * ### How do I boot a local image? - You can use a local file directly, and skip the download, by binding it in your compose file in this way: + You can use a local file directly, and skip the download altogether, by binding it in your compose file in this way: ```yaml volumes: @@ -131,6 +119,29 @@ docker run -it --rm --name qemu -e "BOOT=http://example.com/image.iso" -p 8006:8 You can use [qemu-arm](https://github.com/qemus/qemu-arm/) to run ARM64 images. +* ### How do I verify if my system supports KVM? + + To verify if your system supports KVM, run the following commands: + + ```bash + sudo apt install cpu-checker + sudo kvm-ok + ``` + + If you receive an error from `kvm-ok` indicating that KVM acceleration can't be used, check the virtualization settings in the BIOS. + +* ### How do I increase the amount of CPU or RAM? + + By default, a single CPU core and 1 GB of RAM are allocated to the container. + + If there arises a need to increase this, add the following environment variables: + + ```yaml + environment: + RAM_SIZE: "4G" + CPU_CORES: "4" + ``` + * ### How do I assign an individual IP address to the container? By default, the container uses bridge networking, which shares the IP address with the host. @@ -189,12 +200,15 @@ docker run -it --rm --name qemu -e "BOOT=http://example.com/image.iso" -p 8006:8 It is possible to pass-through disk devices directly by adding them to your compose file in this way: ```yaml + environment: + DEVICE: "/dev/sda" + DEVICE2: "/dev/sdb" devices: - - /dev/sda:/dev/disk1 - - /dev/sdb:/dev/disk2 + - /dev/sda + - /dev/sdb ``` - Use `/dev/disk1` if you want it to become your main drive, and use `/dev/disk2` and higher to add them as secondary drives. + Use `DEVICE` if you want it to become your main drive, and use `DEVICE2` and higher to add them as secondary drives. * ### How do I pass-through a USB device? @@ -207,18 +221,7 @@ docker run -it --rm --name qemu -e "BOOT=http://example.com/image.iso" -p 8006:8 - /dev/bus/usb ``` -* ### How do I verify if my system supports KVM? - - To verify if your system supports KVM, run the following commands: - - ```bash - sudo apt install cpu-checker - sudo kvm-ok - ``` - - If you receive an error from `kvm-ok` indicating that KVM acceleration can't be used, check the virtualization settings in the BIOS. - -* ### How do I provide custom arguments to QEMU? +* ### How can I provide custom arguments to QEMU? You can create the `ARGUMENTS` environment variable to provide additional arguments to QEMU at runtime: From 3a12e6162d18ba507dc6f6afe4bb492f69d12e85 Mon Sep 17 00:00:00 2001 From: Kroese Date: Thu, 2 May 2024 00:18:33 +0200 Subject: [PATCH 06/12] Update readme.md --- readme.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/readme.md b/readme.md index 635e52d3..0865037b 100644 --- a/readme.md +++ b/readme.md @@ -200,15 +200,12 @@ docker run -it --rm --name qemu -e "BOOT=http://example.com/image.iso" -p 8006:8 It is possible to pass-through disk devices directly by adding them to your compose file in this way: ```yaml - environment: - DEVICE: "/dev/sda" - DEVICE2: "/dev/sdb" devices: - - /dev/sda - - /dev/sdb + - /dev/sdb:/dev/disk1 + - /dev/sdc:/dev/disk2 ``` - Use `DEVICE` if you want it to become your main drive, and use `DEVICE2` and higher to add them as secondary drives. + Use `/dev/disk1` if you want it to become your main drive, and use `/dev/disk2` and higher to add them as secondary drives. * ### How do I pass-through a USB device? From 86fe3388af269a542ce473d9ef7295cc12fdb095 Mon Sep 17 00:00:00 2001 From: Kroese Date: Thu, 2 May 2024 19:29:25 +0200 Subject: [PATCH 07/12] feat: Check free RAM before boot --- src/reset.sh | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/reset.sh b/src/reset.sh index d98aab99..0c09d86a 100644 --- a/src/reset.sh +++ b/src/reset.sh @@ -43,7 +43,6 @@ HOST=$(hostname -s) KERNEL=$(echo "$SYS" | cut -b 1) MINOR=$(echo "$SYS" | cut -d '.' -f2) ARCH=$(dpkg --print-architecture) -RAM="$(free -g | grep Mem: | awk '{print $7}')/$(free -g | grep Mem: | awk '{print $2}') GB" CPU=$(lscpu | grep -m 1 'Model name' | cut -f 2 -d ":" | awk '{$1=$1}1' | sed 's# @.*##g' | sed s/"(R)"//g | sed 's/[^[:alnum:] ]\+/ /g' | sed 's/ */ /g') # Check system @@ -60,6 +59,14 @@ if [ ! -d "$STORAGE" ]; then error "Storage folder ($STORAGE) not found!" && exit 13 fi +# Read memory +RAM_AVAIL=$(free | grep Mem: | awk '{print $7}') +RAM_TOTAL=$(free | grep Mem: | awk '{print $2}') +RAM_WANTED=$(numfmt --from=iec "$RAM_SIZE") +AVAIL_GB=$(( (RAM_AVAIL + 1073741823)/1073741824 )) +TOTAL_GB=$(( (RAM_TOTAL + 1073741823)/1073741824 )) +WANTED_GB=$(( (RAM_TOTAL + 1073741823)/1073741824 )) + # Print system info SYS="${SYS/-generic/}" FS=$(stat -f -c %T "$STORAGE") @@ -67,9 +74,20 @@ FS="${FS/ext2\/ext3/ext4}" SPACE=$(df --output=avail -B 1 "$STORAGE" | tail -n 1) SPACE_GB=$(( (SPACE + 1073741823)/1073741824 )) -echo "❯ CPU: ${CPU} | RAM: ${RAM} | DISK: $SPACE_GB GB (${FS}) | HOST: ${SYS}..." +echo "❯ CPU: ${CPU} | RAM: $AVAIL_GB/$TOTAL_GB GB | DISK: $SPACE_GB GB (${FS}) | HOST: ${SYS}..." echo +# Check memory + +if (( RAM_WANTED > RAM_AVAIL )); then + error "You configured RAM_SIZE to $WANTED_GB GB, but your system has only $AVAIL_GB GB available right now." + exit 15 +fi + +if (( (RAM_WANTED + 1950000000) > RAM_AVAIL )); then + warn "you configured RAM_SIZE to $WANTED_GB GB, but that is much too close to the $AVAIL_GB GB you have available." +fi + # Helper functions isAlive() { From 388335d03dff54ff2da442e17cd40364438017b3 Mon Sep 17 00:00:00 2001 From: Kroese Date: Thu, 2 May 2024 19:35:22 +0200 Subject: [PATCH 08/12] Update config.sh --- src/config.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.sh b/src/config.sh index 8c962caa..b05ea0c1 100644 --- a/src/config.sh +++ b/src/config.sh @@ -8,7 +8,7 @@ set -Eeuo pipefail DEF_OPTS="-nodefaults" SERIAL_OPTS="-serial $SERIAL" USB_OPTS="-device $USB -device usb-tablet" -RAM_OPTS=$(echo "-m $RAM_SIZE" | sed 's/MB/M/g;s/GB/G/g;s/TB/T/g') +RAM_OPTS=$(echo "-m ${RAM_SIZE^^}" | sed 's/MB/M/g;s/GB/G/g;s/TB/T/g') CPU_OPTS="-cpu $CPU_FLAGS -smp $CPU_CORES,sockets=1,dies=1,cores=$CPU_CORES,threads=1" MON_OPTS="-monitor $MONITOR -name $PROCESS,process=$PROCESS,debug-threads=on" MAC_OPTS="-machine type=${MACHINE}${SECURE},graphics=off,vmport=off,dump-guest-core=off,hpet=off${KVM_OPTS}" From c12046302039eb491c42d39af7e977f6416cd62c Mon Sep 17 00:00:00 2001 From: Kroese Date: Thu, 2 May 2024 19:44:34 +0200 Subject: [PATCH 09/12] Update reset.sh --- src/reset.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/reset.sh b/src/reset.sh index 0c09d86a..2d758831 100644 --- a/src/reset.sh +++ b/src/reset.sh @@ -60,8 +60,9 @@ if [ ! -d "$STORAGE" ]; then fi # Read memory -RAM_AVAIL=$(free | grep Mem: | awk '{print $7}') -RAM_TOTAL=$(free | grep Mem: | awk '{print $2}') +RAM_AVAIL=$(free | grep -m 1 Mem: | awk '{print $7}') +RAM_TOTAL=$(free | grep -m 1 Mem: | awk '{print $2}') +RAM_SIZE=$(echo "${RAM_SIZE^^}" | sed 's/MB/M/g;s/GB/G/g;s/TB/T/g') RAM_WANTED=$(numfmt --from=iec "$RAM_SIZE") AVAIL_GB=$(( (RAM_AVAIL + 1073741823)/1073741824 )) TOTAL_GB=$(( (RAM_TOTAL + 1073741823)/1073741824 )) From 86d05c722479217b7460e4ffd91555a286000fb4 Mon Sep 17 00:00:00 2001 From: Kroese Date: Thu, 2 May 2024 19:49:32 +0200 Subject: [PATCH 10/12] Update reset.sh --- src/reset.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/reset.sh b/src/reset.sh index 2d758831..d96c6833 100644 --- a/src/reset.sh +++ b/src/reset.sh @@ -60,13 +60,13 @@ if [ ! -d "$STORAGE" ]; then fi # Read memory -RAM_AVAIL=$(free | grep -m 1 Mem: | awk '{print $7}') -RAM_TOTAL=$(free | grep -m 1 Mem: | awk '{print $2}') +RAM_AVAIL=$(free -b | grep -m 1 Mem: | awk '{print $7}') +RAM_TOTAL=$(free -b | grep -m 1 Mem: | awk '{print $2}') RAM_SIZE=$(echo "${RAM_SIZE^^}" | sed 's/MB/M/g;s/GB/G/g;s/TB/T/g') RAM_WANTED=$(numfmt --from=iec "$RAM_SIZE") AVAIL_GB=$(( (RAM_AVAIL + 1073741823)/1073741824 )) TOTAL_GB=$(( (RAM_TOTAL + 1073741823)/1073741824 )) -WANTED_GB=$(( (RAM_TOTAL + 1073741823)/1073741824 )) +WANTED_GB=$(( (RAM_WANTED + 1073741823)/1073741824 )) # Print system info SYS="${SYS/-generic/}" From b0c247a1279c9fe829ed3f47c5c4014a47bafcbb Mon Sep 17 00:00:00 2001 From: Kroese Date: Thu, 2 May 2024 19:51:06 +0200 Subject: [PATCH 11/12] Update reset.sh --- src/reset.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/reset.sh b/src/reset.sh index d96c6833..0f63380a 100644 --- a/src/reset.sh +++ b/src/reset.sh @@ -81,12 +81,12 @@ echo # Check memory if (( RAM_WANTED > RAM_AVAIL )); then - error "You configured RAM_SIZE to $WANTED_GB GB, but your system has only $AVAIL_GB GB available right now." + error "You configured RAM_SIZE to $WANTED_GB GB, but your system has only $AVAIL_GB GB of memory available right now." exit 15 fi if (( (RAM_WANTED + 1950000000) > RAM_AVAIL )); then - warn "you configured RAM_SIZE to $WANTED_GB GB, but that is much too close to the $AVAIL_GB GB you have available." + warn "you configured RAM_SIZE to $WANTED_GB GB, but that is much too close to the $AVAIL_GB GB of memory you have available." fi # Helper functions From 82dca3457ae2d4b0c483471d086376c2c89d95eb Mon Sep 17 00:00:00 2001 From: Kroese Date: Thu, 2 May 2024 19:54:37 +0200 Subject: [PATCH 12/12] Update reset.sh --- src/reset.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/reset.sh b/src/reset.sh index 0f63380a..1a4adc51 100644 --- a/src/reset.sh +++ b/src/reset.sh @@ -81,12 +81,12 @@ echo # Check memory if (( RAM_WANTED > RAM_AVAIL )); then - error "You configured RAM_SIZE to $WANTED_GB GB, but your system has only $AVAIL_GB GB of memory available right now." + error "Your configured RAM_SIZE of $WANTED_GB GB is higher than the $AVAIL_GB GB of memory available." exit 15 fi if (( (RAM_WANTED + 1950000000) > RAM_AVAIL )); then - warn "you configured RAM_SIZE to $WANTED_GB GB, but that is much too close to the $AVAIL_GB GB of memory you have available." + warn "your configured RAM_SIZE of $WANTED_GB GB is much too close to the $AVAIL_GB GB of memory available." fi # Helper functions