mirror of
https://github.com/vdsm/virtual-dsm.git
synced 2025-11-06 10:04:52 +08:00
Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9df3c6db6 | ||
|
|
e383ec30e3 | ||
|
|
1197c4791e | ||
|
|
106c684389 | ||
|
|
a199ced77b | ||
|
|
77ac73666e | ||
|
|
64975557c2 | ||
|
|
b62321806a | ||
|
|
7c392082b1 | ||
|
|
392e9a6417 | ||
|
|
fb5f684e7e | ||
|
|
0dbc794223 | ||
|
|
6295ed3b7b | ||
|
|
0f2d889858 | ||
|
|
60e6b01982 | ||
|
|
1dc69f9e22 | ||
|
|
fcca41ad93 | ||
|
|
9897747425 | ||
|
|
4dbe9dcefd | ||
|
|
be8bee90f2 | ||
|
|
f8879029ec | ||
|
|
7b491b3cee | ||
|
|
2ece865417 | ||
|
|
0d8c693c65 | ||
|
|
9f7d1396b6 | ||
|
|
5ad323486e | ||
|
|
19b4248929 | ||
|
|
c135c4cac3 | ||
|
|
fb1751ff26 | ||
|
|
34f32d4ac6 | ||
|
|
36f1e47c0a | ||
|
|
c5dd5c2e46 | ||
|
|
d1d920372a | ||
|
|
12d8fd3ed0 | ||
|
|
729aed536e | ||
|
|
b588f8c90d | ||
|
|
1f1007a0f1 | ||
|
|
2ec37e2802 | ||
|
|
3126b3847b | ||
|
|
41e0157e9d | ||
|
|
1d64410849 | ||
|
|
55034b0f40 | ||
|
|
acffcf3774 | ||
|
|
fba0eb527b | ||
|
|
d9fc2714a6 | ||
|
|
d1f1772d74 | ||
|
|
bf1d47e4f3 | ||
|
|
3da564dfd1 | ||
|
|
abd30b9d91 | ||
|
|
c86408cbd6 | ||
|
|
1f51974c48 | ||
|
|
29f4cde296 | ||
|
|
c4a0035062 | ||
|
|
6724ddbd7d | ||
|
|
8d8ed63122 |
39
.github/ISSUE_TEMPLATE/1-issue.yml
vendored
Normal file
39
.github/ISSUE_TEMPLATE/1-issue.yml
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
name: "\U0001F6A8 Technical issue"
|
||||
description: When you're experiencing problems using the container
|
||||
body:
|
||||
- type: input
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating system
|
||||
description: Your Linux distribution (can be shown by `lsb_release -a`).
|
||||
placeholder: e.g. Ubuntu 24.04
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: summary
|
||||
attributes:
|
||||
label: Description
|
||||
description: A clear and concise description of your issue.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: compose
|
||||
attributes:
|
||||
label: Docker compose
|
||||
description: The compose file (or otherwise the `docker run` command used).
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: log
|
||||
attributes:
|
||||
label: Docker log
|
||||
description: The logfile of the container (as shown by `docker logs dsm`).
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: screenshot
|
||||
attributes:
|
||||
label: Screenshots (optional)
|
||||
description: Screenshots that might help to make the problem more clear.
|
||||
validations:
|
||||
required: false
|
||||
@@ -3,13 +3,6 @@ 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:
|
||||
41
.github/ISSUE_TEMPLATE/3-bug.yml
vendored
Normal file
41
.github/ISSUE_TEMPLATE/3-bug.yml
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
name: "\U0001F41E Bug report"
|
||||
description: Create a report to help us improve the container
|
||||
title: "[Bug]: "
|
||||
labels: ["bug"]
|
||||
body:
|
||||
- type: input
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating system
|
||||
description: Your Linux distribution (can be shown by `lsb_release -a`).
|
||||
placeholder: e.g. Ubuntu 24.04
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: summary
|
||||
attributes:
|
||||
label: Description
|
||||
description: Describe the expected behaviour, the actual behaviour, and the steps to reproduce.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: compose
|
||||
attributes:
|
||||
label: Docker compose
|
||||
description: The compose file (or otherwise the `docker run` command used).
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: log
|
||||
attributes:
|
||||
label: Docker log
|
||||
description: The logfile of the container (as shown by `docker logs dsm`).
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: screenshot
|
||||
attributes:
|
||||
label: Screenshots (optional)
|
||||
description: Screenshots that might help to make the problem more clear.
|
||||
validations:
|
||||
required: false
|
||||
26
.github/ISSUE_TEMPLATE/4-question.yml
vendored
Normal file
26
.github/ISSUE_TEMPLATE/4-question.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
name: "\U00002753 General question"
|
||||
description: Questions about the container not related to an issue
|
||||
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 questions related to issues you must use the [technical issue](https://github.com/vdsm/virtual-dsm/issues/new?assignees=&labels=&projects=&template=1-issue.yml) 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
|
||||
64
.github/ISSUE_TEMPLATE/BUG_REPORT.yml
vendored
64
.github/ISSUE_TEMPLATE/BUG_REPORT.yml
vendored
@@ -1,64 +0,0 @@
|
||||
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
|
||||
16
.github/ISSUE_TEMPLATE/QUESTION.yml
vendored
16
.github/ISSUE_TEMPLATE/QUESTION.yml
vendored
@@ -1,16 +0,0 @@
|
||||
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
|
||||
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
blank_issues_enabled: false
|
||||
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -73,7 +73,7 @@ jobs:
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
-
|
||||
name: Build Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
|
||||
32
Dockerfile
32
Dockerfile
@@ -1,4 +1,4 @@
|
||||
FROM qemux/qemu-host:2.04 as builder
|
||||
FROM qemux/qemu-host:2.05 AS builder
|
||||
|
||||
# FROM golang as builder
|
||||
# WORKDIR /
|
||||
@@ -10,11 +10,13 @@ FROM qemux/qemu-host:2.04 as builder
|
||||
FROM debian:trixie-slim
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
ARG DEBCONF_NOWARNINGS "yes"
|
||||
ARG DEBIAN_FRONTEND "noninteractive"
|
||||
ARG DEBCONF_NONINTERACTIVE_SEEN "true"
|
||||
ARG VERSION_ARG="0.0"
|
||||
ARG DEBCONF_NOWARNINGS="yes"
|
||||
ARG DEBIAN_FRONTEND="noninteractive"
|
||||
ARG DEBCONF_NONINTERACTIVE_SEEN="true"
|
||||
|
||||
RUN if [ "$TARGETPLATFORM" != "linux/amd64" ]; then extra="qemu-user"; fi && \
|
||||
RUN set -eu && extra="" && \
|
||||
if [ "$TARGETPLATFORM" != "linux/amd64" ]; then extra="qemu-user"; fi && \
|
||||
apt-get update && \
|
||||
apt-get --no-install-recommends -y install \
|
||||
jq \
|
||||
@@ -41,24 +43,20 @@ RUN if [ "$TARGETPLATFORM" != "linux/amd64" ]; then extra="qemu-user"; fi && \
|
||||
apt-get clean && \
|
||||
unlink /etc/nginx/sites-enabled/default && \
|
||||
sed -i 's/^worker_processes.*/worker_processes 1;/' /etc/nginx/nginx.conf && \
|
||||
echo "$VERSION_ARG" > /run/version && \
|
||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
COPY ./src /run/
|
||||
COPY ./web /var/www/
|
||||
COPY --from=builder /qemu-host.bin /run/host.bin
|
||||
|
||||
RUN chmod +x /run/*.sh && chmod +x /run/*.bin
|
||||
RUN mv /var/www/nginx.conf /etc/nginx/sites-enabled/web.conf
|
||||
COPY --chmod=755 ./src /run/
|
||||
COPY --chmod=755 ./web /var/www/
|
||||
COPY --chmod=755 --from=builder /qemu-host.bin /run/host.bin
|
||||
COPY --chmod=744 ./web/nginx.conf /etc/nginx/sites-enabled/web.conf
|
||||
|
||||
VOLUME /storage
|
||||
EXPOSE 22 139 445 5000
|
||||
|
||||
ENV RAM_SIZE "1G"
|
||||
ENV DISK_SIZE "16G"
|
||||
ENV CPU_CORES "1"
|
||||
|
||||
ARG VERSION_ARG "0.0"
|
||||
RUN echo "$VERSION_ARG" > /run/version
|
||||
ENV RAM_SIZE="1G"
|
||||
ENV DISK_SIZE="16G"
|
||||
ENV CPU_CORES="1"
|
||||
|
||||
HEALTHCHECK --interval=60s --start-period=45s --retries=2 CMD /run/check.sh
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
version: "3"
|
||||
services:
|
||||
dsm:
|
||||
container_name: dsm
|
||||
@@ -13,5 +12,4 @@ services:
|
||||
- 5000:5000
|
||||
volumes:
|
||||
- /var/dsm:/storage
|
||||
restart: on-failure
|
||||
stop_grace_period: 2m
|
||||
|
||||
59
kubernetes.yml
Normal file
59
kubernetes.yml
Normal file
@@ -0,0 +1,59 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: dsm-pvc
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 16Gi
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: dsm
|
||||
labels:
|
||||
name: dsm
|
||||
spec:
|
||||
terminationGracePeriodSeconds: 120 # the Kubernetes default is 30 seconds and it may be not enough
|
||||
containers:
|
||||
- name: dsm
|
||||
image: vdsm/virtual-dsm
|
||||
ports:
|
||||
- containerPort: 5000
|
||||
protocol: TCP
|
||||
securityContext:
|
||||
privileged: true
|
||||
env:
|
||||
- name: RAM_SIZE
|
||||
value: 1G
|
||||
- name: CPU_CORES
|
||||
value: "1"
|
||||
- name: DISK_SIZE
|
||||
value: "16G" # Kubernetes uses Gi, but DSM uses GB
|
||||
volumeMounts:
|
||||
- mountPath: /storage
|
||||
name: storage
|
||||
- mountPath: /dev/kvm
|
||||
name: dev-kvm
|
||||
volumes:
|
||||
- name: storage
|
||||
persistentVolumeClaim:
|
||||
claimName: dsm-pvc
|
||||
- name: dev-kvm
|
||||
hostPath:
|
||||
path: /dev/kvm
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: dsm
|
||||
spec:
|
||||
type: NodePort
|
||||
selector:
|
||||
name: dsm
|
||||
ports:
|
||||
- name: tcp-5000
|
||||
port: 5000
|
||||
targetPort: 5000
|
||||
130
readme.md
130
readme.md
@@ -7,24 +7,24 @@
|
||||
[![Build]][build_url]
|
||||
[![Version]][tag_url]
|
||||
[![Size]][tag_url]
|
||||
[![Package]][pkg_url]
|
||||
[![Pulls]][hub_url]
|
||||
|
||||
</div></h1>
|
||||
|
||||
Virtual DSM in a Docker container.
|
||||
|
||||
## Features
|
||||
## Features ✨
|
||||
|
||||
- Multiple disks
|
||||
- KVM acceleration
|
||||
- Upgrades supported
|
||||
|
||||
## Usage
|
||||
## Usage 🐳
|
||||
|
||||
Via Docker Compose:
|
||||
|
||||
```yaml
|
||||
version: "3"
|
||||
services:
|
||||
dsm:
|
||||
container_name: dsm
|
||||
@@ -39,19 +39,24 @@ services:
|
||||
- 5000:5000
|
||||
volumes:
|
||||
- /var/dsm:/storage
|
||||
restart: on-failure
|
||||
stop_grace_period: 2m
|
||||
```
|
||||
|
||||
Via Docker CLI:
|
||||
|
||||
```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 -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMIN --stop-timeout 120 vdsm/virtual-dsm
|
||||
```
|
||||
|
||||
## FAQ
|
||||
Via Kubernetes:
|
||||
|
||||
* ### How do I use it?
|
||||
```shell
|
||||
kubectl apply -f kubernetes.yml
|
||||
```
|
||||
|
||||
## FAQ 💬
|
||||
|
||||
### How do I use it?
|
||||
|
||||
Very simple! These are the steps:
|
||||
|
||||
@@ -61,18 +66,7 @@ docker run -it --rm --name dsm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMI
|
||||
|
||||
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:
|
||||
|
||||
@@ -82,8 +76,20 @@ docker run -it --rm --name dsm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMI
|
||||
```
|
||||
|
||||
Replace the example path `/var/dsm` with the desired storage folder.
|
||||
|
||||
### How do I change the size of the disk?
|
||||
|
||||
* ### How do I create a growable 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"
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> 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?
|
||||
|
||||
By default, the entire capacity of the disk is reserved in advance.
|
||||
|
||||
@@ -94,9 +100,10 @@ docker run -it --rm --name dsm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMI
|
||||
DISK_FMT: "qcow2"
|
||||
```
|
||||
|
||||
Please note that this may reduce the write performance of the disk.
|
||||
> [!NOTE]
|
||||
> This may reduce the write performance of the disk.
|
||||
|
||||
* ### How do I add multiple disks?
|
||||
### How do I add multiple disks?
|
||||
|
||||
To create additional disks, modify your compose file like this:
|
||||
|
||||
@@ -109,25 +116,28 @@ docker run -it --rm --name dsm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMI
|
||||
- /mnt/data/example:/storage3
|
||||
```
|
||||
|
||||
* ### How do I pass-through a disk?
|
||||
### How do I pass-through a disk?
|
||||
|
||||
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 a disk device directly, by adding it to your compose file in this way:
|
||||
|
||||
```yaml
|
||||
devices:
|
||||
- /dev/disk/by-uuid/12345-12345-12345-12345-12345:/dev/disk2
|
||||
- /dev/disk/by-uuid/45678-45678-45678-45678-45678:/dev/disk3
|
||||
- /dev/disk/by-uuid/12345-12345-12345-12345-12345:/disk2
|
||||
```
|
||||
|
||||
Please note that the device needs to be totally empty (without any partition table) otherwise DSM does not always format it into a volume.
|
||||
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.
|
||||
|
||||
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.
|
||||
> [!IMPORTANT]
|
||||
> The device needs to be totally empty (without any partition table) otherwise DSM does not always format it into a volume.
|
||||
|
||||
* ### How do I increase the amount of CPU or RAM?
|
||||
> [!CAUTION]
|
||||
> 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.
|
||||
|
||||
By default, a single CPU core and 1 GB of RAM are allocated to the container.
|
||||
### How do I change the amount of CPU or RAM?
|
||||
|
||||
To increase this, add the following environment variables:
|
||||
By default, the container will be allowed to use a maximum of 1 CPU core and 1 GB of RAM.
|
||||
|
||||
If you want to adjust this, you can specify the desired amount using the following environment variables:
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
@@ -135,18 +145,28 @@ docker run -it --rm --name dsm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMI
|
||||
CPU_CORES: "4"
|
||||
```
|
||||
|
||||
* ### How do I verify if my system supports KVM?
|
||||
### How do I verify if my system supports KVM?
|
||||
|
||||
To verify if your system supports KVM, run the following commands:
|
||||
To verify that your system supports KVM, run the following commands:
|
||||
|
||||
```bash
|
||||
sudo apt install cpu-checker
|
||||
sudo kvm-ok
|
||||
```
|
||||
|
||||
If you receive an error from `kvm-ok` indicating that KVM acceleration can't be used, check the virtualization settings in the BIOS.
|
||||
If you receive an error from `kvm-ok` indicating that KVM acceleration can't be used, please check whether:
|
||||
|
||||
* ### How do I assign an individual IP address to the container?
|
||||
- the virtualization extensions (`Intel VT-x` or `AMD SVM`) are enabled in your BIOS.
|
||||
|
||||
- you are running an operating system that supports them, like Linux or Windows 11 (macOS and Windows 10 do not unfortunately).
|
||||
|
||||
- you enabled "nested virtualization" if you are running the container inside a virtual machine.
|
||||
|
||||
- you are not using a cloud provider, as most of them do not allow nested virtualization for their VPS's.
|
||||
|
||||
If you didn't receive any error from `kvm-ok` at all, but the container still complains that `/dev/kvm` is missing, it might help to add `privileged: true` to your compose file (or `--privileged` to your `run` command), to rule out any permission issue.
|
||||
|
||||
### How do I assign an individual IP address to the container?
|
||||
|
||||
By default, the container uses bridge networking, which shares the IP address with the host.
|
||||
|
||||
@@ -180,11 +200,12 @@ docker run -it --rm --name dsm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMI
|
||||
|
||||
An added benefit of this approach is that you won't have to perform any port mapping anymore, since all ports will be exposed by default.
|
||||
|
||||
Please note that this IP address won't be accessible from the Docker host due to the design of macvlan, which doesn't permit communication between the two. If this is a concern, you need to create a [second macvlan](https://blog.oddbit.com/post/2018-03-12-using-docker-macvlan-networks/#host-access) as a workaround.
|
||||
> [!IMPORTANT]
|
||||
> This IP address won't be accessible from the Docker host due to the design of macvlan, which doesn't permit communication between the two. If this is a concern, you need to create a [second macvlan](https://blog.oddbit.com/post/2018-03-12-using-docker-macvlan-networks/#host-access) as a workaround.
|
||||
|
||||
* ### How can DSM acquire an IP address from my router?
|
||||
### How can DSM acquire an IP address from my router?
|
||||
|
||||
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.
|
||||
After configuring the container for [macvlan](#how-do-i-assign-an-individual-ip-address-to-the-container), 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 mode, add the following lines to your compose file:
|
||||
|
||||
@@ -197,9 +218,10 @@ docker run -it --rm --name dsm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMI
|
||||
- 'c *:* rwm'
|
||||
```
|
||||
|
||||
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.
|
||||
> [!NOTE]
|
||||
> In this mode, the container and DSM will each have their own separate IPs.
|
||||
|
||||
* ### How do I pass-through the GPU?
|
||||
### How do I pass-through the GPU?
|
||||
|
||||
To pass-through your Intel GPU, add the following lines to your compose file:
|
||||
|
||||
@@ -210,9 +232,10 @@ docker run -it --rm --name dsm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMI
|
||||
- /dev/dri
|
||||
```
|
||||
|
||||
This can be used to enable the facial recognition function in Synology Photos for example.
|
||||
> [!TIP]
|
||||
> This can be used to enable the facial recognition function in Synology Photos for example.
|
||||
|
||||
* ### How do I install a specific version of vDSM?
|
||||
### How do I install a specific version of vDSM?
|
||||
|
||||
By default, version 7.2 will be installed, but if you prefer an older version, you can add its download URL to your compose file as follows:
|
||||
|
||||
@@ -223,28 +246,39 @@ docker run -it --rm --name dsm -p 5000:5000 --device=/dev/kvm --cap-add NET_ADMI
|
||||
|
||||
With this method, it is even possible to switch between different versions while keeping all your file data intact.
|
||||
|
||||
* ### What are the differences compared to the standard DSM?
|
||||
If you don't have internet access, it's also possible to skip the download by setting URL to:
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
URL: "DSM_VirtualDSM_42218.pat"
|
||||
```
|
||||
|
||||
after placing a file called `DSM_VirtualDSM_42218.pat` in your `/storage` folder.
|
||||
|
||||
### What are the differences compared to the standard DSM?
|
||||
|
||||
There are only two minor differences: the Virtual Machine Manager package is not available, and Surveillance Station will not include any free licenses.
|
||||
|
||||
* ### Is this project legal?
|
||||
### Is this project 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.
|
||||
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 will 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 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)
|
||||
|
||||
## Disclaimer
|
||||
## 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.
|
||||
*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.*
|
||||
|
||||
[build_url]: https://github.com/vdsm/virtual-dsm/
|
||||
[hub_url]: https://hub.docker.com/r/vdsm/virtual-dsm
|
||||
[tag_url]: https://hub.docker.com/r/vdsm/virtual-dsm/tags
|
||||
[pkg_url]: https://github.com/vdsm/virtual-dsm/pkgs/container/virtual-dsm
|
||||
|
||||
[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
|
||||
[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
|
||||
[Package]: https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fipitio.github.io%2Fbackage%2Fvdsm%2Fvirtual-dsm%2Fvirtual-dsm.json&query=%24.downloads&logo=github&style=flat&color=066da5&label=pulls
|
||||
|
||||
@@ -5,7 +5,7 @@ set -Eeuo pipefail
|
||||
|
||||
[ -f "/run/shm/qemu.end" ] && echo "QEMU is shutting down.." && exit 1
|
||||
[ ! -s "/run/shm/qemu.pid" ] && echo "QEMU is not running yet.." && exit 0
|
||||
[[ "$NETWORK" != [Yy1]* ]] && echo "Networking is disabled.." && exit 0
|
||||
[[ "$NETWORK" == [Nn]* ]] && echo "Networking is disabled.." && exit 0
|
||||
|
||||
file="/run/shm/dsm.url"
|
||||
address="/run/shm/qemu.ip"
|
||||
|
||||
@@ -2,14 +2,36 @@
|
||||
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')
|
||||
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"
|
||||
MAC_OPTS="-machine type=q35,usb=off,vmport=off,dump-guest-core=off,hpet=off${KVM_OPTS}"
|
||||
MAC_OPTS="-machine type=q35,smm=off,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"
|
||||
DEV_OPTS+=" -object rng-random,id=objrng0,filename=/dev/urandom"
|
||||
DEV_OPTS+=" -device virtio-rng-pci,rng=objrng0,id=rng0,bus=pcie.0,addr=0x1c"
|
||||
|
||||
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 ' ')
|
||||
|
||||
# Check available memory as the very last step
|
||||
|
||||
if [[ "$RAM_CHECK" != [Nn]* ]]; then
|
||||
|
||||
RAM_AVAIL=$(free -b | grep -m 1 Mem: | awk '{print $7}')
|
||||
AVAIL_GB=$(( RAM_AVAIL/1073741824 ))
|
||||
|
||||
if (( (RAM_WANTED + RAM_SPARE) > RAM_AVAIL )); then
|
||||
error "Your configured RAM_SIZE of $WANTED_GB GB is too high for the $AVAIL_GB GB of memory available, please set a lower value."
|
||||
exit 17
|
||||
fi
|
||||
|
||||
if (( (RAM_WANTED + (RAM_SPARE * 3)) > RAM_AVAIL )); then
|
||||
warn "your configured RAM_SIZE of $WANTED_GB GB is very close to the $AVAIL_GB GB of memory available, please consider a lower value."
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
if [[ "$DEBUG" == [Yy1]* ]]; then
|
||||
printf "Arguments:\n\n%s" "${ARGS// -/$'\n-'}" && echo
|
||||
fi
|
||||
|
||||
return 0
|
||||
|
||||
174
src/disk.sh
174
src/disk.sh
@@ -5,6 +5,7 @@ set -Eeuo pipefail
|
||||
|
||||
: "${DISK_IO:="native"}" # I/O Mode, can be set to 'native', 'threads' or 'io_turing'
|
||||
: "${DISK_FMT:="raw"}" # Disk file format, 'raw' by default for best performance
|
||||
: "${DISK_TYPE:=""}" # Device type to be used, choose "ide", "usb", "blk" or "scsi"
|
||||
: "${DISK_FLAGS:=""}" # Specifies the options for use with the qcow2 disk format
|
||||
: "${DISK_CACHE:="none"}" # Caching mode, can be set to 'writeback' for better performance
|
||||
: "${DISK_DISCARD:="on"}" # Controls whether unmap (TRIM) commands are passed to the host.
|
||||
@@ -16,15 +17,6 @@ SYSTEM="$STORAGE/$BASE.system.img"
|
||||
[ ! -s "$BOOT" ] && error "Virtual DSM boot-image does not exist ($BOOT)" && exit 81
|
||||
[ ! -s "$SYSTEM" ] && error "Virtual DSM system-image does not exist ($SYSTEM)" && exit 82
|
||||
|
||||
DISK_OPTS="\
|
||||
-object iothread,id=io2 \
|
||||
-device virtio-scsi-pci,id=hw-synoboot,iothread=io2,bus=pcie.0,addr=0xa \
|
||||
-drive file=$BOOT,if=none,id=drive-synoboot,format=raw,cache=$DISK_CACHE,aio=$DISK_IO,discard=$DISK_DISCARD,detect-zeroes=on \
|
||||
-device scsi-hd,bus=hw-synoboot.0,channel=0,scsi-id=0,lun=0,drive=drive-synoboot,id=synoboot0,rotation_rate=$DISK_ROTATION,bootindex=1 \
|
||||
-device virtio-scsi-pci,id=hw-synosys,iothread=io2,bus=pcie.0,addr=0xb \
|
||||
-drive file=$SYSTEM,if=none,id=drive-synosys,format=raw,cache=$DISK_CACHE,aio=$DISK_IO,discard=$DISK_DISCARD,detect-zeroes=on \
|
||||
-device scsi-hd,bus=hw-synosys.0,channel=0,scsi-id=0,lun=0,drive=drive-synosys,id=synosys0,rotation_rate=$DISK_ROTATION,bootindex=2"
|
||||
|
||||
fmt2ext() {
|
||||
local DISK_FMT=$1
|
||||
|
||||
@@ -98,6 +90,7 @@ supportsDirect() {
|
||||
}
|
||||
|
||||
createDisk() {
|
||||
|
||||
local DISK_FILE=$1
|
||||
local DISK_SPACE=$2
|
||||
local DISK_DESC=$3
|
||||
@@ -123,9 +116,9 @@ createDisk() {
|
||||
fi
|
||||
|
||||
html "Creating a $DISK_DESC image..."
|
||||
info "Creating a $DISK_SPACE $DISK_TYPE $DISK_DESC image in $DISK_FMT format..."
|
||||
info "Creating a $DISK_SPACE $DISK_STYLE $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)"
|
||||
local FAIL="Could not create a $DISK_STYLE $DISK_FMT $DISK_DESC image of $DISK_SPACE ($DISK_FILE)"
|
||||
|
||||
case "${DISK_FMT,,}" in
|
||||
raw)
|
||||
@@ -160,8 +153,8 @@ createDisk() {
|
||||
qcow2)
|
||||
|
||||
local DISK_PARAM="$DISK_ALLOC"
|
||||
isCow "$FS" && DISK_PARAM="$DISK_PARAM,nocow=on"
|
||||
[ -n "$DISK_FLAGS" ] && DISK_PARAM="$DISK_PARAM,$DISK_FLAGS"
|
||||
isCow "$FS" && DISK_PARAM+=",nocow=on"
|
||||
[ -n "$DISK_FLAGS" ] && DISK_PARAM+=",$DISK_FLAGS"
|
||||
|
||||
if ! qemu-img create -f "$DISK_FMT" -o "$DISK_PARAM" -- "$DISK_FILE" "$DATA_SIZE" ; then
|
||||
rm -f "$DISK_FILE"
|
||||
@@ -181,6 +174,7 @@ createDisk() {
|
||||
}
|
||||
|
||||
resizeDisk() {
|
||||
|
||||
local DISK_FILE=$1
|
||||
local DISK_SPACE=$2
|
||||
local DISK_DESC=$3
|
||||
@@ -210,7 +204,7 @@ resizeDisk() {
|
||||
MSG="Resizing $DISK_DESC from ${GB}G to $DISK_SPACE..."
|
||||
info "$MSG" && html "$MSG"
|
||||
|
||||
local FAIL="Could not resize the $DISK_TYPE $DISK_FMT $DISK_DESC image from ${GB}G to $DISK_SPACE ($DISK_FILE)"
|
||||
local FAIL="Could not resize the $DISK_STYLE $DISK_FMT $DISK_DESC image from ${GB}G to $DISK_SPACE ($DISK_FILE)"
|
||||
|
||||
case "${DISK_FMT,,}" in
|
||||
raw)
|
||||
@@ -246,6 +240,7 @@ resizeDisk() {
|
||||
}
|
||||
|
||||
convertDisk() {
|
||||
|
||||
local SOURCE_FILE=$1
|
||||
local SOURCE_FMT=$2
|
||||
local DST_FILE=$3
|
||||
@@ -276,34 +271,35 @@ convertDisk() {
|
||||
fi
|
||||
fi
|
||||
|
||||
html "Converting $DISK_DESC to $DST_FMT..."
|
||||
info "Converting $DISK_DESC to $DST_FMT, please wait until completed..."
|
||||
local msg="Converting $DISK_DESC to $DST_FMT"
|
||||
html "$msg..."
|
||||
info "$msg, please wait until completed..."
|
||||
|
||||
local CONV_FLAGS="-p"
|
||||
local DISK_PARAM="$DISK_ALLOC"
|
||||
isCow "$FS" && DISK_PARAM="$DISK_PARAM,nocow=on"
|
||||
isCow "$FS" && DISK_PARAM+=",nocow=on"
|
||||
|
||||
if [[ "$DST_FMT" != "raw" ]]; then
|
||||
if [[ "$ALLOCATE" == [Nn]* ]]; then
|
||||
CONV_FLAGS="$CONV_FLAGS -c"
|
||||
fi
|
||||
[ -n "$DISK_FLAGS" ] && DISK_PARAM="$DISK_PARAM,$DISK_FLAGS"
|
||||
if [[ "$ALLOCATE" == [Nn]* ]]; then
|
||||
CONV_FLAGS+=" -c"
|
||||
fi
|
||||
[ -n "$DISK_FLAGS" ] && DISK_PARAM+=",$DISK_FLAGS"
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
if ! qemu-img convert -f "$SOURCE_FMT" $CONV_FLAGS -o "$DISK_PARAM" -O "$DST_FMT" -- "$SOURCE_FILE" "$TMP_FILE"; then
|
||||
rm -f "$TMP_FILE"
|
||||
error "Failed to convert $DISK_TYPE $DISK_DESC image to $DST_FMT format in $DIR, is there enough space available?" && exit 79
|
||||
error "Failed to convert $DISK_STYLE $DISK_DESC image to $DST_FMT format in $DIR, is there enough space available?" && exit 79
|
||||
fi
|
||||
|
||||
if [[ "$DST_FMT" == "raw" ]]; then
|
||||
if [[ "$ALLOCATE" != [Nn]* ]]; then
|
||||
# Work around qemu-img bug
|
||||
CUR_SIZE=$(stat -c%s "$TMP_FILE")
|
||||
if ! fallocate -l "$CUR_SIZE" "$TMP_FILE"; then
|
||||
error "Failed to allocate $CUR_SIZE bytes for $DISK_DESC image $TMP_FILE"
|
||||
fi
|
||||
if [[ "$ALLOCATE" != [Nn]* ]]; then
|
||||
# Work around qemu-img bug
|
||||
CUR_SIZE=$(stat -c%s "$TMP_FILE")
|
||||
if ! fallocate -l "$CUR_SIZE" "$TMP_FILE"; then
|
||||
error "Failed to allocate $CUR_SIZE bytes for $DISK_DESC image $TMP_FILE"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -f "$SOURCE_FILE"
|
||||
@@ -316,13 +312,15 @@ convertDisk() {
|
||||
fi
|
||||
fi
|
||||
|
||||
html "Conversion of $DISK_DESC completed..."
|
||||
info "Conversion of $DISK_DESC to $DST_FMT completed succesfully!"
|
||||
msg="Conversion of $DISK_DESC"
|
||||
html "$msg completed..."
|
||||
info "$msg to $DST_FMT completed succesfully!"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
checkFS () {
|
||||
|
||||
local FS=$1
|
||||
local DISK_FILE=$2
|
||||
local DISK_DESC=$3
|
||||
@@ -357,27 +355,54 @@ checkFS () {
|
||||
|
||||
createDevice () {
|
||||
|
||||
local DISK_ID=$1
|
||||
local DISK_FILE=$2
|
||||
local DISK_FILE=$1
|
||||
local DISK_TYPE=$2
|
||||
local DISK_INDEX=$3
|
||||
local DISK_ADDRESS=$4
|
||||
local DISK_FMT=$5
|
||||
local DISK_IO=$6
|
||||
local DISK_CACHE=$7
|
||||
local DISK_ID="data$DISK_INDEX"
|
||||
|
||||
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"
|
||||
local index=""
|
||||
[ -n "$DISK_INDEX" ] && index=",bootindex=$DISK_INDEX"
|
||||
local result=" -drive file=$DISK_FILE,id=$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 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"
|
||||
case "${DISK_TYPE,,}" in
|
||||
"auto" )
|
||||
echo "$result"
|
||||
;;
|
||||
"usb" )
|
||||
result+=",if=none \
|
||||
-device usb-storage,drive=${DISK_ID}${index}"
|
||||
echo "$result"
|
||||
;;
|
||||
"ide" )
|
||||
result+=",if=none \
|
||||
-device ich9-ahci,id=ahci${DISK_INDEX},addr=$DISK_ADDRESS \
|
||||
-device ide-hd,drive=${DISK_ID},bus=ahci$DISK_INDEX.0,rotation_rate=$DISK_ROTATION${index}"
|
||||
echo "$result"
|
||||
;;
|
||||
"blk" | "virtio-blk" )
|
||||
result+=",if=none \
|
||||
-device virtio-blk-pci,drive=${DISK_ID},scsi=off,bus=pcie.0,addr=$DISK_ADDRESS,iothread=io2${index}"
|
||||
echo "$result"
|
||||
;;
|
||||
"scsi" | "virtio-scsi" )
|
||||
result+=",if=none \
|
||||
-device virtio-scsi-pci,id=${DISK_ID}b,bus=pcie.0,addr=$DISK_ADDRESS,iothread=io2 \
|
||||
-device scsi-hd,drive=${DISK_ID},bus=${DISK_ID}b.0,channel=0,scsi-id=0,lun=0,rotation_rate=$DISK_ROTATION${index}"
|
||||
echo "$result"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "$result"
|
||||
return 0
|
||||
}
|
||||
|
||||
addDisk () {
|
||||
|
||||
local DISK_BASE=$1
|
||||
local DISK_EXT=$2
|
||||
local DISK_TYPE=$2
|
||||
local DISK_DESC=$3
|
||||
local DISK_SPACE=$4
|
||||
local DISK_INDEX=$5
|
||||
@@ -385,23 +410,25 @@ addDisk () {
|
||||
local DISK_FMT=$7
|
||||
local DISK_IO=$8
|
||||
local DISK_CACHE=$9
|
||||
local DISK_ID="userdata$DISK_INDEX"
|
||||
local DISK_EXT DIR DATA_SIZE FS PREV_FMT PREV_EXT CUR_SIZE OPTS
|
||||
|
||||
DISK_EXT=$(fmt2ext "$DISK_FMT")
|
||||
local DISK_FILE="$DISK_BASE.$DISK_EXT"
|
||||
local DIR DATA_SIZE FS PREV_FMT PREV_EXT CUR_SIZE OPTS
|
||||
|
||||
DIR=$(dirname "$DISK_FILE")
|
||||
[ ! -d "$DIR" ] && return 0
|
||||
|
||||
[ -z "$DISK_SPACE" ] && DISK_SPACE="16G"
|
||||
DISK_SPACE=$(echo "${DISK_SPACE^^}" | sed 's/MB/M/g;s/GB/G/g;s/TB/T/g')
|
||||
[[ -z "${DISK_SPACE//[0-9]}" ]] && DISK_SPACE="${DISK_SPACE}G"
|
||||
DATA_SIZE=$(numfmt --from=iec "$DISK_SPACE")
|
||||
|
||||
if (( DATA_SIZE < 6442450944 )); then
|
||||
if (( DATA_SIZE < 1 )); then
|
||||
if (( DATA_SIZE < 1 )); then
|
||||
error "Invalid value for ${DISK_DESC^^}_SIZE: $DISK_SPACE" && exit 73
|
||||
else
|
||||
fi
|
||||
|
||||
if (( DATA_SIZE < 6442450944 )); then
|
||||
error "Please increase ${DISK_DESC^^}_SIZE to at least 6 GB." && exit 73
|
||||
fi
|
||||
fi
|
||||
|
||||
FS=$(stat -f -c %T "$DIR")
|
||||
@@ -419,6 +446,7 @@ addDisk () {
|
||||
else
|
||||
PREV_FMT="qcow2"
|
||||
fi
|
||||
|
||||
PREV_EXT=$(fmt2ext "$PREV_FMT")
|
||||
|
||||
if [ -s "$DISK_BASE.$PREV_EXT" ] ; then
|
||||
@@ -440,8 +468,7 @@ addDisk () {
|
||||
|
||||
fi
|
||||
|
||||
OPTS=$(createDevice "$DISK_ID" "$DISK_FILE" "$DISK_INDEX" "$DISK_ADDRESS" "$DISK_FMT" "$DISK_IO" "$DISK_CACHE")
|
||||
DISK_OPTS="$DISK_OPTS $OPTS"
|
||||
DISK_OPTS+=$(createDevice "$DISK_FILE" "$DISK_TYPE" "$DISK_INDEX" "$DISK_ADDRESS" "$DISK_FMT" "$DISK_IO" "$DISK_CACHE")
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -449,24 +476,28 @@ addDisk () {
|
||||
addDevice () {
|
||||
|
||||
local DISK_DEV=$1
|
||||
local DISK_DESC=$2
|
||||
local DISK_TYPE=$2
|
||||
local DISK_INDEX=$3
|
||||
local DISK_ADDRESS=$4
|
||||
local DISK_ID="userdata$DISK_INDEX"
|
||||
|
||||
[ -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
|
||||
|
||||
local OPTS
|
||||
OPTS=$(createDevice "$DISK_ID" "$DISK_DEV" "$DISK_INDEX" "$DISK_ADDRESS" "raw" "$DISK_IO" "$DISK_CACHE")
|
||||
DISK_OPTS="$DISK_OPTS $OPTS"
|
||||
DISK_OPTS+=$(createDevice "$DISK_DEV" "$DISK_TYPE" "$DISK_INDEX" "$DISK_ADDRESS" "raw" "$DISK_IO" "$DISK_CACHE")
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
html "Initializing disks..."
|
||||
|
||||
DISK_EXT=$(fmt2ext "$DISK_FMT")
|
||||
[ -z "${DISK_OPTS:-}" ] && DISK_OPTS=""
|
||||
[ -z "${DISK_TYPE:-}" ] && DISK_TYPE="scsi"
|
||||
[ -z "${DISK_NAME:-}" ] && DISK_NAME="data"
|
||||
|
||||
case "${DISK_TYPE,,}" in
|
||||
"ide" | "usb" | "scsi" | "blk" | "auto" ) ;;
|
||||
* ) error "Invalid DISK_TYPE specified, value \"$DISK_TYPE\" is not recognized!" && exit 80 ;;
|
||||
esac
|
||||
|
||||
if [ -z "$ALLOCATE" ]; then
|
||||
if [[ "${DISK_FMT,,}" == "raw" ]]; then
|
||||
@@ -477,20 +508,23 @@ if [ -z "$ALLOCATE" ]; then
|
||||
fi
|
||||
|
||||
if [[ "$ALLOCATE" == [Nn]* ]]; then
|
||||
DISK_TYPE="growable"
|
||||
DISK_STYLE="growable"
|
||||
DISK_ALLOC="preallocation=off"
|
||||
else
|
||||
DISK_TYPE="preallocated"
|
||||
DISK_STYLE="preallocated"
|
||||
DISK_ALLOC="preallocation=falloc"
|
||||
fi
|
||||
|
||||
DISK1_FILE="$STORAGE/data"
|
||||
DISK_OPTS+=$(createDevice "$BOOT" "$DISK_TYPE" "1" "0xa" "raw" "$DISK_IO" "$DISK_CACHE")
|
||||
DISK_OPTS+=$(createDevice "$SYSTEM" "$DISK_TYPE" "2" "0xb" "raw" "$DISK_IO" "$DISK_CACHE")
|
||||
|
||||
DISK1_FILE="$STORAGE/${DISK_NAME}"
|
||||
if [[ ! -f "$DISK1_FILE.img" ]] && [[ -f "$STORAGE/data${DISK_SIZE}.img" ]]; then
|
||||
# Fallback for legacy installs
|
||||
mv "$STORAGE/data${DISK_SIZE}.img" "$DISK1_FILE.img"
|
||||
fi
|
||||
|
||||
DISK2_FILE="/storage2/data2"
|
||||
DISK2_FILE="/storage2/${DISK_NAME}2"
|
||||
if [ ! -f "$DISK2_FILE.img" ]; then
|
||||
# Fallback for legacy installs
|
||||
FALLBACK="/storage2/data.img"
|
||||
@@ -503,7 +537,7 @@ if [ ! -f "$DISK2_FILE.img" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
DISK3_FILE="/storage3/data3"
|
||||
DISK3_FILE="/storage3/${DISK_NAME}3"
|
||||
if [ ! -f "$DISK3_FILE.img" ]; then
|
||||
# Fallback for legacy installs
|
||||
FALLBACK="/storage3/data.img"
|
||||
@@ -516,7 +550,7 @@ if [ ! -f "$DISK3_FILE.img" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
DISK4_FILE="/storage4/data4"
|
||||
DISK4_FILE="/storage4/${DISK_NAME}4"
|
||||
|
||||
: "${DISK2_SIZE:=""}"
|
||||
: "${DISK3_SIZE:=""}"
|
||||
@@ -527,34 +561,42 @@ DISK4_FILE="/storage4/data4"
|
||||
: "${DEVICE3:=""}"
|
||||
: "${DEVICE4:=""}"
|
||||
|
||||
[ -z "$DEVICE" ] && [ -b "/disk" ] && DEVICE="/disk"
|
||||
[ -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
|
||||
addDevice "$DEVICE" "device" "3" "0xc" || exit $?
|
||||
addDevice "$DEVICE" "$DISK_TYPE" "3" "0xc" || exit $?
|
||||
else
|
||||
addDisk "$DISK1_FILE" "$DISK_EXT" "disk" "$DISK_SIZE" "3" "0xc" "$DISK_FMT" "$DISK_IO" "$DISK_CACHE" || exit $?
|
||||
addDisk "$DISK1_FILE" "$DISK_TYPE" "disk" "$DISK_SIZE" "3" "0xc" "$DISK_FMT" "$DISK_IO" "$DISK_CACHE" || exit $?
|
||||
fi
|
||||
|
||||
if [ -n "$DEVICE2" ]; then
|
||||
addDevice "$DEVICE2" "device2" "4" "0xd" || exit $?
|
||||
addDevice "$DEVICE2" "$DISK_TYPE" "4" "0xd" || exit $?
|
||||
else
|
||||
addDisk "$DISK2_FILE" "$DISK_EXT" "disk2" "$DISK2_SIZE" "4" "0xd" "$DISK_FMT" "$DISK_IO" "$DISK_CACHE" || exit $?
|
||||
addDisk "$DISK2_FILE" "$DISK_TYPE" "disk2" "$DISK2_SIZE" "4" "0xd" "$DISK_FMT" "$DISK_IO" "$DISK_CACHE" || exit $?
|
||||
fi
|
||||
|
||||
if [ -n "$DEVICE3" ]; then
|
||||
addDevice "$DEVICE3" "device3" "5" "0xe" || exit $?
|
||||
addDevice "$DEVICE3" "$DISK_TYPE" "5" "0xe" || exit $?
|
||||
else
|
||||
addDisk "$DISK3_FILE" "$DISK_EXT" "disk3" "$DISK3_SIZE" "5" "0xe" "$DISK_FMT" "$DISK_IO" "$DISK_CACHE" || exit $?
|
||||
addDisk "$DISK3_FILE" "$DISK_TYPE" "disk3" "$DISK3_SIZE" "5" "0xe" "$DISK_FMT" "$DISK_IO" "$DISK_CACHE" || exit $?
|
||||
fi
|
||||
|
||||
if [ -n "$DEVICE4" ]; then
|
||||
addDevice "$DEVICE4" "device4" "6" "0xf" || exit $?
|
||||
addDevice "$DEVICE4" "$DISK_TYPE" "6" "0xf" || exit $?
|
||||
else
|
||||
addDisk "$DISK4_FILE" "$DISK_EXT" "disk4" "$DISK4_SIZE" "6" "0xf" "$DISK_FMT" "$DISK_IO" "$DISK_CACHE" || exit $?
|
||||
addDisk "$DISK4_FILE" "$DISK_TYPE" "disk4" "$DISK4_SIZE" "6" "0xf" "$DISK_FMT" "$DISK_IO" "$DISK_CACHE" || exit $?
|
||||
fi
|
||||
|
||||
DISK_OPTS+=" -object iothread,id=io2"
|
||||
|
||||
html "Initialized disks successfully..."
|
||||
return 0
|
||||
|
||||
@@ -16,7 +16,7 @@ if [[ "$GPU" != [Yy1]* ]] || [[ "$ARCH" != "amd64" ]]; then
|
||||
fi
|
||||
|
||||
DISPLAY_OPTS="-display egl-headless,rendernode=/dev/dri/renderD128"
|
||||
DISPLAY_OPTS="$DISPLAY_OPTS -vga $VGA"
|
||||
DISPLAY_OPTS+=" -vga $VGA"
|
||||
|
||||
[ ! -d /dev/dri ] && mkdir -m 755 /dev/dri
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ cd /run
|
||||
|
||||
trap - ERR
|
||||
|
||||
info "Booting ${APP}..."
|
||||
[[ "$DEBUG" == [Yy1]* ]] && echo "Arguments: $ARGS" && echo
|
||||
version=$(qemu-system-x86_64 --version | head -n 1 | cut -d '(' -f 1 | awk '{ print $NF }')
|
||||
info "Booting $APP using QEMU v$version..."
|
||||
|
||||
if [[ "$CONSOLE" == [Yy]* ]]; then
|
||||
exec qemu-system-x86_64 ${ARGS:+ $ARGS}
|
||||
@@ -33,4 +33,4 @@ tail -fn +0 "$QEMU_LOG" 2>/dev/null &
|
||||
cat "$QEMU_TERM" 2>/dev/null & wait $! || :
|
||||
|
||||
sleep 1 & wait $!
|
||||
finish 0
|
||||
[ ! -f "$QEMU_END" ] && finish 0
|
||||
|
||||
114
src/install.sh
114
src/install.sh
@@ -18,6 +18,13 @@ if [ -n "$URL" ]; then
|
||||
: "${BASE//+/ }"; printf -v BASE '%b' "${_//%/\\x}"
|
||||
BASE=$(echo "$BASE" | sed -e 's/[^A-Za-z0-9._-]/_/g')
|
||||
fi
|
||||
if [[ "${URL,,}" != "http"* ]]; then
|
||||
if [ -s "$STORAGE/$BASE.pat" ]; then
|
||||
URL="file://$STORAGE/$BASE.pat"
|
||||
else
|
||||
error "File $STORAGE/$BASE.pat does not exist!" && exit 65
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -s "$STORAGE/$BASE.boot.img" ]] && [[ -s "$STORAGE/$BASE.system.img" ]]; then
|
||||
@@ -39,7 +46,7 @@ if [ -z "$DL" ]; then
|
||||
[[ "${COUNTRY^^}" == "CN" ]] && DL="$DL_CHINA" || DL="$DL_GLOBAL"
|
||||
fi
|
||||
|
||||
[ -z "$URL" ] && URL="$DL/release/7.2.1/69057-1/DSM_VirtualDSM_69057.pat"
|
||||
[ -z "$URL" ] && URL="$DL/release/7.2.2/72806/DSM_VirtualDSM_72806.pat"
|
||||
|
||||
BASE=$(basename "${URL%%\?*}" .pat)
|
||||
: "${BASE//+/ }"; printf -v BASE '%b' "${_//%/\\x}"
|
||||
@@ -53,8 +60,6 @@ rm -f "$STORAGE/$BASE.agent"
|
||||
rm -f "$STORAGE/$BASE.boot.img"
|
||||
rm -f "$STORAGE/$BASE.system.img"
|
||||
|
||||
[[ "$DEBUG" == [Yy1]* ]] && set -x
|
||||
|
||||
# Check filesystem
|
||||
FS=$(stat -f -c %T "$STORAGE")
|
||||
|
||||
@@ -94,10 +99,10 @@ SPACE=$(df --output=avail -B 1 / | tail -n 1)
|
||||
SPACE_MB=$(( (SPACE + 1048575)/1048576 ))
|
||||
(( ROOT_SPACE > SPACE )) && error "Not enough free space inside the container, have $SPACE_MB MB available but need at least 500 MB." && exit 96
|
||||
|
||||
MIN_SPACE=8589934592
|
||||
MIN_SPACE=15032385536
|
||||
SPACE=$(df --output=avail -B 1 "$STORAGE" | tail -n 1)
|
||||
SPACE_GB=$(( (SPACE + 1073741823)/1073741824 ))
|
||||
(( MIN_SPACE > SPACE )) && error "Not enough free space for installation in $STORAGE, have $SPACE_GB GB available but need at least 8 GB." && exit 94
|
||||
(( MIN_SPACE > SPACE )) && error "Not enough free space for installation in $STORAGE, have $SPACE_GB GB available but need at least 14 GB." && exit 94
|
||||
|
||||
# Check if output is to interactive TTY
|
||||
if [ -t 1 ]; then
|
||||
@@ -109,29 +114,46 @@ fi
|
||||
# Download the required files from the Synology website
|
||||
|
||||
ROOT="Y"
|
||||
RD="$TMP/rd.gz"
|
||||
RDC="$STORAGE/dsm.rd"
|
||||
|
||||
if [ ! -s "$RDC" ]; then
|
||||
|
||||
MSG="Downloading installer..."
|
||||
PRG="Downloading installer ([P])..."
|
||||
info "Install: $MSG" && html "$MSG"
|
||||
|
||||
RD="$TMP/rd.gz"
|
||||
POS="65627648-71021835"
|
||||
VERIFY="b4215a4b213ff5154db0488f92c87864"
|
||||
LOC="$DL/release/7.0.1/42218/DSM_VirtualDSM_42218.pat"
|
||||
if [ ! -s "$RDC" ] && [[ "$URL" == "file://"* ]] && [[ "${URL,,}" == *"_42218.pat" ]]; then
|
||||
|
||||
rm -f "$RD"
|
||||
rm -f "$RDC"
|
||||
/run/progress.sh "$RD" "$PRG" &
|
||||
{ curl -r "$POS" -sfk -S -o "$RD" "$LOC"; rc=$?; } || :
|
||||
|
||||
tar --extract --file="${URL:7}" --directory="$(dirname "$RD")"/. "$(basename "$RD")"
|
||||
cp "$RD" "$RDC"
|
||||
|
||||
fi
|
||||
|
||||
if [ ! -s "$RDC" ]; then
|
||||
|
||||
rm -f "$RD"
|
||||
rm -f "$RDC"
|
||||
|
||||
MSG="Downloading installer"
|
||||
info "Install: $MSG..." && html "$MSG..."
|
||||
|
||||
SIZE=5394188
|
||||
POS="65627648-71021835"
|
||||
VERIFY="b4215a4b213ff5154db0488f92c87864"
|
||||
LOC="$DL/release/7.0.1/42218/DSM_VirtualDSM_42218.pat"
|
||||
[[ "${URL,,}" == *"_42218.pat" ]] && LOC="$URL"
|
||||
|
||||
/run/progress.sh "$RD" "$SIZE" "$MSG ([P])..." &
|
||||
{ curl -r "$POS" -sfk --connect-timeout 10 -S -o "$RD" "$LOC"; rc=$?; } || :
|
||||
|
||||
fKill "progress.sh"
|
||||
|
||||
ERR="Failed to download $LOC"
|
||||
(( rc == 3 )) && error "$ERR , cannot write file (disk full?)" && exit 60
|
||||
(( rc == 4 )) && error "$ERR , network failure!" && exit 60
|
||||
(( rc == 8 )) && error "$ERR , server issued an error response!" && exit 60
|
||||
|
||||
if (( rc != 0 )); then
|
||||
if (( rc != 22 )) && (( rc != 56 )); then
|
||||
error "Failed to download $LOC, reason: $rc" && exit 60
|
||||
error "$ERR , reason: $rc" && exit 60
|
||||
fi
|
||||
SUM="skip"
|
||||
else
|
||||
@@ -141,15 +163,22 @@ if [ ! -s "$RDC" ]; then
|
||||
if [ "$SUM" != "$VERIFY" ]; then
|
||||
|
||||
PAT="/install.pat"
|
||||
SIZE=379637760
|
||||
|
||||
rm -f "$RD"
|
||||
rm -f "$PAT"
|
||||
|
||||
html "$MSG"
|
||||
/run/progress.sh "$PAT" "$PRG" &
|
||||
{ wget "$LOC" -O "$PAT" -q --no-check-certificate --show-progress "$PROGRESS"; rc=$?; } || :
|
||||
html "$MSG..."
|
||||
/run/progress.sh "$PAT" "$SIZE" "$MSG ([P])..." &
|
||||
{ wget "$LOC" -O "$PAT" -q --no-check-certificate --timeout=10 --show-progress "$PROGRESS"; rc=$?; } || :
|
||||
|
||||
fKill "progress.sh"
|
||||
(( rc != 0 )) && error "Failed to download $LOC , reason: $rc" && exit 60
|
||||
|
||||
ERR="Failed to download $LOC"
|
||||
(( rc == 3 )) && error "$ERR , cannot write file (disk full?)" && exit 60
|
||||
(( rc == 4 )) && error "$ERR , network failure!" && exit 60
|
||||
(( rc == 8 )) && error "$ERR , server issued an error response!" && exit 60
|
||||
(( rc != 0 )) && error "$ERR , reason: $rc" && exit 60
|
||||
|
||||
tar --extract --file="$PAT" --directory="$(dirname "$RD")"/. "$(basename "$RD")"
|
||||
rm "$PAT"
|
||||
@@ -201,9 +230,10 @@ rm -rf "$TMP" && mkdir -p "$TMP"
|
||||
|
||||
info "Install: Downloading $BASE.pat..."
|
||||
|
||||
MSG="Downloading DSM..."
|
||||
PRG="Downloading DSM ([P])..."
|
||||
html "$MSG"
|
||||
MSG="Downloading DSM"
|
||||
ERR="Failed to download $URL"
|
||||
|
||||
html "$MSG..."
|
||||
|
||||
PAT="/$BASE.pat"
|
||||
rm -f "$PAT"
|
||||
@@ -214,16 +244,25 @@ if [[ "$URL" == "file://"* ]]; then
|
||||
|
||||
else
|
||||
|
||||
/run/progress.sh "$PAT" "$PRG" &
|
||||
SIZE=0
|
||||
[[ "${URL,,}" == *"_72806.pat" ]] && SIZE=361010261
|
||||
[[ "${URL,,}" == *"_69057.pat" ]] && SIZE=363837333
|
||||
[[ "${URL,,}" == *"_42218.pat" ]] && SIZE=379637760
|
||||
|
||||
{ wget "$URL" -O "$PAT" -q --no-check-certificate --show-progress "$PROGRESS"; rc=$?; } || :
|
||||
/run/progress.sh "$PAT" "$SIZE" "$MSG ([P])..." &
|
||||
|
||||
{ wget "$URL" -O "$PAT" -q --no-check-certificate --timeout=10 --show-progress "$PROGRESS"; rc=$?; } || :
|
||||
|
||||
fKill "progress.sh"
|
||||
(( rc != 0 )) && error "Failed to download $URL , reason: $rc" && exit 69
|
||||
|
||||
(( rc == 3 )) && error "$ERR , cannot write file (disk full?)" && exit 69
|
||||
(( rc == 4 )) && error "$ERR , network failure!" && exit 69
|
||||
(( rc == 8 )) && error "$ERR , server issued an error response!" && exit 69
|
||||
(( rc != 0 )) && error "$ERR , reason: $rc" && exit 69
|
||||
|
||||
fi
|
||||
|
||||
[ ! -s "$PAT" ] && error "Failed to download $URL" && exit 69
|
||||
[ ! -s "$PAT" ] && error "$ERR" && exit 69
|
||||
|
||||
SIZE=$(stat -c%s "$PAT")
|
||||
|
||||
@@ -269,12 +308,12 @@ SYSTEM="$STORAGE/$BASE.system.img"
|
||||
rm -f "$SYSTEM"
|
||||
|
||||
# Check free diskspace
|
||||
SYSTEM_SIZE=4954537983
|
||||
SYSTEM_SIZE=10738466816
|
||||
SPACE=$(df --output=avail -B 1 "$STORAGE" | tail -n 1)
|
||||
SPACE_MB=$(( (SPACE + 1048575)/1048576 ))
|
||||
|
||||
if (( SYSTEM_SIZE > SPACE )); then
|
||||
error "Not enough free space in $STORAGE to create a 5 GB system disk, have only $SPACE_MB MB available." && exit 97
|
||||
error "Not enough free space in $STORAGE to create a 10 GB system disk, have only $SPACE_MB MB available." && exit 97
|
||||
fi
|
||||
|
||||
if ! touch "$SYSTEM"; then
|
||||
@@ -304,8 +343,8 @@ PART="$TMP/partition.fdisk"
|
||||
echo "unit: sectors"
|
||||
echo "sector-size: 512"
|
||||
echo ""
|
||||
echo "${SYSTEM}1 : start= 2048, size= 4980480, type=83"
|
||||
echo "${SYSTEM}2 : start= 4982528, size= 4194304, type=82"
|
||||
echo "${SYSTEM}1 : start= 2048, size= 16777216, type=83"
|
||||
echo "${SYSTEM}2 : start= 16779264, size= 4194304, type=82"
|
||||
} > "$PART"
|
||||
|
||||
sfdisk -q "$SYSTEM" < "$PART"
|
||||
@@ -336,8 +375,8 @@ if [ -s "$IDB.txz" ]; then
|
||||
fi
|
||||
|
||||
LABEL="1.44.1-42218"
|
||||
OFFSET="1048576" # 2048 * 512
|
||||
NUMBLOCKS="622560" # (4980480 * 512) / 4096
|
||||
OFFSET="1048576" # 2048 * 512
|
||||
NUMBLOCKS="2097152" # (16777216 * 512) / 4096
|
||||
MSG="Installing system partition..."
|
||||
|
||||
if [[ "$ROOT" != [Nn]* ]]; then
|
||||
@@ -369,8 +408,7 @@ fi
|
||||
mv -f "$BOOT" "$STORAGE/$BASE.boot.img"
|
||||
rm -rf "$TMP"
|
||||
|
||||
{ set +x; } 2>/dev/null
|
||||
[[ "$DEBUG" == [Yy1]* ]] && echo
|
||||
html "Booting DSM instance..."
|
||||
sleep 1.2
|
||||
|
||||
html "Installation finished successfully..."
|
||||
return 0
|
||||
|
||||
169
src/network.sh
169
src/network.sh
@@ -7,10 +7,12 @@ set -Eeuo pipefail
|
||||
: "${DHCP:="N"}"
|
||||
: "${NETWORK:="Y"}"
|
||||
: "${HOST_PORTS:=""}"
|
||||
: "${USER_PORTS:=""}"
|
||||
|
||||
: "${VM_NET_DEV:=""}"
|
||||
: "${VM_NET_TAP:="dsm"}"
|
||||
: "${VM_NET_MAC:="$MAC"}"
|
||||
: "${VM_NET_IP:="20.20.20.21"}"
|
||||
: "${VM_NET_HOST:="VirtualDSM"}"
|
||||
|
||||
: "${DNSMASQ_OPTS:=""}"
|
||||
@@ -37,7 +39,7 @@ configureDHCP() {
|
||||
|
||||
if (( rc != 0 )); then
|
||||
error "Cannot create macvtap interface. Please make sure that the network type is 'macvlan' and not 'ipvlan',"
|
||||
error "that your kernel is recent (>4) and supports it, and that the container has the NET_ADMIN capability set." && exit 16
|
||||
error "that your kernel is recent (>4) and supports it, and that the container has the NET_ADMIN capability set." && return 1
|
||||
fi
|
||||
|
||||
while ! ip link set "$VM_NET_TAP" up; do
|
||||
@@ -51,25 +53,25 @@ configureDHCP() {
|
||||
|
||||
# Create dev file (there is no udev in container: need to be done manually)
|
||||
IFS=: read -r MAJOR MINOR < <(cat /sys/devices/virtual/net/"$VM_NET_TAP"/tap*/dev)
|
||||
(( MAJOR < 1)) && error "Cannot find: sys/devices/virtual/net/$VM_NET_TAP" && exit 18
|
||||
(( MAJOR < 1)) && error "Cannot find: sys/devices/virtual/net/$VM_NET_TAP" && return 1
|
||||
|
||||
[[ ! -e "$TAP_PATH" ]] && [[ -e "/dev0/${TAP_PATH##*/}" ]] && ln -s "/dev0/${TAP_PATH##*/}" "$TAP_PATH"
|
||||
|
||||
if [[ ! -e "$TAP_PATH" ]]; then
|
||||
{ mknod "$TAP_PATH" c "$MAJOR" "$MINOR" ; rc=$?; } || :
|
||||
(( rc != 0 )) && error "Cannot mknod: $TAP_PATH ($rc)" && exit 20
|
||||
(( rc != 0 )) && error "Cannot mknod: $TAP_PATH ($rc)" && return 1
|
||||
fi
|
||||
|
||||
{ exec 30>>"$TAP_PATH"; rc=$?; } 2>/dev/null || :
|
||||
|
||||
if (( rc != 0 )); then
|
||||
error "Cannot create TAP interface ($rc). $ADD_ERR --device-cgroup-rule='c *:* rwm'" && exit 21
|
||||
error "Cannot create TAP interface ($rc). $ADD_ERR --device-cgroup-rule='c *:* rwm'" && return 1
|
||||
fi
|
||||
|
||||
{ exec 40>>/dev/vhost-net; rc=$?; } 2>/dev/null || :
|
||||
|
||||
if (( rc != 0 )); then
|
||||
error "VHOST can not be found ($rc). $ADD_ERR --device=/dev/vhost-net" && exit 22
|
||||
error "VHOST can not be found ($rc). $ADD_ERR --device=/dev/vhost-net" && return 1
|
||||
fi
|
||||
|
||||
NET_OPTS="-netdev tap,id=hostnet0,vhost=on,vhostfd=40,fd=30"
|
||||
@@ -80,31 +82,49 @@ configureDHCP() {
|
||||
configureDNS() {
|
||||
|
||||
# dnsmasq configuration:
|
||||
DNSMASQ_OPTS="$DNSMASQ_OPTS --dhcp-range=$VM_NET_IP,$VM_NET_IP --dhcp-host=$VM_NET_MAC,,$VM_NET_IP,$VM_NET_HOST,infinite --dhcp-option=option:netmask,255.255.255.0"
|
||||
DNSMASQ_OPTS+=" --dhcp-range=$VM_NET_IP,$VM_NET_IP --dhcp-host=$VM_NET_MAC,,$VM_NET_IP,$VM_NET_HOST,infinite --dhcp-option=option:netmask,255.255.255.0"
|
||||
|
||||
# Create lease file for faster resolve
|
||||
echo "0 $VM_NET_MAC $VM_NET_IP $VM_NET_HOST 01:$VM_NET_MAC" > /var/lib/misc/dnsmasq.leases
|
||||
chmod 644 /var/lib/misc/dnsmasq.leases
|
||||
|
||||
# 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+=" --dhcp-option=option:dns-server,${VM_NET_IP%.*}.1 --dhcp-option=option:router,${VM_NET_IP%.*}.1"
|
||||
|
||||
# Add DNS entry for container
|
||||
DNSMASQ_OPTS="$DNSMASQ_OPTS --address=/host.lan/${VM_NET_IP%.*}.1"
|
||||
DNSMASQ_OPTS+=" --address=/host.lan/${VM_NET_IP%.*}.1"
|
||||
|
||||
DNSMASQ_OPTS=$(echo "$DNSMASQ_OPTS" | sed 's/\t/ /g' | tr -s ' ' | sed 's/^ *//')
|
||||
[[ "$DEBUG" == [Yy1]* ]] && set -x
|
||||
|
||||
if ! $DNSMASQ ${DNSMASQ_OPTS:+ $DNSMASQ_OPTS}; then
|
||||
error "Failed to start dnsmasq, reason: $?" && exit 29
|
||||
error "Failed to start dnsmasq, reason: $?" && return 1
|
||||
fi
|
||||
{ set +x; } 2>/dev/null
|
||||
[[ "$DEBUG" == [Yy1]* ]] && echo
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
getPorts() {
|
||||
getUserPorts() {
|
||||
|
||||
local args=""
|
||||
local list=$1
|
||||
local ssh="22"
|
||||
local dsm="5000"
|
||||
|
||||
[ -z "$list" ] && list="$ssh,$dsm" || list+=",$ssh,$dsm"
|
||||
|
||||
list="${list//,/ }"
|
||||
list="${list## }"
|
||||
list="${list%% }"
|
||||
|
||||
for port in $list; do
|
||||
args+="hostfwd=tcp::$port-$VM_NET_IP:$port,"
|
||||
done
|
||||
|
||||
echo "${args%?}"
|
||||
return 0
|
||||
}
|
||||
|
||||
getHostPorts() {
|
||||
|
||||
local list=$1
|
||||
|
||||
@@ -119,6 +139,17 @@ getPorts() {
|
||||
return 0
|
||||
}
|
||||
|
||||
configureUser() {
|
||||
|
||||
NET_OPTS="-netdev user,id=hostnet0,host=${VM_NET_IP%.*}.1,net=${VM_NET_IP%.*}.0/24,dhcpstart=$VM_NET_IP,hostname=$VM_NET_HOST"
|
||||
|
||||
local forward
|
||||
forward=$(getUserPorts "$USER_PORTS")
|
||||
[ -n "$forward" ] && NET_OPTS+=",$forward"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
configureNAT() {
|
||||
|
||||
# Create the necessary file structure for /dev/net/tun
|
||||
@@ -130,14 +161,14 @@ configureNAT() {
|
||||
fi
|
||||
|
||||
if [ ! -c /dev/net/tun ]; then
|
||||
error "TUN device missing. $ADD_ERR --device /dev/net/tun --cap-add NET_ADMIN" && exit 25
|
||||
error "TUN device missing. $ADD_ERR --device /dev/net/tun --cap-add NET_ADMIN" && return 1
|
||||
fi
|
||||
|
||||
# Check port forwarding flag
|
||||
if [[ $(< /proc/sys/net/ipv4/ip_forward) -eq 0 ]]; then
|
||||
{ sysctl -w net.ipv4.ip_forward=1 > /dev/null; rc=$?; } || :
|
||||
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" && return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -146,15 +177,15 @@ configureNAT() {
|
||||
|
||||
# Create a bridge with a static IP for the VM guest
|
||||
|
||||
VM_NET_IP='20.20.20.21'
|
||||
|
||||
{ ip link add dev dockerbridge type bridge ; rc=$?; } || :
|
||||
|
||||
if (( rc != 0 )); then
|
||||
error "Failed to create bridge. $ADD_ERR --cap-add NET_ADMIN" && exit 23
|
||||
error "Failed to create bridge. $ADD_ERR --cap-add NET_ADMIN" && return 1
|
||||
fi
|
||||
|
||||
ip address add ${VM_NET_IP%.*}.1/24 broadcast ${VM_NET_IP%.*}.255 dev dockerbridge
|
||||
if ! ip address add "${VM_NET_IP%.*}.1/24" broadcast "${VM_NET_IP%.*}.255" dev dockerbridge; then
|
||||
error "Failed to add IP address!" && return 1
|
||||
fi
|
||||
|
||||
while ! ip link set dockerbridge up; do
|
||||
info "Waiting for IP address to become available..."
|
||||
@@ -163,7 +194,7 @@ configureNAT() {
|
||||
|
||||
# QEMU Works with taps, set tap to the bridge created
|
||||
if ! ip tuntap add dev "$VM_NET_TAP" mode tap; then
|
||||
error "$tuntap" && exit 31
|
||||
error "$tuntap" && return 1
|
||||
fi
|
||||
|
||||
while ! ip link set "$VM_NET_TAP" up promisc on; do
|
||||
@@ -171,35 +202,44 @@ configureNAT() {
|
||||
sleep 2
|
||||
done
|
||||
|
||||
ip link set dev "$VM_NET_TAP" master dockerbridge
|
||||
if ! ip link set dev "$VM_NET_TAP" master dockerbridge; then
|
||||
error "Failed to set IP link!" && return 1
|
||||
fi
|
||||
|
||||
# Add internet connection to the VM
|
||||
update-alternatives --set iptables /usr/sbin/iptables-legacy > /dev/null
|
||||
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy > /dev/null
|
||||
|
||||
exclude=$(getPorts "$HOST_PORTS")
|
||||
exclude=$(getHostPorts "$HOST_PORTS")
|
||||
|
||||
if ! iptables -t nat -A POSTROUTING -o "$VM_NET_DEV" -j MASQUERADE; then
|
||||
error "$tables" && exit 30
|
||||
error "$tables" && return 1
|
||||
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"
|
||||
if ! iptables -t nat -A PREROUTING -i "$VM_NET_DEV" -d "$IP" -p tcp${exclude} -j DNAT --to "$VM_NET_IP"; then
|
||||
error "Failed to configure IP tables!" && return 1
|
||||
fi
|
||||
|
||||
if ! iptables -t nat -A PREROUTING -i "$VM_NET_DEV" -d "$IP" -p udp -j DNAT --to "$VM_NET_IP"; then
|
||||
error "Failed to configure IP tables!" && return 1
|
||||
fi
|
||||
|
||||
if (( KERNEL > 4 )); then
|
||||
# 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 > /dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
NET_OPTS="-netdev tap,ifname=$VM_NET_TAP,script=no,downscript=no,id=hostnet0"
|
||||
NET_OPTS="-netdev tap,id=hostnet0,ifname=$VM_NET_TAP"
|
||||
|
||||
if [ -c /dev/vhost-net ]; then
|
||||
{ exec 40>>/dev/vhost-net; rc=$?; } 2>/dev/null || :
|
||||
(( rc == 0 )) && NET_OPTS="$NET_OPTS,vhost=on,vhostfd=40"
|
||||
(( rc == 0 )) && NET_OPTS+=",vhost=on,vhostfd=40"
|
||||
fi
|
||||
|
||||
configureDNS
|
||||
NET_OPTS+=",script=no,downscript=no"
|
||||
|
||||
! configureDNS && return 1
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -214,7 +254,7 @@ closeNetwork() {
|
||||
|
||||
fi
|
||||
|
||||
[[ "$NETWORK" != [Yy1]* ]] && return 0
|
||||
[[ "$NETWORK" == [Nn]* ]] && return 0
|
||||
|
||||
exec 30<&- || true
|
||||
exec 40<&- || true
|
||||
@@ -229,6 +269,8 @@ closeNetwork() {
|
||||
local pid="/var/run/dnsmasq.pid"
|
||||
[ -s "$pid" ] && pKill "$(<"$pid")"
|
||||
|
||||
[[ "${NETWORK,,}" == "user"* ]] && return 0
|
||||
|
||||
ip link set "$VM_NET_TAP" down promisc off || true
|
||||
ip link delete "$VM_NET_TAP" || true
|
||||
|
||||
@@ -240,11 +282,32 @@ closeNetwork() {
|
||||
return 0
|
||||
}
|
||||
|
||||
checkOS() {
|
||||
|
||||
local name
|
||||
local os=""
|
||||
name=$(uname -a)
|
||||
|
||||
[[ "${name,,}" == *"darwin"* ]] && os="MacOS"
|
||||
[[ "${name,,}" == *"microsoft"* ]] && os="Windows"
|
||||
|
||||
if [ -n "$os" ]; then
|
||||
warn "you are using Docker Desktop for $os which does not support macvlan, please revert to bridge networking!"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
getInfo() {
|
||||
|
||||
if [ -z "$VM_NET_DEV" ]; then
|
||||
# Give Kubernetes priority over the default interface
|
||||
[ -d "/sys/class/net/net0" ] && VM_NET_DEV="net0"
|
||||
[ -d "/sys/class/net/net1" ] && VM_NET_DEV="net1"
|
||||
[ -d "/sys/class/net/net2" ] && VM_NET_DEV="net2"
|
||||
[ -d "/sys/class/net/net3" ] && VM_NET_DEV="net3"
|
||||
# Automaticly detect the default network interface
|
||||
VM_NET_DEV=$(awk '$2 == 00000000 { print $1 }' /proc/net/route)
|
||||
[ -z "$VM_NET_DEV" ] && VM_NET_DEV=$(awk '$2 == 00000000 { print $1 }' /proc/net/route)
|
||||
[ -z "$VM_NET_DEV" ] && VM_NET_DEV="eth0"
|
||||
fi
|
||||
|
||||
@@ -275,7 +338,7 @@ getInfo() {
|
||||
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}')
|
||||
GATEWAY=$(ip route list dev "$VM_NET_DEV" | awk ' /^default/ {print $3}')
|
||||
IP=$(ip address show dev "$VM_NET_DEV" | grep inet | awk '/inet / { print $2 }' | cut -f1 -d/)
|
||||
echo "$IP" > /run/shm/qemu.ip
|
||||
|
||||
@@ -286,7 +349,7 @@ getInfo() {
|
||||
# Configure Network
|
||||
# ######################################
|
||||
|
||||
if [[ "$NETWORK" != [Yy1]* ]]; then
|
||||
if [[ "$NETWORK" == [Nn]* ]]; then
|
||||
NET_OPTS=""
|
||||
return 0
|
||||
fi
|
||||
@@ -306,27 +369,55 @@ fi
|
||||
|
||||
if [[ "$DHCP" == [Yy1]* ]]; then
|
||||
|
||||
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)!"
|
||||
checkOS
|
||||
|
||||
if [[ "$IP" == "172."* ]]; then
|
||||
warn "container IP starts with 172.* which is often a sign that you are not on a macvlan network (required for DHCP)!"
|
||||
fi
|
||||
|
||||
# Configuration for DHCP IP
|
||||
configureDHCP
|
||||
# Configure for macvtap interface
|
||||
! configureDHCP && exit 20
|
||||
|
||||
MSG="Booting DSM instance..."
|
||||
html "$MSG"
|
||||
|
||||
else
|
||||
|
||||
if [[ "$IP" != "172."* ]] && [[ "$IP" != "10.8"* ]] && [[ "$IP" != "10.9"* ]]; then
|
||||
checkOS
|
||||
fi
|
||||
|
||||
# Shutdown nginx
|
||||
nginx -s stop 2> /dev/null
|
||||
fWait "nginx"
|
||||
|
||||
# Configuration for static IP
|
||||
configureNAT
|
||||
if [[ "${NETWORK,,}" != "user"* ]]; then
|
||||
|
||||
# Configure for tap interface
|
||||
if ! configureNAT; then
|
||||
|
||||
NETWORK="user"
|
||||
warn "falling back to usermode networking! Performance will be bad and port forwarding will not work."
|
||||
|
||||
ip link set "$VM_NET_TAP" down promisc off &> null || true
|
||||
ip link delete "$VM_NET_TAP" &> null || true
|
||||
|
||||
ip link set dockerbridge down &> null || true
|
||||
ip link delete dockerbridge &> null || true
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
if [[ "${NETWORK,,}" == "user"* ]]; then
|
||||
|
||||
# Configure for usermode networking (slirp)
|
||||
! configureUser && exit 24
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
NET_OPTS="$NET_OPTS -device virtio-net-pci,romfile=,netdev=hostnet0,mac=$VM_NET_MAC,id=net0"
|
||||
NET_OPTS+=" -device virtio-net-pci,romfile=,netdev=hostnet0,mac=$VM_NET_MAC,id=net0"
|
||||
|
||||
return 0
|
||||
|
||||
@@ -176,7 +176,7 @@ MON_OPTS="\
|
||||
|
||||
if [[ "$CONSOLE" != [Yy]* ]]; then
|
||||
|
||||
MON_OPTS="$MON_OPTS -daemonize -D $QEMU_LOG"
|
||||
MON_OPTS+=" -daemonize -D $QEMU_LOG"
|
||||
|
||||
_trap _graceful_shutdown SIGTERM SIGHUP SIGINT SIGABRT SIGQUIT
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ set -Eeuo pipefail
|
||||
: "${DHCP:="N"}"
|
||||
: "${NETWORK:="Y"}"
|
||||
|
||||
[[ "$NETWORK" != [Yy1]* ]] && exit 0
|
||||
[[ "$NETWORK" == [Nn]* ]] && exit 0
|
||||
|
||||
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; }
|
||||
|
||||
65
src/proc.sh
65
src/proc.sh
@@ -9,7 +9,10 @@ set -Eeuo pipefail
|
||||
: "${CPU_MODEL:=""}"
|
||||
: "${DEF_MODEL:="qemu64"}"
|
||||
|
||||
[ "$ARCH" != "amd64" ] && KVM="N"
|
||||
if [[ "${ARCH,,}" != "amd64" ]]; then
|
||||
KVM="N"
|
||||
warn "your CPU architecture is ${ARCH^^} and cannot provide KVM acceleration for x64 instructions, this will cause a major loss of performance."
|
||||
fi
|
||||
|
||||
if [[ "$KVM" != [Nn]* ]]; then
|
||||
|
||||
@@ -30,33 +33,71 @@ if [[ "$KVM" != [Nn]* ]]; then
|
||||
|
||||
if [ -n "$KVM_ERR" ]; then
|
||||
KVM="N"
|
||||
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
|
||||
if [[ "$OSTYPE" =~ ^darwin ]]; then
|
||||
warn "you are using MacOS which has no KVM support, this will cause a major loss of performance."
|
||||
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 diagnose the cause, or continue without KVM by setting KVM=N (not recommended)."
|
||||
[[ "$DEBUG" != [Yy1]* ]] && exit 88
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
if [[ "$KVM" != [Nn]* ]]; then
|
||||
|
||||
CPU_FEATURES="kvm=on,l3-cache=on"
|
||||
CPU_FEATURES="kvm=on,l3-cache=on,+hypervisor"
|
||||
CLOCK="/sys/devices/system/clocksource/clocksource0/current_clocksource"
|
||||
KVM_OPTS=",accel=kvm -enable-kvm -global kvm-pit.lost_tick_policy=discard"
|
||||
|
||||
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..."
|
||||
[ -z "$CPU_MODEL" ] && CPU_MODEL="$DEF_MODEL"
|
||||
CPU_FEATURES="$CPU_FEATURES,+ssse3,+sse4.1,+sse4.2"
|
||||
CPU_FEATURES+=",+ssse3,+sse4.1,+sse4.2"
|
||||
fi
|
||||
|
||||
if [ -z "$CPU_MODEL" ]; then
|
||||
CPU_MODEL="host"
|
||||
CPU_FEATURES="$CPU_FEATURES,migratable=no"
|
||||
CPU_FEATURES+=",migratable=no"
|
||||
fi
|
||||
|
||||
if [ -f "$CLOCK" ]; then
|
||||
CLOCK=$(<"$CLOCK")
|
||||
if [[ "${CLOCK,,}" != "tsc" ]]; then
|
||||
warn "unexpected clocksource: $CLOCK"
|
||||
fi
|
||||
else
|
||||
warn "file \"$CLOCK\" cannot not found?"
|
||||
fi
|
||||
|
||||
if grep -qw "svm" <<< "$flags"; then
|
||||
|
||||
# AMD processor
|
||||
|
||||
if grep -qw "tsc_scale" <<< "$flags"; then
|
||||
CPU_FEATURES+=",+invtsc"
|
||||
fi
|
||||
|
||||
else
|
||||
|
||||
# Intel processor
|
||||
|
||||
vmx=$(sed -ne '/^vmx flags/s/^.*: //p' /proc/cpuinfo)
|
||||
|
||||
if grep -qw "tsc_scaling" <<< "$vmx"; then
|
||||
CPU_FEATURES+=",+invtsc"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
else
|
||||
|
||||
KVM_OPTS=""
|
||||
CPU_FEATURES="l3-cache=on"
|
||||
CPU_FEATURES="l3-cache=on,+hypervisor"
|
||||
|
||||
if [[ "$ARCH" == "amd64" ]]; then
|
||||
KVM_OPTS=" -accel tcg,thread=multi"
|
||||
@@ -65,13 +106,13 @@ else
|
||||
if [ -z "$CPU_MODEL" ]; then
|
||||
if [[ "$ARCH" == "amd64" ]]; then
|
||||
CPU_MODEL="max"
|
||||
CPU_FEATURES="$CPU_FEATURES,migratable=no"
|
||||
CPU_FEATURES+=",migratable=no"
|
||||
else
|
||||
CPU_MODEL="$DEF_MODEL"
|
||||
fi
|
||||
fi
|
||||
|
||||
CPU_FEATURES="$CPU_FEATURES,+ssse3,+sse4.1,+sse4.2"
|
||||
CPU_FEATURES+=",+ssse3,+sse4.1,+sse4.2"
|
||||
|
||||
fi
|
||||
|
||||
@@ -98,9 +139,9 @@ if [ -n "$HOST_CPU" ]; then
|
||||
else
|
||||
HOST_CPU="QEMU, Virtual CPU,"
|
||||
if [ "$ARCH" == "amd64" ]; then
|
||||
HOST_CPU="$HOST_CPU X86_64"
|
||||
HOST_CPU+=" X86_64"
|
||||
else
|
||||
HOST_CPU="$HOST_CPU $ARCH"
|
||||
HOST_CPU+=" $ARCH"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@ escape () {
|
||||
}
|
||||
|
||||
file="$1"
|
||||
body=$(escape "$2")
|
||||
total="$2"
|
||||
body=$(escape "$3")
|
||||
info="/run/shm/msg.html"
|
||||
|
||||
if [[ "$body" == *"..." ]]; then
|
||||
@@ -24,7 +25,12 @@ do
|
||||
if [ -s "$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/')
|
||||
if [ -z "$total" ] || [[ "$total" == "0" ]]; then
|
||||
size=$(numfmt --to=iec --suffix=B "$bytes" | sed -r 's/([A-Z])/ \1/')
|
||||
else
|
||||
size="$(echo "$bytes" "$total" | awk '{printf "%.1f", $1 * 100 / $2}')"
|
||||
size="$size%"
|
||||
fi
|
||||
echo "${body//(\[P\])/($size)}"> "$info"
|
||||
fi
|
||||
fi
|
||||
|
||||
39
src/reset.sh
39
src/reset.sh
@@ -23,6 +23,7 @@ echo "❯ For support visit $SUPPORT"
|
||||
: "${ARGUMENTS:=""}" # Extra QEMU parameters
|
||||
: "${CPU_CORES:="1"}" # Amount of CPU cores
|
||||
: "${RAM_SIZE:="1G"}" # Maximum RAM amount
|
||||
: "${RAM_CHECK:="Y"}" # Check available RAM
|
||||
: "${DISK_SIZE:="16G"}" # Initial data disk size
|
||||
|
||||
# Helper variables
|
||||
@@ -37,13 +38,26 @@ TEMPLATE="/var/www/index.html"
|
||||
FOOTER1="$APP for Docker v$(</run/version)"
|
||||
FOOTER2="<a href='$SUPPORT'>$SUPPORT</a>"
|
||||
|
||||
CPI=$(lscpu)
|
||||
SYS=$(uname -r)
|
||||
HOST=$(hostname -s)
|
||||
KERNEL=$(echo "$SYS" | cut -b 1)
|
||||
MINOR=$(echo "$SYS" | cut -d '.' -f2)
|
||||
ARCH=$(dpkg --print-architecture)
|
||||
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')
|
||||
CORES=$(grep -c '^processor' /proc/cpuinfo)
|
||||
|
||||
if ! grep -qi "socket(s)" <<< "$CPI"; then
|
||||
SOCKETS=1
|
||||
else
|
||||
SOCKETS=$(echo "$CPI" | grep -m 1 -i 'socket(s)' | awk '{print $(2)}')
|
||||
fi
|
||||
|
||||
if ! grep -qi "model name" <<< "$CPI"; then
|
||||
CPU="Unknown"
|
||||
else
|
||||
CPU=$(echo "$CPI" | grep -m 1 -i 'model name' | cut -f 2 -d ":" | awk '{$1=$1}1' | sed 's# @.*##g' | sed s/"(R)"//g | sed 's/[^[:alnum:] ]\+/ /g' | sed 's/ */ /g')
|
||||
CPU="${CPU// with Radeon Graphics/}"
|
||||
fi
|
||||
|
||||
# Check system
|
||||
|
||||
@@ -67,15 +81,34 @@ if [[ "${FS,,}" == "ecryptfs" ]] || [[ "${FS,,}" == "tmpfs" ]]; then
|
||||
DISK_CACHE="writeback"
|
||||
fi
|
||||
|
||||
# Read memory
|
||||
RAM_SPARE=500000000
|
||||
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/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: ${RAM} | DISK: $SPACE_GB GB (${FS}) | HOST: ${SYS}..."
|
||||
echo "❯ CPU: ${CPU} | RAM: $AVAIL_GB/$TOTAL_GB GB | DISK: $SPACE_GB GB (${FS}) | HOST: ${SYS}..."
|
||||
echo
|
||||
|
||||
# Check memory
|
||||
|
||||
if [[ "$RAM_CHECK" != [Nn]* ]]; then
|
||||
if (( (RAM_WANTED + RAM_SPARE) > RAM_AVAIL )); then
|
||||
error "Your configured RAM_SIZE of $WANTED_GB GB is too high for the $AVAIL_GB GB of memory available, please set a lower value."
|
||||
exit 17
|
||||
fi
|
||||
fi
|
||||
|
||||
# Cleanup files
|
||||
rm -f /run/shm/qemu.*
|
||||
rm -f /run/shm/dsm.url
|
||||
|
||||
@@ -67,7 +67,7 @@ else
|
||||
SERIAL_OPTS="-serial mon:stdio"
|
||||
fi
|
||||
|
||||
SERIAL_OPTS="$SERIAL_OPTS \
|
||||
SERIAL_OPTS+=" \
|
||||
-device virtio-serial-pci,id=virtio-serial0,bus=pcie.0,addr=0x3 \
|
||||
-chardev socket,id=charchannel0,host=127.0.0.1,port=12345,reconnect=10 \
|
||||
-device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=vchannel"
|
||||
|
||||
Reference in New Issue
Block a user