mirror of
https://github.com/vdsm/virtual-dsm.git
synced 2025-11-07 02:23:42 +08:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f74771a9cc | ||
|
|
f24ba41930 | ||
|
|
f412580a4a | ||
|
|
5cde1b4438 | ||
|
|
7cfb57b1bc | ||
|
|
a478b58f97 | ||
|
|
8297f4f880 | ||
|
|
4c67343d33 | ||
|
|
53cc6998f0 | ||
|
|
d857d71e0d | ||
|
|
003c2766ce | ||
|
|
78594098cc | ||
|
|
3c31bc91e4 | ||
|
|
72141bab7a | ||
|
|
bc52463aa4 |
18
.github/workflows/check.yml
vendored
18
.github/workflows/check.yml
vendored
@@ -7,8 +7,18 @@ jobs:
|
||||
name: shellcheck
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Run ShellCheck
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
name: Run ShellCheck
|
||||
uses: ludeeus/action-shellcheck@master
|
||||
env:
|
||||
SHELLCHECK_OPTS: -x --source-path=src -e SC2001 -e SC2034 -e SC2064 -e SC2317 -e SC2153 -e SC2028
|
||||
env:
|
||||
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
|
||||
|
||||
1
.github/workflows/test.yml
vendored
1
.github/workflows/test.yml
vendored
@@ -3,6 +3,7 @@ on:
|
||||
pull_request:
|
||||
paths:
|
||||
- '**/*.sh'
|
||||
- 'Dockerfile'
|
||||
- '.github/workflows/test.yml'
|
||||
- '.github/workflows/check.yml'
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
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
|
||||
environment:
|
||||
@@ -198,7 +198,7 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
|
||||
- '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?
|
||||
|
||||
@@ -234,6 +234,9 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
|
||||
|
||||
However, by installing Synology's Virtual DSM, you must accept their end-user license agreement, which does not permit installation on non-Synology hardware. So only run this project on an official Synology NAS, as any other use will be a violation of their terms and conditions.
|
||||
|
||||
## Stars
|
||||
[](https://starchart.cc/vdsm/virtual-dsm)
|
||||
|
||||
## Disclaimer
|
||||
|
||||
Only run this container on Synology hardware, any other use is not permitted by their EULA. The product names, logos, brands, and other trademarks referred to within this project are the property of their respective trademark holders. This project is not affiliated, sponsored, or endorsed by Synology, Inc.
|
||||
|
||||
32
src/disk.sh
32
src/disk.sh
@@ -80,7 +80,7 @@ getSize() {
|
||||
isCow() {
|
||||
local FS=$1
|
||||
|
||||
if [[ "${FS,,}" == "xfs" || "${FS,,}" == "zfs" || "${FS,,}" == "btrfs" || "${FS,,}" == "bcachefs" ]]; then
|
||||
if [[ "${FS,,}" == "xfs" || "${FS,,}" == "btrfs" || "${FS,,}" == "bcachefs" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
@@ -341,6 +341,21 @@ checkFS () {
|
||||
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 () {
|
||||
local DISK_ID=$1
|
||||
local DISK_BASE=$2
|
||||
@@ -351,7 +366,7 @@ addDisk () {
|
||||
local DISK_ADDRESS=$7
|
||||
local DISK_FMT=$8
|
||||
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")
|
||||
[ ! -d "$DIR" ] && return 0
|
||||
@@ -399,10 +414,8 @@ addDisk () {
|
||||
|
||||
fi
|
||||
|
||||
DISK_OPTS="$DISK_OPTS \
|
||||
-device virtio-scsi-pci,id=hw-$DISK_ID,iothread=io2,bus=pcie.0,addr=$DISK_ADDRESS \
|
||||
-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"
|
||||
OPTS=$(createDevice "$DISK_ID" "$DISK_FILE" "$DISK_INDEX" "$DISK_ADDRESS" "$DISK_FMT")
|
||||
DISK_OPTS="$DISK_OPTS $OPTS"
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -418,10 +431,9 @@ addDevice () {
|
||||
[ -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
|
||||
|
||||
DISK_OPTS="$DISK_OPTS \
|
||||
-device virtio-scsi-pci,id=hw-$DISK_ID,iothread=io2,bus=pcie.0,addr=$DISK_ADDRESS \
|
||||
-drive file=$DISK_DEV,if=none,id=drive-$DISK_ID,format=raw,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"
|
||||
local OPTS
|
||||
OPTS=$(createDevice "$DISK_ID" "$DISK_DEV" "$DISK_INDEX" "$DISK_ADDRESS" "raw")
|
||||
DISK_OPTS="$DISK_OPTS $OPTS"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@ if [[ "$GPU" != [Yy1]* ]] || [[ "$ARCH" != "amd64" ]]; then
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -265,7 +265,7 @@ if ! touch "$SYSTEM"; then
|
||||
error "Could not create file $SYSTEM for the system disk." && exit 98
|
||||
fi
|
||||
|
||||
if [[ "${FS,,}" == "xfs" || "${FS,,}" == "zfs" || "${FS,,}" == "btrfs" || "${FS,,}" == "bcachefs" ]]; then
|
||||
if [[ "${FS,,}" == "xfs" || "${FS,,}" == "btrfs" || "${FS,,}" == "bcachefs" ]]; then
|
||||
{ chattr +C "$SYSTEM"; } || :
|
||||
FA=$(lsattr "$SYSTEM")
|
||||
if [[ "$FA" != *"C"* ]]; then
|
||||
|
||||
@@ -3,8 +3,8 @@ set -Eeuo pipefail
|
||||
|
||||
# Docker environment variables
|
||||
|
||||
: "${MAC:=""}"
|
||||
: "${DHCP:="N"}"
|
||||
: "${MAC:="02:11:32:AA:BB:CC"}"
|
||||
|
||||
: "${VM_NET_DEV:=""}"
|
||||
: "${VM_NET_TAP:="dsm"}"
|
||||
@@ -33,7 +33,7 @@ configureDHCP() {
|
||||
fi
|
||||
|
||||
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
|
||||
done
|
||||
|
||||
@@ -80,9 +80,13 @@ configureDNS() {
|
||||
|
||||
# Set DNS server and gateway
|
||||
DNSMASQ_OPTS="$DNSMASQ_OPTS --dhcp-option=option:dns-server,${VM_NET_IP%.*}.1 --dhcp-option=option:router,${VM_NET_IP%.*}.1"
|
||||
DNSMASQ_OPTS=$(echo "$DNSMASQ_OPTS" | sed 's/\t/ /g' | tr -s ' ' | sed 's/^ *//')
|
||||
|
||||
# Add DNS entry for container
|
||||
DNSMASQ_OPTS="$DNSMASQ_OPTS --address=/host.lan/${VM_NET_IP%.*}.1"
|
||||
|
||||
DNSMASQ_OPTS=$(echo "$DNSMASQ_OPTS" | sed 's/\t/ /g' | tr -s ' ' | sed 's/^ *//')
|
||||
[[ "$DEBUG" == [Yy1]* ]] && set -x
|
||||
|
||||
if ! $DNSMASQ ${DNSMASQ_OPTS:+ $DNSMASQ_OPTS}; then
|
||||
error "Failed to start dnsmasq, reason: $?" && exit 29
|
||||
fi
|
||||
@@ -117,7 +121,6 @@ configureNAT() {
|
||||
# Create a bridge with a static IP for the VM guest
|
||||
|
||||
VM_NET_IP='20.20.20.21'
|
||||
[[ "$DEBUG" == [Yy1]* ]] && set -x
|
||||
|
||||
{ ip link add dev dockerbridge type bridge ; rc=$?; } || :
|
||||
|
||||
@@ -128,7 +131,7 @@ configureNAT() {
|
||||
ip address add ${VM_NET_IP%.*}.1/24 broadcast ${VM_NET_IP%.*}.255 dev dockerbridge
|
||||
|
||||
while ! ip link set dockerbridge up; do
|
||||
info "Waiting for address to become available..."
|
||||
info "Waiting for IP address to become available..."
|
||||
sleep 2
|
||||
done
|
||||
|
||||
@@ -136,7 +139,7 @@ configureNAT() {
|
||||
ip tuntap add dev "$VM_NET_TAP" mode tap
|
||||
|
||||
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
|
||||
done
|
||||
|
||||
@@ -155,9 +158,6 @@ configureNAT() {
|
||||
iptables -A POSTROUTING -t mangle -p udp --dport bootpc -j CHECKSUM --checksum-fill || true
|
||||
fi
|
||||
|
||||
{ set +x; } 2>/dev/null
|
||||
[[ "$DEBUG" == [Yy1]* ]] && echo
|
||||
|
||||
NET_OPTS="-netdev tap,ifname=$VM_NET_TAP,script=no,downscript=no,id=hostnet0"
|
||||
|
||||
{ exec 40>>/dev/vhost-net; rc=$?; } 2>/dev/null || :
|
||||
@@ -211,14 +211,21 @@ getInfo() {
|
||||
error "$ADD_ERR -e \"VM_NET_DEV=NAME\" to specify another interface name." && exit 27
|
||||
fi
|
||||
|
||||
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^^}"
|
||||
VM_NET_MAC="${VM_NET_MAC//-/:}"
|
||||
|
||||
if [[ ${#VM_NET_MAC} == 12 ]]; then
|
||||
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}"
|
||||
fi
|
||||
|
||||
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
|
||||
|
||||
GATEWAY=$(ip r | grep default | awk '{print $3}')
|
||||
@@ -242,15 +249,15 @@ getInfo
|
||||
html "Initializing network..."
|
||||
|
||||
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
|
||||
|
||||
if [[ "$DHCP" == [Yy1]* ]]; then
|
||||
|
||||
if [[ "$GATEWAY" == "172."* ]]; then
|
||||
if [[ "$DEBUG" != [Yy1]* ]]; then
|
||||
error "You can only enable DHCP while the container is on a macvlan network!" && exit 26
|
||||
fi
|
||||
if [[ "$GATEWAY" == "172."* ]] && [[ "$DEBUG" != [Yy1]* ]]; then
|
||||
error "You can only enable DHCP while the container is on a macvlan network!" && exit 26
|
||||
fi
|
||||
|
||||
# Configuration for DHCP IP
|
||||
|
||||
@@ -168,6 +168,7 @@ _graceful_shutdown() {
|
||||
|
||||
MON_OPTS="\
|
||||
-pidfile $QEMU_PID \
|
||||
-name $PROCESS,process=$PROCESS,debug-threads=on \
|
||||
-monitor telnet:localhost:$QEMU_PORT,server,nowait,nodelay"
|
||||
|
||||
if [[ "$CONSOLE" != [Yy]* ]]; then
|
||||
|
||||
46
src/proc.sh
46
src/proc.sh
@@ -6,7 +6,8 @@ set -Eeuo pipefail
|
||||
: "${KVM:="Y"}"
|
||||
: "${HOST_CPU:=""}"
|
||||
: "${CPU_FLAGS:=""}"
|
||||
: "${CPU_MODEL:="host"}"
|
||||
: "${CPU_MODEL:=""}"
|
||||
: "${DEF_MODEL:="qemu64"}"
|
||||
|
||||
[ "$ARCH" != "amd64" ] && KVM="N"
|
||||
|
||||
@@ -28,7 +29,7 @@ if [[ "$KVM" != [Nn]* ]]; then
|
||||
|
||||
if [ -n "$KVM_ERR" ]; then
|
||||
KVM="N"
|
||||
error "KVM acceleration not detected $KVM_ERR, this will cause a major loss of performance."
|
||||
error "KVM acceleration not available $KVM_ERR, this will cause a major loss of performance."
|
||||
error "See the FAQ on how to enable it, or continue without KVM by setting KVM=N (not recommended)."
|
||||
[[ "$DEBUG" != [Yy1]* ]] && exit 88
|
||||
fi
|
||||
@@ -37,35 +38,54 @@ fi
|
||||
|
||||
if [[ "$KVM" != [Nn]* ]]; then
|
||||
|
||||
CPU_FEATURES="kvm=on"
|
||||
KVM_OPTS=",accel=kvm -enable-kvm"
|
||||
CPU_FEATURES="kvm=on,l3-cache=on"
|
||||
KVM_OPTS=",accel=kvm -enable-kvm -global kvm-pit.lost_tick_policy=discard"
|
||||
|
||||
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 "Disable KVM by setting KVM=N to emulate a compatible CPU, at the cost of performance."
|
||||
[[ "$DEBUG" != [Yy1]* ]] && exit 89
|
||||
info "Your CPU does not have the SSE4 instruction set that Virtual DSM requires, it will be emulated..."
|
||||
[ -z "$CPU_MODEL" ] && CPU_MODEL="$DEF_MODEL"
|
||||
CPU_FEATURES="$CPU_FEATURES,+ssse3,+sse4.1,+sse4.2"
|
||||
fi
|
||||
|
||||
if [ -z "$CPU_MODEL" ]; then
|
||||
CPU_MODEL="host"
|
||||
CPU_FEATURES="$CPU_FEATURES,migratable=no"
|
||||
fi
|
||||
|
||||
else
|
||||
|
||||
KVM_OPTS=""
|
||||
CPU_FEATURES="+ssse3,+sse4.1,+sse4.2"
|
||||
CPU_FEATURES="l3-cache=on"
|
||||
|
||||
if [[ "${CPU_MODEL,,}" == "host"* ]]; then
|
||||
if [[ "$ARCH" == "amd64" ]]; then
|
||||
KVM_OPTS=" -accel tcg,thread=multi"
|
||||
fi
|
||||
|
||||
if [ -z "$CPU_MODEL" ]; then
|
||||
if [[ "$ARCH" == "amd64" ]]; then
|
||||
CPU_MODEL="max"
|
||||
CPU_FEATURES="$CPU_FEATURES,migratable=no"
|
||||
else
|
||||
CPU_MODEL="qemu64"
|
||||
CPU_MODEL="$DEF_MODEL"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
CPU_FEATURES="$CPU_FEATURES,+ssse3,+sse4.1,+sse4.2"
|
||||
|
||||
fi
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
if [ -z "$HOST_CPU" ]; then
|
||||
|
||||
@@ -28,5 +28,5 @@ do
|
||||
echo "${body//(\[P\])/($size)}"> "$info"
|
||||
fi
|
||||
fi
|
||||
sleep 1
|
||||
sleep 1 & wait $!
|
||||
done
|
||||
|
||||
@@ -28,6 +28,9 @@ echo
|
||||
|
||||
# Helper variables
|
||||
|
||||
PROCESS="${APP,,}"
|
||||
PROCESS="${PROCESS// /-}"
|
||||
|
||||
STORAGE="/storage"
|
||||
INFO="/run/shm/msg.html"
|
||||
PAGE="/run/shm/index.html"
|
||||
@@ -35,6 +38,7 @@ TEMPLATE="/var/www/index.html"
|
||||
FOOTER1="$APP for Docker v$(</run/version)"
|
||||
FOOTER2="<a href='$SUPPORT'>$SUPPORT</a>"
|
||||
|
||||
HOST=$(hostname -s)
|
||||
KERNEL=$(uname -r | cut -b 1)
|
||||
MINOR=$(uname -r | cut -d '.' -f2)
|
||||
ARCH=$(dpkg --print-architecture)
|
||||
|
||||
@@ -9,6 +9,21 @@ set -Eeuo pipefail
|
||||
: "${HOST_MODEL:=""}"
|
||||
: "${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+=("-cpu=$CPU_CORES")
|
||||
HOST_ARGS+=("-cpu_arch=$HOST_CPU")
|
||||
|
||||
Reference in New Issue
Block a user