Compare commits

..

21 Commits
v7.01 ... v7.06

Author SHA1 Message Date
Kroese
6d162744ec feat: Improved networking (#712) 2024-04-30 00:30:44 +02:00
Kroese
145b4aab5b docs: Update issue templates (#708) 2024-04-26 16:53:15 +02:00
Kroese
2e4eb56d0b fix: Curl error on Chinese mirror (#707) 2024-04-26 16:32:08 +02:00
Kroese
39c019193e fix: Curl error on Chinese mirror (#706) 2024-04-26 16:30:30 +02:00
Kroese
faec563b4a feat: Display kernel version (#704) 2024-04-26 13:59:51 +02:00
Kroese
9840f8e07a feat: Support ecryptfs filesystem (#703) 2024-04-26 06:04:48 +02:00
Kroese
3a5895fa0f build: Remove armv7 support (#702) 2024-04-26 04:16:46 +02:00
Kroese
1bac5c8a7f feat: Print system info (#701) 2024-04-25 14:31:49 +02:00
Kroese
dd76c60e2a fix: CPU detection (#697) 2024-04-22 16:48:41 +02:00
Kroese
ac78cc7dc5 feat: Display system info on boot (#696) 2024-04-22 16:29:23 +02:00
Kroese
66ac2d2002 docs: Update issue template (#692) 2024-04-17 19:03:17 +02:00
Kroese
0bd099d704 docs: Update issue templates (#691) 2024-04-17 18:32:43 +02:00
Kroese
d2dac3cfb4 docs: Add issue templates (#690) 2024-04-17 18:14:51 +02:00
Kroese
e81dc0f31d fix: Verify files are not empty (#689) 2024-04-16 15:35:35 +02:00
Kroese
5015597183 fix: Ignore empty MAC address (#688) 2024-04-13 23:33:17 +02:00
Kroese
64e2af9fa2 fix: Continue if file is missing (#682) 2024-04-08 09:54:42 +02:00
Kroese
debb4b69fc fix: Continue when range request fails (#680) 2024-04-08 04:53:30 +02:00
Kroese
c6d3dda171 docs: Readme (#677) 2024-04-07 01:59:50 +02:00
Kroese
7c0693c2ff build: Update qemu-host to v2.04 (#670) 2024-03-31 05:24:54 +02:00
Kroese
76355d4857 fix: TUN error message (#669) 2024-03-31 04:57:56 +02:00
Kroese
404aaadefc build: Dockerfile (#663) 2024-03-25 16:49:25 +01:00
18 changed files with 305 additions and 90 deletions

View File

@@ -6,7 +6,10 @@
.gitmodules .gitmodules
Dockerfile Dockerfile
Dockerfile.archive Dockerfile.archive
compose.yml
compose.yaml
docker-compose.yml docker-compose.yml
docker-compose.yaml
*.md *.md

64
.github/ISSUE_TEMPLATE/BUG_REPORT.yml vendored Normal file
View File

@@ -0,0 +1,64 @@
name: "\U0001F41E Bug Report"
description: Create a report to help us improve the container
title: "[Bug]: "
labels: ["bug"]
body:
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the bug you encountered.
options:
- label: I have searched the existing issues
required: true
- type: input
id: cpu
attributes:
label: Machine specifications
description: The processor and RAM amount in your machine.
placeholder: e.g. Intel N5105 / 16 GB
validations:
required: true
- type: input
id: os
attributes:
label: Operating system
description: The Linux distribution and kernel version as shown by `uname -a`.
placeholder: e.g. Ubuntu 24.04 / Kernel 6.8.0-22-generic
validations:
required: true
- type: input
id: docker
attributes:
label: Docker version
description: The Docker version as shown by `docker -v`.
placeholder: e.g. Docker version 26.0.1, build d260a54
validations:
required: true
- type: textarea
id: summary
attributes:
label: Description
description: A clear and concise description of the problem.
validations:
required: true
- type: textarea
id: compose
attributes:
label: Docker compose
description: The Docker compose file (or otherwise `run` command).
validations:
required: true
- type: textarea
id: log
attributes:
label: Docker log
description: The Docker logfile of the container.
validations:
required: true
- type: textarea
id: screenshot
attributes:
label: Screenshots (optional)
description: Screenshots of the problem.
validations:
required: false

View File

@@ -0,0 +1,44 @@
name: "\U0001F680 Feature request"
description: Suggest an idea for improving the container
title: "[Feature]: "
labels: ["enhancement"]
body:
- type: checkboxes
attributes:
label: Is there an existing feature request for this?
description: Please search to see if the feature request already exists.
options:
- label: I have searched the existing feature requests
required: true
- type: textarea
id: problem
attributes:
label: Is your proposal related to a problem?
description: |
Provide a clear and concise description of what the problem is.
For example, "I'm always frustrated when..."
validations:
required: true
- type: textarea
id: solution
attributes:
label: Describe the solution you'd like.
description: |
Provide a clear and concise description of what you want to happen.
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Describe alternatives you've considered.
description: |
Let us know about other solutions you've tried or researched.
validations:
required: true
- type: textarea
id: context
attributes:
label: Additional context
description: |
Is there anything else you can add about the proposal?
You might want to link to related issues here, if you haven't already.

16
.github/ISSUE_TEMPLATE/QUESTION.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
name: "? Question"
description: General questions about the container
title: "[Question]: "
labels: ["question"]
body:
- type: markdown
attributes:
value: |
Please do not use this form for technical issues, and make sure to check the [FAQ](https://github.com/vdsm/virtual-dsm/blob/master/readme.md) first!
- type: textarea
id: question
attributes:
label: Question
description: What's the question you have about the container?
validations:
required: true

View File

@@ -78,7 +78,7 @@ jobs:
context: . context: .
push: true push: true
provenance: false provenance: false
platforms: linux/amd64,linux/arm64,linux/arm platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
annotations: ${{ steps.meta.outputs.annotations }} annotations: ${{ steps.meta.outputs.annotations }}

View File

@@ -1,4 +1,4 @@
FROM qemux/qemu-host as builder FROM qemux/qemu-host:2.04 as builder
# FROM golang as builder # FROM golang as builder
# WORKDIR / # WORKDIR /
@@ -14,9 +14,9 @@ ARG DEBCONF_NOWARNINGS "yes"
ARG DEBIAN_FRONTEND "noninteractive" ARG DEBIAN_FRONTEND "noninteractive"
ARG DEBCONF_NONINTERACTIVE_SEEN "true" ARG DEBCONF_NONINTERACTIVE_SEEN "true"
RUN if [ "$TARGETPLATFORM" != "linux/amd64" ]; then extra="qemu-user"; fi \ RUN if [ "$TARGETPLATFORM" != "linux/amd64" ]; then extra="qemu-user"; fi && \
&& apt-get update \ apt-get update && \
&& apt-get --no-install-recommends -y install \ apt-get --no-install-recommends -y install \
jq \ jq \
tini \ tini \
curl \ curl \
@@ -37,11 +37,11 @@ RUN if [ "$TARGETPLATFORM" != "linux/amd64" ]; then extra="qemu-user"; fi \
ca-certificates \ ca-certificates \
netcat-openbsd \ netcat-openbsd \
qemu-system-x86 \ qemu-system-x86 \
"$extra" \ "$extra" && \
&& apt-get clean \ apt-get clean && \
&& unlink /etc/nginx/sites-enabled/default \ unlink /etc/nginx/sites-enabled/default && \
&& sed -i 's/^worker_processes.*/worker_processes 1;/' /etc/nginx/nginx.conf \ sed -i 's/^worker_processes.*/worker_processes 1;/' /etc/nginx/nginx.conf && \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
COPY ./src /run/ COPY ./src /run/
COPY ./web /var/www/ COPY ./web /var/www/

View File

@@ -21,7 +21,7 @@ Virtual DSM in a Docker container.
## Usage ## Usage
Via `docker-compose.yml` Via Docker Compose:
```yaml ```yaml
version: "3" version: "3"
@@ -43,7 +43,7 @@ services:
stop_grace_period: 2m stop_grace_period: 2m
``` ```
Via `docker run` Via Docker CLI:
```bash ```bash
docker run -it --rm --name dsm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-timeout 120 vdsm/virtual-dsm docker run -it --rm --name dsm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-timeout 120 vdsm/virtual-dsm
@@ -249,5 +249,5 @@ Only run this container on Synology hardware, any other use is not permitted by
[Build]: https://github.com/vdsm/virtual-dsm/actions/workflows/build.yml/badge.svg [Build]: https://github.com/vdsm/virtual-dsm/actions/workflows/build.yml/badge.svg
[Size]: https://img.shields.io/docker/image-size/vdsm/virtual-dsm/latest?color=066da5&label=size [Size]: https://img.shields.io/docker/image-size/vdsm/virtual-dsm/latest?color=066da5&label=size
[Pulls]: https://img.shields.io/docker/pulls/kroese/virtual-dsm.svg?style=flat&label=pulls&logo=docker [Pulls]: https://img.shields.io/docker/pulls/vdsm/virtual-dsm.svg?style=flat&label=pulls&logo=docker
[Version]: https://img.shields.io/docker/v/vdsm/virtual-dsm/latest?arch=amd64&sort=semver&color=066da5 [Version]: https://img.shields.io/docker/v/vdsm/virtual-dsm/latest?arch=amd64&sort=semver&color=066da5

View File

@@ -4,13 +4,13 @@ set -Eeuo pipefail
: "${NETWORK:="Y"}" : "${NETWORK:="Y"}"
[ -f "/run/shm/qemu.end" ] && echo "QEMU is shutting down.." && exit 1 [ -f "/run/shm/qemu.end" ] && echo "QEMU is shutting down.." && exit 1
[ ! -f "/run/shm/qemu.pid" ] && echo "QEMU is not running yet.." && exit 0 [ ! -s "/run/shm/qemu.pid" ] && echo "QEMU is not running yet.." && exit 0
[[ "$NETWORK" != [Yy1]* ]] && echo "Networking is disabled.." && exit 0 [[ "$NETWORK" != [Yy1]* ]] && echo "Networking is disabled.." && exit 0
file="/run/shm/dsm.url" file="/run/shm/dsm.url"
address="/run/shm/qemu.ip" address="/run/shm/qemu.ip"
[ ! -f "$file" ] && echo "DSM has not enabled networking yet.." && exit 1 [ ! -s "$file" ] && echo "DSM has not enabled networking yet.." && exit 1
location=$(<"$file") location=$(<"$file")

View File

@@ -13,8 +13,8 @@ set -Eeuo pipefail
BOOT="$STORAGE/$BASE.boot.img" BOOT="$STORAGE/$BASE.boot.img"
SYSTEM="$STORAGE/$BASE.system.img" SYSTEM="$STORAGE/$BASE.system.img"
[ ! -f "$BOOT" ] && error "Virtual DSM boot-image does not exist ($BOOT)" && exit 81 [ ! -s "$BOOT" ] && error "Virtual DSM boot-image does not exist ($BOOT)" && exit 81
[ ! -f "$SYSTEM" ] && error "Virtual DSM system-image does not exist ($SYSTEM)" && exit 82 [ ! -s "$SYSTEM" ] && error "Virtual DSM system-image does not exist ($SYSTEM)" && exit 82
DISK_OPTS="\ DISK_OPTS="\
-object iothread,id=io2 \ -object iothread,id=io2 \
@@ -87,6 +87,16 @@ isCow() {
return 1 return 1
} }
supportsDirect() {
local FS=$1
if [[ "${FS,,}" == "ecryptfs" ]] || [[ "${FS,,}" == "tmpfs" ]]; then
return 1
fi
return 0
}
createDisk() { createDisk() {
local DISK_FILE=$1 local DISK_FILE=$1
local DISK_SPACE=$2 local DISK_SPACE=$2
@@ -329,6 +339,10 @@ checkFS () {
info "Warning: the filesystem of $DIR is FUSE, this extra layer will negatively affect performance!" info "Warning: the filesystem of $DIR is FUSE, this extra layer will negatively affect performance!"
fi fi
if ! supportsDirect "$FS"; then
info "Warning: the filesystem of $DIR is $FS, which does not support O_DIRECT mode, adjusting settings..."
fi
if isCow "$FS"; then if isCow "$FS"; then
if [ -f "$DISK_FILE" ]; then if [ -f "$DISK_FILE" ]; then
FA=$(lsattr "$DISK_FILE") FA=$(lsattr "$DISK_FILE")
@@ -348,23 +362,30 @@ createDevice () {
local DISK_INDEX=$3 local DISK_INDEX=$3
local DISK_ADDRESS=$4 local DISK_ADDRESS=$4
local DISK_FMT=$5 local DISK_FMT=$5
local DISK_IO=$6
local DISK_CACHE=$7
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 \ local result="-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"
result="$result \
-device virtio-scsi-pci,id=hw-$DISK_ID,iothread=io2,bus=pcie.0,addr=$DISK_ADDRESS \ -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" -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"
echo "$result"
return 0 return 0
} }
addDisk () { addDisk () {
local DISK_ID=$1 local DISK_BASE=$1
local DISK_BASE=$2 local DISK_EXT=$2
local DISK_EXT=$3 local DISK_DESC=$3
local DISK_DESC=$4 local DISK_SPACE=$4
local DISK_SPACE=$5 local DISK_INDEX=$5
local DISK_INDEX=$6 local DISK_ADDRESS=$6
local DISK_ADDRESS=$7 local DISK_FMT=$7
local DISK_FMT=$8 local DISK_IO=$8
local DISK_CACHE=$9
local DISK_ID="userdata$DISK_INDEX"
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 OPTS local DIR DATA_SIZE FS PREV_FMT PREV_EXT CUR_SIZE OPTS
@@ -386,7 +407,12 @@ addDisk () {
FS=$(stat -f -c %T "$DIR") FS=$(stat -f -c %T "$DIR")
checkFS "$FS" "$DISK_FILE" "$DISK_DESC" || exit $? checkFS "$FS" "$DISK_FILE" "$DISK_DESC" || exit $?
if ! [ -f "$DISK_FILE" ] ; then if ! supportsDirect "$FS"; then
DISK_IO="threads"
DISK_CACHE="writeback"
fi
if ! [ -s "$DISK_FILE" ] ; then
if [[ "${DISK_FMT,,}" != "raw" ]]; then if [[ "${DISK_FMT,,}" != "raw" ]]; then
PREV_FMT="raw" PREV_FMT="raw"
@@ -395,12 +421,12 @@ addDisk () {
fi fi
PREV_EXT=$(fmt2ext "$PREV_FMT") PREV_EXT=$(fmt2ext "$PREV_FMT")
if [ -f "$DISK_BASE.$PREV_EXT" ] ; then if [ -s "$DISK_BASE.$PREV_EXT" ] ; then
convertDisk "$DISK_BASE.$PREV_EXT" "$PREV_FMT" "$DISK_FILE" "$DISK_FMT" "$DISK_BASE" "$DISK_DESC" "$FS" || exit $? convertDisk "$DISK_BASE.$PREV_EXT" "$PREV_FMT" "$DISK_FILE" "$DISK_FMT" "$DISK_BASE" "$DISK_DESC" "$FS" || exit $?
fi fi
fi fi
if [ -f "$DISK_FILE" ]; then if [ -s "$DISK_FILE" ]; then
CUR_SIZE=$(getSize "$DISK_FILE") CUR_SIZE=$(getSize "$DISK_FILE")
@@ -414,7 +440,7 @@ addDisk () {
fi fi
OPTS=$(createDevice "$DISK_ID" "$DISK_FILE" "$DISK_INDEX" "$DISK_ADDRESS" "$DISK_FMT") OPTS=$(createDevice "$DISK_ID" "$DISK_FILE" "$DISK_INDEX" "$DISK_ADDRESS" "$DISK_FMT" "$DISK_IO" "$DISK_CACHE")
DISK_OPTS="$DISK_OPTS $OPTS" DISK_OPTS="$DISK_OPTS $OPTS"
return 0 return 0
@@ -422,17 +448,17 @@ addDisk () {
addDevice () { addDevice () {
local DISK_ID=$1 local DISK_DEV=$1
local DISK_DEV=$2 local DISK_DESC=$2
local DISK_DESC=$3 local DISK_INDEX=$3
local DISK_INDEX=$4 local DISK_ADDRESS=$4
local DISK_ADDRESS=$5 local DISK_ID="userdata$DISK_INDEX"
[ -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
local OPTS local OPTS
OPTS=$(createDevice "$DISK_ID" "$DISK_DEV" "$DISK_INDEX" "$DISK_ADDRESS" "raw") OPTS=$(createDevice "$DISK_ID" "$DISK_DEV" "$DISK_INDEX" "$DISK_ADDRESS" "raw" "$DISK_IO" "$DISK_CACHE")
DISK_OPTS="$DISK_OPTS $OPTS" DISK_OPTS="$DISK_OPTS $OPTS"
return 0 return 0
@@ -502,27 +528,27 @@ DISK4_FILE="/storage4/data4"
: "${DEVICE4:=""}" : "${DEVICE4:=""}"
if [ -n "$DEVICE" ]; then if [ -n "$DEVICE" ]; then
addDevice "userdata" "$DEVICE" "device" "3" "0xc" || exit $? addDevice "$DEVICE" "device" "3" "0xc" || exit $?
else else
addDisk "userdata" "$DISK1_FILE" "$DISK_EXT" "disk" "$DISK_SIZE" "3" "0xc" "$DISK_FMT" || exit $? addDisk "$DISK1_FILE" "$DISK_EXT" "disk" "$DISK_SIZE" "3" "0xc" "$DISK_FMT" "$DISK_IO" "$DISK_CACHE" || exit $?
fi fi
if [ -n "$DEVICE2" ]; then if [ -n "$DEVICE2" ]; then
addDevice "userdata2" "$DEVICE2" "device2" "4" "0xd" || exit $? addDevice "$DEVICE2" "device2" "4" "0xd" || exit $?
else else
addDisk "userdata2" "$DISK2_FILE" "$DISK_EXT" "disk2" "$DISK2_SIZE" "4" "0xd" "$DISK_FMT" || exit $? addDisk "$DISK2_FILE" "$DISK_EXT" "disk2" "$DISK2_SIZE" "4" "0xd" "$DISK_FMT" "$DISK_IO" "$DISK_CACHE" || exit $?
fi fi
if [ -n "$DEVICE3" ]; then if [ -n "$DEVICE3" ]; then
addDevice "userdata3" "$DEVICE3" "device3" "5" "0xe" || exit $? addDevice "$DEVICE3" "device3" "5" "0xe" || exit $?
else else
addDisk "userdata3" "$DISK3_FILE" "$DISK_EXT" "disk3" "$DISK3_SIZE" "5" "0xe" "$DISK_FMT" || exit $? addDisk "$DISK3_FILE" "$DISK_EXT" "disk3" "$DISK3_SIZE" "5" "0xe" "$DISK_FMT" "$DISK_IO" "$DISK_CACHE" || exit $?
fi fi
if [ -n "$DEVICE4" ]; then if [ -n "$DEVICE4" ]; then
addDevice "userdata4" "$DEVICE4" "device4" "6" "0xf" || exit $? addDevice "$DEVICE4" "device4" "6" "0xf" || exit $?
else else
addDisk "userdata4" "$DISK4_FILE" "$DISK_EXT" "disk4" "$DISK4_SIZE" "6" "0xf" "$DISK_FMT" || exit $? addDisk "$DISK4_FILE" "$DISK_EXT" "disk4" "$DISK4_SIZE" "6" "0xf" "$DISK_FMT" "$DISK_IO" "$DISK_CACHE" || exit $?
fi fi
html "Initialized disks successfully..." html "Initialized disks successfully..."

View File

@@ -18,7 +18,7 @@ cd /run
trap - ERR trap - ERR
info "Booting $APP using $VERS..." info "Booting ${APP}..."
[[ "$DEBUG" == [Yy1]* ]] && echo "Arguments: $ARGS" && echo [[ "$DEBUG" == [Yy1]* ]] && echo "Arguments: $ARGS" && echo
if [[ "$CONSOLE" == [Yy]* ]]; then if [[ "$CONSOLE" == [Yy]* ]]; then

View File

@@ -5,6 +5,7 @@ set -Eeuo pipefail
if [ -f "$STORAGE/dsm.ver" ]; then if [ -f "$STORAGE/dsm.ver" ]; then
BASE=$(<"$STORAGE/dsm.ver") BASE=$(<"$STORAGE/dsm.ver")
[ -z "$BASE" ] && BASE="DSM_VirtualDSM_69057"
else else
# Fallback for old installs # Fallback for old installs
BASE="DSM_VirtualDSM_42962" BASE="DSM_VirtualDSM_42962"
@@ -12,14 +13,14 @@ fi
if [ -n "$URL" ]; then if [ -n "$URL" ]; then
BASE=$(basename "$URL" .pat) BASE=$(basename "$URL" .pat)
if [ ! -f "$STORAGE/$BASE.system.img" ]; then if [ ! -s "$STORAGE/$BASE.system.img" ]; then
BASE=$(basename "${URL%%\?*}" .pat) BASE=$(basename "${URL%%\?*}" .pat)
: "${BASE//+/ }"; printf -v BASE '%b' "${_//%/\\x}" : "${BASE//+/ }"; printf -v BASE '%b' "${_//%/\\x}"
BASE=$(echo "$BASE" | sed -e 's/[^A-Za-z0-9._-]/_/g') BASE=$(echo "$BASE" | sed -e 's/[^A-Za-z0-9._-]/_/g')
fi fi
fi fi
if [[ -f "$STORAGE/$BASE.boot.img" ]] && [[ -f "$STORAGE/$BASE.system.img" ]]; then if [[ -s "$STORAGE/$BASE.boot.img" ]] && [[ -s "$STORAGE/$BASE.system.img" ]]; then
return 0 # Previous installation found return 0 # Previous installation found
fi fi
@@ -65,6 +66,10 @@ if [[ "${FS,,}" == "fuse"* ]]; then
info "Warning: the filesystem of $STORAGE is FUSE, this extra layer will negatively affect performance!" info "Warning: the filesystem of $STORAGE is FUSE, this extra layer will negatively affect performance!"
fi fi
if [[ "${FS,,}" == "ecryptfs" ]] || [[ "${FS,,}" == "tmpfs" ]]; then
info "Warning: the filesystem of $STORAGE is $FS, which does not support O_DIRECT mode, adjusting settings..."
fi
if [[ "${FS,,}" == "fat"* || "${FS,,}" == "vfat"* || "${FS,,}" == "msdos"* ]]; then if [[ "${FS,,}" == "fat"* || "${FS,,}" == "vfat"* || "${FS,,}" == "msdos"* ]]; then
error "Unable to install on $FS filesystems, please use a different filesystem for /storage." && exit 61 error "Unable to install on $FS filesystems, please use a different filesystem for /storage." && exit 61
fi fi
@@ -106,7 +111,7 @@ fi
ROOT="Y" ROOT="Y"
RDC="$STORAGE/dsm.rd" RDC="$STORAGE/dsm.rd"
if [ ! -f "$RDC" ]; then if [ ! -s "$RDC" ]; then
MSG="Downloading installer..." MSG="Downloading installer..."
PRG="Downloading installer ([P])..." PRG="Downloading installer ([P])..."
@@ -118,18 +123,25 @@ if [ ! -f "$RDC" ]; then
LOC="$DL/release/7.0.1/42218/DSM_VirtualDSM_42218.pat" LOC="$DL/release/7.0.1/42218/DSM_VirtualDSM_42218.pat"
rm -f "$RD" rm -f "$RD"
rm -f "$RDC"
/run/progress.sh "$RD" "$PRG" & /run/progress.sh "$RD" "$PRG" &
{ curl -r "$POS" -sfk -S -o "$RD" "$LOC"; rc=$?; } || : { curl -r "$POS" -sfk -S -o "$RD" "$LOC"; rc=$?; } || :
fKill "progress.sh" fKill "progress.sh"
(( rc != 0 )) && error "Failed to download $LOC, reason: $rc" && exit 60
SUM=$(md5sum "$RD" | cut -f 1 -d " ") if (( rc != 0 )); then
if (( rc != 22 )) && (( rc != 56 )); then
error "Failed to download $LOC, reason: $rc" && exit 60
fi
SUM="skip"
else
SUM=$(md5sum "$RD" | cut -f 1 -d " ")
fi
if [ "$SUM" != "$VERIFY" ]; then if [ "$SUM" != "$VERIFY" ]; then
PAT="/install.pat" PAT="/install.pat"
rm "$RD" rm -f "$RD"
rm -f "$PAT" rm -f "$PAT"
html "$MSG" html "$MSG"
@@ -211,7 +223,7 @@ else
fi fi
[ ! -f "$PAT" ] && error "Failed to download $URL" && exit 69 [ ! -s "$PAT" ] && error "Failed to download $URL" && exit 69
SIZE=$(stat -c%s "$PAT") SIZE=$(stat -c%s "$PAT")
@@ -248,7 +260,7 @@ MSG="Preparing system partition..."
info "Install: $MSG" && html "$MSG" info "Install: $MSG" && html "$MSG"
BOOT=$(find "$TMP" -name "*.bin.zip") BOOT=$(find "$TMP" -name "*.bin.zip")
[ ! -f "$BOOT" ] && error "The PAT file contains no boot image." && exit 67 [ ! -s "$BOOT" ] && error "The PAT file contains no boot image." && exit 67
BOOT=$(echo "$BOOT" | head -c -5) BOOT=$(echo "$BOOT" | head -c -5)
unzip -q -o "$BOOT".zip -d "$TMP" unzip -q -o "$BOOT".zip -d "$TMP"
@@ -309,15 +321,15 @@ IDB="$TMP/indexdb"
PKG="$TMP/packages" PKG="$TMP/packages"
HDP="$TMP/synohdpack_img" HDP="$TMP/synohdpack_img"
[ ! -f "$HDA.tgz" ] && error "The PAT file contains no OS image." && exit 64 [ ! -s "$HDA.tgz" ] && error "The PAT file contains no OS image." && exit 64
mv "$HDA.tgz" "$HDA.txz" mv "$HDA.tgz" "$HDA.txz"
[ -d "$PKG" ] && mv "$PKG/" "$MOUNT/.SynoUpgradePackages/" [ -d "$PKG" ] && mv "$PKG/" "$MOUNT/.SynoUpgradePackages/"
rm -f "$MOUNT/.SynoUpgradePackages/ActiveInsight-"* rm -f "$MOUNT/.SynoUpgradePackages/ActiveInsight-"*
[ -f "$HDP.txz" ] && tar xpfJ "$HDP.txz" --absolute-names -C "$MOUNT/" [ -s "$HDP.txz" ] && tar xpfJ "$HDP.txz" --absolute-names -C "$MOUNT/"
if [ -f "$IDB.txz" ]; then if [ -s "$IDB.txz" ]; then
INDEX_DB="$MOUNT/usr/syno/synoman/indexdb/" INDEX_DB="$MOUNT/usr/syno/synoman/indexdb/"
mkdir -p "$INDEX_DB" mkdir -p "$INDEX_DB"
tar xpfJ "$IDB.txz" --absolute-names -C "$INDEX_DB" tar xpfJ "$IDB.txz" --absolute-names -C "$INDEX_DB"

View File

@@ -6,6 +6,7 @@ set -Eeuo pipefail
: "${MAC:=""}" : "${MAC:=""}"
: "${DHCP:="N"}" : "${DHCP:="N"}"
: "${NETWORK:="Y"}" : "${NETWORK:="Y"}"
: "${HOST_PORTS:=""}"
: "${VM_NET_DEV:=""}" : "${VM_NET_DEV:=""}"
: "${VM_NET_TAP:="dsm"}" : "${VM_NET_TAP:="dsm"}"
@@ -35,8 +36,8 @@ configureDHCP() {
{ ip link add link "$VM_NET_DEV" name "$VM_NET_TAP" address "$VM_NET_MAC" type macvtap mode bridge ; rc=$?; } || : { ip link add link "$VM_NET_DEV" name "$VM_NET_TAP" address "$VM_NET_MAC" type macvtap mode bridge ; rc=$?; } || :
if (( rc != 0 )); then if (( rc != 0 )); then
error "Cannot create macvtap interface. Please make sure the network type is 'macvlan' and not 'ipvlan'," error "Cannot create macvtap interface. Please make sure that the network type is 'macvlan' and not 'ipvlan',"
error "and that the NET_ADMIN capability has been added to the container: --cap-add NET_ADMIN" && exit 16 error "that your kernel is recent (>4) and supports it, and that the container has the NET_ADMIN capability set." && exit 16
fi fi
while ! ip link set "$VM_NET_TAP" up; do while ! ip link set "$VM_NET_TAP" up; do
@@ -103,6 +104,21 @@ configureDNS() {
return 0 return 0
} }
getPorts() {
local list=$1
[ -z "$list" ] && echo "" && return 0
if [[ "$list" != *","* ]]; then
echo " ! --dport $list"
else
echo " -m multiport ! --dports $list"
fi
return 0
}
configureNAT() { configureNAT() {
# Create the necessary file structure for /dev/net/tun # Create the necessary file structure for /dev/net/tun
@@ -114,17 +130,20 @@ configureNAT() {
fi fi
if [ ! -c /dev/net/tun ]; then if [ ! -c /dev/net/tun ]; then
error "TUN device missing. $ADD_ERR --cap-add NET_ADMIN" && exit 25 error "TUN device missing. $ADD_ERR --device /dev/net/tun --cap-add NET_ADMIN" && exit 25
fi fi
# Check port forwarding flag # Check port forwarding flag
if [[ $(< /proc/sys/net/ipv4/ip_forward) -eq 0 ]]; then if [[ $(< /proc/sys/net/ipv4/ip_forward) -eq 0 ]]; then
{ sysctl -w net.ipv4.ip_forward=1 ; rc=$?; } || : { sysctl -w net.ipv4.ip_forward=1 > /dev/null; rc=$?; } || :
if (( rc != 0 )); then if (( rc != 0 )) || [[ $(< /proc/sys/net/ipv4/ip_forward) -eq 0 ]]; then
error "IP forwarding is disabled. $ADD_ERR --sysctl net.ipv4.ip_forward=1" && exit 24 error "IP forwarding is disabled. $ADD_ERR --sysctl net.ipv4.ip_forward=1" && exit 24
fi fi
fi fi
local tables="The 'ip_tables' kernel module is not loaded. Try this command: sudo modprobe ip_tables iptable_nat"
local tuntap="The 'tun' kernel module is not available. Try this command: 'sudo modprobe tun' or run the container with 'privileged: true'."
# 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'
@@ -143,7 +162,9 @@ configureNAT() {
done done
# QEMU Works with taps, set tap to the bridge created # QEMU Works with taps, set tap to the bridge created
ip tuntap add dev "$VM_NET_TAP" mode tap if ! ip tuntap add dev "$VM_NET_TAP" mode tap; then
error "$tuntap" && exit 31
fi
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..."
@@ -156,13 +177,19 @@ configureNAT() {
update-alternatives --set iptables /usr/sbin/iptables-legacy > /dev/null update-alternatives --set iptables /usr/sbin/iptables-legacy > /dev/null
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy > /dev/null update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy > /dev/null
iptables -t nat -A POSTROUTING -o "$VM_NET_DEV" -j MASQUERADE exclude=$(getPorts "$HOST_PORTS")
iptables -t nat -A PREROUTING -i "$VM_NET_DEV" -d "$IP" -p tcp -j DNAT --to "$VM_NET_IP"
if ! iptables -t nat -A POSTROUTING -o "$VM_NET_DEV" -j MASQUERADE; then
error "$tables" && exit 30
fi
# shellcheck disable=SC2086
iptables -t nat -A PREROUTING -i "$VM_NET_DEV" -d "$IP" -p tcp${exclude} -j DNAT --to "$VM_NET_IP"
iptables -t nat -A PREROUTING -i "$VM_NET_DEV" -d "$IP" -p udp -j DNAT --to "$VM_NET_IP" iptables -t nat -A PREROUTING -i "$VM_NET_DEV" -d "$IP" -p udp -j DNAT --to "$VM_NET_IP"
if (( KERNEL > 4 )); then if (( KERNEL > 4 )); then
# Hack for guest VMs complaining about "bad udp checksums in 5 packets" # Hack for guest VMs complaining about "bad udp checksums in 5 packets"
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 > /dev/null 2>&1 || true
fi fi
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"
@@ -200,7 +227,7 @@ closeNetwork() {
else else
local pid="/var/run/dnsmasq.pid" local pid="/var/run/dnsmasq.pid"
[ -f "$pid" ] && pKill "$(<"$pid")" [ -s "$pid" ] && pKill "$(<"$pid")"
ip link set "$VM_NET_TAP" down promisc off || true ip link set "$VM_NET_TAP" down promisc off || true
ip link delete "$VM_NET_TAP" || true ip link delete "$VM_NET_TAP" || true
@@ -228,9 +255,8 @@ getInfo() {
if [ -z "$VM_NET_MAC" ]; then if [ -z "$VM_NET_MAC" ]; then
local file="$STORAGE/dsm.mac" local file="$STORAGE/dsm.mac"
if [ -f "$file" ]; then [ -s "$file" ] && VM_NET_MAC=$(<"$file")
VM_NET_MAC=$(<"$file") if [ -z "$VM_NET_MAC" ]; then
else
# Generate MAC address based on Docker container ID in hostname # Generate MAC address based on Docker container ID in hostname
VM_NET_MAC=$(echo "$HOST" | md5sum | sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:11:32:\3:\4:\5/') VM_NET_MAC=$(echo "$HOST" | md5sum | sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:11:32:\3:\4:\5/')
echo "${VM_NET_MAC^^}" > "$file" echo "${VM_NET_MAC^^}" > "$file"
@@ -274,10 +300,14 @@ if [[ "$DEBUG" == [Yy1]* ]]; then
echo echo
fi fi
if [[ "$IP" == "172.17."* ]]; then
warn "your container IP starts with 172.17.* which will cause conflicts when you install the Container Manager package inside DSM!"
fi
if [[ "$DHCP" == [Yy1]* ]]; then if [[ "$DHCP" == [Yy1]* ]]; then
if [[ "$GATEWAY" == "172."* ]] && [[ "$DEBUG" != [Yy1]* ]]; then if [[ "$GATEWAY" == "172."* ]]; then
error "You can only enable DHCP while the container is on a macvlan network!" && exit 26 warn "your gateway IP starts with 172.* which is often a sign that you are not on a macvlan network (required for DHCP)!"
fi fi
# Configuration for DHCP IP # Configuration for DHCP IP

View File

@@ -10,10 +10,11 @@ API_HOST="127.0.0.1:2210"
QEMU_TERM="" QEMU_TERM=""
QEMU_PORT=7100 QEMU_PORT=7100
QEMU_TIMEOUT=50 QEMU_TIMEOUT=50
QEMU_PID="/run/shm/qemu.pid" QEMU_DIR="/run/shm"
QEMU_LOG="/run/shm/qemu.log" QEMU_PID="$QEMU_DIR/qemu.pid"
QEMU_OUT="/run/shm/qemu.out" QEMU_LOG="$QEMU_DIR/qemu.log"
QEMU_END="/run/shm/qemu.end" QEMU_OUT="$QEMU_DIR/qemu.out"
QEMU_END="$QEMU_DIR/qemu.end"
if [[ "$KVM" == [Nn]* ]]; then if [[ "$KVM" == [Nn]* ]]; then
API_TIMEOUT=$(( API_TIMEOUT*2 )) API_TIMEOUT=$(( API_TIMEOUT*2 ))
@@ -36,7 +37,7 @@ finish() {
touch "$QEMU_END" touch "$QEMU_END"
if [ -f "$QEMU_PID" ]; then if [ -s "$QEMU_PID" ]; then
pid=$(<"$QEMU_PID") pid=$(<"$QEMU_PID")
echo && error "Forcefully terminating QEMU process, reason: $reason..." echo && error "Forcefully terminating QEMU process, reason: $reason..."
@@ -45,7 +46,7 @@ finish() {
while isAlive "$pid"; do while isAlive "$pid"; do
sleep 1 sleep 1
# Workaround for zombie pid # Workaround for zombie pid
[ ! -f "$QEMU_PID" ] && break [ ! -s "$QEMU_PID" ] && break
done done
fi fi
@@ -64,7 +65,7 @@ terminal() {
local dev="" local dev=""
if [ -f "$QEMU_OUT" ]; then if [ -s "$QEMU_OUT" ]; then
local msg local msg
msg=$(<"$QEMU_OUT") msg=$(<"$QEMU_OUT")
@@ -113,7 +114,7 @@ _graceful_shutdown() {
touch "$QEMU_END" touch "$QEMU_END"
echo && info "Received $1 signal, sending shutdown command..." echo && info "Received $1 signal, sending shutdown command..."
if [ ! -f "$QEMU_PID" ]; then if [ ! -s "$QEMU_PID" ]; then
echo && error "QEMU PID file does not exist?" echo && error "QEMU PID file does not exist?"
finish "$code" && return "$code" finish "$code" && return "$code"
fi fi
@@ -157,7 +158,7 @@ _graceful_shutdown() {
[[ "$DEBUG" == [Yy1]* ]] && info "Shutting down, waiting... ($cnt/$QEMU_TIMEOUT)" [[ "$DEBUG" == [Yy1]* ]] && info "Shutting down, waiting... ($cnt/$QEMU_TIMEOUT)"
# Workaround for zombie pid # Workaround for zombie pid
[ ! -f "$QEMU_PID" ] && break [ ! -s "$QEMU_PID" ] && break
done done

View File

@@ -21,7 +21,7 @@ resp_err="Guest returned an invalid response:"
curl_err="Failed to connect to guest: curl error" curl_err="Failed to connect to guest: curl error"
jq_err="Failed to parse response from guest: jq error" jq_err="Failed to parse response from guest: jq error"
while [ ! -f "$file" ] while [ ! -s "$file" ]
do do
# Check if not shutting down # Check if not shutting down
@@ -30,7 +30,7 @@ do
sleep 3 sleep 3
[ -f "$shutdown" ] && exit 1 [ -f "$shutdown" ] && exit 1
[ -f "$file" ] && break [ -s "$file" ] && break
# Retrieve network info from guest VM # Retrieve network info from guest VM
{ json=$(curl -m 20 -sk "$url"); rc=$?; } || : { json=$(curl -m 20 -sk "$url"); rc=$?; } || :

View File

@@ -21,7 +21,8 @@ if [[ "$KVM" != [Nn]* ]]; then
if ! sh -c 'echo -n > /dev/kvm' &> /dev/null; then if ! sh -c 'echo -n > /dev/kvm' &> /dev/null; then
KVM_ERR="(no write access)" KVM_ERR="(no write access)"
else else
if ! grep -q -e vmx -e svm /proc/cpuinfo; then flags=$(sed -ne '/^flags/s/^.*: //p' /proc/cpuinfo)
if ! grep -qw "vmx\|svm" <<< "$flags"; then
KVM_ERR="(vmx/svm disabled)" KVM_ERR="(vmx/svm disabled)"
fi fi
fi fi
@@ -41,7 +42,7 @@ if [[ "$KVM" != [Nn]* ]]; then
CPU_FEATURES="kvm=on,l3-cache=on" CPU_FEATURES="kvm=on,l3-cache=on"
KVM_OPTS=",accel=kvm -enable-kvm -global kvm-pit.lost_tick_policy=discard" KVM_OPTS=",accel=kvm -enable-kvm -global kvm-pit.lost_tick_policy=discard"
if ! grep -qE '^flags.* (sse4_2)' /proc/cpuinfo; then if ! grep -qw "sse4_2" <<< "$flags"; then
info "Your CPU does not have the SSE4 instruction set that Virtual DSM requires, it will be emulated..." 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" [ -z "$CPU_MODEL" ] && CPU_MODEL="$DEF_MODEL"
CPU_FEATURES="$CPU_FEATURES,+ssse3,+sse4.1,+sse4.2" CPU_FEATURES="$CPU_FEATURES,+ssse3,+sse4.1,+sse4.2"
@@ -89,7 +90,7 @@ else
fi fi
if [ -z "$HOST_CPU" ]; then 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') HOST_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')
fi fi
if [ -n "$HOST_CPU" ]; then if [ -n "$HOST_CPU" ]; then

View File

@@ -21,7 +21,7 @@ fi
while true while true
do do
if [ -f "$file" ]; then if [ -s "$file" ]; then
bytes=$(du -sb "$file" | cut -f1) bytes=$(du -sb "$file" | cut -f1)
if (( bytes > 1000 )); then if (( bytes > 1000 )); then
size=$(echo "$bytes" | numfmt --to=iec --suffix=B | sed -r 's/([A-Z])/ \1/') size=$(echo "$bytes" | numfmt --to=iec --suffix=B | sed -r 's/([A-Z])/ \1/')

View File

@@ -12,7 +12,6 @@ trap 'error "Status $? while: $BASH_COMMAND (line $LINENO/$BASH_LINENO)"' ERR
echo " Starting $APP for Docker v$(</run/version)..." echo " Starting $APP for Docker v$(</run/version)..."
echo " For support visit $SUPPORT" echo " For support visit $SUPPORT"
echo
# Docker environment variables # Docker environment variables
@@ -38,11 +37,13 @@ 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>"
SYS=$(uname -r)
HOST=$(hostname -s) HOST=$(hostname -s)
KERNEL=$(uname -r | cut -b 1) KERNEL=$(echo "$SYS" | cut -b 1)
MINOR=$(uname -r | cut -d '.' -f2) MINOR=$(echo "$SYS" | cut -d '.' -f2)
ARCH=$(dpkg --print-architecture) ARCH=$(dpkg --print-architecture)
VERS=$(qemu-system-x86_64 --version | head -n 1 | cut -d '(' -f 1) 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 # Check system
@@ -58,6 +59,23 @@ if [ ! -d "$STORAGE" ]; then
error "Storage folder ($STORAGE) not found!" && exit 13 error "Storage folder ($STORAGE) not found!" && exit 13
fi fi
# Check filesystem
FS=$(stat -f -c %T "$STORAGE")
if [[ "${FS,,}" == "ecryptfs" ]] || [[ "${FS,,}" == "tmpfs" ]]; then
DISK_IO="threads"
DISK_CACHE="writeback"
fi
# Print system info
SYS="${SYS/-generic/}"
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
# Cleanup files # Cleanup files
rm -f /run/shm/qemu.* rm -f /run/shm/qemu.*
rm -f /run/shm/dsm.url rm -f /run/shm/dsm.url