Compare commits

...

8 Commits
v5.19 ... v5.22

Author SHA1 Message Date
Kroese
4c67343d33 feat: Enable L3 cache and multi-threaded TCG (#618) 2024-02-04 19:25:22 +01:00
Kroese
53cc6998f0 fix: CPU features 2024-02-02 22:44:43 +01:00
Kroese
d857d71e0d fix: Merge drive function (#614) 2024-02-01 11:05:33 +01:00
Kroese
003c2766ce docs: Readme (#613) 2024-01-31 04:28:24 +01:00
Kroese
78594098cc feat: Disable CoW check on ZFS (#612) 2024-01-31 03:54:40 +01:00
Kroese
3c31bc91e4 feat: Generate unique MAC address (#611) 2024-01-30 04:46:44 +01:00
Kroese
72141bab7a build: Lint Dockerfile (#610) 2024-01-29 11:51:28 +01:00
Kroese
bc52463aa4 fix: Process signal faster (#609) 2024-01-29 05:54:22 +01:00
11 changed files with 97 additions and 47 deletions

View File

@@ -7,8 +7,18 @@ jobs:
name: shellcheck name: shellcheck
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 -
- name: Run ShellCheck name: Checkout
uses: actions/checkout@v4
-
name: Run ShellCheck
uses: ludeeus/action-shellcheck@master uses: ludeeus/action-shellcheck@master
env: env:
SHELLCHECK_OPTS: -x --source-path=src -e SC2001 -e SC2034 -e SC2064 -e SC2317 -e SC2153 -e SC2028 SHELLCHECK_OPTS: -x --source-path=src -e SC2001 -e SC2034 -e SC2064 -e SC2317 -e SC2153 -e SC2028
-
name: Lint Dockerfile
uses: hadolint/hadolint-action@v3.1.0
with:
dockerfile: Dockerfile
ignore: DL3008,DL3003,DL3006
failure-threshold: warning

View File

@@ -3,6 +3,7 @@ on:
pull_request: pull_request:
paths: paths:
- '**/*.sh' - '**/*.sh'
- 'Dockerfile'
- '.github/workflows/test.yml' - '.github/workflows/test.yml'
- '.github/workflows/check.yml' - '.github/workflows/check.yml'

View File

@@ -189,7 +189,7 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
After configuring the container for macvlan (see above), it is possible for DSM to become part of your home network by requesting an IP from your router, just like your other devices. After configuring the container for macvlan (see above), it is possible for DSM to become part of your home network by requesting an IP from your router, just like your other devices.
To enable this feature, add the following lines to your compose file: To enable this mode, add the following lines to your compose file:
```yaml ```yaml
environment: environment:
@@ -198,7 +198,7 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
- 'c *:* rwm' - 'c *:* rwm'
``` ```
Please note that even if you don't want DHCP, it's still recommended to enable this feature, as it prevents NAT issues and increases performance by using a `macvtap` interface. In that case, just set a static IP from the DSM control panel after you enabled this mode. Please note that even if you don't need DHCP, it's still recommended to enable this mode, as it prevents NAT issues and increases performance by using a `macvtap` interface. You can just set a static IP from the DSM control panel afterwards.
* ### How do I pass-through the GPU? * ### How do I pass-through the GPU?

View File

@@ -80,7 +80,7 @@ getSize() {
isCow() { isCow() {
local FS=$1 local FS=$1
if [[ "${FS,,}" == "xfs" || "${FS,,}" == "zfs" || "${FS,,}" == "btrfs" || "${FS,,}" == "bcachefs" ]]; then if [[ "${FS,,}" == "xfs" || "${FS,,}" == "btrfs" || "${FS,,}" == "bcachefs" ]]; then
return 0 return 0
fi fi
@@ -341,6 +341,21 @@ checkFS () {
return 0 return 0
} }
createDevice () {
local DISK_ID=$1
local DISK_FILE=$2
local DISK_INDEX=$3
local DISK_ADDRESS=$4
local DISK_FMT=$5
echo "-drive file=$DISK_FILE,if=none,id=drive-$DISK_ID,format=$DISK_FMT,cache=$DISK_CACHE,aio=$DISK_IO,discard=$DISK_DISCARD,detect-zeroes=on \
-device virtio-scsi-pci,id=hw-$DISK_ID,iothread=io2,bus=pcie.0,addr=$DISK_ADDRESS \
-device scsi-hd,bus=hw-$DISK_ID.0,channel=0,scsi-id=0,lun=0,drive=drive-$DISK_ID,id=$DISK_ID,rotation_rate=$DISK_ROTATION,bootindex=$DISK_INDEX"
return 0
}
addDisk () { addDisk () {
local DISK_ID=$1 local DISK_ID=$1
local DISK_BASE=$2 local DISK_BASE=$2
@@ -351,7 +366,7 @@ addDisk () {
local DISK_ADDRESS=$7 local DISK_ADDRESS=$7
local DISK_FMT=$8 local DISK_FMT=$8
local DISK_FILE="$DISK_BASE.$DISK_EXT" local DISK_FILE="$DISK_BASE.$DISK_EXT"
local DIR DATA_SIZE FS PREV_FMT PREV_EXT CUR_SIZE local DIR DATA_SIZE FS PREV_FMT PREV_EXT CUR_SIZE OPTS
DIR=$(dirname "$DISK_FILE") DIR=$(dirname "$DISK_FILE")
[ ! -d "$DIR" ] && return 0 [ ! -d "$DIR" ] && return 0
@@ -399,10 +414,8 @@ addDisk () {
fi fi
DISK_OPTS="$DISK_OPTS \ OPTS=$(createDevice "$DISK_ID" "$DISK_FILE" "$DISK_INDEX" "$DISK_ADDRESS" "$DISK_FMT")
-device virtio-scsi-pci,id=hw-$DISK_ID,iothread=io2,bus=pcie.0,addr=$DISK_ADDRESS \ DISK_OPTS="$DISK_OPTS $OPTS"
-drive file=$DISK_FILE,if=none,id=drive-$DISK_ID,format=$DISK_FMT,cache=$DISK_CACHE,aio=$DISK_IO,discard=$DISK_DISCARD,detect-zeroes=on \
-device scsi-hd,bus=hw-$DISK_ID.0,channel=0,scsi-id=0,lun=0,drive=drive-$DISK_ID,id=$DISK_ID,rotation_rate=$DISK_ROTATION,bootindex=$DISK_INDEX"
return 0 return 0
} }
@@ -418,10 +431,9 @@ addDevice () {
[ -z "$DISK_DEV" ] && return 0 [ -z "$DISK_DEV" ] && return 0
[ ! -b "$DISK_DEV" ] && error "Device $DISK_DEV cannot be found! Please add it to the 'devices' section of your compose file." && exit 55 [ ! -b "$DISK_DEV" ] && error "Device $DISK_DEV cannot be found! Please add it to the 'devices' section of your compose file." && exit 55
DISK_OPTS="$DISK_OPTS \ local OPTS
-device virtio-scsi-pci,id=hw-$DISK_ID,iothread=io2,bus=pcie.0,addr=$DISK_ADDRESS \ OPTS=$(createDevice "$DISK_ID" "$DISK_DEV" "$DISK_INDEX" "$DISK_ADDRESS" "raw")
-drive file=$DISK_DEV,if=none,id=drive-$DISK_ID,format=raw,cache=$DISK_CACHE,aio=$DISK_IO,discard=$DISK_DISCARD,detect-zeroes=on \ DISK_OPTS="$DISK_OPTS $OPTS"
-device scsi-hd,bus=hw-$DISK_ID.0,channel=0,scsi-id=0,lun=0,drive=drive-$DISK_ID,id=$DISK_ID,rotation_rate=$DISK_ROTATION,bootindex=$DISK_INDEX"
return 0 return 0
} }

View File

@@ -15,7 +15,8 @@ if [[ "$GPU" != [Yy1]* ]] || [[ "$ARCH" != "amd64" ]]; then
fi fi
DISPLAY_OPTS="-display egl-headless,rendernode=/dev/dri/renderD128 -vga $VGA" DISPLAY_OPTS="-display egl-headless,rendernode=/dev/dri/renderD128"
DISPLAY_OPTS="$DISPLAY_OPTS -vga $VGA"
[ ! -d /dev/dri ] && mkdir -m 755 /dev/dri [ ! -d /dev/dri ] && mkdir -m 755 /dev/dri

View File

@@ -265,7 +265,7 @@ if ! touch "$SYSTEM"; then
error "Could not create file $SYSTEM for the system disk." && exit 98 error "Could not create file $SYSTEM for the system disk." && exit 98
fi fi
if [[ "${FS,,}" == "xfs" || "${FS,,}" == "zfs" || "${FS,,}" == "btrfs" || "${FS,,}" == "bcachefs" ]]; then if [[ "${FS,,}" == "xfs" || "${FS,,}" == "btrfs" || "${FS,,}" == "bcachefs" ]]; then
{ chattr +C "$SYSTEM"; } || : { chattr +C "$SYSTEM"; } || :
FA=$(lsattr "$SYSTEM") FA=$(lsattr "$SYSTEM")
if [[ "$FA" != *"C"* ]]; then if [[ "$FA" != *"C"* ]]; then

View File

@@ -3,8 +3,8 @@ set -Eeuo pipefail
# Docker environment variables # Docker environment variables
: "${MAC:=""}"
: "${DHCP:="N"}" : "${DHCP:="N"}"
: "${MAC:="02:11:32:AA:BB:CC"}"
: "${VM_NET_DEV:=""}" : "${VM_NET_DEV:=""}"
: "${VM_NET_TAP:="dsm"}" : "${VM_NET_TAP:="dsm"}"
@@ -33,7 +33,7 @@ configureDHCP() {
fi fi
while ! ip link set "$VM_NET_TAP" up; do while ! ip link set "$VM_NET_TAP" up; do
info "Waiting for address to become available..." info "Waiting for MAC address $VM_NET_MAC to become available..."
sleep 2 sleep 2
done done
@@ -117,7 +117,6 @@ configureNAT() {
# Create a bridge with a static IP for the VM guest # Create a bridge with a static IP for the VM guest
VM_NET_IP='20.20.20.21' VM_NET_IP='20.20.20.21'
[[ "$DEBUG" == [Yy1]* ]] && set -x
{ ip link add dev dockerbridge type bridge ; rc=$?; } || : { ip link add dev dockerbridge type bridge ; rc=$?; } || :
@@ -128,7 +127,7 @@ configureNAT() {
ip address add ${VM_NET_IP%.*}.1/24 broadcast ${VM_NET_IP%.*}.255 dev dockerbridge ip address add ${VM_NET_IP%.*}.1/24 broadcast ${VM_NET_IP%.*}.255 dev dockerbridge
while ! ip link set dockerbridge up; do while ! ip link set dockerbridge up; do
info "Waiting for address to become available..." info "Waiting for IP address to become available..."
sleep 2 sleep 2
done done
@@ -136,7 +135,7 @@ configureNAT() {
ip tuntap add dev "$VM_NET_TAP" mode tap ip tuntap add dev "$VM_NET_TAP" mode tap
while ! ip link set "$VM_NET_TAP" up promisc on; do while ! ip link set "$VM_NET_TAP" up promisc on; do
info "Waiting for tap to become available..." info "Waiting for TAP to become available..."
sleep 2 sleep 2
done done
@@ -155,9 +154,6 @@ configureNAT() {
iptables -A POSTROUTING -t mangle -p udp --dport bootpc -j CHECKSUM --checksum-fill || true iptables -A POSTROUTING -t mangle -p udp --dport bootpc -j CHECKSUM --checksum-fill || true
fi fi
{ set +x; } 2>/dev/null
[[ "$DEBUG" == [Yy1]* ]] && echo
NET_OPTS="-netdev tap,ifname=$VM_NET_TAP,script=no,downscript=no,id=hostnet0" NET_OPTS="-netdev tap,ifname=$VM_NET_TAP,script=no,downscript=no,id=hostnet0"
{ exec 40>>/dev/vhost-net; rc=$?; } 2>/dev/null || : { exec 40>>/dev/vhost-net; rc=$?; } 2>/dev/null || :
@@ -211,14 +207,20 @@ getInfo() {
error "$ADD_ERR -e \"VM_NET_DEV=NAME\" to specify another interface name." && exit 27 error "$ADD_ERR -e \"VM_NET_DEV=NAME\" to specify another interface name." && exit 27
fi fi
VM_NET_MAC="${VM_NET_MAC//-/:}" if [ -z "$VM_NET_MAC" ]; then
# Generate MAC address based on Docker container ID in hostname
VM_NET_MAC=$(echo "$HOST" | md5sum | sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:11:32:\3:\4:\5/')
fi
VM_NET_MAC="${VM_NET_MAC,,//-/:}"
if [[ ${#VM_NET_MAC} == 12 ]]; then if [[ ${#VM_NET_MAC} == 12 ]]; then
m="$VM_NET_MAC" m="$VM_NET_MAC"
VM_NET_MAC="${m:0:2}:${m:2:2}:${m:4:2}:${m:6:2}:${m:8:2}:${m:10:2}" VM_NET_MAC="${m:0:2}:${m:2:2}:${m:4:2}:${m:6:2}:${m:8:2}:${m:10:2}"
fi fi
if [[ ${#VM_NET_MAC} != 17 ]]; then if [[ ${#VM_NET_MAC} != 17 ]]; then
error "Invalid mac address: '$VM_NET_MAC', should be 12 or 17 digits long!" && exit 28 error "Invalid MAC address: '$VM_NET_MAC', should be 12 or 17 digits long!" && exit 28
fi fi
GATEWAY=$(ip r | grep default | awk '{print $3}') GATEWAY=$(ip r | grep default | awk '{print $3}')
@@ -242,15 +244,15 @@ getInfo
html "Initializing network..." html "Initializing network..."
if [[ "$DEBUG" == [Yy1]* ]]; then if [[ "$DEBUG" == [Yy1]* ]]; then
info "Container IP is $IP with gateway $GATEWAY on interface $VM_NET_DEV" && echo info "Host: $HOST IP: $IP Gateway: $GATEWAY Interface: $VM_NET_DEV MAC: $VM_NET_MAC"
[ -f /etc/resolv.conf ] && grep '^nameserver*' /etc/resolv.conf
echo
fi fi
if [[ "$DHCP" == [Yy1]* ]]; then if [[ "$DHCP" == [Yy1]* ]]; then
if [[ "$GATEWAY" == "172."* ]]; then if [[ "$GATEWAY" == "172."* ]] && [[ "$DEBUG" != [Yy1]* ]]; then
if [[ "$DEBUG" != [Yy1]* ]]; then error "You can only enable DHCP while the container is on a macvlan network!" && exit 26
error "You can only enable DHCP while the container is on a macvlan network!" && exit 26
fi
fi fi
# Configuration for DHCP IP # Configuration for DHCP IP

View File

@@ -6,7 +6,7 @@ set -Eeuo pipefail
: "${KVM:="Y"}" : "${KVM:="Y"}"
: "${HOST_CPU:=""}" : "${HOST_CPU:=""}"
: "${CPU_FLAGS:=""}" : "${CPU_FLAGS:=""}"
: "${CPU_MODEL:="host"}" : "${CPU_MODEL:="qemu64"}"
[ "$ARCH" != "amd64" ] && KVM="N" [ "$ARCH" != "amd64" ] && KVM="N"
@@ -37,8 +37,9 @@ fi
if [[ "$KVM" != [Nn]* ]]; then if [[ "$KVM" != [Nn]* ]]; then
CPU_FEATURES="kvm=on" CPU_MODEL="host"
KVM_OPTS=",accel=kvm -enable-kvm" KVM_OPTS=",accel=kvm -enable-kvm"
CPU_FEATURES="kvm=on,l3-cache=on,migratable=no"
if ! grep -qE '^flags.* (sse4_2)' /proc/cpuinfo; then if ! grep -qE '^flags.* (sse4_2)' /proc/cpuinfo; then
error "Your host CPU does not have the SSE4.2 instruction set that Virtual DSM requires to boot." error "Your host CPU does not have the SSE4.2 instruction set that Virtual DSM requires to boot."
@@ -49,23 +50,30 @@ if [[ "$KVM" != [Nn]* ]]; then
else else
KVM_OPTS="" KVM_OPTS=""
CPU_FEATURES="+ssse3,+sse4.1,+sse4.2" CPU_FEATURES="l3-cache=on"
if [[ "${CPU_MODEL,,}" == "host"* ]]; then
if [[ "$ARCH" == "amd64" ]]; then
CPU_MODEL="max"
else
CPU_MODEL="qemu64"
fi
if [[ "$ARCH" == "amd64" ]]; then
CPU_MODEL="max"
KVM_OPTS=" -accel tcg,thread=multi"
CPU_FEATURES="$CPU_FEATURES,migratable=no"
fi fi
CPU_FEATURES="$CPU_FEATURES,+ssse3,+sse4.1,+sse4.2"
fi fi
if [ -z "$CPU_FLAGS" ]; then if [ -z "$CPU_FLAGS" ]; then
CPU_FLAGS="$CPU_MODEL,$CPU_FEATURES" if [ -z "$CPU_FEATURES" ]; then
CPU_FLAGS="$CPU_MODEL"
else
CPU_FLAGS="$CPU_MODEL,$CPU_FEATURES"
fi
else else
CPU_FLAGS="$CPU_MODEL,$CPU_FEATURES,$CPU_FLAGS" if [ -z "$CPU_FEATURES" ]; then
CPU_FLAGS="$CPU_MODEL,$CPU_FLAGS"
else
CPU_FLAGS="$CPU_MODEL,$CPU_FEATURES,$CPU_FLAGS"
fi
fi fi
if [ -z "$HOST_CPU" ]; then if [ -z "$HOST_CPU" ]; then

View File

@@ -28,5 +28,5 @@ do
echo "${body//(\[P\])/($size)}"> "$info" echo "${body//(\[P\])/($size)}"> "$info"
fi fi
fi fi
sleep 1 sleep 1 & wait $!
done done

View File

@@ -35,6 +35,7 @@ TEMPLATE="/var/www/index.html"
FOOTER1="$APP for Docker v$(</run/version)" FOOTER1="$APP for Docker v$(</run/version)"
FOOTER2="<a href='$SUPPORT'>$SUPPORT</a>" FOOTER2="<a href='$SUPPORT'>$SUPPORT</a>"
HOST=$(hostname -s)
KERNEL=$(uname -r | cut -b 1) KERNEL=$(uname -r | cut -b 1)
MINOR=$(uname -r | cut -d '.' -f2) MINOR=$(uname -r | cut -d '.' -f2)
ARCH=$(dpkg --print-architecture) ARCH=$(dpkg --print-architecture)

View File

@@ -9,6 +9,21 @@ set -Eeuo pipefail
: "${HOST_MODEL:=""}" : "${HOST_MODEL:=""}"
: "${GUEST_SERIAL:=""}" : "${GUEST_SERIAL:=""}"
if [ -n "$HOST_MAC" ]; then
HOST_MAC="${HOST_MAC//-/:}"
if [[ ${#HOST_MAC} == 12 ]]; then
m="$HOST_MAC"
HOST_MAC="${m:0:2}:${m:2:2}:${m:4:2}:${m:6:2}:${m:8:2}:${m:10:2}"
fi
if [[ ${#HOST_MAC} != 17 ]]; then
error "Invalid HOST_MAC address: '$HOST_MAC', should be 12 or 17 digits long!" && exit 28
fi
fi
HOST_ARGS=() HOST_ARGS=()
HOST_ARGS+=("-cpu=$CPU_CORES") HOST_ARGS+=("-cpu=$CPU_CORES")
HOST_ARGS+=("-cpu_arch=$HOST_CPU") HOST_ARGS+=("-cpu_arch=$HOST_CPU")