mirror of
https://github.com/vdsm/virtual-dsm.git
synced 2025-11-07 02:23:42 +08:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44d3e23545 | ||
|
|
d340361320 | ||
|
|
f8f8c16200 | ||
|
|
47fd7931eb | ||
|
|
7ac9c242da | ||
|
|
78d330055f | ||
|
|
06cf0a4edc | ||
|
|
e26c208cc7 | ||
|
|
c2f4823d8b | ||
|
|
ca01bf8cb9 | ||
|
|
a5b2b655dd | ||
|
|
0f2f3b2ea8 | ||
|
|
0705c1c21b | ||
|
|
e4de05ce88 | ||
|
|
a24b62ae67 | ||
|
|
b5a9361b68 | ||
|
|
0e35e4a6d9 | ||
|
|
208a6e6636 | ||
|
|
3fec9bf5ef | ||
|
|
8d8efeb341 | ||
|
|
e9f27899a6 | ||
|
|
0c1c422758 | ||
|
|
f56c523627 | ||
|
|
66879b5a6a | ||
|
|
b4eef6161b | ||
|
|
cf38b1f237 | ||
|
|
2c09811365 | ||
|
|
761f5babfc | ||
|
|
26be942a74 |
11
Dockerfile
11
Dockerfile
@@ -7,16 +7,16 @@ FROM qemux/qemu-host as builder
|
||||
# RUN go mod download
|
||||
# RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o /qemu-host.bin .
|
||||
|
||||
FROM debian:bookworm-slim
|
||||
FROM debian:trixie-slim
|
||||
|
||||
ARG DEBCONF_NOWARNINGS="yes"
|
||||
ARG DEBIAN_FRONTEND noninteractive
|
||||
|
||||
RUN apt-get update && apt-get -y upgrade && \
|
||||
apt-get --no-install-recommends -y install \
|
||||
tini \
|
||||
curl \
|
||||
cpio \
|
||||
tini \
|
||||
wget \
|
||||
fdisk \
|
||||
unzip \
|
||||
@@ -57,11 +57,14 @@ ARG BUILD_ARG=0
|
||||
ARG VERSION_ARG="0.0"
|
||||
ENV VERSION=$VERSION_ARG
|
||||
|
||||
LABEL org.opencontainers.image.licenses="MIT"
|
||||
LABEL org.opencontainers.image.title="Virtual DSM"
|
||||
LABEL org.opencontainers.image.created=${DATE_ARG}
|
||||
LABEL org.opencontainers.image.revision=${BUILD_ARG}
|
||||
LABEL org.opencontainers.image.version=${VERSION_ARG}
|
||||
LABEL org.opencontainers.image.source=https://github.com/kroese/virtual-dsm/
|
||||
LABEL org.opencontainers.image.url=https://hub.docker.com/r/kroese/virtual-dsm/
|
||||
LABEL org.opencontainers.image.source="https://github.com/kroese/virtual-dsm/"
|
||||
LABEL org.opencontainers.image.url="https://hub.docker.com/r/kroese/virtual-dsm/"
|
||||
LABEL org.opencontainers.image.description="Virtual DSM in a docker container"
|
||||
|
||||
HEALTHCHECK --interval=60s --retries=2 CMD /run/check.sh
|
||||
|
||||
|
||||
79
readme.md
79
readme.md
@@ -16,9 +16,10 @@ Virtual DSM in a docker container.
|
||||
|
||||
- Multi-platform
|
||||
- KVM acceleration
|
||||
- Graceful shutdown
|
||||
- GPU passthrough
|
||||
- Graceful shutdowns
|
||||
- Upgrades supported
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
Via `docker-compose.yml`
|
||||
@@ -26,22 +27,22 @@ Via `docker-compose.yml`
|
||||
```yaml
|
||||
version: "3"
|
||||
services:
|
||||
dsm:
|
||||
container_name: dsm
|
||||
image: kroese/virtual-dsm:latest
|
||||
environment:
|
||||
DISK_SIZE: "16G"
|
||||
devices:
|
||||
- /dev/kvm
|
||||
- /dev/vhost-net
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
ports:
|
||||
- 5000:5000
|
||||
volumes:
|
||||
- /opt/dsm:/storage
|
||||
restart: on-failure
|
||||
stop_grace_period: 1m
|
||||
dsm:
|
||||
container_name: dsm
|
||||
image: kroese/virtual-dsm:latest
|
||||
environment:
|
||||
DISK_SIZE: "16G"
|
||||
devices:
|
||||
- /dev/kvm
|
||||
- /dev/vhost-net
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
ports:
|
||||
- 5000:5000
|
||||
volumes:
|
||||
- /opt/dsm:/storage
|
||||
restart: on-failure
|
||||
stop_grace_period: 1m
|
||||
```
|
||||
|
||||
Via `docker run`
|
||||
@@ -58,7 +59,7 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
DISK_SIZE: "256G"
|
||||
DISK_SIZE: "256G"
|
||||
```
|
||||
|
||||
This can also be used to resize the existing disk to a larger capacity without data loss.
|
||||
@@ -69,7 +70,7 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
- /home/user/data:/storage
|
||||
- /home/user/data:/storage
|
||||
```
|
||||
|
||||
Replace the example path `/home/user/data` with the desired storage folder.
|
||||
@@ -80,7 +81,7 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
ALLOCATE: "N"
|
||||
ALLOCATE: "N"
|
||||
```
|
||||
|
||||
Keep in mind that this will not affect any of your existing disks, it only applies to newly created disks.
|
||||
@@ -91,8 +92,8 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
CPU_CORES: "4"
|
||||
RAM_SIZE: "2048M"
|
||||
CPU_CORES: "4"
|
||||
RAM_SIZE: "2048M"
|
||||
```
|
||||
|
||||
* ### How do I verify if my system supports KVM?
|
||||
@@ -126,16 +127,16 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
|
||||
|
||||
```yaml
|
||||
services:
|
||||
dsm:
|
||||
container_name: dsm
|
||||
..<snip>..
|
||||
networks:
|
||||
vdsm:
|
||||
ipv4_address: 192.168.0.100
|
||||
dsm:
|
||||
container_name: dsm
|
||||
..<snip>..
|
||||
networks:
|
||||
vdsm:
|
||||
ipv4_address: 192.168.0.100
|
||||
|
||||
networks:
|
||||
vdsm:
|
||||
external: true
|
||||
vdsm:
|
||||
external: true
|
||||
```
|
||||
|
||||
An added benefit of this approach is that you won't have to perform any port mapping anymore since all ports will be exposed by default.
|
||||
@@ -150,11 +151,11 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
DHCP: "Y"
|
||||
DHCP: "Y"
|
||||
devices:
|
||||
- /dev/vhost-net
|
||||
- /dev/vhost-net
|
||||
device_cgroup_rules:
|
||||
- 'c *:* rwm'
|
||||
- 'c *:* rwm'
|
||||
```
|
||||
|
||||
Please note that even if you don't need DHCP, it's still recommended to enable this feature as it prevents NAT issues and increases performance by using a `macvtap` interface.
|
||||
@@ -165,21 +166,23 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
URL: "https://global.synologydownload.com/download/DSM/release/7.0.1/42218/DSM_VirtualDSM_42218.pat"
|
||||
URL: "https://global.synologydownload.com/download/DSM/release/7.0.1/42218/DSM_VirtualDSM_42218.pat"
|
||||
```
|
||||
|
||||
With this method, you are able to switch between different versions while keeping your file data.
|
||||
|
||||
* ### How do I passthrough my GPU?
|
||||
|
||||
To enable this feature, add the following lines to your compose file:
|
||||
To passthrough your GPU, add the following lines to your compose file:
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
GPU: "Y"
|
||||
GPU: "Y"
|
||||
devices:
|
||||
- /dev/dri
|
||||
- /dev/dri
|
||||
```
|
||||
|
||||
This can be used to enable facial recognition in Synology Photos for example.
|
||||
|
||||
* ### What are the differences compared to the standard DSM?
|
||||
|
||||
|
||||
42
run/disk.sh
42
run/disk.sh
@@ -136,13 +136,6 @@ if [[ SIZE -ne DATA_SIZE ]]; then
|
||||
error "Virtual disk has the wrong size: ${SIZE}" && exit 89
|
||||
fi
|
||||
|
||||
AGENT="${STORAGE}/${BASE}.agent"
|
||||
[ -f "$AGENT" ] && AGENT_VERSION=$(cat "${AGENT}") || AGENT_VERSION=1
|
||||
|
||||
if ((AGENT_VERSION < 5)); then
|
||||
info "The installed VirtualDSM Agent v${AGENT_VERSION} is an outdated version, please upgrade it."
|
||||
fi
|
||||
|
||||
DISK_OPTS="\
|
||||
-device virtio-scsi-pci,id=hw-synoboot,bus=pcie.0,addr=0xa \
|
||||
-drive file=${BOOT},if=none,id=drive-synoboot,format=raw,cache=${DISK_CACHE},aio=${DISK_IO},discard=${DISK_DISCARD},detect-zeroes=on \
|
||||
@@ -154,26 +147,45 @@ DISK_OPTS="\
|
||||
-drive file=${DATA},if=none,id=drive-userdata,format=raw,cache=${DISK_CACHE},aio=${DISK_IO},discard=${DISK_DISCARD},detect-zeroes=on \
|
||||
-device scsi-hd,bus=hw-userdata.0,channel=0,scsi-id=0,lun=0,drive=drive-userdata,id=userdata0,rotation_rate=${DISK_ROTATION},bootindex=3"
|
||||
|
||||
STORAGE2="/storage2"
|
||||
DATA2="${STORAGE2}/data.img"
|
||||
EXTRA_DISK="/storage2/data.img"
|
||||
|
||||
if [ -f "${DATA2}" ]; then
|
||||
if [ -f "${EXTRA_DISK}" ]; then
|
||||
|
||||
DISK_OPTS="${DISK_OPTS} \
|
||||
-device virtio-scsi-pci,id=hw-userdata2,bus=pcie.0,addr=0xd \
|
||||
-drive file=${DATA2},if=none,id=drive-userdata2,format=raw,cache=${DISK_CACHE},aio=${DISK_IO},discard=${DISK_DISCARD},detect-zeroes=on \
|
||||
-drive file=${EXTRA_DISK},if=none,id=drive-userdata2,format=raw,cache=${DISK_CACHE},aio=${DISK_IO},discard=${DISK_DISCARD},detect-zeroes=on \
|
||||
-device scsi-hd,bus=hw-userdata2.0,channel=0,scsi-id=0,lun=0,drive=drive-userdata2,id=userdata2,rotation_rate=${DISK_ROTATION},bootindex=4"
|
||||
|
||||
else
|
||||
|
||||
[ -d "$(dirname "${EXTRA_DISK}")" ] && error "Disk image ${EXTRA_DISK} does not exist! Please supply an empty file of at least 6 GB." && exit 53
|
||||
|
||||
fi
|
||||
|
||||
STORAGE3="/storage3"
|
||||
DATA3="${STORAGE3}/data.img"
|
||||
EXTRA_DISK="/storage3/data.img"
|
||||
|
||||
if [ -f "${DATA3}" ]; then
|
||||
if [ -f "${EXTRA_DISK}" ]; then
|
||||
|
||||
DISK_OPTS="${DISK_OPTS} \
|
||||
-device virtio-scsi-pci,id=hw-userdata3,bus=pcie.0,addr=0xe \
|
||||
-drive file=${DATA3},if=none,id=drive-userdata3,format=raw,cache=${DISK_CACHE},aio=${DISK_IO},discard=${DISK_DISCARD},detect-zeroes=on \
|
||||
-drive file=${EXTRA_DISK},if=none,id=drive-userdata3,format=raw,cache=${DISK_CACHE},aio=${DISK_IO},discard=${DISK_DISCARD},detect-zeroes=on \
|
||||
-device scsi-hd,bus=hw-userdata3.0,channel=0,scsi-id=0,lun=0,drive=drive-userdata3,id=userdata3,rotation_rate=${DISK_ROTATION},bootindex=5"
|
||||
|
||||
else
|
||||
|
||||
[ -d "$(dirname "${EXTRA_DISK}")" ] && error "Disk image ${EXTRA_DISK} does not exist! Please supply an empty file of at least 6 GB." && exit 54
|
||||
|
||||
fi
|
||||
|
||||
: ${DEVICE:=''} # Docker variable to passthrough a block device, like /dev/vdc1.
|
||||
|
||||
if [ -n "${DEVICE}" ]; then
|
||||
|
||||
[ ! -b "${DEVICE}" ] && error "Device ${DEVICE} 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-userdata4,bus=pcie.0,addr=0xf \
|
||||
-drive file=${DEVICE},if=none,id=drive-userdata4,format=raw,cache=${DISK_CACHE},aio=${DISK_IO},discard=${DISK_DISCARD},detect-zeroes=on \
|
||||
-device scsi-hd,bus=hw-userdata4.0,channel=0,scsi-id=0,lun=0,drive=drive-userdata4,id=userdata4,rotation_rate=${DISK_ROTATION},bootindex=6"
|
||||
|
||||
fi
|
||||
|
||||
14
run/gpu.sh
14
run/gpu.sh
@@ -19,7 +19,7 @@ DEF_OPTS="${DEF_OPTS} -device virtio-vga,id=video0,max_outputs=1,bus=pcie.0,addr
|
||||
|
||||
if ! apt-mark showinstall | grep -q "xserver-xorg-video-intel"; then
|
||||
|
||||
info "Installing GPU drivers..."
|
||||
info "Installing Intel GPU drivers..."
|
||||
|
||||
export DEBCONF_NOWARNINGS="yes"
|
||||
export DEBIAN_FRONTEND="noninteractive"
|
||||
@@ -28,3 +28,15 @@ if ! apt-mark showinstall | grep -q "xserver-xorg-video-intel"; then
|
||||
apt-get -qq --no-install-recommends -y install xserver-xorg-video-intel > /dev/null
|
||||
|
||||
fi
|
||||
|
||||
if ! apt-mark showinstall | grep -q "qemu-system-modules-opengl"; then
|
||||
|
||||
info "Installing OpenGL module..."
|
||||
|
||||
export DEBCONF_NOWARNINGS="yes"
|
||||
export DEBIAN_FRONTEND="noninteractive"
|
||||
|
||||
apt-get -qq update
|
||||
apt-get -qq --no-install-recommends -y install qemu-system-modules-opengl > /dev/null
|
||||
|
||||
fi
|
||||
|
||||
@@ -242,9 +242,6 @@ mkdir -p "$LOC"
|
||||
cp /agent/service.sh "$LOC/agent.sh"
|
||||
chmod 755 "$LOC/agent.sh"
|
||||
|
||||
# Store agent version
|
||||
echo "7" > "$STORAGE"/"$BASE".agent
|
||||
|
||||
info "Install: Installing system partition..."
|
||||
|
||||
LABEL="1.44.1-42218"
|
||||
|
||||
@@ -234,7 +234,11 @@ fi
|
||||
if [[ "${DHCP}" == [Yy1]* ]]; then
|
||||
|
||||
if [[ "$GATEWAY" == "172."* ]]; then
|
||||
error "You can only enable DHCP while the container is on a macvlan network!" && exit 86
|
||||
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
|
||||
fi
|
||||
fi
|
||||
|
||||
# Configuration for DHCP IP
|
||||
|
||||
23
run/power.sh
23
run/power.sh
@@ -39,28 +39,14 @@ _graceful_shutdown() {
|
||||
|
||||
echo && error "Could not send shutdown command to the guest ($RESPONSE)"
|
||||
|
||||
# If we cannot shutdown the usual way, fallback to the NMI method
|
||||
|
||||
AGENT="${STORAGE}/${BASE}.agent"
|
||||
[ -f "$AGENT" ] && AGENT_VERSION=$(cat "${AGENT}") || AGENT_VERSION=1
|
||||
|
||||
if ((AGENT_VERSION > 1)); then
|
||||
|
||||
# Send a NMI interrupt which will be detected by the kernel
|
||||
if ! echo 'nmi' | nc -q 1 -w 1 localhost "${QEMU_MONPORT}" > /dev/null ; then
|
||||
AGENT_VERSION=0
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
if ((AGENT_VERSION < 2)); then
|
||||
|
||||
echo && info "Please update the VirtualDSM Agent to allow for gracefull shutdowns..."
|
||||
# Send a NMI interrupt which will be detected by the agent script
|
||||
if ! echo 'nmi' | nc -q 1 -w 1 localhost "${QEMU_MONPORT}" > /dev/null ; then
|
||||
|
||||
kill -15 "$(cat "${_QEMU_PID}")"
|
||||
pkill -f qemu-system-x86_64 || true
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
while [ "$(cat ${_QEMU_SHUTDOWN_COUNTER})" -lt "${QEMU_POWERDOWN_TIMEOUT}" ]; do
|
||||
@@ -72,7 +58,8 @@ _graceful_shutdown() {
|
||||
if echo 'info version'| nc -q 1 -w 1 localhost "${QEMU_MONPORT}" >/dev/null 2>&1 ; then
|
||||
|
||||
sleep 1
|
||||
#info "Shutting down, waiting... ($(cat ${_QEMU_SHUTDOWN_COUNTER})/${QEMU_POWERDOWN_TIMEOUT})"
|
||||
CNT="$(cat ${_QEMU_SHUTDOWN_COUNTER})/${QEMU_POWERDOWN_TIMEOUT}"
|
||||
[[ "${DEBUG}" == [Yy1]* ]] && info "Shutting down, waiting... (${CNT})"
|
||||
|
||||
fi
|
||||
|
||||
|
||||
Reference in New Issue
Block a user