mirror of
https://github.com/vdsm/virtual-dsm.git
synced 2025-11-07 02:23:42 +08:00
Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
abd30b9d91 | ||
|
|
c86408cbd6 | ||
|
|
1f51974c48 | ||
|
|
29f4cde296 | ||
|
|
c4a0035062 | ||
|
|
6724ddbd7d | ||
|
|
8d8ed63122 | ||
|
|
6f4ea81907 | ||
|
|
6d162744ec | ||
|
|
145b4aab5b | ||
|
|
2e4eb56d0b | ||
|
|
39c019193e | ||
|
|
faec563b4a | ||
|
|
9840f8e07a | ||
|
|
3a5895fa0f | ||
|
|
1bac5c8a7f | ||
|
|
dd76c60e2a | ||
|
|
ac78cc7dc5 | ||
|
|
66ac2d2002 | ||
|
|
0bd099d704 | ||
|
|
d2dac3cfb4 | ||
|
|
e81dc0f31d | ||
|
|
5015597183 | ||
|
|
64e2af9fa2 | ||
|
|
debb4b69fc | ||
|
|
c6d3dda171 | ||
|
|
7c0693c2ff | ||
|
|
76355d4857 | ||
|
|
404aaadefc | ||
|
|
be027e10be | ||
|
|
1c8cad92f8 | ||
|
|
fabb8ea3b7 | ||
|
|
2ee4abca54 | ||
|
|
5896928030 | ||
|
|
8652544982 | ||
|
|
a70338ec3c | ||
|
|
a84878abfc | ||
|
|
8421a391b7 | ||
|
|
f9340ec3d6 | ||
|
|
0cca9c5f83 | ||
|
|
13d60b7f47 |
@@ -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
64
.github/ISSUE_TEMPLATE/BUG_REPORT.yml
vendored
Normal 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
|
||||||
44
.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml
vendored
Normal file
44
.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml
vendored
Normal 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.
|
||||||
26
.github/ISSUE_TEMPLATE/QUESTION.yml
vendored
Normal file
26
.github/ISSUE_TEMPLATE/QUESTION.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
name: "? Question"
|
||||||
|
description: General questions about the container
|
||||||
|
title: "[Question]: "
|
||||||
|
labels: ["question"]
|
||||||
|
body:
|
||||||
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: Is your question not already answered in the FAQ?
|
||||||
|
description: Please read the [FAQ](https://github.com/vdsm/virtual-dsm/blob/master/readme.md) carefully to avoid asking duplicate questions.
|
||||||
|
options:
|
||||||
|
- label: I made sure the question is not listed in the [FAQ](https://github.com/vdsm/virtual-dsm/blob/master/readme.md).
|
||||||
|
required: true
|
||||||
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: Is this a general question and not a technical issue?
|
||||||
|
description: For technical issues you must use the [bug report](https://github.com/vdsm/virtual-dsm/issues/new?assignees=&labels=bug&projects=&template=BUG_REPORT.yml&title=%5BBug%5D%3A+) form instead. It contains all the right fields (system info, logfiles, etc.) we need in order to be able to help you.
|
||||||
|
options:
|
||||||
|
- label: I am sure my question is not about a technical issue.
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: question
|
||||||
|
attributes:
|
||||||
|
label: Question
|
||||||
|
description: What's the question you have about the container?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
14
.github/workflows/build.yml
vendored
14
.github/workflows/build.yml
vendored
@@ -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 }}
|
||||||
@@ -103,3 +103,15 @@ jobs:
|
|||||||
url: ${{ secrets.GITLAB_URL }}
|
url: ${{ secrets.GITLAB_URL }}
|
||||||
token: ${{ secrets.GITLAB_TOKEN }}
|
token: ${{ secrets.GITLAB_TOKEN }}
|
||||||
username: ${{ secrets.GITLAB_USERNAME }}
|
username: ${{ secrets.GITLAB_USERNAME }}
|
||||||
|
-
|
||||||
|
name: Send mail
|
||||||
|
uses: action-pack/send-mail@v1
|
||||||
|
with:
|
||||||
|
to: ${{secrets.MAILTO}}
|
||||||
|
from: Github Actions <${{secrets.MAILTO}}>
|
||||||
|
connection_url: ${{secrets.MAIL_CONNECTION}}
|
||||||
|
subject: Build of ${{ github.event.repository.name }} v${{ steps.meta.outputs.version }} completed
|
||||||
|
body: |
|
||||||
|
The build job of ${{ github.event.repository.name }} v${{ steps.meta.outputs.version }} was completed successfully!
|
||||||
|
|
||||||
|
See https://github.com/${{ github.repository }}/actions for more information.
|
||||||
|
|||||||
18
Dockerfile
18
Dockerfile
@@ -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/
|
||||||
|
|||||||
@@ -5,12 +5,8 @@ services:
|
|||||||
image: vdsm/virtual-dsm:latest
|
image: vdsm/virtual-dsm:latest
|
||||||
environment:
|
environment:
|
||||||
DISK_SIZE: "16G"
|
DISK_SIZE: "16G"
|
||||||
RAM_SIZE: "1G"
|
|
||||||
CPU_CORES: "1"
|
|
||||||
devices:
|
devices:
|
||||||
- /dev/kvm
|
- /dev/kvm
|
||||||
device_cgroup_rules:
|
|
||||||
- 'c *:* rwm'
|
|
||||||
cap_add:
|
cap_add:
|
||||||
- NET_ADMIN
|
- NET_ADMIN
|
||||||
ports:
|
ports:
|
||||||
49
readme.md
49
readme.md
@@ -1,6 +1,6 @@
|
|||||||
<h1 align="center">Virtual DSM<br />
|
<h1 align="center">Virtual DSM<br />
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<img src="https://github.com/vdsm/virtual-dsm/raw/master/.github/screen.jpg" title="Screenshot" style="max-width:100%;" width="432" />
|
<a href="https://github.com/vdsm/virtual-dsm"><img src="https://github.com/vdsm/virtual-dsm/raw/master/.github/screen.jpg" title="Screenshot" style="max-width:100%;" width="432" /></a>
|
||||||
</div>
|
</div>
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
</div></h1>
|
</div></h1>
|
||||||
|
|
||||||
Virtual DSM in a docker container.
|
Virtual DSM in a Docker container.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@@ -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,10 +43,10 @@ services:
|
|||||||
stop_grace_period: 2m
|
stop_grace_period: 2m
|
||||||
```
|
```
|
||||||
|
|
||||||
Via `docker run`
|
Via Docker CLI:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -it --rm -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
|
||||||
```
|
```
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
@@ -61,17 +61,6 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
|
|||||||
|
|
||||||
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?
|
|
||||||
|
|
||||||
To expand the default size of 16 GB, locate the `DISK_SIZE` setting in your compose file and modify it to your preferred capacity:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
environment:
|
|
||||||
DISK_SIZE: "128G"
|
|
||||||
```
|
|
||||||
|
|
||||||
This can also be used to resize the existing disk to a larger capacity without any data loss.
|
|
||||||
|
|
||||||
* ### How do I change the storage location?
|
* ### How do I change the storage location?
|
||||||
|
|
||||||
To change the storage location, include the following bind mount in your compose file:
|
To change the storage location, include the following bind mount in your compose file:
|
||||||
@@ -82,6 +71,17 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
|
|||||||
```
|
```
|
||||||
|
|
||||||
Replace the example path `/var/dsm` with the desired storage folder.
|
Replace the example path `/var/dsm` with the desired storage folder.
|
||||||
|
|
||||||
|
* ### How do I change the size of the disk?
|
||||||
|
|
||||||
|
To expand the default size of 16 GB, locate the `DISK_SIZE` setting in your compose file and modify it to your preferred capacity:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
environment:
|
||||||
|
DISK_SIZE: "128G"
|
||||||
|
```
|
||||||
|
|
||||||
|
This can also be used to resize the existing disk to a larger capacity without any data loss.
|
||||||
|
|
||||||
* ### How do I create a growable disk?
|
* ### How do I create a growable disk?
|
||||||
|
|
||||||
@@ -114,14 +114,13 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
|
|||||||
It is possible to pass-through disk devices directly by adding them to your compose file in this way:
|
It is possible to pass-through disk devices directly by adding them to your compose file in this way:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
environment:
|
|
||||||
DEVICE2: "/dev/sda"
|
|
||||||
DEVICE3: "/dev/sdb"
|
|
||||||
devices:
|
devices:
|
||||||
- /dev/sda
|
- /dev/disk/by-uuid/12345-12345-12345-12345-12345:/disk2
|
||||||
- /dev/sdb
|
- /dev/disk/by-uuid/45678-45678-45678-45678-45678:/disk3
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Make sure to bind the disk via its UUID (obtainable via `lsblk -o name,uuid`) instead of its name (`/dev/sdc`), to prevent ever binding the wrong disk when the drive letters happen to change.
|
||||||
|
|
||||||
Please note that the device needs to be totally empty (without any partition table) otherwise DSM does not always format it into a volume.
|
Please note that the device needs to be totally empty (without any partition table) otherwise DSM does not always format it into a volume.
|
||||||
|
|
||||||
Do NOT use this feature with the goal of sharing files from the host, they will all be lost without warning when DSM creates the volume.
|
Do NOT use this feature with the goal of sharing files from the host, they will all be lost without warning when DSM creates the volume.
|
||||||
@@ -130,7 +129,7 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
|
|||||||
|
|
||||||
By default, a single CPU core and 1 GB of RAM are allocated to the container.
|
By default, a single CPU core and 1 GB of RAM are allocated to the container.
|
||||||
|
|
||||||
To increase this, add the following environment variables:
|
If there arises a need to increase this, add the following environment variables:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
environment:
|
environment:
|
||||||
@@ -194,6 +193,8 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
|
|||||||
```yaml
|
```yaml
|
||||||
environment:
|
environment:
|
||||||
DHCP: "Y"
|
DHCP: "Y"
|
||||||
|
devices:
|
||||||
|
- /dev/vhost-net
|
||||||
device_cgroup_rules:
|
device_cgroup_rules:
|
||||||
- 'c *:* rwm'
|
- 'c *:* rwm'
|
||||||
```
|
```
|
||||||
@@ -232,7 +233,7 @@ docker run -it --rm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
|
|||||||
|
|
||||||
Yes, this project contains only open-source code and does not distribute any copyrighted material. Neither does it try to circumvent any copyright protection measures. So under all applicable laws, this project would be considered legal.
|
Yes, this project contains only open-source code and does not distribute any copyrighted material. Neither does it try to circumvent any copyright protection measures. So under all applicable laws, this project would be considered legal.
|
||||||
|
|
||||||
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.
|
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 container on an official Synology NAS, as any other use will be a violation of their terms and conditions.
|
||||||
|
|
||||||
## Stars
|
## Stars
|
||||||
[](https://starchart.cc/vdsm/virtual-dsm)
|
[](https://starchart.cc/vdsm/virtual-dsm)
|
||||||
@@ -247,5 +248,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
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
|
|
||||||
|
: "${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
|
||||||
|
|
||||||
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")
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
|
|
||||||
DEF_OPTS="-nodefaults -boot strict=on"
|
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')
|
RAM_OPTS=$(echo "-m ${RAM_SIZE^^}" | sed 's/MB/M/g;s/GB/G/g;s/TB/T/g')
|
||||||
CPU_OPTS="-cpu $CPU_FLAGS -smp $CPU_CORES,sockets=1,dies=1,cores=$CPU_CORES,threads=1"
|
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}"
|
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="-device virtio-balloon-pci,id=balloon0,bus=pcie.0,addr=0x4"
|
||||||
@@ -12,4 +12,18 @@ DEV_OPTS="$DEV_OPTS -device virtio-rng-pci,rng=objrng0,id=rng0,bus=pcie.0,addr=0
|
|||||||
ARGS="$DEF_OPTS $CPU_OPTS $RAM_OPTS $MAC_OPTS $DISPLAY_OPTS $MON_OPTS $SERIAL_OPTS $NET_OPTS $DISK_OPTS $DEV_OPTS $ARGUMENTS"
|
ARGS="$DEF_OPTS $CPU_OPTS $RAM_OPTS $MAC_OPTS $DISPLAY_OPTS $MON_OPTS $SERIAL_OPTS $NET_OPTS $DISK_OPTS $DEV_OPTS $ARGUMENTS"
|
||||||
ARGS=$(echo "$ARGS" | sed 's/\t/ /g' | tr -s ' ')
|
ARGS=$(echo "$ARGS" | sed 's/\t/ /g' | tr -s ' ')
|
||||||
|
|
||||||
|
# Check available memory as the very last step
|
||||||
|
|
||||||
|
RAM_AVAIL=$(free -b | grep -m 1 Mem: | awk '{print $7}')
|
||||||
|
AVAIL_GB=$(( (RAM_AVAIL + 1073741823)/1073741824 ))
|
||||||
|
|
||||||
|
if (( (RAM_WANTED + 500000000) > RAM_AVAIL )); then
|
||||||
|
error "Your configured RAM_SIZE of $WANTED_GB GB is higher than the $AVAIL_GB GB of memory available, please set a lower value."
|
||||||
|
exit 17
|
||||||
|
fi
|
||||||
|
|
||||||
|
if (( (RAM_WANTED + 1450000000) > RAM_AVAIL )); then
|
||||||
|
warn "your configured RAM_SIZE of $WANTED_GB GB is much too close to the $AVAIL_GB GB of memory available, please set a lower value."
|
||||||
|
fi
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
96
src/disk.sh
96
src/disk.sh
@@ -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 \
|
||||||
@@ -80,13 +80,23 @@ getSize() {
|
|||||||
isCow() {
|
isCow() {
|
||||||
local FS=$1
|
local FS=$1
|
||||||
|
|
||||||
if [[ "${FS,,}" == "xfs" || "${FS,,}" == "btrfs" || "${FS,,}" == "bcachefs" ]]; then
|
if [[ "${FS,,}" == "btrfs" ]]; then
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
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
|
||||||
@@ -501,28 +527,38 @@ DISK4_FILE="/storage4/data4"
|
|||||||
: "${DEVICE3:=""}"
|
: "${DEVICE3:=""}"
|
||||||
: "${DEVICE4:=""}"
|
: "${DEVICE4:=""}"
|
||||||
|
|
||||||
|
[ -z "$DEVICE" ] && [ -b "/disk1" ] && DEVICE="/disk1"
|
||||||
|
[ -z "$DEVICE2" ] && [ -b "/disk2" ] && DEVICE2="/disk2"
|
||||||
|
[ -z "$DEVICE3" ] && [ -b "/disk3" ] && DEVICE3="/disk3"
|
||||||
|
[ -z "$DEVICE4" ] && [ -b "/disk4" ] && DEVICE4="/disk4"
|
||||||
|
|
||||||
|
[ -z "$DEVICE" ] && [ -b "/dev/disk1" ] && DEVICE="/dev/disk1"
|
||||||
|
[ -z "$DEVICE2" ] && [ -b "/dev/disk2" ] && DEVICE2="/dev/disk2"
|
||||||
|
[ -z "$DEVICE3" ] && [ -b "/dev/disk3" ] && DEVICE3="/dev/disk3"
|
||||||
|
[ -z "$DEVICE4" ] && [ -b "/dev/disk4" ] && DEVICE4="/dev/disk4"
|
||||||
|
|
||||||
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..."
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -32,4 +32,5 @@ terminal
|
|||||||
tail -fn +0 "$QEMU_LOG" 2>/dev/null &
|
tail -fn +0 "$QEMU_LOG" 2>/dev/null &
|
||||||
cat "$QEMU_TERM" 2>/dev/null & wait $! || :
|
cat "$QEMU_TERM" 2>/dev/null & wait $! || :
|
||||||
|
|
||||||
sleep 1 && finish 0
|
sleep 1 & wait $!
|
||||||
|
finish 0
|
||||||
|
|||||||
@@ -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,7 +66,15 @@ 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,,}" != "fat"* && "${FS,,}" != "vfat"* && "${FS,,}" != "exfat"* && "${FS,,}" != "ntfs"* && "${FS,,}" != "msdos"* ]]; then
|
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
|
||||||
|
error "Unable to install on $FS filesystems, please use a different filesystem for /storage." && exit 61
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${FS,,}" != "exfat"* && "${FS,,}" != "ntfs"* && "${FS,,}" != "unknown"* ]]; then
|
||||||
TMP="$STORAGE/tmp"
|
TMP="$STORAGE/tmp"
|
||||||
else
|
else
|
||||||
TMP="/tmp/dsm"
|
TMP="/tmp/dsm"
|
||||||
@@ -102,35 +111,45 @@ 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])..."
|
||||||
info "Install: $MSG" && html "$MSG"
|
info "Install: $MSG" && html "$MSG"
|
||||||
|
|
||||||
RD="$TMP/rd.gz"
|
RD="$TMP/rd.gz"
|
||||||
|
SIZE=5394188
|
||||||
POS="65627648-71021835"
|
POS="65627648-71021835"
|
||||||
VERIFY="b4215a4b213ff5154db0488f92c87864"
|
VERIFY="b4215a4b213ff5154db0488f92c87864"
|
||||||
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"
|
||||||
/run/progress.sh "$RD" "$PRG" &
|
rm -f "$RDC"
|
||||||
{ curl -r "$POS" -sfk -S -o "$RD" "$LOC"; rc=$?; } || :
|
/run/progress.sh "$RD" "$SIZE" "$PRG" &
|
||||||
|
{ curl -r "$POS" -sfk --connect-timeout 10 -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"
|
SIZE=379637760
|
||||||
|
|
||||||
|
rm -f "$RD"
|
||||||
rm -f "$PAT"
|
rm -f "$PAT"
|
||||||
|
|
||||||
html "$MSG"
|
html "$MSG"
|
||||||
/run/progress.sh "$PAT" "$PRG" &
|
/run/progress.sh "$PAT" "$SIZE" "$PRG" &
|
||||||
{ wget "$LOC" -O "$PAT" -q --no-check-certificate --show-progress "$PROGRESS"; rc=$?; } || :
|
{ wget "$LOC" -O "$PAT" -q --no-check-certificate --timeout=10 --show-progress "$PROGRESS"; rc=$?; } || :
|
||||||
|
|
||||||
fKill "progress.sh"
|
fKill "progress.sh"
|
||||||
(( rc != 0 )) && error "Failed to download $LOC , reason: $rc" && exit 60
|
(( rc != 0 )) && error "Failed to download $LOC , reason: $rc" && exit 60
|
||||||
@@ -147,14 +166,14 @@ fi
|
|||||||
if [ -f "$RDC" ]; then
|
if [ -f "$RDC" ]; then
|
||||||
|
|
||||||
{ xz -dc <"$RDC" >"$TMP/rd" 2>/dev/null; rc=$?; } || :
|
{ xz -dc <"$RDC" >"$TMP/rd" 2>/dev/null; rc=$?; } || :
|
||||||
(( rc != 1 )) && error "Failed to unxz $RDC, reason $rc" && exit 91
|
(( rc != 1 )) && error "Failed to unxz $RDC on $FS, reason $rc" && exit 91
|
||||||
|
|
||||||
{ (cd "$TMP" && cpio -idm <"$TMP/rd" 2>/dev/null); rc=$?; } || :
|
{ (cd "$TMP" && cpio -idm <"$TMP/rd" 2>/dev/null); rc=$?; } || :
|
||||||
|
|
||||||
if (( rc != 0 )); then
|
if (( rc != 0 )); then
|
||||||
ROOT="N"
|
ROOT="N"
|
||||||
{ (cd "$TMP" && fakeroot cpio -idmu <"$TMP/rd" 2>/dev/null); rc=$?; } || :
|
{ (cd "$TMP" && fakeroot cpio -idmu <"$TMP/rd" 2>/dev/null); rc=$?; } || :
|
||||||
(( rc != 0 )) && error "Failed to extract $RDC, reason $rc" && exit 92
|
(( rc != 0 )) && error "Failed to extract $RDC on $FS, reason $rc" && exit 92
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -rf /run/extract && mkdir -p /run/extract
|
rm -rf /run/extract && mkdir -p /run/extract
|
||||||
@@ -192,22 +211,25 @@ html "$MSG"
|
|||||||
PAT="/$BASE.pat"
|
PAT="/$BASE.pat"
|
||||||
rm -f "$PAT"
|
rm -f "$PAT"
|
||||||
|
|
||||||
|
SIZE=0
|
||||||
|
[[ "$URL" == *"DSM_VirtualDSM_69057.pat" ]] && SIZE=363837333
|
||||||
|
|
||||||
if [[ "$URL" == "file://"* ]]; then
|
if [[ "$URL" == "file://"* ]]; then
|
||||||
|
|
||||||
cp "${URL:7}" "$PAT"
|
cp "${URL:7}" "$PAT"
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
/run/progress.sh "$PAT" "$PRG" &
|
/run/progress.sh "$PAT" "$SIZE" "$PRG" &
|
||||||
|
|
||||||
{ wget "$URL" -O "$PAT" -q --no-check-certificate --show-progress "$PROGRESS"; rc=$?; } || :
|
{ wget "$URL" -O "$PAT" -q --no-check-certificate --timeout=10 --show-progress "$PROGRESS"; rc=$?; } || :
|
||||||
|
|
||||||
fKill "progress.sh"
|
fKill "progress.sh"
|
||||||
(( rc != 0 )) && error "Failed to download $URL , reason: $rc" && exit 69
|
(( rc != 0 )) && error "Failed to download $URL , reason: $rc" && exit 69
|
||||||
|
|
||||||
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")
|
||||||
|
|
||||||
@@ -244,7 +266,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"
|
||||||
@@ -265,11 +287,11 @@ 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,,}" == "btrfs" || "${FS,,}" == "bcachefs" ]]; then
|
if [[ "${FS,,}" == "btrfs" ]]; then
|
||||||
{ chattr +C "$SYSTEM"; } || :
|
{ chattr +C "$SYSTEM"; } || :
|
||||||
FA=$(lsattr "$SYSTEM")
|
FA=$(lsattr "$SYSTEM")
|
||||||
if [[ "$FA" != *"C"* ]]; then
|
if [[ "$FA" != *"C"* ]]; then
|
||||||
error "Failed to disable COW for system image $SYSTEM on ${FS^^} filesystem (returned $FA)"
|
error "Failed to disable COW for system image $SYSTEM on ${FS^^} filesystem."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -305,15 +327,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"
|
||||||
|
|||||||
121
src/network.sh
121
src/network.sh
@@ -5,6 +5,8 @@ set -Eeuo pipefail
|
|||||||
|
|
||||||
: "${MAC:=""}"
|
: "${MAC:=""}"
|
||||||
: "${DHCP:="N"}"
|
: "${DHCP:="N"}"
|
||||||
|
: "${NETWORK:="Y"}"
|
||||||
|
: "${HOST_PORTS:=""}"
|
||||||
|
|
||||||
: "${VM_NET_DEV:=""}"
|
: "${VM_NET_DEV:=""}"
|
||||||
: "${VM_NET_TAP:="dsm"}"
|
: "${VM_NET_TAP:="dsm"}"
|
||||||
@@ -23,13 +25,19 @@ ADD_ERR="Please add the following setting to your container:"
|
|||||||
|
|
||||||
configureDHCP() {
|
configureDHCP() {
|
||||||
|
|
||||||
# Create a macvtap network for the VM guest
|
# Create the necessary file structure for /dev/vhost-net
|
||||||
|
if [ ! -c /dev/vhost-net ]; then
|
||||||
|
if mknod /dev/vhost-net c 10 238; then
|
||||||
|
chmod 660 /dev/vhost-net
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create a macvtap network for the VM guest
|
||||||
{ 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
|
||||||
@@ -96,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
|
||||||
@@ -107,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'
|
||||||
@@ -136,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..."
|
||||||
@@ -149,19 +177,27 @@ 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"
|
||||||
|
|
||||||
{ exec 40>>/dev/vhost-net; rc=$?; } 2>/dev/null || :
|
if [ -c /dev/vhost-net ]; then
|
||||||
(( rc == 0 )) && NET_OPTS="$NET_OPTS,vhost=on,vhostfd=40"
|
{ exec 40>>/dev/vhost-net; rc=$?; } 2>/dev/null || :
|
||||||
|
(( rc == 0 )) && NET_OPTS="$NET_OPTS,vhost=on,vhostfd=40"
|
||||||
|
fi
|
||||||
|
|
||||||
configureDNS
|
configureDNS
|
||||||
|
|
||||||
@@ -170,22 +206,28 @@ configureNAT() {
|
|||||||
|
|
||||||
closeNetwork() {
|
closeNetwork() {
|
||||||
|
|
||||||
exec 30<&- || true
|
|
||||||
exec 40<&- || true
|
|
||||||
|
|
||||||
if [[ "$DHCP" == [Yy1]* ]]; then
|
if [[ "$DHCP" == [Yy1]* ]]; then
|
||||||
|
|
||||||
# Shutdown nginx
|
# Shutdown nginx
|
||||||
nginx -s stop 2> /dev/null
|
nginx -s stop 2> /dev/null
|
||||||
fWait "nginx"
|
fWait "nginx"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ "$NETWORK" != [Yy1]* ]] && return 0
|
||||||
|
|
||||||
|
exec 30<&- || true
|
||||||
|
exec 40<&- || true
|
||||||
|
|
||||||
|
if [[ "$DHCP" == [Yy1]* ]]; then
|
||||||
|
|
||||||
ip link set "$VM_NET_TAP" down || true
|
ip link set "$VM_NET_TAP" down || true
|
||||||
ip link delete "$VM_NET_TAP" || true
|
ip link delete "$VM_NET_TAP" || true
|
||||||
|
|
||||||
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
|
||||||
@@ -198,6 +240,23 @@ closeNetwork() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkOS() {
|
||||||
|
|
||||||
|
local name
|
||||||
|
local os=""
|
||||||
|
name=$(uname -a)
|
||||||
|
|
||||||
|
[[ "${name,,}" == *"darwin"* ]] && os="MacOS"
|
||||||
|
[[ "${name,,}" == *"microsoft"* ]] && os="Windows"
|
||||||
|
|
||||||
|
if [ -n "$os" ]; then
|
||||||
|
error "You are using Docker Desktop for $os which does not support macvlan, please revert to bridge networking!"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
getInfo() {
|
getInfo() {
|
||||||
|
|
||||||
if [ -z "$VM_NET_DEV" ]; then
|
if [ -z "$VM_NET_DEV" ]; then
|
||||||
@@ -212,8 +271,13 @@ getInfo() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$VM_NET_MAC" ]; then
|
if [ -z "$VM_NET_MAC" ]; then
|
||||||
# Generate MAC address based on Docker container ID in hostname
|
local file="$STORAGE/dsm.mac"
|
||||||
VM_NET_MAC=$(echo "$HOST" | md5sum | sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:11:32:\3:\4:\5/')
|
[ -s "$file" ] && VM_NET_MAC=$(<"$file")
|
||||||
|
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/')
|
||||||
|
echo "${VM_NET_MAC^^}" > "$file"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
VM_NET_MAC="${VM_NET_MAC^^}"
|
VM_NET_MAC="${VM_NET_MAC^^}"
|
||||||
@@ -239,10 +303,9 @@ getInfo() {
|
|||||||
# Configure Network
|
# Configure Network
|
||||||
# ######################################
|
# ######################################
|
||||||
|
|
||||||
if [ ! -c /dev/vhost-net ]; then
|
if [[ "$NETWORK" != [Yy1]* ]]; then
|
||||||
if mknod /dev/vhost-net c 10 238; then
|
NET_OPTS=""
|
||||||
chmod 660 /dev/vhost-net
|
return 0
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
getInfo
|
getInfo
|
||||||
@@ -254,10 +317,16 @@ 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
|
! checkOS && exit 19
|
||||||
error "You can only enable DHCP while the container is on a macvlan network!" && exit 26
|
|
||||||
|
if [[ "$GATEWAY" == "172."* ]]; then
|
||||||
|
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
|
||||||
@@ -268,6 +337,10 @@ if [[ "$DHCP" == [Yy1]* ]]; then
|
|||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
|
if [[ "$GATEWAY" != "172."* ]]; then
|
||||||
|
! checkOS && exit 19
|
||||||
|
fi
|
||||||
|
|
||||||
# Shutdown nginx
|
# Shutdown nginx
|
||||||
nginx -s stop 2> /dev/null
|
nginx -s stop 2> /dev/null
|
||||||
fWait "nginx"
|
fWait "nginx"
|
||||||
|
|||||||
21
src/power.sh
21
src/power.sh
@@ -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 ))
|
||||||
@@ -34,7 +35,9 @@ finish() {
|
|||||||
local pid
|
local pid
|
||||||
local reason=$1
|
local reason=$1
|
||||||
|
|
||||||
if [ -f "$QEMU_PID" ]; then
|
touch "$QEMU_END"
|
||||||
|
|
||||||
|
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..."
|
||||||
@@ -43,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
|
||||||
|
|
||||||
@@ -62,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")
|
||||||
@@ -111,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
|
||||||
@@ -155,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
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
|
|
||||||
: "${DHCP:="N"}"
|
: "${DHCP:="N"}"
|
||||||
|
: "${NETWORK:="Y"}"
|
||||||
|
|
||||||
|
[[ "$NETWORK" != [Yy1]* ]] && exit 0
|
||||||
|
|
||||||
info () { printf "%b%s%b" "\E[1;34m❯ \E[1;36m" "$1" "\E[0m\n" >&2; }
|
info () { printf "%b%s%b" "\E[1;34m❯ \E[1;36m" "$1" "\E[0m\n" >&2; }
|
||||||
error () { printf "%b%s%b" "\E[1;31m❯ " "ERROR: $1" "\E[0m\n" >&2; }
|
error () { printf "%b%s%b" "\E[1;31m❯ " "ERROR: $1" "\E[0m\n" >&2; }
|
||||||
@@ -18,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
|
||||||
@@ -27,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=$?; } || :
|
||||||
@@ -101,3 +104,5 @@ info "-----------------------------------------------------------"
|
|||||||
info " You can now login to DSM at $msg"
|
info " You can now login to DSM at $msg"
|
||||||
info "-----------------------------------------------------------"
|
info "-----------------------------------------------------------"
|
||||||
echo "" >&2
|
echo "" >&2
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|||||||
23
src/proc.sh
23
src/proc.sh
@@ -9,7 +9,7 @@ set -Eeuo pipefail
|
|||||||
: "${CPU_MODEL:=""}"
|
: "${CPU_MODEL:=""}"
|
||||||
: "${DEF_MODEL:="qemu64"}"
|
: "${DEF_MODEL:="qemu64"}"
|
||||||
|
|
||||||
[ "$ARCH" != "amd64" ] && KVM="N"
|
[[ "${ARCH,,}" != "amd64" ]] && KVM="N"
|
||||||
|
|
||||||
if [[ "$KVM" != [Nn]* ]]; then
|
if [[ "$KVM" != [Nn]* ]]; then
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -29,9 +30,17 @@ if [[ "$KVM" != [Nn]* ]]; then
|
|||||||
|
|
||||||
if [ -n "$KVM_ERR" ]; then
|
if [ -n "$KVM_ERR" ]; then
|
||||||
KVM="N"
|
KVM="N"
|
||||||
error "KVM acceleration not available $KVM_ERR, this will cause a major loss of performance."
|
if [[ "$OSTYPE" =~ ^darwin ]]; then
|
||||||
error "See the FAQ on how to enable it, or continue without KVM by setting KVM=N (not recommended)."
|
warn "you are using MacOS which has no KVM support, this will cause a major loss of performance."
|
||||||
[[ "$DEBUG" != [Yy1]* ]] && exit 88
|
else
|
||||||
|
if grep -qi Microsoft /proc/version; then
|
||||||
|
warn "you are using Windows 10 which has no KVM support, this will cause a major loss of performance."
|
||||||
|
else
|
||||||
|
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
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
fi
|
fi
|
||||||
@@ -41,7 +50,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 +98,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
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ escape () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
file="$1"
|
file="$1"
|
||||||
body=$(escape "$2")
|
total="$2"
|
||||||
|
body=$(escape "$3")
|
||||||
info="/run/shm/msg.html"
|
info="/run/shm/msg.html"
|
||||||
|
|
||||||
if [[ "$body" == *"..." ]]; then
|
if [[ "$body" == *"..." ]]; then
|
||||||
@@ -21,10 +22,15 @@ 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/')
|
if [ -z "$total" ] || [[ "$total" == "0" ]]; then
|
||||||
|
size=$(numfmt --to=iec --suffix=B "$bytes" | sed -r 's/([A-Z])/ \1/')
|
||||||
|
else
|
||||||
|
size=$(printf '%.1f\n' "$((bytes*100*100/total))e-2")
|
||||||
|
size="$size%"
|
||||||
|
fi
|
||||||
echo "${body//(\[P\])/($size)}"> "$info"
|
echo "${body//(\[P\])/($size)}"> "$info"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|||||||
47
src/reset.sh
47
src/reset.sh
@@ -1,9 +1,9 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
|
|
||||||
info () { printf "%b%s%b" "\E[1;34m❯ \E[1;36m" "$1" "\E[0m\n"; }
|
info () { printf "%b%s%b" "\E[1;34m❯ \E[1;36m" "${1:-}" "\E[0m\n"; }
|
||||||
error () { printf "%b%s%b" "\E[1;31m❯ " "ERROR: $1" "\E[0m\n" >&2; }
|
error () { printf "%b%s%b" "\E[1;31m❯ " "ERROR: ${1:-}" "\E[0m\n" >&2; }
|
||||||
warn () { printf "%b%s%b" "\E[1;31m❯ " "Warning: $1" "\E[0m\n" >&2; }
|
warn () { printf "%b%s%b" "\E[1;31m❯ " "Warning: ${1:-}" "\E[0m\n" >&2; }
|
||||||
|
|
||||||
trap 'error "Status $? while: $BASH_COMMAND (line $LINENO/$BASH_LINENO)"' ERR
|
trap 'error "Status $? while: $BASH_COMMAND (line $LINENO/$BASH_LINENO)"' ERR
|
||||||
|
|
||||||
@@ -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,12 @@ 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)
|
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 +58,39 @@ 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
|
||||||
|
|
||||||
|
# Read memory
|
||||||
|
RAM_AVAIL=$(free -b | grep -m 1 Mem: | awk '{print $7}')
|
||||||
|
RAM_TOTAL=$(free -b | grep -m 1 Mem: | awk '{print $2}')
|
||||||
|
RAM_SIZE=$(echo "${RAM_SIZE^^}" | sed 's/MB/M/g;s/GB/G/g;s/TB/T/g')
|
||||||
|
RAM_WANTED=$(numfmt --from=iec "$RAM_SIZE")
|
||||||
|
AVAIL_GB=$(( (RAM_AVAIL + 1073741823)/1073741824 ))
|
||||||
|
TOTAL_GB=$(( (RAM_TOTAL + 1073741823)/1073741824 ))
|
||||||
|
WANTED_GB=$(( (RAM_WANTED + 1073741823)/1073741824 ))
|
||||||
|
|
||||||
|
# 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: $AVAIL_GB/$TOTAL_GB GB | DISK: $SPACE_GB GB (${FS}) | HOST: ${SYS}..."
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Check memory
|
||||||
|
|
||||||
|
if (( (RAM_WANTED + 500000000) > RAM_AVAIL )); then
|
||||||
|
error "Your configured RAM_SIZE of $WANTED_GB GB is higher than the $AVAIL_GB GB of memory available, please set a lower value."
|
||||||
|
exit 17
|
||||||
|
fi
|
||||||
|
|
||||||
# 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
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
listen [::]:80;
|
|
||||||
listen 5000 default_server;
|
listen 5000 default_server;
|
||||||
listen [::]:5000 default_server;
|
|
||||||
|
|
||||||
autoindex on;
|
autoindex on;
|
||||||
tcp_nodelay on;
|
tcp_nodelay on;
|
||||||
|
|||||||
Reference in New Issue
Block a user