mirror of
https://github.com/vdsm/virtual-dsm.git
synced 2025-11-08 02:53:45 +08:00
Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f74771a9cc | ||
|
|
f24ba41930 | ||
|
|
f412580a4a | ||
|
|
5cde1b4438 | ||
|
|
7cfb57b1bc | ||
|
|
a478b58f97 | ||
|
|
8297f4f880 | ||
|
|
4c67343d33 | ||
|
|
53cc6998f0 | ||
|
|
d857d71e0d | ||
|
|
003c2766ce | ||
|
|
78594098cc | ||
|
|
3c31bc91e4 | ||
|
|
72141bab7a | ||
|
|
bc52463aa4 | ||
|
|
9fa68908a9 | ||
|
|
740dbec1b1 | ||
|
|
440d203730 | ||
|
|
1a83c67e2c | ||
|
|
34a707a2a5 | ||
|
|
cabb2cdfc9 | ||
|
|
dc52ccf172 | ||
|
|
bdd7fec3c3 | ||
|
|
bd8b03d089 | ||
|
|
a10588b0ce | ||
|
|
3503b86e12 | ||
|
|
9e124980cd | ||
|
|
675aa5e122 | ||
|
|
2a62d4e938 | ||
|
|
9cbb51cc86 | ||
|
|
7790f81d15 | ||
|
|
fdbff4879b | ||
|
|
739e679a66 | ||
|
|
0dea507d85 | ||
|
|
4f524c47d8 | ||
|
|
0c74201eb4 |
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@@ -8,6 +8,10 @@ on:
|
||||
paths-ignore:
|
||||
- '**/*.md'
|
||||
- '**/*.yml'
|
||||
- '**/*.js'
|
||||
- '**/*.css'
|
||||
- '**/*.html'
|
||||
- 'web/**'
|
||||
- '.gitignore'
|
||||
- '.dockerignore'
|
||||
- '.github/**'
|
||||
|
||||
14
.github/workflows/check.yml
vendored
14
.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
|
||||
-
|
||||
name: Lint Dockerfile
|
||||
uses: hadolint/hadolint-action@v3.1.0
|
||||
with:
|
||||
dockerfile: Dockerfile
|
||||
ignore: DL3008,DL3003,DL3006
|
||||
failure-threshold: warning
|
||||
|
||||
2
.github/workflows/hub.yml
vendored
2
.github/workflows/hub.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
-
|
||||
name: Docker Hub Description
|
||||
uses: peter-evans/dockerhub-description@v3
|
||||
uses: peter-evans/dockerhub-description@v4
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
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'
|
||||
|
||||
|
||||
16
readme.md
16
readme.md
@@ -17,7 +17,6 @@ Virtual DSM in a docker container.
|
||||
|
||||
- Multiple disks
|
||||
- KVM acceleration
|
||||
- GPU pass-through
|
||||
- Upgrades supported
|
||||
|
||||
## Usage
|
||||
@@ -47,7 +46,7 @@ services:
|
||||
Via `docker run`
|
||||
|
||||
```bash
|
||||
docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-timeout 60 vdsm/virtual-dsm
|
||||
docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-timeout 120 vdsm/virtual-dsm
|
||||
```
|
||||
|
||||
## FAQ
|
||||
@@ -56,13 +55,11 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
|
||||
|
||||
Very simple! These are the steps:
|
||||
|
||||
- Start the container and get some coffee.
|
||||
|
||||
- Connect to [port 5000](http://localhost:5000) of the container in your web browser.
|
||||
- Start the container and connect to [port 5000](http://localhost:5000) using your web browser.
|
||||
|
||||
- Wait until DSM is ready, choose an username and password, and you will be taken to the desktop.
|
||||
|
||||
- Enjoy your brand new machine, and don't forget to star this repo!
|
||||
Enjoy your brand new machine, and don't forget to star this repo!
|
||||
|
||||
* ### How do I change the size of the disk?
|
||||
|
||||
@@ -192,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:
|
||||
@@ -201,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?
|
||||
|
||||
@@ -237,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.
|
||||
|
||||
@@ -3,8 +3,8 @@ set -Eeuo pipefail
|
||||
|
||||
DEF_OPTS="-nodefaults -boot strict=on"
|
||||
RAM_OPTS=$(echo "-m $RAM_SIZE" | sed 's/MB/M/g;s/GB/G/g;s/TB/T/g')
|
||||
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}"
|
||||
CPU_OPTS="-cpu $CPU_FLAGS -smp $CPU_CORES,sockets=1,dies=1,cores=$CPU_CORES,threads=1"
|
||||
MAC_OPTS="-machine type=q35,usb=off,vmport=off,dump-guest-core=off,hpet=off${KVM_OPTS}"
|
||||
DEV_OPTS="-device virtio-balloon-pci,id=balloon0,bus=pcie.0,addr=0x4"
|
||||
DEV_OPTS="$DEV_OPTS -object rng-random,id=objrng0,filename=/dev/urandom"
|
||||
DEV_OPTS="$DEV_OPTS -device virtio-rng-pci,rng=objrng0,id=rng0,bus=pcie.0,addr=0x1c"
|
||||
|
||||
44
src/disk.sh
44
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
|
||||
|
||||
@@ -112,8 +112,8 @@ createDisk() {
|
||||
fi
|
||||
fi
|
||||
|
||||
MSG="Creating a $DISK_TYPE $DISK_DESC image in $DISK_FMT format with a size of $DISK_SPACE..."
|
||||
info "$MSG" && html "$MSG"
|
||||
html "Creating a $DISK_DESC image..."
|
||||
info "Creating a $DISK_SPACE $DISK_TYPE $DISK_DESC image in $DISK_FMT format..."
|
||||
|
||||
local FAIL="Could not create a $DISK_TYPE $DISK_FMT $DISK_DESC image of $DISK_SPACE ($DISK_FILE)"
|
||||
|
||||
@@ -266,8 +266,8 @@ convertDisk() {
|
||||
fi
|
||||
fi
|
||||
|
||||
MSG="Converting $DISK_DESC to $DST_FMT, please wait until completed..."
|
||||
info "$MSG" && html "$MSG"
|
||||
html "Converting $DISK_DESC to $DST_FMT..."
|
||||
info "Converting $DISK_DESC to $DST_FMT, please wait until completed..."
|
||||
|
||||
local CONV_FLAGS="-p"
|
||||
local DISK_PARAM="$DISK_ALLOC"
|
||||
@@ -306,8 +306,8 @@ convertDisk() {
|
||||
fi
|
||||
fi
|
||||
|
||||
MSG="Conversion of $DISK_DESC to $DST_FMT completed succesfully!"
|
||||
info "$MSG" && html "$MSG"
|
||||
html "Conversion of $DISK_DESC completed..."
|
||||
info "Conversion of $DISK_DESC to $DST_FMT completed succesfully!"
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -18,11 +18,13 @@ cd /run
|
||||
|
||||
trap - ERR
|
||||
|
||||
info "Booting $APP using $VERS..."
|
||||
[[ "$DEBUG" == [Yy1]* ]] && echo "Arguments: $ARGS" && echo
|
||||
|
||||
if [[ "$CONSOLE" == [Yy]* ]]; then
|
||||
exec qemu-system-x86_64 ${ARGS:+ $ARGS}
|
||||
fi
|
||||
|
||||
[[ "$DEBUG" == [Yy1]* ]] && info "$VERS" && echo "Arguments: $ARGS" && echo
|
||||
{ qemu-system-x86_64 ${ARGS:+ $ARGS} >"$QEMU_OUT" 2>"$QEMU_LOG"; rc=$?; } || :
|
||||
(( rc != 0 )) && error "$(<"$QEMU_LOG")" && exit 15
|
||||
|
||||
|
||||
@@ -105,6 +105,7 @@ RDC="$STORAGE/dsm.rd"
|
||||
if [ ! -f "$RDC" ]; then
|
||||
|
||||
MSG="Downloading installer..."
|
||||
PRG="Downloading installer ([P])..."
|
||||
info "Install: $MSG" && html "$MSG"
|
||||
|
||||
RD="$TMP/rd.gz"
|
||||
@@ -112,7 +113,11 @@ if [ ! -f "$RDC" ]; then
|
||||
VERIFY="b4215a4b213ff5154db0488f92c87864"
|
||||
LOC="$DL/release/7.0.1/42218/DSM_VirtualDSM_42218.pat"
|
||||
|
||||
rm -f "$RD"
|
||||
/run/progress.sh "$RD" "$PRG" &
|
||||
{ curl -r "$POS" -sfk -S -o "$RD" "$LOC"; rc=$?; } || :
|
||||
|
||||
fKill "progress.sh"
|
||||
(( rc != 0 )) && error "Failed to download $LOC, reason: $rc" && exit 60
|
||||
|
||||
SUM=$(md5sum "$RD" | cut -f 1 -d " ")
|
||||
@@ -123,7 +128,11 @@ if [ ! -f "$RDC" ]; then
|
||||
rm "$RD"
|
||||
rm -f "$PAT"
|
||||
|
||||
html "$MSG"
|
||||
/run/progress.sh "$PAT" "$PRG" &
|
||||
{ wget "$LOC" -O "$PAT" -q --no-check-certificate --show-progress "$PROGRESS"; rc=$?; } || :
|
||||
|
||||
fKill "progress.sh"
|
||||
(( rc != 0 )) && error "Failed to download $LOC , reason: $rc" && exit 60
|
||||
|
||||
tar --extract --file="$PAT" --directory="$(dirname "$RD")"/. "$(basename "$RD")"
|
||||
@@ -175,7 +184,10 @@ fi
|
||||
rm -rf "$TMP" && mkdir -p "$TMP"
|
||||
|
||||
info "Install: Downloading $BASE.pat..."
|
||||
html "Install: Downloading DSM from Synology..."
|
||||
|
||||
MSG="Downloading DSM..."
|
||||
PRG="Downloading DSM ([P])..."
|
||||
html "$MSG"
|
||||
|
||||
PAT="/$BASE.pat"
|
||||
rm -f "$PAT"
|
||||
@@ -186,7 +198,11 @@ if [[ "$URL" == "file://"* ]]; then
|
||||
|
||||
else
|
||||
|
||||
/run/progress.sh "$PAT" "$PRG" &
|
||||
|
||||
{ wget "$URL" -O "$PAT" -q --no-check-certificate --show-progress "$PROGRESS"; rc=$?; } || :
|
||||
|
||||
fKill "progress.sh"
|
||||
(( rc != 0 )) && error "Failed to download $URL , reason: $rc" && exit 69
|
||||
|
||||
fi
|
||||
@@ -249,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,10 +80,16 @@ 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
|
||||
$DNSMASQ ${DNSMASQ_OPTS:+ $DNSMASQ_OPTS}
|
||||
|
||||
if ! $DNSMASQ ${DNSMASQ_OPTS:+ $DNSMASQ_OPTS}; then
|
||||
error "Failed to start dnsmasq, reason: $?" && exit 29
|
||||
fi
|
||||
{ set +x; } 2>/dev/null
|
||||
[[ "$DEBUG" == [Yy1]* ]] && echo
|
||||
|
||||
@@ -115,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=$?; } || :
|
||||
|
||||
@@ -126,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
|
||||
|
||||
@@ -134,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
|
||||
|
||||
@@ -153,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 || :
|
||||
@@ -209,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}')
|
||||
@@ -240,16 +249,16 @@ 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
|
||||
if [[ "$GATEWAY" == "172."* ]] && [[ "$DEBUG" != [Yy1]* ]]; then
|
||||
error "You can only enable DHCP while the container is on a macvlan network!" && exit 26
|
||||
fi
|
||||
fi
|
||||
|
||||
# Configuration for DHCP IP
|
||||
configureDHCP
|
||||
|
||||
@@ -98,7 +98,6 @@ terminal() {
|
||||
|
||||
_graceful_shutdown() {
|
||||
|
||||
local cnt=0
|
||||
local code=$?
|
||||
local pid url response
|
||||
|
||||
@@ -144,6 +143,8 @@ _graceful_shutdown() {
|
||||
|
||||
fi
|
||||
|
||||
local cnt=0
|
||||
|
||||
while [ "$cnt" -lt "$QEMU_TIMEOUT" ]; do
|
||||
|
||||
! isAlive "$pid" && break
|
||||
@@ -167,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
|
||||
|
||||
49
src/proc.sh
49
src/proc.sh
@@ -5,8 +5,9 @@ set -Eeuo pipefail
|
||||
|
||||
: "${KVM:="Y"}"
|
||||
: "${HOST_CPU:=""}"
|
||||
: "${CPU_MODEL:="host"}"
|
||||
: "${CPU_FEATURES:="+ssse3,+sse4.1,+sse4.2"}"
|
||||
: "${CPU_FLAGS:=""}"
|
||||
: "${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,26 +38,54 @@ fi
|
||||
|
||||
if [[ "$KVM" != [Nn]* ]]; then
|
||||
|
||||
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="l3-cache=on"
|
||||
|
||||
if [[ "$CPU_MODEL" == "host"* ]]; then
|
||||
if [[ "$ARCH" == "amd64" ]]; then
|
||||
CPU_MODEL="max,$CPU_FEATURES"
|
||||
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_FEATURES"
|
||||
CPU_MODEL="$DEF_MODEL"
|
||||
fi
|
||||
fi
|
||||
|
||||
CPU_FEATURES="$CPU_FEATURES,+ssse3,+sse4.1,+sse4.2"
|
||||
|
||||
fi
|
||||
|
||||
if [ -z "$CPU_FLAGS" ]; then
|
||||
if [ -z "$CPU_FEATURES" ]; then
|
||||
CPU_FLAGS="$CPU_MODEL"
|
||||
else
|
||||
CPU_FLAGS="$CPU_MODEL,$CPU_FEATURES"
|
||||
fi
|
||||
else
|
||||
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
|
||||
|
||||
32
src/progress.sh
Normal file
32
src/progress.sh
Normal file
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
|
||||
escape () {
|
||||
local s
|
||||
s=${1//&/\&}
|
||||
s=${s//</\<}
|
||||
s=${s//>/\>}
|
||||
s=${s//'"'/\"}
|
||||
printf -- %s "$s"
|
||||
return 0
|
||||
}
|
||||
|
||||
file="$1"
|
||||
body=$(escape "$2")
|
||||
info="/run/shm/msg.html"
|
||||
|
||||
if [[ "$body" == *"..." ]]; then
|
||||
body="<p class=\"loading\">${body/.../}</p>"
|
||||
fi
|
||||
|
||||
while true
|
||||
do
|
||||
if [ -f "$file" ]; then
|
||||
bytes=$(du -sb "$file" | cut -f1)
|
||||
if (( bytes > 1000 )); then
|
||||
size=$(echo "$bytes" | numfmt --to=iec --suffix=B | sed -r 's/([A-Z])/ \1/')
|
||||
echo "${body//(\[P\])/($size)}"> "$info"
|
||||
fi
|
||||
fi
|
||||
sleep 1 & wait $!
|
||||
done
|
||||
22
src/reset.sh
22
src/reset.sh
@@ -28,32 +28,36 @@ echo
|
||||
|
||||
# Helper variables
|
||||
|
||||
PROCESS="${APP,,}"
|
||||
PROCESS="${PROCESS// /-}"
|
||||
|
||||
STORAGE="/storage"
|
||||
INFO="/dev/shm/msg.html"
|
||||
INFO="/run/shm/msg.html"
|
||||
PAGE="/run/shm/index.html"
|
||||
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)
|
||||
VERS=$(qemu-system-x86_64 --version | head -n 1 | cut -d '(' -f 1)
|
||||
|
||||
# Check system
|
||||
|
||||
if [ ! -d "/dev/shm" ]; then
|
||||
error "Directory /dev/shm not found!" && exit 14
|
||||
else
|
||||
[ ! -d "/run/shm" ] && ln -s /dev/shm /run/shm
|
||||
fi
|
||||
|
||||
# Check folder
|
||||
|
||||
if [ ! -d "$STORAGE" ]; then
|
||||
error "Storage folder ($STORAGE) not found!" && exit 13
|
||||
fi
|
||||
|
||||
if [ ! -d "/run/shm" ]; then
|
||||
if [ -d "/dev/shm" ]; then
|
||||
ln -s /dev/shm /run/shm
|
||||
else
|
||||
error "Folder /dev/shm not found!" && exit 14
|
||||
fi
|
||||
fi
|
||||
|
||||
# Cleanup files
|
||||
rm -f /run/shm/qemu.*
|
||||
rm -f /run/shm/dsm.url
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
body {
|
||||
color: white;
|
||||
background-color: #125bdb;
|
||||
font-family: Verdana, Arial, sans-serif;
|
||||
font-smoothing: antialiased;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
font-family: Verdana, Geneva, sans-serif;
|
||||
}
|
||||
|
||||
#info {
|
||||
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
#content {
|
||||
@@ -17,6 +24,7 @@ footer {
|
||||
height: 40px;
|
||||
text-align: center;
|
||||
color: #0c8aeb;
|
||||
text-shadow: 0 0 1px #0c8aeb;
|
||||
}
|
||||
|
||||
#empty {
|
||||
@@ -33,8 +41,13 @@ a:visited {
|
||||
|
||||
footer a:link,
|
||||
footer a:visited,
|
||||
footer a:active { color: #0c8aeb; }
|
||||
footer a:hover { color: #73e6ff; }
|
||||
footer a:active {
|
||||
color: #0c8aeb;
|
||||
}
|
||||
|
||||
footer a:hover {
|
||||
color: #73e6ff;
|
||||
}
|
||||
|
||||
.loading:after {
|
||||
content: " .";
|
||||
|
||||
Reference in New Issue
Block a user