diff --git a/Dockerfile b/Dockerfile index 156c4a1..9d37f1d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,11 +9,13 @@ FROM qemux/qemu-host as builder FROM debian:trixie-slim +ARG TARGETPLATFORM ARG DEBCONF_NOWARNINGS="yes" ARG DEBIAN_FRONTEND noninteractive -RUN apt-get update && apt-get -y upgrade && \ - apt-get --no-install-recommends -y install \ +RUN apt-get update && apt-get -y upgrade \ + && if [ "$TARGETPLATFORM" != "linux/amd64" ]; then extra="qemu-user"; fi \ + && apt-get --no-install-recommends -y install \ jq \ tini \ curl \ @@ -32,6 +34,7 @@ RUN apt-get update && apt-get -y upgrade && \ ca-certificates \ netcat-openbsd \ qemu-system-x86 \ + "$extra" \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* diff --git a/src/config.sh b/src/config.sh index 60e6c05..05fc7a3 100644 --- a/src/config.sh +++ b/src/config.sh @@ -1,29 +1,9 @@ #!/bin/bash set -Eeuo pipefail -KVM_ERR="" -KVM_OPTS="" - -if [ -e /dev/kvm ] && sh -c 'echo -n > /dev/kvm' &> /dev/null; then - if ! grep -q -e vmx -e svm /proc/cpuinfo; then - KVM_ERR="(vmx/svm disabled)" - fi -else - [ -e /dev/kvm ] && KVM_ERR="(no write access)" || KVM_ERR="(device file missing)" -fi - -if [ -n "$KVM_ERR" ]; then - if [ "$ARCH" == "amd64" ]; then - error "KVM acceleration not detected $KVM_ERR, see the FAQ about this." - [[ "$DEBUG" != [Yy1]* ]] && exit 88 - fi -else - KVM_OPTS=",accel=kvm -enable-kvm -cpu host" -fi - DEF_OPTS="-nographic -nodefaults -boot strict=on -display none" RAM_OPTS=$(echo "-m $RAM_SIZE" | sed 's/MB/M/g;s/GB/G/g;s/TB/T/g') -CPU_OPTS="-smp $CPU_CORES,sockets=1,dies=1,cores=$CPU_CORES,threads=1" +CPU_OPTS="-cpu $CPU_MODEL -smp $CPU_CORES,sockets=1,dies=1,cores=$CPU_CORES,threads=1" MAC_OPTS="-machine type=q35,usb=off,dump-guest-core=off,hpet=off${KVM_OPTS}" EXTRA_OPTS="-device virtio-balloon-pci,id=balloon0,bus=pcie.0,addr=0x4" EXTRA_OPTS="$EXTRA_OPTS -object rng-random,id=objrng0,filename=/dev/urandom" diff --git a/src/cpu.sh b/src/cpu.sh new file mode 100644 index 0000000..edb8800 --- /dev/null +++ b/src/cpu.sh @@ -0,0 +1,60 @@ +#!/bin/bash +set -Eeuo pipefail + +# Docker environment variables + +: ${HOST_CPU:=''} +: ${CPU_MODEL:='host'} +: ${CPU_FEATURES:='+ssse3,+sse4.1,+sse4.2'} + +KVM_ERR="" +KVM_OPTS="" + +if [[ "$ARCH" == "amd64" && "$KVM" != [Nn]* ]]; then + + if [ -e /dev/kvm ] && sh -c 'echo -n > /dev/kvm' &> /dev/null; then + if ! grep -q -e vmx -e svm /proc/cpuinfo; then + KVM_ERR="(vmx/svm disabled)" + fi + else + [ -e /dev/kvm ] && KVM_ERR="(no write access)" || KVM_ERR="(device file missing)" + fi + + if [ -n "$KVM_ERR" ]; then + error "KVM acceleration not detected $KVM_ERR, this will cause a major loss of performance." + error "See the FAQ on how to enable it, or skip this error by setting KVM=N (not recommended)." + [[ "$DEBUG" != [Yy1]* ]] && exit 88 + [[ "$CPU_MODEL" == "host"* ]] && CPU_MODEL="max,$CPU_FEATURES" + else + KVM_OPTS=",accel=kvm -enable-kvm" + fi + + if [[ "$CPU_MODEL" != *"$CPU_FEATURES"* ]]; then + if ! grep -qE '^flags.* (sse4_2)' /proc/cpuinfo; then + info "Your CPU does not have the SSE4.2 instruction set that DSM needs, it will be emulated.." + CPU_MODEL="host,$CPU_FEATURES" + fi + fi + +else + + [[ "$CPU_MODEL" == "host"* ]] && CPU_MODEL="max,$CPU_FEATURES" + +fi + +if [ -z "$HOST_CPU" ]; then + HOST_CPU=$(lscpu | grep 'Model name' | cut -f 2 -d ":" | awk '{$1=$1}1' | sed 's# @.*##g' | sed s/"(R)"//g | sed 's/[^[:alnum:] ]\+/ /g' | sed 's/ */ /g') +fi + +if [ -n "$HOST_CPU" ]; then + HOST_CPU="${HOST_CPU%%,*},," +else + HOST_CPU="QEMU, Virtual CPU," + if [ "$ARCH" == "amd64" ]; then + HOST_CPU="$HOST_CPU X86_64" + else + HOST_CPU="$HOST_CPU $ARCH" + fi +fi + +return 0 diff --git a/src/disk.sh b/src/disk.sh index e89bcf6..fee7afd 100644 --- a/src/disk.sh +++ b/src/disk.sh @@ -34,7 +34,7 @@ fmt2ext() { echo "img" ;; *) - error "Unrecognized disk format: $DISK_FMT" && exit 88 + error "Unrecognized disk format: $DISK_FMT" && exit 78 ;; esac } @@ -50,7 +50,7 @@ ext2fmt() { echo "raw" ;; *) - error "Unrecognized file extension: .$DISK_EXT" && exit 88 + error "Unrecognized file extension: .$DISK_EXT" && exit 78 ;; esac } @@ -70,7 +70,7 @@ getSize() { qemu-img info "$DISK_FILE" -f "$DISK_FMT" | grep '^virtual size: ' | sed 's/.*(\(.*\) bytes)/\1/' ;; *) - error "Unrecognized disk format: $DISK_FMT" && exit 88 + error "Unrecognized disk format: $DISK_FMT" && exit 78 ;; esac } @@ -89,7 +89,7 @@ resizeDisk() { FAIL="Could not resize $DISK_FMT file of $DISK_DESC ($DISK_FILE) from ${GB}G to $DISK_SPACE .." REQ=$((DATA_SIZE-CUR_SIZE)) - (( REQ < 1 )) && error "Shrinking disks is not supported!" && exit 84 + (( REQ < 1 )) && error "Shrinking disks is not supported!" && exit 71 case "${DISK_FMT,,}" in raw) @@ -97,7 +97,7 @@ resizeDisk() { # Resize file by changing its length if ! truncate -s "$DISK_SPACE" "$DISK_FILE"; then - error "$FAIL" && exit 85 + error "$FAIL" && exit 75 fi else @@ -108,13 +108,13 @@ resizeDisk() { if (( REQ > SPACE )); then error "Not enough free space to resize $DISK_DESC to $DISK_SPACE in $DIR, it has only $SPACE_GB GB available.." - error "Please specify a smaller ${DISK_DESC^^}_SIZE or disable preallocation by setting DISK_FMT to \"qcow2\"." && exit 84 + error "Please specify a smaller ${DISK_DESC^^}_SIZE or disable preallocation by setting DISK_FMT to \"qcow2\"." && exit 74 fi # Resize file by allocating more space if ! fallocate -l "$DISK_SPACE" "$DISK_FILE"; then if ! truncate -s "$DISK_SPACE" "$DISK_FILE"; then - error "$FAIL" && exit 85 + error "$FAIL" && exit 75 fi fi @@ -122,7 +122,7 @@ resizeDisk() { ;; qcow2) if ! qemu-img resize -f "$DISK_FMT" "$DISK_FILE" "$DISK_SPACE" ; then - error "$FAIL" && exit 85 + error "$FAIL" && exit 72 fi ;; esac @@ -161,7 +161,7 @@ createDisk() { # Create an empty file if ! truncate -s "$DISK_SPACE" "$DISK_FILE"; then rm -f "$DISK_FILE" - error "$FAIL" && exit 87 + error "$FAIL" && exit 77 fi else @@ -172,14 +172,14 @@ createDisk() { if (( DATA_SIZE > SPACE )); then error "Not enough free space to create a $DISK_DESC of $DISK_SPACE in $DIR, it has only $SPACE_GB GB available.." - error "Please specify a smaller ${DISK_DESC^^}_SIZE or disable preallocation by setting DISK_FMT to \"qcow2\"." && exit 86 + error "Please specify a smaller ${DISK_DESC^^}_SIZE or disable preallocation by setting DISK_FMT to \"qcow2\"." && exit 76 fi # Create an empty file if ! fallocate -l "$DISK_SPACE" "$DISK_FILE"; then if ! truncate -s "$DISK_SPACE" "$DISK_FILE"; then rm -f "$DISK_FILE" - error "$FAIL" && exit 87 + error "$FAIL" && exit 77 fi fi @@ -188,7 +188,7 @@ createDisk() { qcow2) if ! qemu-img create -f "$DISK_FMT" -- "$DISK_FILE" "$DISK_SPACE" ; then rm -f "$DISK_FILE" - error "$FAIL" && exit 89 + error "$FAIL" && exit 70 fi ;; esac @@ -219,7 +219,7 @@ addDisk () { DATA_SIZE=$(numfmt --from=iec "$DISK_SPACE") if (( DATA_SIZE < 6442450944 )); then - error "Please increase ${DISK_DESC^^}_SIZE to at least 6 GB." && exit 83 + error "Please increase ${DISK_DESC^^}_SIZE to at least 6 GB." && exit 73 fi if ! [ -f "$DISK_FILE" ] ; then @@ -243,7 +243,7 @@ addDisk () { if ! convertDisk "$PREV_FILE" "$PREV_FMT" "$TMP_FILE" "$DISK_FMT" ; then rm -f "$TMP_FILE" - error "Failed to convert $DISK_DESC to $DISK_FMT format." && exit 89 + error "Failed to convert $DISK_DESC to $DISK_FMT format." && exit 79 fi mv "$TMP_FILE" "$DISK_FILE" diff --git a/src/entry.sh b/src/entry.sh index c936130..d9ba03f 100755 --- a/src/entry.sh +++ b/src/entry.sh @@ -11,6 +11,7 @@ cd /run . disk.sh # Initialize disks . network.sh # Initialize network . gpu.sh # Initialize graphics +. cpu.sh # Initialize processor . serial.sh # Initialize serialport . power.sh # Configure shutdown . config.sh # Configure arguments diff --git a/src/install.sh b/src/install.sh index dfb7420..aa106a4 100644 --- a/src/install.sh +++ b/src/install.sh @@ -33,13 +33,7 @@ if [ -z "$DL" ]; then [[ "${COUNTRY^^}" == "CN" ]] && DL="$DL_CHINA" || DL="$DL_GLOBAL" fi -if [ -z "$URL" ]; then - if [ "$ARCH" == "amd64" ]; then - URL="$DL/release/7.2.1/69057-1/DSM_VirtualDSM_69057.pat" - else - URL="$DL/release/7.0.1/42218/DSM_VirtualDSM_42218.pat" - fi -fi +[ -z "$URL" ] && URL="$DL/release/7.2.1/69057-1/DSM_VirtualDSM_69057.pat" BASE=$(basename "$URL" .pat) @@ -205,8 +199,6 @@ if { tar tf "$PAT"; } >/dev/null 2>&1; then else - [ "$ARCH" != "amd64" ] && addPackage "qemu-user" "QEMU" - info "Install: Extracting downloaded image..." export LD_LIBRARY_PATH="/run/extract" @@ -242,16 +234,16 @@ SYSTEM_SIZE=4954537983 # Check free diskspace SPACE=$(df --output=avail -B 1 "$TMP" | tail -n 1) SPACE_GB=$(( (SPACE + 1073741823)/1073741824 )) -(( SYSTEM_SIZE > SPACE )) && error "Not enough free space to create a 4 GB system disk, have only $SPACE_GB GB available." && exit 87 +(( SYSTEM_SIZE > SPACE )) && error "Not enough free space to create a 4 GB system disk, have only $SPACE_GB GB available." && exit 97 if ! fallocate -l "$SYSTEM_SIZE" "$SYSTEM"; then if ! truncate -s "$SYSTEM_SIZE" "$SYSTEM"; then - rm -f "$SYSTEM" && error "Could not allocate a file for the system disk." && exit 88 + rm -f "$SYSTEM" && error "Could not allocate a file for the system disk." && exit 98 fi fi # Check if file exists -[ ! -f "$SYSTEM" ] && error "System disk does not exist ($SYSTEM)" && exit 89 +[ ! -f "$SYSTEM" ] && error "System disk does not exist ($SYSTEM)" && exit 99 # Check the filesize SIZE=$(stat -c%s "$SYSTEM") diff --git a/src/network.sh b/src/network.sh index eed1b52..c498549 100644 --- a/src/network.sh +++ b/src/network.sh @@ -187,7 +187,7 @@ if [ ! -c /dev/net/tun ]; then chmod 666 /dev/net/tun fi -[ ! -c /dev/net/tun ] && error "TUN network interface not available..." && exit 85 +[ ! -c /dev/net/tun ] && error "TUN network interface not available..." && exit 25 # Create the necessary file structure for /dev/vhost-net if [ ! -c /dev/vhost-net ]; then @@ -212,7 +212,7 @@ if [[ "$DHCP" == [Yy1]* ]]; then if [[ "$DEBUG" == [Yy1]* ]]; then info "Warning: Are you sure the container is on a macvlan network?" else - error "You can only enable DHCP while the container is on a macvlan network!" && exit 86 + error "You can only enable DHCP while the container is on a macvlan network!" && exit 26 fi fi diff --git a/src/reset.sh b/src/reset.sh index d142d30..e2ac97a 100644 --- a/src/reset.sh +++ b/src/reset.sh @@ -11,10 +11,11 @@ trap 'error "Status $? while: $BASH_COMMAND (line $LINENO/$BASH_LINENO)"' ERR # Docker environment variables -: ${GPU:='N'} # Enable GPU passthrough -: ${DEBUG:='N'} # Enable debugging mode +: ${GPU:='N'} # Disable GPU passthrough +: ${KVM:='Y'} # Enable KVM acceleration +: ${DEBUG:='N'} # Disable debugging mode : ${COUNTRY:=''} # Country code for mirror -: ${CONSOLE:='N'} # Start in console mode +: ${CONSOLE:='N'} # Disable console mode : ${ALLOCATE:='Y'} # Preallocate diskspace : ${ARGUMENTS:=''} # Extra QEMU parameters : ${CPU_CORES:='1'} # Amount of CPU cores diff --git a/src/serial.sh b/src/serial.sh index 924497c..db473ef 100644 --- a/src/serial.sh +++ b/src/serial.sh @@ -3,27 +3,12 @@ set -Eeuo pipefail # Docker environment variables -: ${HOST_CPU:=''} : ${HOST_MAC:=''} : ${HOST_DEBUG:=''} : ${HOST_SERIAL:=''} : ${HOST_MODEL:=''} : ${GUEST_SERIAL:=''} -if [ -z "$HOST_CPU" ]; then - HOST_CPU=$(lscpu | grep 'Model name' | cut -f 2 -d ":" | awk '{$1=$1}1' | sed 's# @.*##g' | sed s/"(R)"//g | sed 's/[^[:alnum:] ]\+/ /g' | sed 's/ */ /g') -fi - -if [ -n "$HOST_CPU" ]; then - HOST_CPU="$HOST_CPU,," -else - if [ "$ARCH" == "amd64" ]; then - HOST_CPU="QEMU, Virtual CPU, X86_64" - else - HOST_CPU="QEMU, Virtual CPU, $ARCH" - fi -fi - HOST_ARGS=() HOST_ARGS+=("-cpu=$CPU_CORES") HOST_ARGS+=("-cpu_arch=$HOST_CPU")